头部颜色替换

master
Lee 2022-10-24 11:17:43 +08:00
parent 8f458cfe87
commit 56b25ea84c
17232 changed files with 1788899 additions and 77 deletions

View File

@ -308,7 +308,7 @@ button {
}
::-webkit-scrollbar-thumb {
border-radius: 10px;
background-color: #3b52f6;
background-color: #00db6d;
}
.dot {
overflow: hidden;
@ -363,7 +363,7 @@ body {
box-sizing: border-box;
}
#mb-header #navbar-main #search-ico .iconf {
color: #3b52f6;
color: #00db6d;
font-size: 1.5rem;
}
#mb-header #navbar-main #logo {
@ -420,7 +420,7 @@ body {
width: 50%;
}
#mb-header #sidebar-main .member a.c1 {
background-color: #3b52f6;
background-color: #00db6d;
}
#mb-header #sidebar-main .member a.c2 {
background-color: #ff204f;
@ -437,9 +437,9 @@ body {
#mb-header #sidebar-main-trigger {
width: 26px;
height: 20px;
border-top: 2px solid #3b52f6;
border-bottom: 2px solid #3b52f6;
background-color: #3b52f6;
border-top: 2px solid #00db6d;
border-bottom: 2px solid #00db6d;
background-color: #00db6d;
padding: 7px 0;
background-clip: content-box;
cursor: pointer;
@ -454,7 +454,7 @@ body {
border-bottom: 1px solid #ebebeb;
}
#mb-header #sidebar-main #accordion > li .iconf {
color: #3b52f6;
color: #00db6d;
}
#mb-header #sidebar-main #accordion > li > a {
padding-left: 0.9rem;
@ -480,7 +480,7 @@ div[data-sidebar-main="mask"] {
.pagination .page-link,
.pagination .page-num {
padding: 0.3rem 0.5rem;
border: 1px solid #3b52f6;
border: 1px solid #00db6d;
margin: 0 0.2rem;
border-radius: 0.0.9rem;
}
@ -493,7 +493,7 @@ div[data-sidebar-main="mask"] {
.pagination .page-link:hover,
.pagination .page-num:hover,
.page-num-current {
background-color: #3b52f6;
background-color: #00db6d;
}
.pagination .page-link:hover,
.pagination .page-num:hover,
@ -538,7 +538,7 @@ div[data-sidebar-main="mask"] {
color: #999;
}
.article-content .article-left .article-navi p a:hover {
color: #3b52f6;
color: #00db6d;
}
.article-content .article-right {
width: 18rem;
@ -583,7 +583,7 @@ div[data-sidebar-main="mask"] {
left: 0;
padding: 0.3rem;
font-size: 0.6rem;
background-color: #3b52f6;
background-color: #00db6d;
color: #fff;
}
.article-content .article-right .article-rec .rec-con .txt {
@ -621,7 +621,7 @@ div[data-sidebar-main="mask"] {
.swiper-button {
width: 2rem;
height: 2rem;
border: 1px solid #3b52f6;
border: 1px solid #00db6d;
border-radius: 50%;
}
.swiper-button svg {
@ -649,7 +649,7 @@ div[data-sidebar-main="mask"] {
}
}
.swiper-button:hover {
background-color: #3b52f6;
background-color: #00db6d;
}
.swiper-button:hover::after {
color: #fff;
@ -659,7 +659,7 @@ div[data-sidebar-main="mask"] {
}
.swiper-button::after {
font-size: 0.9rem;
color: #3b52f6;
color: #00db6d;
}
.swiper-button.swiper-button-prev {
left: 0;
@ -681,7 +681,7 @@ div[data-sidebar-main="mask"] {
}
.swiper-pagination .swiper-pagination-bullet.swiper-pagination-bullet-active {
width: 0.9rem;
background-color: #3b52f6;
background-color: #00db6d;
}
.swiper-container-horizontal > .swiper-pagination-progressbar {
bottom: 0;
@ -693,7 +693,7 @@ div[data-sidebar-main="mask"] {
background-color: rgba(255, 255, 255, 0.2);
}
.swiper-pagination-progressbar .swiper-pagination-progressbar-fill {
background-color: #3b52f6;
background-color: #00db6d;
}
.img-radius .img {
border-radius: 0.5rem;
@ -720,8 +720,8 @@ div[data-sidebar-main="mask"] {
padding: 0.6rem 2rem;
font-size: 0.9rem;
border-radius: 2rem;
border: 1px solid #3b52f6;
color: #3b52f6;
border: 1px solid #00db6d;
color: #00db6d;
transition: all ease 0.3s;
line-height: 1 !important;
}
@ -749,18 +749,18 @@ div[data-sidebar-main="mask"] {
.more-btn > span:hover,
.more-btn button:hover {
color: #fff;
background-color: #3b52f6;
background-color: #00db6d;
}
.more-btn1 {
text-align: center;
}
.more-btn1 a {
color: #3b52f6;
border-bottom: 1px solid #3b52f6;
color: #00db6d;
border-bottom: 1px solid #00db6d;
text-transform: capitalize;
}
.c1 {
color: #3b52f6;
color: #00db6d;
}
.c2 {
color: #ff204f;
@ -769,7 +769,7 @@ p {
line-height: 2;
}
.a-hover:hover {
color: #3b52f6;
color: #00db6d;
transform: translateX(0.2rem);
}
.main-title {
@ -808,7 +808,7 @@ p {
font-size: 0.9rem;
}
.par i {
color: #3b52f6;
color: #00db6d;
margin-right: 0.2rem;
}
.par strong {
@ -866,7 +866,7 @@ p {
color: #999;
}
.pagination li.active {
background-color: #3b52f6;
background-color: #00db6d;
}
.pagination li.active a,
.pagination li.active span {
@ -933,7 +933,7 @@ p {
border-radius: 2rem;
font-size: 0.9rem;
color: #fff;
background-color: #3b52f6;
background-color: #00db6d;
margin: 0.9rem auto 0;
cursor: pointer;
}
@ -1041,7 +1041,7 @@ p {
margin-bottom: 0.5rem;
}
.list-banner .con1 .left .tags .list a:hover {
color: #3b52f6;
color: #00db6d;
}
.list-banner .con1 .img {
max-width: 50%;
@ -1070,7 +1070,7 @@ p {
height: 3rem;
background-color: #fff;
border-radius: 0.2rem;
border: 1px solid #3b52f6;
border: 1px solid #00db6d;
position: relative;
}
.list-banner .search-con .inp i {
@ -1098,7 +1098,7 @@ p {
margin-right: 0.9rem;
}
.list-banner .search-con .hot-s a:hover {
color: #3b52f6;
color: #00db6d;
transform: translateX(0.2rem);
}
.list-banner .search-con1 {
@ -1120,7 +1120,7 @@ p {
border-radius: 0.2rem;
background-color: #fff;
border-radius: 0.5rem;
border: 1px solid #3b52f6;
border: 1px solid #00db6d;
position: relative;
}
.list-banner .search-con1 .inp .submit-btn {
@ -1158,7 +1158,7 @@ p {
margin-right: 0.9rem;
}
.list-banner .search-con1 .hot-s a:hover {
color: #3b52f6;
color: #00db6d;
transform: translateX(0.2rem);
}
.list-banner .con2 {
@ -1183,7 +1183,7 @@ p {
margin-right: 0;
}
.list-banner .con2 .filter-container > div p {
color: #3b52f6;
color: #00db6d;
margin-bottom: 0.5rem;
}
.list-banner .con2 .filter-container > div select {
@ -1191,7 +1191,7 @@ p {
height: 2.4rem;
background-color: #fff;
border-radius: 0.2rem;
border: 1px solid #3b52f6;
border: 1px solid #00db6d;
padding: 0 2%;
}
.list-banner .con2 .filter-container > div select,
@ -1237,7 +1237,7 @@ p {
cursor: pointer;
}
.list-banner .con2 .sort-container .selected .clear {
color: #3b52f6;
color: #00db6d;
cursor: pointer;
}
.list-banner .con2 .sort-container .sort {
@ -1253,7 +1253,7 @@ p {
height: 2.4rem;
background-color: #fff;
border-radius: 0.2rem;
border: 1px solid #3b52f6;
border: 1px solid #00db6d;
padding: 0 2%;
cursor: pointer;
}
@ -1340,7 +1340,7 @@ p {
}
.main-QA .content .accordion li.open h5 span {
font-size: 1.3rem;
/*color: #3b52f6;*/
/*color: #00db6d;*/
}
.main-QA .content .accordion li.open h5 i::after {
transform: rotate(0);
@ -1369,7 +1369,7 @@ p {
.main-QA .content .accordion li h5 i {
display: block;
width: 0.9rem;
border-bottom: 2px solid #3b52f6;
border-bottom: 2px solid #00db6d;
position: relative;
}
.main-QA .content .accordion li h5 i::after {
@ -1378,13 +1378,13 @@ p {
top: 0;
left: 0;
width: 100%;
border-bottom: 2px solid #3b52f6;
border-bottom: 2px solid #00db6d;
transform: rotate(-90deg);
transition: all ease 0.3s;
}
.main-QA .content .accordion li h6 {
font-size: 0.9rem;
color: #3b52f6;
color: #00db6d;
margin-top: 0.9rem;
margin-bottom: 0.5rem;
font-weight: 500;
@ -1415,7 +1415,7 @@ p {
}
.main-contact-us .container h4 {
font-size: 1.3rem;
color: #3b52f6;
color: #00db6d;
margin-bottom: 1.3rem;
}
.main-other-qa {
@ -1431,7 +1431,7 @@ p {
box-shadow: 0 0 0.5rem rgba(59, 82, 246, 0.4);
}
.main-other-qa .container > h6 {
color: #3b52f6;
color: #00db6d;
}
.main-other-qa .container .left > p {
font-size: 0.9rem;
@ -1472,7 +1472,7 @@ p {
position: relative;
font-weight: bold;
padding-bottom: 0.3rem;
background-color: #3b52f6;
background-color: #00db6d;
padding: 0.6rem;
color: #fff;
border-radius: 0.2rem;
@ -1545,7 +1545,7 @@ p {
}
.container-mask h5 {
font-size: 0.9rem !important;
color: #3b52f6;
color: #00db6d;
text-align: center;
margin-bottom: 0.9rem;
}
@ -1571,7 +1571,7 @@ p {
align-items: center;
}
.container-mask .price-container .item strong {
color: #3b52f6;
color: #00db6d;
}
.container-mask .price-container .item select {
width: 100%;
@ -1622,7 +1622,7 @@ p {
width: 5rem;
height: 5rem;
border-radius: 50%;
border: 1px solid #3b52f6;
border: 1px solid #00db6d;
display: flex;
flex-direction: column;
align-items: center;
@ -1631,7 +1631,7 @@ p {
}
.container-mask .hint .item .i .iconf {
font-size: 1.3rem;
color: #3b52f6;
color: #00db6d;
}
.container-mask .hint .item p {
font-size: 0.9rem;
@ -1711,7 +1711,7 @@ p {
margin-top: 0.9rem;
}
.container-mask .form-mask button {
background-color: #3b52f6 !important;
background-color: #00db6d !important;
}
.rec-course .container {
display: flex;
@ -1757,7 +1757,7 @@ p {
.rec-course .container .item .text .par-con .icon {
font-weight: bold;
font-size: 0.9rem;
color: #3b52f6;
color: #00db6d;
margin-right: 0.2rem;
display: none;
}
@ -1768,12 +1768,12 @@ p {
justify-content: center;
width: 13rem;
height: 3rem;
border: 1px solid #3b52f6;
border: 1px solid #00db6d;
border-radius: 0.2rem;
color: #3b52f6;
color: #00db6d;
}
.f-btn:hover {
background-color: #3b52f6;
background-color: #00db6d;
color: #fff !important;
}
.hint-search-content {
@ -1809,7 +1809,7 @@ p {
}
.hint-search-content .item .link em {
padding: 0.2rem 0.4rem;
background-color: #3b52f6;
background-color: #00db6d;
color: #fff;
border-radius: 0.0.9rem;
font-size: 0.65rem;
@ -1830,7 +1830,7 @@ header {
header #pc-header > div {
display: flex;
align-items: center;
max-width: 80rem;
max-width: 60rem;
}
header #pc-header > div > ul {
display: flex;
@ -1838,7 +1838,7 @@ header #pc-header > div > ul {
}
header #pc-header > div > ul li > a {
display: inline-block;
height: 5rem;
height: 3.2rem;
margin-left: 0.9rem;
font-family: "robotoMedium";
display: flex;
@ -1849,7 +1849,7 @@ header #pc-header > div > ul li > a {
}
header #pc-header > div > ul li.active a,
header #pc-header > div > ul li:hover a {
color: #3b52f6;
color: #00db6d;
}
header #pc-header > div > ul li:hover .two-menu {
max-height: 30rem;
@ -1862,7 +1862,7 @@ header #pc-header .map {
header #pc-header .map > div {
display: flex;
justify-content: flex-end;
max-width: 80rem;
max-width: 60rem;
}
header #pc-header .map > div a {
height: 2rem;
@ -1872,7 +1872,7 @@ header #pc-header .map > div a {
font-family:'robotoLight'!important;
}
header #pc-header .map > div a:hover {
color: #3b52f6;
color: #00db6d;
}
header #pc-header .logo {
width: 8rem;
@ -1887,7 +1887,7 @@ header #pc-header .search-form select,
header #pc-header .search-form .h-btn {
height: 2rem;
padding: 0 0.3rem;
background-color: #3b52f6;
background-color: #00db6d;
color: #fff;
border-radius: 0.2rem;
font-size: 0.9rem;
@ -1900,7 +1900,7 @@ header #pc-header .search-form .h-btn .iconf {
header #pc-header .search-form > div {
display: flex;
align-items: center;
border: 1px solid #3b52f6;
border: 1px solid #00db6d;
border-radius: 0.2rem;
padding-left: 0.5rem;
margin-left: 0.5rem;
@ -1921,7 +1921,7 @@ header #pc-header .search-form > div .i {
justify-content: center;
width: 3rem;
height: 2rem;
background-color: #3b52f6;
background-color: #00db6d;
margin-right: -1px;
border-radius: 0 0.2rem 0.2rem 0;
}
@ -1983,7 +1983,7 @@ header #pc-header .search-form .content nav ul > li > div:hover {
background-color: #fff;
}
header #pc-header .search-form .content nav ul > li > div:hover * {
color: #3b52f6;
color: #00db6d;
}
header #pc-header .search-form .content nav ul .more-btn {
margin-top: 0.9rem;
@ -2030,9 +2030,9 @@ header #pc-header .search-form .content aside .courses-wrap ol h5 {
}
header #pc-header .search-form .content aside .courses-wrap ol h5 em {
font-size: 0.6rem;
color: #3b52f6;
color: #00db6d;
padding: 0.0.9rem 0.3rem;
border: 1px solid #3b52f6;
border: 1px solid #00db6d;
border-radius: 2rem;
margin-left: 0.5rem;
white-space: nowrap;
@ -2087,7 +2087,7 @@ header #pc-header .search-form .content aside .program-wrap ol > li .field .list
padding: 0.5rem 0;
}
header #pc-header .search-form .content aside .program-wrap ol > li .field .list .iconf {
color: #3b52f6;
color: #00db6d;
font-size: 0.9rem;
}
header #pc-header .search-form .content aside .program-wrap ol > li .field .list label {
@ -2137,7 +2137,7 @@ header #pc-header .search-form .content aside .tit h4 {
line-height: 1;
}
header #pc-header .search-form .content aside .tit .iconf {
color: #3b52f6;
color: #00db6d;
font-size: 1.3rem;
}
header #pc-header .search-form .content aside .tit p {
@ -2170,7 +2170,7 @@ header #pc-header .search-form .content aside ol > li {
width: 100%;
}
header #pc-header .search-form .content aside ol a:hover h5 {
color: #3b52f6;
color: #00db6d;
}
header #pc-header .search-form .search-inp {
position: relative;
@ -2196,7 +2196,7 @@ header #pc-header .right .member p a {
margin: 0 0.3rem;
}
header #pc-header .right .member p a:hover {
color: #3b52f6;
color: #00db6d;
}
header #pc-header .right .member .member-on {
position: relative;
@ -2236,7 +2236,7 @@ header #pc-header .right .h-btn .i {
flex-direction: column;
align-items: center;
justify-content: center;
background-color: #3b52f6;
background-color: #00db6d;
border-radius: 50%;
margin-left: 0.5rem;
position: relative;
@ -2300,7 +2300,7 @@ footer .foot .container ul a {
padding: 0.3rem 0;
}
footer .foot .container ul a:hover {
color: #3b52f6;
color: #00db6d;
transform: translateX(0.2rem);
}
footer .foot .container .copyright {
@ -2325,8 +2325,8 @@ footer .foot .container .copyright .link .item {
justify-content: center;
}
footer .foot .container .copyright .link .item:hover {
border-color: #3b52f6;
background-color: #3b52f6;
border-color: #00db6d;
background-color: #00db6d;
}
footer .foot .container .copyright .link .item:hover i {
color: #fff;
@ -2337,7 +2337,7 @@ footer .foot .container .copyright p * {
font-size: 0.9rem;
}
footer .footer {
background-color: #3b52f6;
background-color: #00db6d;
padding: 2rem 0;
}
footer .footer > div {
@ -2376,7 +2376,7 @@ footer .footer .left .ico .i:hover {
background-color: #fff;
}
footer .footer .left .ico .i:hover i {
color: #3b52f6;
color: #00db6d;
}
footer .footer .left .copyright * {
font-size: 0.9rem;
@ -2412,7 +2412,7 @@ footer .cookie {
bottom: 0;
left: 0;
width: 100%;
background-color: #3b52f6;
background-color: #00db6d;
z-index: 99;
transform: translateY(100%);
}
@ -2427,7 +2427,7 @@ footer .cookie .container p {
}
footer .cookie .container a {
padding: 0.5rem 1.3rem;
color: #3b52f6;
color: #00db6d;
border-radius: 3rem;
background-color: #fff;
white-space: nowrap;
@ -2448,7 +2448,7 @@ footer .cookie .container a {
padding: 0.3rem 0.5rem;
color: #fff;
font-size: 0.9rem;
background-color: #3b52f6;
background-color: #00db6d;
border-radius: 0.0.9rem;
margin-right: 0.9rem;
margin-bottom: 0.9rem;
@ -2473,7 +2473,7 @@ footer .cookie .container a {
border-radius: 0.2rem;
color: #fff;
text-transform: capitalize;
background-color: #3b52f6;
background-color: #00db6d;
font-size: 0.9rem;
white-space: nowrap;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -0,0 +1,21 @@
# The MIT License (MIT)
Copyright (c) 2016-2019 Riku Särkinen
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.

View File

@ -0,0 +1,29 @@
{
"name": "adbario/php-dot-notation",
"description": "PHP dot notation access to arrays",
"keywords": ["dotnotation", "arrayaccess"],
"homepage": "https://github.com/adbario/php-dot-notation",
"license": "MIT",
"authors": [
{
"name": "Riku Särkinen",
"email": "riku@adbar.io"
}
],
"require": {
"php": ">=5.5",
"ext-json": "*"
},
"require-dev": {
"phpunit/phpunit": "^4.0|^5.0|^6.0",
"squizlabs/php_codesniffer": "^3.0"
},
"autoload": {
"files": [
"src/helpers.php"
],
"psr-4": {
"Adbar\\": "src"
}
}
}

View File

@ -0,0 +1,601 @@
<?php
/**
* Dot - PHP dot notation access to arrays
*
* @author Riku Särkinen <riku@adbar.io>
* @link https://github.com/adbario/php-dot-notation
* @license https://github.com/adbario/php-dot-notation/blob/2.x/LICENSE.md (MIT License)
*/
namespace Adbar;
use Countable;
use ArrayAccess;
use ArrayIterator;
use JsonSerializable;
use IteratorAggregate;
/**
* Dot
*
* This class provides a dot notation access and helper functions for
* working with arrays of data. Inspired by Laravel Collection.
*/
class Dot implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable
{
/**
* The stored items
*
* @var array
*/
protected $items = [];
/**
* Create a new Dot instance
*
* @param mixed $items
*/
public function __construct($items = [])
{
$this->items = $this->getArrayItems($items);
}
/**
* Set a given key / value pair or pairs
* if the key doesn't exist already
*
* @param array|int|string $keys
* @param mixed $value
*/
public function add($keys, $value = null)
{
if (is_array($keys)) {
foreach ($keys as $key => $value) {
$this->add($key, $value);
}
} elseif (is_null($this->get($keys))) {
$this->set($keys, $value);
}
}
/**
* Return all the stored items
*
* @return array
*/
public function all()
{
return $this->items;
}
/**
* Delete the contents of a given key or keys
*
* @param array|int|string|null $keys
*/
public function clear($keys = null)
{
if (is_null($keys)) {
$this->items = [];
return;
}
$keys = (array) $keys;
foreach ($keys as $key) {
$this->set($key, []);
}
}
/**
* Delete the given key or keys
*
* @param array|int|string $keys
*/
public function delete($keys)
{
$keys = (array) $keys;
foreach ($keys as $key) {
if ($this->exists($this->items, $key)) {
unset($this->items[$key]);
continue;
}
$items = &$this->items;
$segments = explode('.', $key);
$lastSegment = array_pop($segments);
foreach ($segments as $segment) {
if (!isset($items[$segment]) || !is_array($items[$segment])) {
continue 2;
}
$items = &$items[$segment];
}
unset($items[$lastSegment]);
}
}
/**
* Checks if the given key exists in the provided array.
*
* @param array $array Array to validate
* @param int|string $key The key to look for
*
* @return bool
*/
protected function exists($array, $key)
{
return array_key_exists($key, $array);
}
/**
* Flatten an array with the given character as a key delimiter
*
* @param string $delimiter
* @param array|null $items
* @param string $prepend
* @return array
*/
public function flatten($delimiter = '.', $items = null, $prepend = '')
{
$flatten = [];
if (is_null($items)) {
$items = $this->items;
}
foreach ($items as $key => $value) {
if (is_array($value) && !empty($value)) {
$flatten = array_merge(
$flatten,
$this->flatten($delimiter, $value, $prepend.$key.$delimiter)
);
} else {
$flatten[$prepend.$key] = $value;
}
}
return $flatten;
}
/**
* Return the value of a given key
*
* @param int|string|null $key
* @param mixed $default
* @return mixed
*/
public function get($key = null, $default = null)
{
if (is_null($key)) {
return $this->items;
}
if ($this->exists($this->items, $key)) {
return $this->items[$key];
}
if (strpos($key, '.') === false) {
return $default;
}
$items = $this->items;
foreach (explode('.', $key) as $segment) {
if (!is_array($items) || !$this->exists($items, $segment)) {
return $default;
}
$items = &$items[$segment];
}
return $items;
}
/**
* Return the given items as an array
*
* @param mixed $items
* @return array
*/
protected function getArrayItems($items)
{
if (is_array($items)) {
return $items;
} elseif ($items instanceof self) {
return $items->all();
}
return (array) $items;
}
/**
* Check if a given key or keys exists
*
* @param array|int|string $keys
* @return bool
*/
public function has($keys)
{
$keys = (array) $keys;
if (!$this->items || $keys === []) {
return false;
}
foreach ($keys as $key) {
$items = $this->items;
if ($this->exists($items, $key)) {
continue;
}
foreach (explode('.', $key) as $segment) {
if (!is_array($items) || !$this->exists($items, $segment)) {
return false;
}
$items = $items[$segment];
}
}
return true;
}
/**
* Check if a given key or keys are empty
*
* @param array|int|string|null $keys
* @return bool
*/
public function isEmpty($keys = null)
{
if (is_null($keys)) {
return empty($this->items);
}
$keys = (array) $keys;
foreach ($keys as $key) {
if (!empty($this->get($key))) {
return false;
}
}
return true;
}
/**
* Merge a given array or a Dot object with the given key
* or with the whole Dot object
*
* @param array|string|self $key
* @param array|self $value
*/
public function merge($key, $value = [])
{
if (is_array($key)) {
$this->items = array_merge($this->items, $key);
} elseif (is_string($key)) {
$items = (array) $this->get($key);
$value = array_merge($items, $this->getArrayItems($value));
$this->set($key, $value);
} elseif ($key instanceof self) {
$this->items = array_merge($this->items, $key->all());
}
}
/**
* Recursively merge a given array or a Dot object with the given key
* or with the whole Dot object.
*
* Duplicate keys are converted to arrays.
*
* @param array|string|self $key
* @param array|self $value
*/
public function mergeRecursive($key, $value = [])
{
if (is_array($key)) {
$this->items = array_merge_recursive($this->items, $key);
} elseif (is_string($key)) {
$items = (array) $this->get($key);
$value = array_merge_recursive($items, $this->getArrayItems($value));
$this->set($key, $value);
} elseif ($key instanceof self) {
$this->items = array_merge_recursive($this->items, $key->all());
}
}
/**
* Recursively merge a given array or a Dot object with the given key
* or with the whole Dot object.
*
* Instead of converting duplicate keys to arrays, the value from
* given array will replace the value in Dot object.
*
* @param array|string|self $key
* @param array|self $value
*/
public function mergeRecursiveDistinct($key, $value = [])
{
if (is_array($key)) {
$this->items = $this->arrayMergeRecursiveDistinct($this->items, $key);
} elseif (is_string($key)) {
$items = (array) $this->get($key);
$value = $this->arrayMergeRecursiveDistinct($items, $this->getArrayItems($value));
$this->set($key, $value);
} elseif ($key instanceof self) {
$this->items = $this->arrayMergeRecursiveDistinct($this->items, $key->all());
}
}
/**
* Merges two arrays recursively. In contrast to array_merge_recursive,
* duplicate keys are not converted to arrays but rather overwrite the
* value in the first array with the duplicate value in the second array.
*
* @param array $array1 Initial array to merge
* @param array $array2 Array to recursively merge
* @return array
*/
protected function arrayMergeRecursiveDistinct(array $array1, array $array2)
{
$merged = &$array1;
foreach ($array2 as $key => $value) {
if (is_array($value) && isset($merged[$key]) && is_array($merged[$key])) {
$merged[$key] = $this->arrayMergeRecursiveDistinct($merged[$key], $value);
} else {
$merged[$key] = $value;
}
}
return $merged;
}
/**
* Return the value of a given key and
* delete the key
*
* @param int|string|null $key
* @param mixed $default
* @return mixed
*/
public function pull($key = null, $default = null)
{
if (is_null($key)) {
$value = $this->all();
$this->clear();
return $value;
}
$value = $this->get($key, $default);
$this->delete($key);
return $value;
}
/**
* Push a given value to the end of the array
* in a given key
*
* @param mixed $key
* @param mixed $value
*/
public function push($key, $value = null)
{
if (is_null($value)) {
$this->items[] = $key;
return;
}
$items = $this->get($key);
if (is_array($items) || is_null($items)) {
$items[] = $value;
$this->set($key, $items);
}
}
/**
* Replace all values or values within the given key
* with an array or Dot object
*
* @param array|string|self $key
* @param array|self $value
*/
public function replace($key, $value = [])
{
if (is_array($key)) {
$this->items = array_replace($this->items, $key);
} elseif (is_string($key)) {
$items = (array) $this->get($key);
$value = array_replace($items, $this->getArrayItems($value));
$this->set($key, $value);
} elseif ($key instanceof self) {
$this->items = array_replace($this->items, $key->all());
}
}
/**
* Set a given key / value pair or pairs
*
* @param array|int|string $keys
* @param mixed $value
*/
public function set($keys, $value = null)
{
if (is_array($keys)) {
foreach ($keys as $key => $value) {
$this->set($key, $value);
}
return;
}
$items = &$this->items;
foreach (explode('.', $keys) as $key) {
if (!isset($items[$key]) || !is_array($items[$key])) {
$items[$key] = [];
}
$items = &$items[$key];
}
$items = $value;
}
/**
* Replace all items with a given array
*
* @param mixed $items
*/
public function setArray($items)
{
$this->items = $this->getArrayItems($items);
}
/**
* Replace all items with a given array as a reference
*
* @param array $items
*/
public function setReference(array &$items)
{
$this->items = &$items;
}
/**
* Return the value of a given key or all the values as JSON
*
* @param mixed $key
* @param int $options
* @return string
*/
public function toJson($key = null, $options = 0)
{
if (is_string($key)) {
return json_encode($this->get($key), $options);
}
$options = $key === null ? 0 : $key;
return json_encode($this->items, $options);
}
/*
* --------------------------------------------------------------
* ArrayAccess interface
* --------------------------------------------------------------
*/
/**
* Check if a given key exists
*
* @param int|string $key
* @return bool
*/
public function offsetExists($key)
{
return $this->has($key);
}
/**
* Return the value of a given key
*
* @param int|string $key
* @return mixed
*/
public function offsetGet($key)
{
return $this->get($key);
}
/**
* Set a given value to the given key
*
* @param int|string|null $key
* @param mixed $value
*/
public function offsetSet($key, $value)
{
if (is_null($key)) {
$this->items[] = $value;
return;
}
$this->set($key, $value);
}
/**
* Delete the given key
*
* @param int|string $key
*/
public function offsetUnset($key)
{
$this->delete($key);
}
/*
* --------------------------------------------------------------
* Countable interface
* --------------------------------------------------------------
*/
/**
* Return the number of items in a given key
*
* @param int|string|null $key
* @return int
*/
public function count($key = null)
{
return count($this->get($key));
}
/*
* --------------------------------------------------------------
* IteratorAggregate interface
* --------------------------------------------------------------
*/
/**
* Get an iterator for the stored items
*
* @return \ArrayIterator
*/
public function getIterator()
{
return new ArrayIterator($this->items);
}
/*
* --------------------------------------------------------------
* JsonSerializable interface
* --------------------------------------------------------------
*/
/**
* Return items for JSON serialization
*
* @return array
*/
public function jsonSerialize()
{
return $this->items;
}
}

View File

@ -0,0 +1,23 @@
<?php
/**
* Dot - PHP dot notation access to arrays
*
* @author Riku Särkinen <riku@adbar.io>
* @link https://github.com/adbario/php-dot-notation
* @license https://github.com/adbario/php-dot-notation/blob/2.x/LICENSE.md (MIT License)
*/
use Adbar\Dot;
if (! function_exists('dot')) {
/**
* Create a new Dot object with the given items
*
* @param mixed $items
* @return \Adbar\Dot
*/
function dot($items)
{
return new Dot($items);
}
}

284
vendor/alibabacloud/client/CHANGELOG.md vendored Normal file
View File

@ -0,0 +1,284 @@
# CHANGELOG
## 1.5.24 - 2020-06-04
- Fixed Resolve Host.
## 1.5.23 - 2020-05-22
- Optimized global product support.
## 1.5.22 - 2020-05-12
- Updated Endpoints.
## 1.5.21 - 2020-02-26
- Improved Nonce.
- Updated Endpoints.
## 1.5.20 - 2019-12-30
- Improved Docs.
- Updated Endpoints.
## 1.5.19 - 2019-12-17
- Updated Endpoints.
## 1.5.18 - 2019-10-11
- Updated Request link.
- Updated Endpoints data.
## 1.5.17 - 2019-09-15
- Improved Host Finder.
- Updated Endpoints Data.
## 1.5.16 - 2019-08-21
- Updated Endpoints Data.
## 1.5.15 - 2019-08-14
- Improved Client.
## 1.5.14 - 2019-07-25
- Improved Credential Filter.
## 1.5.13 - 2019-07-18
- Improved API Resolver.
## 1.5.12 - 2019-06-20
- Fixed Signature for ROA.
## 1.5.11 - 2019-06-14
- Added endpoint rules.
## 1.5.10 - 2019-06-13
- Improved `Resovler`.
- Updated `endpoints`.
## 1.5.9 - 2019-06-04
- Improved `UUID`.
## 1.5.8 - 2019-05-30
- Improved `Arrays`.
## 1.5.7 - 2019-05-29
- Improved `uuid`.
## 1.5.6 - 2019-05-29
- Fixed `uuid` version lock.
## 1.5.5 - 2019-05-23
- Improved `Signature`.
## 1.5.4 - 2019-05-22
- Updated `Endpoints`.
- Fixed `Content-Type` in header.
## 1.5.3 - 2019-05-13
- Improved `Endpoint` tips.
- Improved `Endpoints` for `STS`.
## 1.5.2 - 2019-05-10
- Improved `Result` object.
## 1.5.1 - 2019-05-09
- Supported `Resolver` for Third-party dependencies.
## 1.5.0 - 2019-05-07
- Improved `Resolver` for products.
## 1.4.0 - 2019-05-06
- Support `Retry` and `Asynchronous` for Request.
## 1.3.1 - 2019-04-30
- Allow timeouts to be set in microseconds.
## 1.3.0 - 2019-04-18
- Improved parameters methods.
- Optimized the logic for body encode.
## 1.2.1 - 2019-04-11
- Improve exception code and message for `Region ID`.
## 1.2.0 - 2019-04-11
- Improve exception message for `Region ID`.
## 1.1.1 - 2019-04-02
- Added endpoints for `batchcomputenew`, `privatelink`.
- Improve Region ID tips.
## 1.1.0 - 2019-04-01
- Updated `composer.json`.
## 1.0.27 - 2019-03-31
- Support `Policy` for `ramRoleArnClient`.
## 1.0.26 - 2019-03-27
- Support `pid`, `cost`, `start_time` for Log.
## 1.0.25 - 2019-03-27
- Updated default log format.
- Add endpoints for `dbs`.
## 1.0.24 - 2019-03-26
- Support Log.
## 1.0.23 - 2019-03-23
- Remove SVG.
## 1.0.22 - 2019-03-20
- Add endpoint `cn-hangzhou` for `idaas` .
## 1.0.21 - 2019-03-19
- Installing by Using the ZIP file.
- Update Docs.
## 1.0.20 - 2019-03-13
- Improve Tests.
- Update Docs.
## 1.0.19 - 2019-03-12
- Add SSL Verify Option `verify()`.
## 1.0.18 - 2019-03-11
- Add endpoints for `acr`.
- Add endpoints for `faas`.
- Add endpoints for `ehs`.
- SSL certificates are not validated by default.
## 1.0.17 - 2019-03-08
- Support Mock for Test.
## 1.0.16 - 2019-03-07
- Support Credential Provider Chain.
- Support `CCC`.
- Add `ap-south-1` for `cas`.
- Add `ap-southeast-1` for `waf`.
- Update Docs.
## 1.0.15 - 2019-02-27
- Add endpoints for `Chatbot`.
- Change endpoints for `drdspost` and `drdspre`.
## 1.0.14 - 2019-02-21
- Enable debug mode by set environment variable `DEBUG=sdk`.
## 1.0.13 - 2019-02-18
- Support Release Script `composer release`.
- Add endpoints for apigateway in `drdspre` in `cn-qingdao`.
- Add endpoints for apigateway in `drdspre` in `cn-beijing`.
- Add endpoints for apigateway in `drdspre` in `cn-hangzhou`.
- Add endpoints for apigateway in `drdspre` in `cn-shanghai`.
- Add endpoints for apigateway in `drdspre` in `cn-shenzhen`.
- Add endpoints for apigateway in `drdspre` in `cn-hongkong`.
- Add endpoints for apigateway in `drdspost` in `ap-southeast-1`.
- Add endpoints for apigateway in `drdspost` in `cn-shanghai`.
- Add endpoints for apigateway in `drdspost` in `cn-hongkong`.
- Add endpoints for apigateway in `vod` in `ap-southeast-1`.
- Add endpoints for apigateway in `vod` in `eu-central-1`.
## 1.0.12 - 2019-02-16
- Support `open_basedir`.
## 1.0.11 - 2019-02-13
- Improve User Agent.
## 1.0.10 - 2019-02-12
- `userAgentAppend` is renamed to `appendUserAgent`.
## 1.0.9 - 2019-02-12
- `userAgent` is renamed to `userAgentAppend`.
## 1.0.8 - 2019-02-11
- `userAgent` - Support DIY User Agent.
- Add endpoints for apigateway in Zhangjiakou.
- Add endpoints for apigateway in Hu He Hao Te.
- Add endpoints for vod in Hu He Hao Te.
- Add endpoints for hsm in Zhangjiakou.
- Add endpoints for luban in Germany.
- Add endpoints for linkwan in Hangzhou.
- Add endpoints for drdspost in Singapore.
## 1.0.7 - 2019-01-28
- Add endpoints for gpdb in Tokyo.
- Add endpoints for elasticsearch in Beijing.
## 1.0.6 - 2019-01-23
- Add endpoints for dysmsapi in Singapore.
- Add endpoints for dybaseapi.
- Add endpoints for dyiotapi.
- Add endpoints for dycdpapi.
- Add endpoints for dyplsapi.
- Add endpoints for dypnsapi.
- Add endpoints for dyvmsapi.
- Add endpoints for snsuapi.
## 1.0.5 - 2019-01-21
- Add endpoints for ApiGateway in Silicon Valley, Virginia.
- Add endpoints for Image Search in Shanghai.
## 1.0.4 - 2019-01-17
- Support fixer all.
- Add Endpoints.
## 1.0.3 - 2019-01-15
- Update Endpoints.
- Update README.md.
- Update Return Result Message.
## 1.0.2 - 2019-01-15
- Optimize the documentation.
- Adjust the CI configuration.
## 1.0.1 - 2019-01-09
- Distinguish credential error.
- Add endpoints for NLS.
- Add not found product tip.
## 1.0.0 - 2019-01-07
- Initial release of the Alibaba Cloud Client for PHP Version 1.0.0 on Packagist See <https://github.com/aliyun/openapi-sdk-php-client> for more information.

View File

@ -0,0 +1,30 @@
# Contributing to the Alibaba Cloud Client for PHP
We work hard to provide a high-quality and useful SDK for Alibaba Cloud, and
we greatly value feedback and contributions from our community. Please submit
your [issues][issues] or [pull requests][pull-requests] through GitHub.
## Tips
- The SDK is released under the [Apache license][license]. Any code you submit
will be released under that license. For substantial contributions, we may
ask you to sign a [Alibaba Documentation Corporate Contributor License
Agreement (CLA)][cla].
- We follow all of the relevant PSR recommendations from the [PHP Framework
Interop Group][php-fig]. Please submit code that follows these standards.
The [PHP CS Fixer][cs-fixer] tool can be helpful for formatting your code.
Your can use `composer fixer` to fix code.
- We maintain a high percentage of code coverage in our unit tests. If you make
changes to the code, please add, update, and/or remove tests as appropriate.
- If your code does not conform to the PSR standards, does not include adequate
tests, or does not contain a changelog document, we may ask you to update
your pull requests before we accept them. We also reserve the right to deny
any pull requests that do not align with our standards or goals.
[issues]: https://github.com/aliyun/openapi-sdk-php-client/issues
[pull-requests]: https://github.com/aliyun/openapi-sdk-php-client/pulls
[license]: http://www.apache.org/licenses/LICENSE-2.0
[cla]: https://alibaba-cla-2018.oss-cn-beijing.aliyuncs.com/Alibaba_Documentation_Open_Source_Corporate_CLA.pdf
[php-fig]: http://php-fig.org
[cs-fixer]: http://cs.sensiolabs.org/
[docs-readme]: https://github.com/aliyun/openapi-sdk-php-client/blob/master/README.md

13
vendor/alibabacloud/client/LICENSE.md vendored Normal file
View File

@ -0,0 +1,13 @@
Copyright (c) 2009-present, Alibaba Cloud All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

88
vendor/alibabacloud/client/NOTICE.md vendored Normal file
View File

@ -0,0 +1,88 @@
# Alibaba Cloud Client for PHP
<https://www.alibabacloud.com/>
Copyright (c) 2009-present, Alibaba Cloud All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
A copy of the License is located at
<http://www.apache.org/licenses/LICENSE-2.0>
or in the "license" file accompanying this file. This file is distributed
on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
express or implied. See the License for the specific language governing
permissions and limitations under the License.
# Guzzle
<https://github.com/guzzle/guzzle>
Copyright (c) 2011-2018 Michael Dowling, https://github.com/mtdowling <mtdowling@gmail.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.
# jmespath.php
<https://github.com/mtdowling/jmespath.php>
Copyright (c) 2014 Michael Dowling, https://github.com/mtdowling
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.
# Dot
<https://github.com/adbario/php-dot-notation>
Copyright (c) 2016-2019 Riku Särkinen
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.

View File

@ -0,0 +1,166 @@
[English](/README.md) | 简体中文
# Alibaba Cloud Client for PHP
[![Latest Stable Version](https://poser.pugx.org/alibabacloud/client/v/stable)](https://packagist.org/packages/alibabacloud/client)
[![composer.lock](https://poser.pugx.org/alibabacloud/client/composerlock)](https://packagist.org/packages/alibabacloud/client)
[![Total Downloads](https://poser.pugx.org/alibabacloud/client/downloads)](https://packagist.org/packages/alibabacloud/client)
[![License](https://poser.pugx.org/alibabacloud/client/license)](https://packagist.org/packages/alibabacloud/client)
[![codecov](https://codecov.io/gh/aliyun/openapi-sdk-php-client/branch/master/graph/badge.svg)](https://codecov.io/gh/aliyun/openapi-sdk-php-client)
[![Travis Build Status](https://travis-ci.org/aliyun/openapi-sdk-php-client.svg?branch=master)](https://travis-ci.org/aliyun/openapi-sdk-php-client)
[![Appveyor Build Status](https://ci.appveyor.com/api/projects/status/qb8j3lhg8349k0hk/branch/master?svg=true)](https://ci.appveyor.com/project/aliyun/openapi-sdk-php-client/branch/master)
![](https://aliyunsdk-pages.alicdn.com/icons/AlibabaCloud.svg)
Alibaba Cloud Client for PHP 是帮助 PHP 开发者管理凭据、发送请求的客户端工具,[Alibaba Cloud SDK for PHP][SDK] 由本工具提供底层支持。
## 在线示例
[API Explorer](https://api.aliyun.com) 提供在线调用阿里云产品,并动态生成 SDK 代码和快速检索接口等能力,能显著降低使用云 API 的难度。
## 先决条件
您的系统需要满足[先决条件](/docs/zh-CN/0-Prerequisites.md),包括 PHP> = 5.5。 我们强烈建议使用cURL扩展并使用TLS后端编译cURL 7.16.2+。
## 安装依赖
如果已在系统上[全局安装 Composer](https://getcomposer.org/doc/00-intro.md#globally),请直接在项目目录中运行以下内容来安装 Alibaba Cloud Client for PHP 作为依赖项:
```
composer require alibabacloud/client
```
> 一些用户可能由于网络问题无法安装,可以使用[阿里云 Composer 全量镜像](https://developer.aliyun.com/composer)。
请看[安装](/docs/zh-CN/1-Installation.md)有关通过 Composer 和其他方式安装的详细信息。
## 快速使用
在您开始之前,您需要注册阿里云帐户并获取您的[凭证](https://usercenter.console.aliyun.com/#/manage/ak)。
```php
<?php
use AlibabaCloud\Client\AlibabaCloud;
AlibabaCloud::accessKeyClient('accessKeyId', 'accessKeySecret')->asDefaultClient();
```
## 请求
> 请求风格分为 `ROA``RPC`,不同产品风格不同,使用前,请参考产品文档。推荐使用 [Alibaba Cloud SDK for PHP][SDK] ,细节已被封装,无需关心风格。
### ROA 请求
```php
<?php
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
try {
$result = AlibabaCloud::roa()
->regionId('cn-hangzhou') // 指定请求的区域,不指定则使用客户端区域、默认区域
->product('CS') // 指定产品
->version('2015-12-15') // 指定产品版本
->action('DescribeClusterServices') // 指定产品接口
->serviceCode('cs') // 设置 ServiceCode 以备寻址,非必须
->endpointType('openAPI') // 设置类型,非必须
->method('GET') // 指定请求方式
->host('cs.aliyun.com') // 指定域名则不会寻址,如认证方式为 Bearer Token 的服务则需要指定
->pathPattern('/clusters/[ClusterId]/services') // 指定ROA风格路径规则
->withClusterId('123456') // 为路径中参数赋值方法名with + 参数
->request(); // 发起请求并返回结果对象,请求需要放在设置的最后面
print_r($result->toArray());
} catch (ClientException $exception) {
print_r($exception->getErrorMessage());
} catch (ServerException $exception) {
print_r($exception->getErrorMessage());
}
```
### RPC 请求
```php
<?php
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
try {
$result = AlibabaCloud::rpc()
->product('Cdn')
->version('2014-11-11')
->action('DescribeCdnService')
->method('POST')
->request();
print_r($result->toArray());
} catch (ClientException $exception) {
print_r($exception->getErrorMessage());
} catch (ServerException $exception) {
print_r($exception->getErrorMessage());
}
```
## 文档
* [先决条件](/docs/zh-CN/0-Prerequisites.md)
* [安装](/docs/zh-CN/1-Installation.md)
* [客户端](/docs/zh-CN/2-Client.md)
* [请求](/docs/zh-CN/3-Request.md)
* [结果](/docs/zh-CN/4-Result.md)
* [区域](/docs/zh-CN/5-Region.md)
* [域名](/docs/zh-CN/6-Host.md)
* [SSL 验证](/docs/zh-CN/7-Verify.md)
* [调试](/docs/zh-CN/8-Debug.md)
* [日志](/docs/zh-CN/9-Log.md)
* [测试](/docs/zh-CN/10-Test.md)
## 问题
[提交 Issue](https://github.com/aliyun/openapi-sdk-php-client/issues/new/choose),不符合指南的问题可能会立即关闭。
## 发行说明
每个版本的详细更改记录在[发行说明](/CHANGELOG.md)中。
## 贡献
提交 Pull Request 之前请阅读[贡献指南](/CONTRIBUTING.md)。
## 相关
* [阿里云服务 Regions & Endpoints][endpoints]
* [OpenAPI Explorer][open-api]
* [Packagist][packagist]
* [Composer][composer]
* [Guzzle中文文档][guzzle-docs]
* [最新源码][latest-release]
## 许可证
[Apache-2.0](/LICENSE.md)
Copyright (c) 2009-present, Alibaba Cloud All rights reserved.
[SDK]: https://github.com/aliyun/openapi-sdk-php
[open-api]: https://api.aliyun.com
[latest-release]: https://github.com/aliyun/openapi-sdk-php-client
[guzzle-docs]: https://guzzle-cn.readthedocs.io/zh_CN/latest/request-options.html
[composer]: https://getcomposer.org
[packagist]: https://packagist.org/packages/alibabacloud/sdk
[home]: https://home.console.aliyun.com
[aliyun]: https://www.aliyun.com
[regions]: https://help.aliyun.com/document_detail/40654.html
[endpoints]: https://developer.aliyun.com/endpoints
[cURL]: http://php.net/manual/zh/book.curl.php
[OPCache]: http://php.net/manual/zh/book.opcache.php
[xdebug]: http://xdebug.org
[OpenSSL]: http://php.net/manual/zh/book.openssl.php
[client]: https://github.com/aliyun/openapi-sdk-php-client

167
vendor/alibabacloud/client/README.md vendored Normal file
View File

@ -0,0 +1,167 @@
English | [简体中文](/README-zh-CN.md)
# Alibaba Cloud Client for PHP
[![Latest Stable Version](https://poser.pugx.org/alibabacloud/client/v/stable)](https://packagist.org/packages/alibabacloud/client)
[![composer.lock](https://poser.pugx.org/alibabacloud/client/composerlock)](https://packagist.org/packages/alibabacloud/client)
[![Total Downloads](https://poser.pugx.org/alibabacloud/client/downloads)](https://packagist.org/packages/alibabacloud/client)
[![License](https://poser.pugx.org/alibabacloud/client/license)](https://packagist.org/packages/alibabacloud/client)
[![codecov](https://codecov.io/gh/aliyun/openapi-sdk-php-client/branch/master/graph/badge.svg)](https://codecov.io/gh/aliyun/openapi-sdk-php-client)
[![Travis Build Status](https://travis-ci.org/aliyun/openapi-sdk-php-client.svg?branch=master)](https://travis-ci.org/aliyun/openapi-sdk-php-client)
[![Appveyor Build Status](https://ci.appveyor.com/api/projects/status/qb8j3lhg8349k0hk/branch/master?svg=true)](https://ci.appveyor.com/project/aliyun/openapi-sdk-php-client/branch/master)
![](https://aliyunsdk-pages.alicdn.com/icons/AlibabaCloud.svg)
Alibaba Cloud Client for PHP is a client tool that helps PHP developers manage credentials and send requests, [Alibaba Cloud SDK for PHP][SDK] dependency on this tool.
## Online Demo
[API Explorer](https://api.aliyun.com) provides the ability to call the cloud product OpenAPI online, and dynamically generate SDK Example code and quick retrieval interface, which can significantly reduce the difficulty of using the cloud API.
## Prerequisites
Your system will need to meet the [Prerequisites](/docs/en-US/0-Prerequisites.md), including having PHP >= 5.5. We highly recommend having it compiled with the cURL extension and cURL 7.16.2+.
## Installation
If Composer is already [installed globally on your system](https://getcomposer.org/doc/00-intro.md#globally), run the following in the base directory of your project to install Alibaba Cloud Client for PHP as a dependency:
```
composer require alibabacloud/client
```
> Some users may not be able to install due to network problems, you can try to switch the Composer mirror.
Please see the [Installation](/docs/en-US/1-Installation.md) for more detailed information about installing the Alibaba Cloud Client for PHP through Composer and other means.
## Quick Examples
Before you begin, you need to sign up for an Alibaba Cloud account and retrieve your [Credentials](https://usercenter.console.aliyun.com/#/manage/ak).
### Create Client
```php
<?php
use AlibabaCloud\Client\AlibabaCloud;
AlibabaCloud::accessKeyClient('accessKeyId', 'accessKeySecret')->asDefaultClient();
```
## Request
> Request styles are divided into `ROA` and `RPC`. Different product styles are different. Please refer to the product documentation before using. It is recommended to use [Alibaba cloud SDK for PHP][SDK], the details have been encapsulated, and you do not need to care about the style.
### ROA Request
```php
<?php
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
try {
$result = AlibabaCloud::roa()
->regionId('cn-hangzhou') // Specify the requested regionId, if not specified, use the client regionId, then default regionId
->product('CS') // Specify product
->version('2015-12-15') // Specify product version
->action('DescribeClusterServices') // Specify product interface
->serviceCode('cs') // Set ServiceCode for addressing, optional
->endpointType('openAPI') // Set type, optional
->method('GET') // Set request method
->host('cs.aliyun.com') // Location Service will not be enabled if the host is specified. For example, service with a Certification type-Bearer Token should be specified
->pathPattern('/clusters/[ClusterId]/services') // Specify path rule with ROA-style
->withClusterId('123456') // Assign values to parameters in the path. Method: with + Parameter
->request(); // Make a request and return to result object. The request is to be placed at the end of the setting
print_r($result->toArray());
} catch (ClientException $exception) {
print_r($exception->getErrorMessage());
} catch (ServerException $exception) {
print_r($exception->getErrorMessage());
}
```
### RPC Request
```php
<?php
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
try {
$result = AlibabaCloud::rpc()
->product('Cdn')
->version('2014-11-11')
->action('DescribeCdnService')
->method('POST')
->request();
print_r($result->toArray());
} catch (ClientException $exception) {
print_r($exception->getErrorMessage());
} catch (ServerException $exception) {
print_r($exception->getErrorMessage());
}
```
## Documentation
* [Prerequisites](/docs/en-US/0-Prerequisites.md)
* [Installation](/docs/en-US/1-Installation.md)
* [Client](/docs/en-US/2-Client.md)
* [Request](/docs/en-US/3-Request.md)
* [Result](/docs/en-US/4-Result.md)
* [Region](/docs/en-US/5-Region.md)
* [Host](/docs/en-US/6-Host.md)
* [SSL Verify](/docs/en-US/7-Verify.md)
* [Debug](/docs/en-US/8-Debug.md)
* [Log](/docs/en-US/9-Log.md)
* [Test](/docs/en-US/10-Test.md)
## Issues
[Opening an Issue](https://github.com/aliyun/openapi-sdk-php-client/issues/new/choose), Issues not conforming to the guidelines may be closed immediately.
## Changelog
Detailed changes for each release are documented in the [release notes](/CHANGELOG.md).
## Contribution
Please make sure to read the [Contributing Guide](/CONTRIBUTING.md) before making a pull request.
## References
* [Alibaba Cloud Regions & Endpoints][endpoints]
* [OpenAPI Explorer][open-api]
* [Packagist][packagist]
* [Composer][composer]
* [Guzzle Documentation][guzzle-docs]
* [Latest Release][latest-release]
## License
[Apache-2.0](/LICENSE.md)
Copyright (c) 2009-present, Alibaba Cloud All rights reserved.
[SDK]: https://github.com/aliyun/openapi-sdk-php
[open-api]: https://api.alibabacloud.com
[latest-release]: https://github.com/aliyun/openapi-sdk-php-client
[guzzle-docs]: http://docs.guzzlephp.org/en/stable/request-options.html
[composer]: https://getcomposer.org
[packagist]: https://packagist.org/packages/alibabacloud/sdk
[home]: https://home.console.aliyun.com
[alibabacloud]: https://www.alibabacloud.com
[regions]: https://www.alibabacloud.com/help/doc-detail/40654.html
[endpoints]: https://developer.aliyun.com/endpoints
[cURL]: http://php.net/manual/en/book.curl.php
[OPCache]: http://php.net/manual/en/book.opcache.php
[xdebug]: http://xdebug.org
[OpenSSL]: http://php.net/manual/en/book.openssl.php
[client]: https://github.com/aliyun/openapi-sdk-php-client

View File

@ -0,0 +1,6 @@
Upgrading Guide
===============
1.x
-----------------------
- This is the first version. See <https://github.com/aliyun/openapi-sdk-php-client> for more information.

116
vendor/alibabacloud/client/composer.json vendored Normal file
View File

@ -0,0 +1,116 @@
{
"name": "alibabacloud/client",
"homepage": "https://www.alibabacloud.com/",
"description": "Alibaba Cloud Client for PHP - Use Alibaba Cloud in your PHP project",
"keywords": [
"sdk",
"tool",
"cloud",
"client",
"aliyun",
"library",
"alibaba",
"alibabacloud"
],
"type": "library",
"license": "Apache-2.0",
"support": {
"source": "https://github.com/aliyun/openapi-sdk-php-client",
"issues": "https://github.com/aliyun/openapi-sdk-php-client/issues"
},
"authors": [
{
"name": "Alibaba Cloud SDK",
"email": "sdk-team@alibabacloud.com",
"homepage": "http://www.alibabacloud.com"
}
],
"require": {
"php": ">=5.5",
"ext-curl": "*",
"ext-json": "*",
"ext-libxml": "*",
"ext-openssl": "*",
"ext-mbstring": "*",
"ext-simplexml": "*",
"ext-xmlwriter": "*",
"guzzlehttp/guzzle": "^6.3|^7.0",
"danielstjules/stringy": "^3.1",
"mtdowling/jmespath.php": "^2.5",
"adbario/php-dot-notation": "^2.2",
"clagiordano/weblibs-configmanager": "^1.0"
},
"require-dev": {
"ext-spl": "*",
"ext-dom": "*",
"ext-pcre": "*",
"psr/cache": "^1.0",
"ext-sockets": "*",
"drupal/coder": "^8.3",
"symfony/dotenv": "^3.4",
"league/climate": "^3.2.4",
"phpunit/phpunit": "^5.7.27",
"monolog/monolog": "^1.24",
"composer/composer": "^1.8",
"mikey179/vfsstream": "^1.6",
"symfony/var-dumper": "^3.4"
},
"suggest": {
"ext-sockets": "To use client-side monitoring"
},
"autoload": {
"psr-4": {
"AlibabaCloud\\Client\\": "src"
},
"files": [
"src/Functions.php"
]
},
"autoload-dev": {
"psr-4": {
"AlibabaCloud\\Client\\Tests\\": "tests/"
}
},
"config": {
"preferred-install": "dist",
"optimize-autoloader": true
},
"minimum-stability": "dev",
"prefer-stable": true,
"scripts-descriptions": {
"cs": "Tokenizes PHP, JavaScript and CSS files to detect violations of a defined coding standard.",
"cbf": "Automatically correct coding standard violations.",
"fixer": "Fixes code to follow standards.",
"test": "Run all tests.",
"unit": "Run Unit tests.",
"feature": "Run Feature tests.",
"clearCache": "Clear cache like coverage.",
"coverage": "Show Coverage html.",
"endpoints": "Update endpoints from OSS."
},
"scripts": {
"cs": "phpcs --standard=PSR2 -n ./",
"cbf": "phpcbf --standard=PSR2 -n ./",
"fixer": "php-cs-fixer fix ./",
"test": [
"phpunit --colors=always"
],
"unit": [
"@clearCache",
"phpunit --testsuite=Unit --colors=always"
],
"feature": [
"@clearCache",
"phpunit --testsuite=Feature --colors=always"
],
"coverage": "open cache/coverage/index.html",
"clearCache": "rm -rf cache/*",
"endpoints": [
"AlibabaCloud\\Client\\Regions\\LocationService::updateEndpoints",
"@fixer"
],
"release": [
"AlibabaCloud\\Client\\Release::release"
]
}
}

View File

@ -0,0 +1,53 @@
<?php
namespace AlibabaCloud\Client;
/**
* Class Accept
*
* @package AlibabaCloud\Client
*/
class Accept
{
/**
* @var string
*/
private $format;
/**
* Accept constructor.
*
* @param string $format
*/
private function __construct($format)
{
$this->format = $format;
}
/**
* @param $format
*
* @return Accept
*/
public static function create($format)
{
return new static($format);
}
/**
* @return mixed|string
*/
public function toString()
{
$key = \strtoupper($this->format);
$list = [
'JSON' => 'application/json',
'XML' => 'application/xml',
'RAW' => 'application/octet-stream',
'FORM' => 'application/x-www-form-urlencoded'
];
return isset($list[$key]) ? $list[$key] : $list['RAW'];
}
}

View File

@ -0,0 +1,62 @@
<?php
namespace AlibabaCloud\Client;
use AlibabaCloud\Client\Traits\LogTrait;
use AlibabaCloud\Client\Traits\MockTrait;
use AlibabaCloud\Client\Traits\ClientTrait;
use AlibabaCloud\Client\Traits\HistoryTrait;
use AlibabaCloud\Client\Traits\RequestTrait;
use AlibabaCloud\Client\Traits\EndpointTrait;
use AlibabaCloud\Client\Traits\DefaultRegionTrait;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Class AlibabaCloud
*
* @package AlibabaCloud\Client
* @mixin \AlibabaCloud\IdeHelper
*/
class AlibabaCloud
{
use ClientTrait;
use DefaultRegionTrait;
use EndpointTrait;
use RequestTrait;
use MockTrait;
use HistoryTrait;
use LogTrait;
/**
* Version of the Client
*/
const VERSION = '1.5.24';
/**
* This static method can directly call the specific service.
*
* @param string $product
* @param array $arguments
*
* @codeCoverageIgnore
* @return object
* @throws ClientException
*/
public static function __callStatic($product, $arguments)
{
$product = \ucfirst($product);
$product_class = 'AlibabaCloud' . '\\' . $product . '\\' . $product;
if (\class_exists($product_class)) {
return new $product_class;
}
throw new ClientException(
"May not yet support product $product quick access, "
. 'you can use [Alibaba Cloud Client for PHP] to send any custom '
. 'requests: https://github.com/aliyun/openapi-sdk-php-client/blob/master/docs/en-US/3-Request.md',
SDK::SERVICE_NOT_FOUND
);
}
}

View File

@ -0,0 +1,30 @@
<?php
namespace AlibabaCloud\Client\Clients;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Signature\ShaHmac1Signature;
use AlibabaCloud\Client\Credentials\AccessKeyCredential;
/**
* Use the AccessKey to complete the authentication.
*
* @package AlibabaCloud\Client\Clients
*/
class AccessKeyClient extends Client
{
/**
* @param string $accessKeyId
* @param string $accessKeySecret
*
* @throws ClientException
*/
public function __construct($accessKeyId, $accessKeySecret)
{
parent::__construct(
new AccessKeyCredential($accessKeyId, $accessKeySecret),
new ShaHmac1Signature()
);
}
}

View File

@ -0,0 +1,29 @@
<?php
namespace AlibabaCloud\Client\Clients;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Signature\BearerTokenSignature;
use AlibabaCloud\Client\Credentials\BearerTokenCredential;
/**
* Use the Bearer Token to complete the authentication.
*
* @package AlibabaCloud\Client\Clients
*/
class BearerTokenClient extends Client
{
/**
* @param string $bearerToken
*
* @throws ClientException
*/
public function __construct($bearerToken)
{
parent::__construct(
new BearerTokenCredential($bearerToken),
new BearerTokenSignature()
);
}
}

View File

@ -0,0 +1,72 @@
<?php
namespace AlibabaCloud\Client\Clients;
use AlibabaCloud\Client\Request\Request;
use AlibabaCloud\Client\Traits\HttpTrait;
use AlibabaCloud\Client\Traits\RegionTrait;
use AlibabaCloud\Client\Credentials\StsCredential;
use AlibabaCloud\Client\Signature\ShaHmac1Signature;
use AlibabaCloud\Client\Signature\SignatureInterface;
use AlibabaCloud\Client\Signature\ShaHmac256Signature;
use AlibabaCloud\Client\Signature\BearerTokenSignature;
use AlibabaCloud\Client\Credentials\AccessKeyCredential;
use AlibabaCloud\Client\Credentials\CredentialsInterface;
use AlibabaCloud\Client\Credentials\EcsRamRoleCredential;
use AlibabaCloud\Client\Credentials\RamRoleArnCredential;
use AlibabaCloud\Client\Credentials\RsaKeyPairCredential;
use AlibabaCloud\Client\Credentials\BearerTokenCredential;
use AlibabaCloud\Client\Signature\ShaHmac256WithRsaSignature;
/**
* Custom Client.
*
* @package AlibabaCloud\Client\Clients
*/
class Client
{
use HttpTrait;
use RegionTrait;
use ManageTrait;
/**
* @var CredentialsInterface|AccessKeyCredential|BearerTokenCredential|StsCredential|EcsRamRoleCredential|RamRoleArnCredential|RsaKeyPairCredential
*/
private $credential;
/**
* @var SignatureInterface
*/
private $signature;
/**
* Self constructor.
*
* @param CredentialsInterface $credential
* @param SignatureInterface $signature
*/
public function __construct(CredentialsInterface $credential, SignatureInterface $signature)
{
$this->credential = $credential;
$this->signature = $signature;
$this->options['connect_timeout'] = Request::CONNECT_TIMEOUT;
$this->options['timeout'] = Request::TIMEOUT;
$this->options['verify'] = false;
}
/**
* @return AccessKeyCredential|BearerTokenCredential|CredentialsInterface|EcsRamRoleCredential|RamRoleArnCredential|RsaKeyPairCredential|StsCredential
*/
public function getCredential()
{
return $this->credential;
}
/**
* @return SignatureInterface|BearerTokenSignature|ShaHmac1Signature|ShaHmac256Signature|ShaHmac256WithRsaSignature
*/
public function getSignature()
{
return $this->signature;
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace AlibabaCloud\Client\Clients;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Signature\ShaHmac1Signature;
use AlibabaCloud\Client\Credentials\EcsRamRoleCredential;
/**
* Use the RAM role of an ECS instance to complete the authentication.
*/
class EcsRamRoleClient extends Client
{
/**
* @param string $roleName
*
* @throws ClientException
*/
public function __construct($roleName)
{
parent::__construct(
new EcsRamRoleCredential($roleName),
new ShaHmac1Signature()
);
}
}

View File

@ -0,0 +1,98 @@
<?php
namespace AlibabaCloud\Client\Clients;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Filter\Filter;
use AlibabaCloud\Client\Request\Request;
use AlibabaCloud\Client\Credentials\StsCredential;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
use AlibabaCloud\Client\Credentials\CredentialsInterface;
use AlibabaCloud\Client\Credentials\EcsRamRoleCredential;
use AlibabaCloud\Client\Credentials\RamRoleArnCredential;
use AlibabaCloud\Client\Credentials\RsaKeyPairCredential;
use AlibabaCloud\Client\Credentials\Providers\EcsRamRoleProvider;
use AlibabaCloud\Client\Credentials\Providers\RamRoleArnProvider;
use AlibabaCloud\Client\Credentials\Providers\RsaKeyPairProvider;
use AlibabaCloud\Client\Credentials\Providers\CredentialsProvider;
/**
* Trait ManageTrait.
*
* @mixin Client
*/
trait ManageTrait
{
/**
* @param int $timeout
* @param int $connectTimeout
*
* @return CredentialsInterface|StsCredential
*
* @throws ClientException
* @throws ServerException
*/
public function getSessionCredential($timeout = Request::TIMEOUT, $connectTimeout = Request::CONNECT_TIMEOUT)
{
switch (\get_class($this->credential)) {
case EcsRamRoleCredential::class:
return (new EcsRamRoleProvider($this))->get();
case RamRoleArnCredential::class:
return (new RamRoleArnProvider($this))->get($timeout, $connectTimeout);
case RsaKeyPairCredential::class:
return (new RsaKeyPairProvider($this))->get($timeout, $connectTimeout);
default:
return $this->credential;
}
}
/**
* @return static
* @throws ClientException
* @deprecated
* @codeCoverageIgnore
*/
public function asGlobalClient()
{
return $this->asDefaultClient();
}
/**
* Set the current client as the default client.
*
* @return static
* @throws ClientException
*/
public function asDefaultClient()
{
return $this->name(CredentialsProvider::getDefaultName());
}
/**
* Naming clients.
*
* @param string $name
*
* @return static
* @throws ClientException
*/
public function name($name)
{
Filter::name($name);
return AlibabaCloud::set($name, $this);
}
/**
* @return bool
*/
public function isDebug()
{
if (isset($this->options['debug'])) {
return $this->options['debug'] === true && PHP_SAPI === 'cli';
}
return false;
}
}

View File

@ -0,0 +1,33 @@
<?php
namespace AlibabaCloud\Client\Clients;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Signature\ShaHmac1Signature;
use AlibabaCloud\Client\Credentials\RamRoleArnCredential;
/**
* Use the AssumeRole of the RAM account to complete the authentication.
*
* @package AlibabaCloud\Client\Clients
*/
class RamRoleArnClient extends Client
{
/**
* @param string $accessKeyId
* @param string $accessKeySecret
* @param string $roleArn
* @param string $roleSessionName
* @param string|array $policy
*
* @throws ClientException
*/
public function __construct($accessKeyId, $accessKeySecret, $roleArn, $roleSessionName, $policy = '')
{
parent::__construct(
new RamRoleArnCredential($accessKeyId, $accessKeySecret, $roleArn, $roleSessionName, $policy),
new ShaHmac1Signature()
);
}
}

View File

@ -0,0 +1,30 @@
<?php
namespace AlibabaCloud\Client\Clients;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Signature\ShaHmac1Signature;
use AlibabaCloud\Client\Credentials\RsaKeyPairCredential;
/**
* Use the RSA key pair to complete the authentication (supported only on Japanese site)
*
* @package AlibabaCloud\Client\Clients
*/
class RsaKeyPairClient extends Client
{
/**
* @param string $publicKeyId
* @param string $privateKeyFile
*
* @throws ClientException
*/
public function __construct($publicKeyId, $privateKeyFile)
{
parent::__construct(
new RsaKeyPairCredential($publicKeyId, $privateKeyFile),
new ShaHmac1Signature()
);
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace AlibabaCloud\Client\Clients;
use AlibabaCloud\Client\Credentials\StsCredential;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Signature\ShaHmac1Signature;
/**
* Use the STS Token to complete the authentication.
*/
class StsClient extends Client
{
/**
* @param string $accessKeyId Access key ID
* @param string $accessKeySecret Access Key Secret
* @param string $securityToken Security Token
*
* @throws ClientException
*/
public function __construct($accessKeyId, $accessKeySecret, $securityToken = '')
{
parent::__construct(
new StsCredential($accessKeyId, $accessKeySecret, $securityToken),
new ShaHmac1Signature()
);
}
}

View File

@ -0,0 +1,62 @@
<?php
namespace AlibabaCloud\Client\Config;
use Exception;
use clagiordano\weblibs\configmanager\ConfigManager;
/**
* Class Config
*
* @package AlibabaCloud\Client\Config
*/
class Config
{
/**
* @var ConfigManager|null
*/
private static $configManager;
/**
* @param string $configPath
*
* @param string|null $defaultValue
*
* @return mixed
*/
public static function get($configPath, $defaultValue = null)
{
return self::getConfigManager()
->getValue(
\strtolower($configPath),
$defaultValue
);
}
/**
* @return ConfigManager
*/
private static function getConfigManager()
{
if (!self::$configManager instanceof ConfigManager) {
self::$configManager = new ConfigManager(__DIR__ . DIRECTORY_SEPARATOR . 'Data.php');
}
return self::$configManager;
}
/**
* @param string $configPath
* @param mixed $newValue
*
* @return ConfigManager
* @throws Exception
*/
public static function set($configPath, $newValue)
{
self::getConfigManager()->setValue(\strtolower($configPath), $newValue);
return self::getConfigManager()->saveConfigFile();
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,65 @@
<?php
namespace AlibabaCloud\Client\Credentials;
use AlibabaCloud\Client\Filter\CredentialFilter;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Use the AccessKey to complete the authentication.
*
* @package AlibabaCloud\Client\Credentials
*/
class AccessKeyCredential implements CredentialsInterface
{
/**
* @var string
*/
private $accessKeyId;
/**
* @var string
*/
private $accessKeySecret;
/**
* AccessKeyCredential constructor.
*
* @param string $accessKeyId Access key ID
* @param string $accessKeySecret Access Key Secret
*
* @throws ClientException
*/
public function __construct($accessKeyId, $accessKeySecret)
{
CredentialFilter::AccessKey($accessKeyId, $accessKeySecret);
$this->accessKeyId = $accessKeyId;
$this->accessKeySecret = $accessKeySecret;
}
/**
* @return string
*/
public function getAccessKeyId()
{
return $this->accessKeyId;
}
/**
* @return string
*/
public function getAccessKeySecret()
{
return $this->accessKeySecret;
}
/**
* @return string
*/
public function __toString()
{
return "$this->accessKeyId#$this->accessKeySecret";
}
}

View File

@ -0,0 +1,66 @@
<?php
namespace AlibabaCloud\Client\Credentials;
use AlibabaCloud\Client\Filter\CredentialFilter;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Class BearerTokenCredential
*
* @package AlibabaCloud\Client\Credentials
*/
class BearerTokenCredential implements CredentialsInterface
{
/**
* @var string
*/
private $bearerToken;
/**
* Class constructor.
*
* @param string $bearerToken
*
* @throws ClientException
*/
public function __construct($bearerToken)
{
CredentialFilter::bearerToken($bearerToken);
$this->bearerToken = $bearerToken;
}
/**
* @return string
*/
public function getBearerToken()
{
return $this->bearerToken;
}
/**
* @return string
*/
public function getAccessKeyId()
{
return '';
}
/**
* @return string
*/
public function getAccessKeySecret()
{
return '';
}
/**
* @return string
*/
public function __toString()
{
return "bearerToken#$this->bearerToken";
}
}

View File

@ -0,0 +1,18 @@
<?php
namespace AlibabaCloud\Client\Credentials;
/**
* interface CredentialsInterface
*
* @package AlibabaCloud\Client\Credentials
*
* @codeCoverageIgnore
*/
interface CredentialsInterface
{
/**
* @return string
*/
public function __toString();
}

View File

@ -0,0 +1,50 @@
<?php
namespace AlibabaCloud\Client\Credentials;
use AlibabaCloud\Client\Filter\CredentialFilter;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Use the RAM role of an ECS instance to complete the authentication.
*
* @package AlibabaCloud\Client\Credentials
*/
class EcsRamRoleCredential implements CredentialsInterface
{
/**
* @var string
*/
private $roleName;
/**
* Class constructor.
*
* @param string $roleName
*
* @throws ClientException
*/
public function __construct($roleName)
{
CredentialFilter::roleName($roleName);
$this->roleName = $roleName;
}
/**
* @return string
*/
public function getRoleName()
{
return $this->roleName;
}
/**
* @return string
*/
public function __toString()
{
return "roleName#$this->roleName";
}
}

View File

@ -0,0 +1,181 @@
<?php
namespace AlibabaCloud\Client\Credentials\Ini;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\Clients\Client;
use AlibabaCloud\Client\Clients\AccessKeyClient;
use AlibabaCloud\Client\Clients\RamRoleArnClient;
use AlibabaCloud\Client\Clients\RsaKeyPairClient;
use AlibabaCloud\Client\Clients\EcsRamRoleClient;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Clients\BearerTokenClient;
/**
* Trait CreateTrait
*
* @package AlibabaCloud\Client\Credentials\Ini
*
* @mixin IniCredential
*/
trait CreateTrait
{
/**
* @param string $clientName
* @param array $credential
*
* @return Client|bool
* @throws ClientException
*/
protected function createClient($clientName, array $credential)
{
if (!isset($credential['enable']) || !$credential['enable']) {
return false;
}
if (!isset($credential['type'])) {
$this->missingRequired('type', $clientName);
}
return $this->createClientByType($clientName, $credential)->name($clientName);
}
/**
* @param string $clientName
* @param array $credential
*
* @return AccessKeyClient|BearerTokenClient|EcsRamRoleClient|RamRoleArnClient|RsaKeyPairClient
* @throws ClientException
*/
private function createClientByType($clientName, array $credential)
{
switch (\strtolower($credential['type'])) {
case 'access_key':
return $this->accessKeyClient($clientName, $credential);
case 'ecs_ram_role':
return $this->ecsRamRoleClient($clientName, $credential);
case 'ram_role_arn':
return $this->ramRoleArnClient($clientName, $credential);
case 'bearer_token':
return $this->bearerTokenClient($clientName, $credential);
case 'rsa_key_pair':
return $this->rsaKeyPairClient($clientName, $credential);
default:
throw new ClientException(
"Invalid type '{$credential['type']}' for '$clientName' in {$this->filename}",
SDK::INVALID_CREDENTIAL
);
}
}
/**
* @param array $credential
* @param string $clientName
*
* @return AccessKeyClient
* @throws ClientException
*/
private function accessKeyClient($clientName, array $credential)
{
if (!isset($credential['access_key_id'])) {
$this->missingRequired('access_key_id', $clientName);
}
if (!isset($credential['access_key_secret'])) {
$this->missingRequired('access_key_secret', $clientName);
}
return new AccessKeyClient(
$credential['access_key_id'],
$credential['access_key_secret']
);
}
/**
* @param string $clientName
* @param array $credential
*
* @return EcsRamRoleClient
* @throws ClientException
*/
private function ecsRamRoleClient($clientName, array $credential)
{
if (!isset($credential['role_name'])) {
$this->missingRequired('role_name', $clientName);
}
return new EcsRamRoleClient($credential['role_name']);
}
/**
* @param string $clientName
* @param array $credential
*
* @return RamRoleArnClient
* @throws ClientException
*/
private function ramRoleArnClient($clientName, array $credential)
{
if (!isset($credential['access_key_id'])) {
$this->missingRequired('access_key_id', $clientName);
}
if (!isset($credential['access_key_secret'])) {
$this->missingRequired('access_key_secret', $clientName);
}
if (!isset($credential['role_arn'])) {
$this->missingRequired('role_arn', $clientName);
}
if (!isset($credential['role_session_name'])) {
$this->missingRequired('role_session_name', $clientName);
}
return new RamRoleArnClient(
$credential['access_key_id'],
$credential['access_key_secret'],
$credential['role_arn'],
$credential['role_session_name']
);
}
/**
* @param string $clientName
* @param array $credential
*
* @return BearerTokenClient
* @throws ClientException
*/
private function bearerTokenClient($clientName, array $credential)
{
if (!isset($credential['bearer_token'])) {
$this->missingRequired('bearer_token', $clientName);
}
return new BearerTokenClient($credential['bearer_token']);
}
/**
* @param array $credential
* @param string $clientName
*
* @return RsaKeyPairClient
* @throws ClientException
*/
private function rsaKeyPairClient($clientName, array $credential)
{
if (!isset($credential['public_key_id'])) {
$this->missingRequired('public_key_id', $clientName);
}
if (!isset($credential['private_key_file'])) {
$this->missingRequired('private_key_file', $clientName);
}
return new RsaKeyPairClient(
$credential['public_key_id'],
$credential['private_key_file']
);
}
}

View File

@ -0,0 +1,209 @@
<?php
namespace AlibabaCloud\Client\Credentials\Ini;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\Clients\Client;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Class IniCredential
*
* @package AlibabaCloud\Client\Credentials\Ini
*/
class IniCredential
{
use CreateTrait;
use OptionsTrait;
/**
* @var array
*/
private static $hasLoaded;
/**
* @var string
*/
protected $filename;
/**
* IniCredential constructor.
*
* @param string $filename
*/
public function __construct($filename = '')
{
$this->filename = $filename ?: $this->getDefaultFile();
}
/**
* Get the default credential file.
*
* @return string
*/
public function getDefaultFile()
{
return self::getHomeDirectory() . DIRECTORY_SEPARATOR . '.alibabacloud' . DIRECTORY_SEPARATOR . 'credentials';
}
/**
* Gets the environment's HOME directory.
*
* @return null|string
*/
private static function getHomeDirectory()
{
if (getenv('HOME')) {
return getenv('HOME');
}
return (getenv('HOMEDRIVE') && getenv('HOMEPATH'))
? getenv('HOMEDRIVE') . getenv('HOMEPATH')
: null;
}
/**
* Clear credential cache.
*
* @return void
*/
public static function forgetLoadedCredentialsFile()
{
self::$hasLoaded = [];
}
/**
* Get the credential file.
*
* @return string
*/
public function getFilename()
{
return $this->filename;
}
/**
* @param array $array
* @param string $key
*
* @return bool
*/
protected static function isNotEmpty(array $array, $key)
{
return isset($array[$key]) && !empty($array[$key]);
}
/**
* @param string $key
* @param string $clientName
*
* @throws ClientException
*/
public function missingRequired($key, $clientName)
{
throw new ClientException(
"Missing required '$key' option for '$clientName' in " . $this->getFilename(),
SDK::INVALID_CREDENTIAL
);
}
/**
* @return array|mixed
* @throws ClientException
*/
public function load()
{
// If it has been loaded, assign the client directly.
if (isset(self::$hasLoaded[$this->filename])) {
/**
* @var $client Client
*/
foreach (self::$hasLoaded[$this->filename] as $projectName => $client) {
$client->name($projectName);
}
return self::$hasLoaded[$this->filename];
}
return $this->loadFile();
}
/**
* Exceptions will be thrown if the file is unreadable and not the default file.
*
* @return array|mixed
* @throws ClientException
*/
private function loadFile()
{
if (!\AlibabaCloud\Client\inOpenBasedir($this->filename)) {
return [];
}
if (!\is_readable($this->filename) || !\is_file($this->filename)) {
if ($this->filename === $this->getDefaultFile()) {
// @codeCoverageIgnoreStart
return [];
// @codeCoverageIgnoreEnd
}
throw new ClientException(
'Credential file is not readable: ' . $this->getFilename(),
SDK::INVALID_CREDENTIAL
);
}
return $this->parseFile();
}
/**
* Decode the ini file into an array.
*
* @return array|mixed
* @throws ClientException
*/
private function parseFile()
{
try {
$file = \parse_ini_file($this->filename, true);
if (\is_array($file) && $file !== []) {
return $this->initClients($file);
}
throw new ClientException(
'Format error: ' . $this->getFilename(),
SDK::INVALID_CREDENTIAL
);
} catch (\Exception $e) {
throw new ClientException(
$e->getMessage(),
SDK::INVALID_CREDENTIAL,
$e
);
}
}
/**
* Initialize clients.
*
* @param array $array
*
* @return array|mixed
* @throws ClientException
*/
private function initClients($array)
{
foreach (\array_change_key_case($array) as $clientName => $configures) {
$configures = \array_change_key_case($configures);
$clientInstance = $this->createClient($clientName, $configures);
if ($clientInstance instanceof Client) {
self::$hasLoaded[$this->filename][$clientName] = $clientInstance;
self::setClientAttributes($configures, $clientInstance);
self::setCert($configures, $clientInstance);
self::setProxy($configures, $clientInstance);
}
}
return isset(self::$hasLoaded[$this->filename])
? self::$hasLoaded[$this->filename]
: [];
}
}

View File

@ -0,0 +1,111 @@
<?php
namespace AlibabaCloud\Client\Credentials\Ini;
use AlibabaCloud\Client\Clients\Client;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Trait OptionsTrait
*
* @package AlibabaCloud\Client\Credentials\Ini
*
* @mixin IniCredential
*/
trait OptionsTrait
{
/**
* @param array $configures
* @param Client $client
*
* @throws ClientException
*/
private static function setClientAttributes($configures, Client $client)
{
if (self::isNotEmpty($configures, 'region_id')) {
$client->regionId($configures['region_id']);
}
if (isset($configures['debug'])) {
$client->options(
[
'debug' => (bool)$configures['debug'],
]
);
}
if (self::isNotEmpty($configures, 'timeout')) {
$client->options(
[
'timeout' => $configures['timeout'],
]
);
}
if (self::isNotEmpty($configures, 'connect_timeout')) {
$client->options(
[
'connect_timeout' => $configures['connect_timeout'],
]
);
}
}
/**
* @param array $configures
* @param Client $client
*/
private static function setProxy($configures, Client $client)
{
if (self::isNotEmpty($configures, 'proxy')) {
$client->options(
[
'proxy' => $configures['proxy'],
]
);
}
$proxy = [];
if (self::isNotEmpty($configures, 'proxy_http')) {
$proxy['http'] = $configures['proxy_http'];
}
if (self::isNotEmpty($configures, 'proxy_https')) {
$proxy['https'] = $configures['proxy_https'];
}
if (self::isNotEmpty($configures, 'proxy_no')) {
$proxy['no'] = \explode(',', $configures['proxy_no']);
}
if ($proxy !== []) {
$client->options(
[
'proxy' => $proxy,
]
);
}
}
/**
* @param array $configures
* @param Client $client
*/
private static function setCert($configures, Client $client)
{
if (self::isNotEmpty($configures, 'cert_file') && !self::isNotEmpty($configures, 'cert_password')) {
$client->options(
[
'cert' => $configures['cert_file'],
]
);
}
if (self::isNotEmpty($configures, 'cert_file') && self::isNotEmpty($configures, 'cert_password')) {
$client->options(
[
'cert' => [
$configures['cert_file'],
$configures['cert_password'],
],
]
);
}
}
}

View File

@ -0,0 +1,170 @@
<?php
namespace AlibabaCloud\Client\Credentials\Providers;
use Closure;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Class CredentialsProvider
*
* @package AlibabaCloud\Client\Credentials\Providers
*/
class CredentialsProvider
{
/**
* @var array
*/
private static $customChains;
/**
* @throws ClientException
*/
public static function chain()
{
$providers = func_get_args();
if (empty($providers)) {
throw new ClientException('No providers in chain', SDK::INVALID_ARGUMENT);
}
foreach ($providers as $provider) {
if (!$provider instanceof Closure) {
throw new ClientException('Providers must all be Closures', SDK::INVALID_ARGUMENT);
}
}
self::$customChains = $providers;
}
/**
* Forget the custom providers chain.
*/
public static function flush()
{
self::$customChains = [];
}
/**
* @return bool
*/
public static function hasCustomChain()
{
return (bool)self::$customChains;
}
/**
* @param string $clientName
*
* @throws ClientException
*/
public static function customProvider($clientName)
{
foreach (self::$customChains as $provider) {
$provider();
if (AlibabaCloud::has($clientName)) {
break;
}
}
}
/**
* @param string $clientName
*
* @throws ClientException
*/
public static function defaultProvider($clientName)
{
$providers = [
self::env(),
self::ini(),
self::instance(),
];
foreach ($providers as $provider) {
$provider();
if (AlibabaCloud::has($clientName)) {
break;
}
}
}
/**
* @return Closure
*/
public static function env()
{
return static function () {
$accessKeyId = \AlibabaCloud\Client\envNotEmpty('ALIBABA_CLOUD_ACCESS_KEY_ID');
$accessKeySecret = \AlibabaCloud\Client\envNotEmpty('ALIBABA_CLOUD_ACCESS_KEY_SECRET');
if ($accessKeyId && $accessKeySecret) {
AlibabaCloud::accessKeyClient($accessKeyId, $accessKeySecret)->asDefaultClient();
}
};
}
/**
* @return Closure
*/
public static function ini()
{
return static function () {
$ini = \AlibabaCloud\Client\envNotEmpty('ALIBABA_CLOUD_CREDENTIALS_FILE');
if ($ini) {
AlibabaCloud::load($ini);
} else {
// @codeCoverageIgnoreStart
AlibabaCloud::load();
// @codeCoverageIgnoreEnd
}
self::compatibleWithGlobal();
};
}
/**
* @codeCoverageIgnore
*
* Compatible with global
*
* @throws ClientException
*/
private static function compatibleWithGlobal()
{
if (AlibabaCloud::has('global') && !AlibabaCloud::has(self::getDefaultName())) {
AlibabaCloud::get('global')->name(self::getDefaultName());
}
}
/**
* @return array|false|string
* @throws ClientException
*/
public static function getDefaultName()
{
$name = \AlibabaCloud\Client\envNotEmpty('ALIBABA_CLOUD_PROFILE');
if ($name) {
return $name;
}
return 'default';
}
/**
* @return Closure
*/
public static function instance()
{
return static function () {
$instance = \AlibabaCloud\Client\envNotEmpty('ALIBABA_CLOUD_ECS_METADATA');
if ($instance) {
AlibabaCloud::ecsRamRoleClient($instance)->asDefaultClient();
}
};
}
}

View File

@ -0,0 +1,128 @@
<?php
namespace AlibabaCloud\Client\Credentials\Providers;
use Exception;
use Stringy\Stringy;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\Result\Result;
use Psr\Http\Message\ResponseInterface;
use GuzzleHttp\Exception\GuzzleException;
use AlibabaCloud\Client\Request\RpcRequest;
use AlibabaCloud\Client\Credentials\StsCredential;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
use AlibabaCloud\Client\Credentials\EcsRamRoleCredential;
/**
* Class EcsRamRoleProvider
*
* @package AlibabaCloud\Client\Credentials\Providers
*/
class EcsRamRoleProvider extends Provider
{
/**
* Expiration time slot for temporary security credentials.
*
* @var int
*/
protected $expirationSlot = 10;
/**
* @var string
*/
private $uri = 'http://100.100.100.200/latest/meta-data/ram/security-credentials/';
/**
* Get credential.
*
* @return StsCredential
* @throws ClientException
* @throws ServerException
*/
public function get()
{
$result = $this->getCredentialsInCache();
if ($result === null) {
$result = $this->request();
if (!isset($result['AccessKeyId'], $result['AccessKeySecret'], $result['SecurityToken'])) {
throw new ServerException($result, $this->error, SDK::INVALID_CREDENTIAL);
}
$this->cache($result->toArray());
}
return new StsCredential(
$result['AccessKeyId'],
$result['AccessKeySecret'],
$result['SecurityToken']
);
}
/**
* Get credentials by request.
*
* @return Result
* @throws ClientException
* @throws ServerException
*/
public function request()
{
$result = $this->getResponse();
if ($result->getStatusCode() === 404) {
$message = 'The role was not found in the instance';
throw new ClientException($message, SDK::INVALID_CREDENTIAL);
}
if (!$result->isSuccess()) {
$message = 'Error retrieving credentials from result';
throw new ServerException($result, $message, SDK::INVALID_CREDENTIAL);
}
return $result;
}
/**
* Get data from meta.
*
* @return mixed|ResponseInterface
* @throws ClientException
* @throws Exception
*/
public function getResponse()
{
/**
* @var EcsRamRoleCredential $credential
*/
$credential = $this->client->getCredential();
$url = $this->uri . $credential->getRoleName();
$options = [
'http_errors' => false,
'timeout' => 1,
'connect_timeout' => 1,
'debug' => $this->client->isDebug(),
];
try {
return RpcRequest::createClient()->request('GET', $url, $options);
} catch (GuzzleException $exception) {
if (Stringy::create($exception->getMessage())->contains('timed')) {
$message = 'Timeout or instance does not belong to Alibaba Cloud';
} else {
$message = $exception->getMessage();
}
throw new ClientException(
$message,
SDK::SERVER_UNREACHABLE,
$exception
);
}
}
}

View File

@ -0,0 +1,88 @@
<?php
namespace AlibabaCloud\Client\Credentials\Providers;
use AlibabaCloud\Client\Clients\Client;
/**
* Class Provider
*
* @package AlibabaCloud\Client\Credentials\Providers
*/
class Provider
{
/**
* For TSC Duration Seconds
*/
const DURATION_SECONDS = 3600;
/**
* @var array
*/
protected static $credentialsCache = [];
/**
* Expiration time slot for temporary security credentials.
*
* @var int
*/
protected $expirationSlot = 180;
/**
* @var Client
*/
protected $client;
/**
* @var string
*/
protected $error = 'Result contains no credentials';
/**
* CredentialTrait constructor.
*
* @param Client $client
*/
public function __construct(Client $client)
{
$this->client = $client;
}
/**
* Get the credentials from the cache in the validity period.
*
* @return array|null
*/
public function getCredentialsInCache()
{
if (isset(self::$credentialsCache[$this->key()])) {
$result = self::$credentialsCache[$this->key()];
if (\strtotime($result['Expiration']) - \time() >= $this->expirationSlot) {
return $result;
}
unset(self::$credentialsCache[$this->key()]);
}
return null;
}
/**
* Get the toString of the credentials as the key.
*
* @return string
*/
protected function key()
{
return (string)$this->client->getCredential();
}
/**
* Cache credentials.
*
* @param array $credential
*/
protected function cache(array $credential)
{
self::$credentialsCache[$this->key()] = $credential;
}
}

View File

@ -0,0 +1,84 @@
<?php
namespace AlibabaCloud\Client\Credentials\Providers;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Result\Result;
use AlibabaCloud\Client\Request\Request;
use AlibabaCloud\Client\Credentials\StsCredential;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
use AlibabaCloud\Client\Credentials\Requests\AssumeRole;
/**
* Class RamRoleArnProvider
*
* @package AlibabaCloud\Client\Credentials\Providers
*/
class RamRoleArnProvider extends Provider
{
/**
* Get credential.
*
*
* @param int $timeout
* @param int $connectTimeout
*
* @return StsCredential
* @throws ClientException
* @throws ServerException
*/
public function get($timeout = Request::TIMEOUT, $connectTimeout = Request::CONNECT_TIMEOUT)
{
$credential = $this->getCredentialsInCache();
if (null === $credential) {
$result = $this->request($timeout, $connectTimeout);
if (!isset($result['Credentials']['AccessKeyId'],
$result['Credentials']['AccessKeySecret'],
$result['Credentials']['SecurityToken'])) {
throw new ServerException($result, $this->error, SDK::INVALID_CREDENTIAL);
}
$credential = $result['Credentials'];
$this->cache($credential);
}
return new StsCredential(
$credential['AccessKeyId'],
$credential['AccessKeySecret'],
$credential['SecurityToken']
);
}
/**
* Get credentials by request.
*
* @param $timeout
* @param $connectTimeout
*
* @return Result
* @throws ClientException
* @throws ServerException
*/
private function request($timeout, $connectTimeout)
{
$clientName = __CLASS__ . \uniqid('ak', true);
$credential = $this->client->getCredential();
AlibabaCloud::accessKeyClient(
$credential->getAccessKeyId(),
$credential->getAccessKeySecret()
)->name($clientName);
return (new AssumeRole($credential))
->client($clientName)
->timeout($timeout)
->connectTimeout($connectTimeout)
->debug($this->client->isDebug())
->request();
}
}

View File

@ -0,0 +1,86 @@
<?php
namespace AlibabaCloud\Client\Credentials\Providers;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Result\Result;
use AlibabaCloud\Client\Request\Request;
use AlibabaCloud\Client\Credentials\StsCredential;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
use AlibabaCloud\Client\Credentials\AccessKeyCredential;
use AlibabaCloud\Client\Signature\ShaHmac256WithRsaSignature;
use AlibabaCloud\Client\Credentials\Requests\GenerateSessionAccessKey;
/**
* Class RsaKeyPairProvider
*
* @package AlibabaCloud\Client\Credentials\Providers
*/
class RsaKeyPairProvider extends Provider
{
/**
* Get credential.
*
* @param int $timeout
* @param int $connectTimeout
*
* @return StsCredential
* @throws ClientException
* @throws ServerException
*/
public function get($timeout = Request::TIMEOUT, $connectTimeout = Request::CONNECT_TIMEOUT)
{
$credential = $this->getCredentialsInCache();
if ($credential === null) {
$result = $this->request($timeout, $connectTimeout);
if (!isset($result['SessionAccessKey']['SessionAccessKeyId'],
$result['SessionAccessKey']['SessionAccessKeySecret'])) {
throw new ServerException($result, $this->error, SDK::INVALID_CREDENTIAL);
}
$credential = $result['SessionAccessKey'];
$this->cache($credential);
}
return new StsCredential(
$credential['SessionAccessKeyId'],
$credential['SessionAccessKeySecret']
);
}
/**
* Get credentials by request.
*
* @param $timeout
* @param $connectTimeout
*
* @return Result
* @throws ClientException
* @throws ServerException
*/
private function request($timeout, $connectTimeout)
{
$clientName = __CLASS__ . \uniqid('rsa', true);
$credential = $this->client->getCredential();
AlibabaCloud::client(
new AccessKeyCredential(
$credential->getPublicKeyId(),
$credential->getPrivateKey()
),
new ShaHmac256WithRsaSignature()
)->name($clientName);
return (new GenerateSessionAccessKey($credential->getPublicKeyId()))
->client($clientName)
->timeout($timeout)
->connectTimeout($connectTimeout)
->debug($this->client->isDebug())
->request();
}
}

View File

@ -0,0 +1,110 @@
<?php
namespace AlibabaCloud\Client\Credentials;
use AlibabaCloud\Client\Filter\CredentialFilter;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Use the AssumeRole of the RAM account to complete the authentication.
*
* @package AlibabaCloud\Client\Credentials
*/
class RamRoleArnCredential implements CredentialsInterface
{
/**
* @var string
*/
private $accessKeyId;
/**
* @var string
*/
private $accessKeySecret;
/**
* @var string
*/
private $roleArn;
/**
* @var string
*/
private $roleSessionName;
/**
* @var string
*/
private $policy;
/**
* Class constructor.
*
* @param string $accessKeyId
* @param string $accessKeySecret
* @param string $roleArn
* @param string $roleSessionName
* @param string|array $policy
*
* @throws ClientException
*/
public function __construct($accessKeyId, $accessKeySecret, $roleArn, $roleSessionName, $policy = '')
{
CredentialFilter::AccessKey($accessKeyId, $accessKeySecret);
$this->accessKeyId = $accessKeyId;
$this->accessKeySecret = $accessKeySecret;
$this->roleArn = $roleArn;
$this->roleSessionName = $roleSessionName;
$this->policy = $policy;
}
/**
* @return string
*/
public function getAccessKeyId()
{
return $this->accessKeyId;
}
/**
* @return string
*/
public function getAccessKeySecret()
{
return $this->accessKeySecret;
}
/**
* @return string
*/
public function getRoleArn()
{
return $this->roleArn;
}
/**
* @return string
*/
public function getRoleSessionName()
{
return $this->roleSessionName;
}
/**
* @return string
*/
public function getPolicy()
{
return $this->policy;
}
/**
* @return string
*/
public function __toString()
{
return "$this->accessKeyId#$this->accessKeySecret#$this->roleArn#$this->roleSessionName";
}
}

View File

@ -0,0 +1,47 @@
<?php
namespace AlibabaCloud\Client\Credentials\Requests;
use AlibabaCloud\Client\Request\RpcRequest;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Credentials\Providers\Provider;
use AlibabaCloud\Client\Credentials\RamRoleArnCredential;
/**
* Retrieving assume role credentials.
*
* @package AlibabaCloud\Client\Credentials\Requests
*/
class AssumeRole extends RpcRequest
{
/**
* AssumeRole constructor.
*
* @param RamRoleArnCredential $arnCredential
*
* @throws ClientException
*/
public function __construct(RamRoleArnCredential $arnCredential)
{
parent::__construct();
$this->product('Sts');
$this->version('2015-04-01');
$this->action('AssumeRole');
$this->host('sts.aliyuncs.com');
$this->scheme('https');
$this->regionId('cn-hangzhou');
$this->options['verify'] = false;
$this->options['query']['RoleArn'] = $arnCredential->getRoleArn();
$this->options['query']['RoleSessionName'] = $arnCredential->getRoleSessionName();
$this->options['query']['DurationSeconds'] = Provider::DURATION_SECONDS;
if ($arnCredential->getPolicy()) {
if (is_array($arnCredential->getPolicy())) {
$this->options['query']['Policy'] = json_encode($arnCredential->getPolicy());
}
if (is_string($arnCredential->getPolicy())) {
$this->options['query']['Policy'] = $arnCredential->getPolicy();
}
}
}
}

View File

@ -0,0 +1,37 @@
<?php
namespace AlibabaCloud\Client\Credentials\Requests;
use AlibabaCloud\Client\Request\RpcRequest;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Credentials\Providers\Provider;
/**
* Use the RSA key pair to complete the authentication (supported only on Japanese site)
*
* @package AlibabaCloud\Client\Credentials\Requests
*/
class GenerateSessionAccessKey extends RpcRequest
{
/**
* GenerateSessionAccessKey constructor.
*
* @param string $publicKeyId
*
* @throws ClientException
*/
public function __construct($publicKeyId)
{
parent::__construct();
$this->product('Sts');
$this->version('2015-04-01');
$this->action('GenerateSessionAccessKey');
$this->host('sts.ap-northeast-1.aliyuncs.com');
$this->scheme('https');
$this->regionId('cn-hangzhou');
$this->options['verify'] = false;
$this->options['query']['PublicKeyId'] = $publicKeyId;
$this->options['query']['DurationSeconds'] = Provider::DURATION_SECONDS;
}
}

View File

@ -0,0 +1,75 @@
<?php
namespace AlibabaCloud\Client\Credentials;
use Exception;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\Filter\CredentialFilter;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Use the RSA key pair to complete the authentication (supported only on Japanese site)
*
* @package AlibabaCloud\Client\Credentials
*/
class RsaKeyPairCredential implements CredentialsInterface
{
/**
* @var string
*/
private $publicKeyId;
/**
* @var string
*/
private $privateKey;
/**
* RsaKeyPairCredential constructor.
*
* @param string $publicKeyId
* @param string $privateKeyFile
*
* @throws ClientException
*/
public function __construct($publicKeyId, $privateKeyFile)
{
CredentialFilter::publicKeyId($publicKeyId);
CredentialFilter::privateKeyFile($privateKeyFile);
$this->publicKeyId = $publicKeyId;
try {
$this->privateKey = file_get_contents($privateKeyFile);
} catch (Exception $exception) {
throw new ClientException(
$exception->getMessage(),
SDK::INVALID_CREDENTIAL
);
}
}
/**
* @return mixed
*/
public function getPrivateKey()
{
return $this->privateKey;
}
/**
* @return string
*/
public function getPublicKeyId()
{
return $this->publicKeyId;
}
/**
* @return string
*/
public function __toString()
{
return "publicKeyId#$this->publicKeyId";
}
}

View File

@ -0,0 +1,80 @@
<?php
namespace AlibabaCloud\Client\Credentials;
use AlibabaCloud\Client\Filter\CredentialFilter;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Use the STS Token to complete the authentication.
*
* @package AlibabaCloud\Client\Credentials
*/
class StsCredential implements CredentialsInterface
{
/**
* @var string
*/
private $accessKeyId;
/**
* @var string
*/
private $accessKeySecret;
/**
* @var string
*/
private $securityToken;
/**
* StsCredential constructor.
*
* @param string $accessKeyId Access key ID
* @param string $accessKeySecret Access Key Secret
* @param string $securityToken Security Token
*
* @throws ClientException
*/
public function __construct($accessKeyId, $accessKeySecret, $securityToken = '')
{
CredentialFilter::AccessKey($accessKeyId, $accessKeySecret);
$this->accessKeyId = $accessKeyId;
$this->accessKeySecret = $accessKeySecret;
$this->securityToken = $securityToken;
}
/**
* @return string
*/
public function getAccessKeyId()
{
return $this->accessKeyId;
}
/**
* @return string
*/
public function getAccessKeySecret()
{
return $this->accessKeySecret;
}
/**
* @return string
*/
public function getSecurityToken()
{
return $this->securityToken;
}
/**
* @return string
*/
public function __toString()
{
return "$this->accessKeyId#$this->accessKeySecret#$this->securityToken";
}
}

View File

@ -0,0 +1,55 @@
<?php
namespace AlibabaCloud\Client;
use AlibabaCloud\Client\Result\Result;
use AlibabaCloud\Client\Clients\Client;
use AlibabaCloud\Client\Request\Request;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
/**
* Class DefaultAcsClient
*
* @package AlibabaCloud
*
* @deprecated deprecated since version 2.0, Use AlibabaCloud instead.
* @codeCoverageIgnore
*/
class DefaultAcsClient
{
/**
* @var string
*/
public $randClientName;
/**
* DefaultAcsClient constructor.
*
* @param Client $client
*
* @throws ClientException
*/
public function __construct(Client $client)
{
$this->randClientName = \uniqid('', true);
$client->name($this->randClientName);
}
/**
* @param Request|Result $request
*
* @return Result|string
* @throws ClientException
* @throws ServerException
*/
public function getAcsResponse($request)
{
if ($request instanceof Result) {
return $request;
}
return $request->client($this->randClientName)->request();
}
}

View File

@ -0,0 +1,64 @@
<?php
namespace AlibabaCloud\Client;
/**
* Class Encode
*
* @package AlibabaCloud\Client
*/
class Encode
{
/**
* @var array
*/
private $data;
/**
* @param array $data
*
* @return static
*/
public static function create(array $data)
{
return new static($data);
}
/**
* Encode constructor.
*
* @param array $data
*/
private function __construct(array $data)
{
$this->data = $data;
}
/**
* @return bool|string
*/
public function toString()
{
$string = '';
foreach ($this->data as $key => $value) {
$encode = rawurlencode($value);
$string .= "$key=$encode&";
}
if (0 < count($this->data)) {
$string = substr($string, 0, -1);
}
return $string;
}
/**
* @return $this
*/
public function ksort()
{
ksort($this->data);
return $this;
}
}

View File

@ -0,0 +1,70 @@
<?php
namespace AlibabaCloud\Client\Exception;
use Exception;
use RuntimeException;
/**
* Class AlibabaCloudException
*
* @package AlibabaCloud\Client\Exception
*/
abstract class AlibabaCloudException extends Exception
{
/**
* @var string
*/
protected $errorCode;
/**
* @var string
*/
protected $errorMessage;
/**
* @return string
*/
public function getErrorCode()
{
return $this->errorCode;
}
/**
* @codeCoverageIgnore
* @deprecated
*/
public function setErrorCode()
{
throw new RuntimeException('deprecated since 2.0.');
}
/**
* @return string
*/
public function getErrorMessage()
{
return $this->errorMessage;
}
/**
* @codeCoverageIgnore
*
* @param $errorMessage
*
* @deprecated
*/
public function setErrorMessage($errorMessage)
{
$this->errorMessage = $errorMessage;
}
/**
* @codeCoverageIgnore
* @deprecated
*/
public function setErrorType()
{
}
}

View File

@ -0,0 +1,38 @@
<?php
namespace AlibabaCloud\Client\Exception;
use Exception;
use RuntimeException;
/**
* Class ClientException
*
* @package AlibabaCloud\Client\Exception
*/
class ClientException extends AlibabaCloudException
{
/**
* ClientException constructor.
*
* @param string $errorMessage
* @param string $errorCode
* @param Exception|null $previous
*/
public function __construct($errorMessage, $errorCode, $previous = null)
{
parent::__construct($errorMessage, 0, $previous);
$this->errorMessage = $errorMessage;
$this->errorCode = $errorCode;
}
/**
* @codeCoverageIgnore
* @deprecated
*/
public function getErrorType()
{
return 'Client';
}
}

View File

@ -0,0 +1,158 @@
<?php
namespace AlibabaCloud\Client\Exception;
use Stringy\Stringy;
use RuntimeException;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\Result\Result;
/**
* Class ServerException
*
* @package AlibabaCloud\Client\Exception
*/
class ServerException extends AlibabaCloudException
{
/**
* @var string
*/
protected $requestId;
/**
* @var Result
*/
protected $result;
/**
* ServerException constructor.
*
* @param Result|null $result
* @param string $errorMessage
* @param string $errorCode
*/
public function __construct(
Result $result,
$errorMessage = SDK::RESPONSE_EMPTY,
$errorCode = SDK::SERVICE_UNKNOWN_ERROR
) {
$this->result = $result;
$this->errorMessage = $errorMessage;
$this->errorCode = $errorCode;
$this->resolvePropertiesByReturn();
$this->distinguishSignatureErrors();
$this->bodyAsErrorMessage();
parent::__construct(
$this->getMessageString(),
$this->result->getStatusCode()
);
}
/**
* Resolve the error message based on the return of the server.
*
* @return void
*/
private function resolvePropertiesByReturn()
{
if (isset($this->result['message'])) {
$this->errorMessage = $this->result['message'];
$this->errorCode = $this->result['code'];
}
if (isset($this->result['Message'])) {
$this->errorMessage = $this->result['Message'];
$this->errorCode = $this->result['Code'];
}
if (isset($this->result['errorMsg'])) {
$this->errorMessage = $this->result['errorMsg'];
$this->errorCode = $this->result['errorCode'];
}
if (isset($this->result['requestId'])) {
$this->requestId = $this->result['requestId'];
}
if (isset($this->result['RequestId'])) {
$this->requestId = $this->result['RequestId'];
}
}
/**
* If the string to be signed are the same with server's, it is considered a credential error.
*/
private function distinguishSignatureErrors()
{
if ($this->result->getRequest()
&& Stringy::create($this->errorMessage)->contains($this->result->getRequest()->stringToSign())) {
$this->errorCode = 'InvalidAccessKeySecret';
$this->errorMessage = 'Specified Access Key Secret is not valid.';
}
}
/**
* If the error message matches the default message and
* the server has returned content, use the return content
*/
private function bodyAsErrorMessage()
{
$body = (string)$this->result->getBody();
if ($this->errorMessage === SDK::RESPONSE_EMPTY && $body) {
$this->errorMessage = $body;
}
}
/**
* Get standard exception message.
*
* @return string
*/
private function getMessageString()
{
$message = "$this->errorCode: $this->errorMessage RequestId: $this->requestId";
if ($this->getResult()->getRequest()) {
$method = $this->getResult()->getRequest()->method;
$uri = (string)$this->getResult()->getRequest()->uri;
$message .= " $method \"$uri\"";
if ($this->result) {
$message .= ' ' . $this->result->getStatusCode();
}
}
return $message;
}
/**
* @return Result
*/
public function getResult()
{
return $this->result;
}
/**
* @return string
*/
public function getRequestId()
{
return $this->requestId;
}
/**
* @codeCoverageIgnore
* @deprecated
*/
public function getErrorType()
{
return 'Server';
}
/**
* @codeCoverageIgnore
* @deprecated
*/
public function getHttpStatus()
{
return $this->getResult()->getStatusCode();
}
}

View File

@ -0,0 +1,245 @@
<?php
namespace AlibabaCloud\Client\Filter;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Class ApiFilter
*
* @package AlibabaCloud\Client\Filter
*/
class ApiFilter
{
/**
* @param $serviceCode
*
* @return mixed
* @throws ClientException
*/
public static function serviceCode($serviceCode)
{
if (!is_string($serviceCode)) {
throw new ClientException(
'Service Code must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($serviceCode === '') {
throw new ClientException(
'Service Code cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $serviceCode;
}
/**
* @param $endpointType
*
* @return mixed
* @throws ClientException
*/
public static function endpointType($endpointType)
{
if (!is_string($endpointType)) {
throw new ClientException(
'Endpoint Type must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($endpointType === '') {
throw new ClientException(
'Endpoint Type cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $endpointType;
}
/**
* @param $action
*
* @return mixed
* @throws ClientException
*/
public static function action($action)
{
if (!is_string($action)) {
throw new ClientException(
'Action must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($action === '') {
throw new ClientException(
'Action cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $action;
}
/**
* @codeCoverageIgnore
*
* @param string $endpointSuffix
*
* @return mixed
* @throws ClientException
*/
public static function endpointSuffix($endpointSuffix)
{
if (!is_string($endpointSuffix)) {
throw new ClientException(
'Endpoint Suffix must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($endpointSuffix === '') {
throw new ClientException(
'Endpoint Suffix cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $endpointSuffix;
}
/**
* @codeCoverageIgnore
*
* @param string $network
*
* @return mixed
* @throws ClientException
*/
public static function network($network)
{
if (!is_string($network)) {
throw new ClientException(
'Network Suffix must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($network === '') {
throw new ClientException(
'Network Suffix cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $network;
}
/**
* @param string $version
*
* @return mixed
* @throws ClientException
*/
public static function version($version)
{
if (!is_string($version)) {
throw new ClientException(
'Version must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($version === '') {
throw new ClientException(
'Version cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $version;
}
/**
* @param $format
*
* @return mixed
* @throws ClientException
*/
public static function format($format)
{
if (!is_string($format)) {
throw new ClientException(
'Format must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($format === '') {
throw new ClientException(
'Format cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return \strtoupper($format);
}
/**
* @param $product
*
* @return string
*
* @throws ClientException
*/
public static function product($product)
{
if (!is_string($product)) {
throw new ClientException(
'Product must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($product === '') {
throw new ClientException(
'Product cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $product;
}
/**
* @param $pattern
*
* @return string
*
* @throws ClientException
*/
public static function pattern($pattern)
{
if (!is_string($pattern)) {
throw new ClientException(
'Pattern must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($pattern === '') {
throw new ClientException(
'Pattern cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $pattern;
}
}

View File

@ -0,0 +1,139 @@
<?php
namespace AlibabaCloud\Client\Filter;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Class ClientFilter
*
* @package AlibabaCloud\Client\Filter
*/
class ClientFilter
{
/**
* @param $regionId
*
* @return string
*
* @throws ClientException
*/
public static function regionId($regionId)
{
if (!is_string($regionId)) {
throw new ClientException(
'Region ID must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($regionId === '') {
throw new ClientException(
'Region ID cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return strtolower($regionId);
}
/**
* @param $clientName
*
* @return string
*
* @throws ClientException
*/
public static function clientName($clientName)
{
if (!is_string($clientName)) {
throw new ClientException(
'Client Name must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($clientName === '') {
throw new ClientException(
'Client Name cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return strtolower($clientName);
}
/**
* @param $times
*
* @return string
*
* @throws ClientException
*/
public static function retry($times)
{
if (!is_int($times)) {
throw new ClientException(
'Retry must be a int',
SDK::INVALID_ARGUMENT
);
}
return $times;
}
/**
* @param $connectTimeout
*
* @return mixed
* @throws ClientException
*/
public static function connectTimeout($connectTimeout)
{
if ($connectTimeout === '') {
throw new ClientException(
'Connect Timeout cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $connectTimeout;
}
/**
* @param $timeout
*
* @return mixed
* @throws ClientException
*/
public static function timeout($timeout)
{
if ($timeout === '') {
throw new ClientException(
'Timeout cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $timeout;
}
/**
* @param int $Milliseconds
*
* @return mixed
* @throws ClientException
*/
public static function milliseconds($Milliseconds)
{
if (!is_int($Milliseconds)) {
throw new ClientException(
'Milliseconds must be int',
SDK::INVALID_ARGUMENT
);
}
return $Milliseconds;
}
}

View File

@ -0,0 +1,152 @@
<?php
namespace AlibabaCloud\Client\Filter;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Class CredentialFilter
*
* @package AlibabaCloud\Client\Filter
*/
class CredentialFilter
{
/**
* @param $bearerToken
*
* @return mixed
* @throws ClientException
*/
public static function bearerToken($bearerToken)
{
if (!is_string($bearerToken)) {
throw new ClientException(
'Bearer Token must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($bearerToken === '') {
throw new ClientException(
'Bearer Token cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $bearerToken;
}
/**
* @param $publicKeyId
*
* @return mixed
* @throws ClientException
*/
public static function publicKeyId($publicKeyId)
{
if (!is_string($publicKeyId)) {
throw new ClientException(
'Public Key ID must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($publicKeyId === '') {
throw new ClientException(
'Public Key ID cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $publicKeyId;
}
/**
* @param $privateKeyFile
*
* @return mixed
* @throws ClientException
*/
public static function privateKeyFile($privateKeyFile)
{
if (!is_string($privateKeyFile)) {
throw new ClientException(
'Private Key File must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($privateKeyFile === '') {
throw new ClientException(
'Private Key File cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $privateKeyFile;
}
/**
* @param $roleName
*
* @return string
*
* @throws ClientException
*/
public static function roleName($roleName)
{
if (!is_string($roleName)) {
throw new ClientException(
'Role Name must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($roleName === '') {
throw new ClientException(
'Role Name cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $roleName;
}
/**
* @param string $accessKeyId
* @param string $accessKeySecret
*
* @throws ClientException
*/
public static function AccessKey($accessKeyId, $accessKeySecret)
{
if (!is_string($accessKeyId)) {
throw new ClientException(
'AccessKey ID must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($accessKeyId === '') {
throw new ClientException(
'AccessKey ID cannot be empty',
SDK::INVALID_ARGUMENT
);
}
if (!is_string($accessKeySecret)) {
throw new ClientException(
'AccessKey Secret must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($accessKeySecret === '') {
throw new ClientException(
'AccessKey Secret cannot be empty',
SDK::INVALID_ARGUMENT
);
}
}
}

View File

@ -0,0 +1,67 @@
<?php
namespace AlibabaCloud\Client\Filter;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Class Filter
*
* @package AlibabaCloud\Client\Filter
*/
class Filter
{
/**
* @param $name
*
* @return string
*
* @throws ClientException
*/
public static function name($name)
{
if (!is_string($name)) {
throw new ClientException(
'Name must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($name === '') {
throw new ClientException(
'Name cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $name;
}
/**
* @param $value
*
* @return string
*
* @throws ClientException
*/
public static function value($value)
{
if (!is_numeric($value) && !is_string($value)) {
throw new ClientException(
'Value must be a string or int',
SDK::INVALID_ARGUMENT
);
}
if ($value === '') {
throw new ClientException(
'Value cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $value;
}
}

View File

@ -0,0 +1,166 @@
<?php
namespace AlibabaCloud\Client\Filter;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Class HttpFilter
*
* @package AlibabaCloud\Client\Filter
*/
class HttpFilter
{
/**
* @param $host
*
* @return string
*
* @throws ClientException
*/
public static function host($host)
{
if (!is_string($host)) {
throw new ClientException(
'Host must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($host === '') {
throw new ClientException(
'Host cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $host;
}
/**
* @param $scheme
*
* @return string
*
* @throws ClientException
*/
public static function scheme($scheme)
{
if (!is_string($scheme)) {
throw new ClientException(
'Scheme must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($scheme === '') {
throw new ClientException(
'Scheme cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $scheme;
}
/**
* @param $body
*
* @return mixed
* @throws ClientException
*/
public static function body($body)
{
if (!is_string($body) && !is_numeric($body)) {
throw new ClientException(
'Body must be a string or int',
SDK::INVALID_ARGUMENT
);
}
if ($body === '') {
throw new ClientException(
'Body cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $body;
}
/**
* @param $method
*
* @return mixed
* @throws ClientException
*/
public static function method($method)
{
if (!is_string($method)) {
throw new ClientException(
'Method must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($method === '') {
throw new ClientException(
'Method cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return \strtoupper($method);
}
/**
* @param $contentType
*
* @return mixed
* @throws ClientException
*/
public static function contentType($contentType)
{
if (!is_string($contentType)) {
throw new ClientException(
'Content-Type must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($contentType === '') {
throw new ClientException(
'Content-Type cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $contentType;
}
/**
* @param $accept
*
* @return mixed
* @throws ClientException
*/
public static function accept($accept)
{
if (!is_string($accept)) {
throw new ClientException(
'Accept must be a string',
SDK::INVALID_ARGUMENT
);
}
if ($accept === '') {
throw new ClientException(
'Accept cannot be empty',
SDK::INVALID_ARGUMENT
);
}
return $accept;
}
}

View File

@ -0,0 +1,289 @@
<?php
namespace AlibabaCloud\Client;
use Closure;
use Stringy\Stringy;
use League\CLImate\CLImate;
use AlibabaCloud\Client\Exception\ClientException;
/*
|--------------------------------------------------------------------------
| Global Functions for Alibaba Cloud
|--------------------------------------------------------------------------
|
| Some common global functions are defined here.
| This file will be automatically loaded.
|
*/
/**
* @param $filename
* @param bool $throwException
*
* @return bool
* @throws ClientException
*/
function inOpenBasedir($filename, $throwException = false)
{
$open_basedir = ini_get('open_basedir');
if (!$open_basedir) {
return true;
}
$dirs = explode(PATH_SEPARATOR, $open_basedir);
if (empty($dirs)) {
return true;
}
if (inDir($filename, $dirs)) {
return true;
}
if ($throwException === false) {
return false;
}
throw new ClientException(
'open_basedir restriction in effect. '
. "File($filename) is not within the allowed path(s): ($open_basedir)",
'SDK.InvalidPath'
);
}
/**
* @param string $filename
* @param array $dirs
*
* @return bool
*/
function inDir($filename, array $dirs)
{
foreach ($dirs as $dir) {
if (!Stringy::create($dir)->endsWith(DIRECTORY_SEPARATOR)) {
$dir .= DIRECTORY_SEPARATOR;
}
if (0 === strpos($filename, $dir)) {
return true;
}
}
return false;
}
/**
* @return bool
*/
function isWindows()
{
return PATH_SEPARATOR === ';';
}
/**
* @return CLImate
*/
function cliMate()
{
return new CLImate();
}
/**
* @param string $string
* @param string|null $flank
* @param string|null $char
* @param int|null $length
*
* @return void
*/
function backgroundRed($string, $flank = null, $char = null, $length = null)
{
cliMate()->br();
if ($flank !== null) {
cliMate()->backgroundRed()->flank($flank, $char, $length);
cliMate()->br();
}
cliMate()->backgroundRed($string);
cliMate()->br();
}
/**
* @param string $string
* @param string|null $flank
* @param string|null $char
* @param int|null $length
*
* @return void
*/
function backgroundGreen($string, $flank = null, $char = null, $length = null)
{
cliMate()->br();
if ($flank !== null) {
cliMate()->backgroundGreen()->flank($flank, $char, $length);
}
cliMate()->backgroundGreen($string);
cliMate()->br();
}
/**
* @param string $string
* @param string|null $flank
* @param string|null $char
* @param int|null $length
*
* @return void
*/
function backgroundBlue($string, $flank = null, $char = null, $length = null)
{
cliMate()->br();
if ($flank !== null) {
cliMate()->backgroundBlue()->flank($flank, $char, $length);
}
cliMate()->backgroundBlue($string);
cliMate()->br();
}
/**
* @param string $string
* @param string|null $flank
* @param string|null $char
* @param int|null $length
*
* @return void
*/
function backgroundMagenta($string, $flank = null, $char = null, $length = null)
{
cliMate()->br();
if ($flank !== null) {
cliMate()->backgroundMagenta()->flank($flank, $char, $length);
}
cliMate()->backgroundMagenta($string);
cliMate()->br();
}
/**
* @param array $array
*/
function json(array $array)
{
cliMate()->br();
cliMate()->backgroundGreen()->json($array);
cliMate()->br();
}
/**
* @param array $array
*
* @return void
*/
function redTable($array)
{
/**
* @noinspection PhpUndefinedMethodInspection
*/
cliMate()->redTable($array);
}
/**
* @param mixed $result
* @param string $title
*
* @return void
*/
function block($result, $title)
{
cliMate()->backgroundGreen()->flank($title, '--', 20);
dump($result);
}
/**
* Gets the value of an environment variable.
*
* @param string $key
* @param mixed $default
*
* @return mixed
*/
function env($key, $default = null)
{
$value = getenv($key);
if ($value === false) {
return value($default);
}
if (envSubstr($value)) {
return substr($value, 1, -1);
}
return envConversion($value);
}
/**
* @param $value
*
* @return bool|string|null
*/
function envConversion($value)
{
$key = strtolower($value);
if ($key === 'null' || $key === '(null)') {
return null;
}
$list = [
'true' => true,
'(true)' => true,
'false' => false,
'(false)' => false,
'empty' => '',
'(empty)' => '',
];
return isset($list[$key]) ? $list[$key] : $value;
}
/**
* @param $key
*
* @return bool|mixed
* @throws ClientException
*/
function envNotEmpty($key)
{
$value = env($key, false);
if ($value !== false && !$value) {
throw new ClientException(
"Environment variable '$key' cannot be empty",
SDK::INVALID_ARGUMENT
);
}
if ($value) {
return $value;
}
return false;
}
/**
* @param $value
*
* @return bool
*/
function envSubstr($value)
{
return ($valueLength = strlen($value)) > 1 && strpos($value, '"') === 0 && $value[$valueLength - 1] === '"';
}
/**
* Return the default value of the given value.
*
* @param mixed $value
*
* @return mixed
*/
function value($value)
{
return $value instanceof Closure ? $value() : $value;
}

View File

@ -0,0 +1,78 @@
<?php
namespace AlibabaCloud\Client\Log;
use DateTime;
use Exception;
use DateTimeZone;
use GuzzleHttp\MessageFormatter;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
/**
* Class LogFormatter
*
* @package AlibabaCloud\Client\Log
*/
class LogFormatter extends MessageFormatter
{
/**
* @var float
*/
private static $logStartTime = 0;
/**
* @var DateTime
*/
private static $ts;
/** @var string Template used to format log messages */
public $template;
/**
* @param string $template Log message template
*
* @throws Exception
*/
public function __construct($template)
{
parent::__construct($template);
self::$logStartTime = microtime(true);
$this->template = $template;
$timezone = new DateTimeZone(date_default_timezone_get() ?: 'UTC');
if (PHP_VERSION_ID < 70100) {
self::$ts = DateTime::createFromFormat('U.u', sprintf('%.6F', microtime(true)), $timezone);
} else {
self::$ts = new DateTime(null, $timezone);
}
}
/**
* Returns a formatted message string.
*
* @param RequestInterface $request Request that was sent
* @param ResponseInterface $response Response that was received
* @param Exception $error Exception that was received
*
* @return string
*/
public function format(
RequestInterface $request,
ResponseInterface $response = null,
Exception $error = null
) {
$this->template = str_replace('{pid}', getmypid(), $this->template);
$this->template = str_replace('{cost}', self::getCost(), $this->template);
$this->template = str_replace('{start_time}', self::$ts->format('Y-m-d H:i:s.u'), $this->template);
return (new MessageFormatter($this->template))->format($request, $response, $error);
}
/**
* @return float|mixed
*/
private static function getCost()
{
return microtime(true) - self::$logStartTime;
}
}

View File

@ -0,0 +1,74 @@
<?php
namespace AlibabaCloud\Client\Profile;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Clients\Client;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Class DefaultProfile
*
* @package AlibabaCloud\Client\Profile
* @codeCoverageIgnore
* @deprecated deprecated since version 2.0, Use AlibabaCloud instead.
*/
class DefaultProfile
{
/**
* @param string $regionId
* @param string $accessKeyId
* @param string $accessKeySecret
*
* @return Client
* @throws ClientException
*/
public static function getProfile($regionId, $accessKeyId, $accessKeySecret)
{
return AlibabaCloud::accessKeyClient($accessKeyId, $accessKeySecret)
->regionId($regionId);
}
/**
* @param string $regionId
* @param string $accessKeyId
* @param string $accessKeySecret
* @param string $roleArn
* @param string $roleSessionName
*
* @return Client
* @throws ClientException
*/
public static function getRamRoleArnProfile($regionId, $accessKeyId, $accessKeySecret, $roleArn, $roleSessionName)
{
return AlibabaCloud::ramRoleArnClient($accessKeyId, $accessKeySecret, $roleArn, $roleSessionName)
->regionId($regionId);
}
/**
* @param string $regionId
* @param string $roleName
*
* @return Client
* @throws ClientException
*/
public static function getEcsRamRoleProfile($regionId, $roleName)
{
return AlibabaCloud::ecsRamRoleClient($roleName)
->regionId($regionId);
}
/**
* @param string $regionId
* @param string $bearerToken
*
* @return Client
* @throws ClientException
*/
public static function getBearerTokenProfile($regionId, $bearerToken)
{
return AlibabaCloud::bearerTokenClient($bearerToken)
->regionId($regionId);
}
}

View File

@ -0,0 +1,18 @@
<?php
namespace AlibabaCloud\Client\Regions;
use AlibabaCloud\Client\Traits\EndpointTrait;
/**
* Class EndpointProvider
*
* @package AlibabaCloud\Client\Regions
*
* @deprecated deprecated since version 2.0, Use AlibabaCloud instead.
* @codeCoverageIgnore
*/
class EndpointProvider
{
use EndpointTrait;
}

View File

@ -0,0 +1,160 @@
<?php
namespace AlibabaCloud\Client\Regions;
use Exception;
use RuntimeException;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\Config\Config;
use AlibabaCloud\Client\Request\Request;
use AlibabaCloud\Client\Filter\ApiFilter;
use AlibabaCloud\Client\Filter\HttpFilter;
use AlibabaCloud\Client\Filter\ClientFilter;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
/**
* Class LocationService
*
* @package AlibabaCloud\Client\Regions
*/
class LocationService
{
/**
* Global Region Name
*/
const GLOBAL_REGION = 'global';
/**
* @var array
*/
protected static $hosts = [];
/**
* @var Request
*/
protected $request;
/**
* LocationService constructor.
*
* @param Request $request
*/
private function __construct(Request $request)
{
$this->request = $request;
}
/**
* @param Request $request
* @param string $domain
*
* @return string
* @throws ClientException
* @throws ServerException
* @deprecated
* @codeCoverageIgnore
*/
public static function findProductDomain(Request $request, $domain = 'location.aliyuncs.com')
{
return self::resolveHost($request, $domain);
}
/**
* @param $regionId
* @param $product
* @param $domain
*
* @throws ClientException
* @deprecated
* @codeCoverageIgnore
*/
public static function addEndPoint($regionId, $product, $domain)
{
self::addHost($product, $domain, $regionId);
}
/**
* @param Request $request
* @param string $domain
*
* @return string
* @throws ClientException
* @throws ServerException
*/
public static function resolveHost(Request $request, $domain = 'location.aliyuncs.com')
{
$locationService = new static($request);
$product = $locationService->request->product;
$regionId = $locationService->request->realRegionId();
if (!isset(self::$hosts[$product][$regionId])) {
self::$hosts[$product][$regionId] = self::getResult($locationService, $domain);
}
return self::$hosts[$product][$regionId];
}
/**
* @param static $locationService
* @param string $domain
*
* @return string
* @throws ClientException
* @throws ServerException
*/
private static function getResult($locationService, $domain)
{
$locationRequest = new LocationServiceRequest($locationService->request, $domain);
$result = $locationRequest->request();
if (!isset($result['Endpoints']['Endpoint'][0]['Endpoint'])) {
throw new ClientException(
'Not found Region ID in ' . $domain,
SDK::INVALID_REGION_ID
);
}
return $result['Endpoints']['Endpoint'][0]['Endpoint'];
}
/**
* @param string $product
* @param string $host
* @param string $regionId
*
* @throws ClientException
*/
public static function addHost($product, $host, $regionId = self::GLOBAL_REGION)
{
ApiFilter::product($product);
HttpFilter::host($host);
ClientFilter::regionId($regionId);
self::$hosts[$product][$regionId] = $host;
}
/**
* Update endpoints from OSS.
*
* @codeCoverageIgnore
* @throws Exception
*/
public static function updateEndpoints()
{
$ossUrl = 'https://openapi-endpoints.oss-cn-hangzhou.aliyuncs.com/endpoints.json';
$json = \file_get_contents($ossUrl);
$list = \json_decode($json, true);
foreach ($list['endpoints'] as $endpoint) {
Config::set(
"endpoints.{$endpoint['service']}.{$endpoint['regionid']}",
\strtolower($endpoint['endpoint'])
);
}
}
}

View File

@ -0,0 +1,46 @@
<?php
namespace AlibabaCloud\Client\Regions;
use AlibabaCloud\Client\Request\Request;
use AlibabaCloud\Client\Request\RpcRequest;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Class LocationServiceRequest
*
* @package AlibabaCloud\Client\Regions
*/
class LocationServiceRequest extends RpcRequest
{
/**
* LocationServiceRequest constructor.
*
* @param Request $request
* @param string $domain
*
* @throws ClientException
*/
public function __construct(Request $request, $domain)
{
parent::__construct();
$this->product('Location');
$this->version('2015-06-12');
$this->action('DescribeEndpoints');
$this->regionId('cn-hangzhou');
$this->format('JSON');
$this->options['query']['Id'] = $request->realRegionId();
$this->options['query']['ServiceCode'] = $request->serviceCode;
$this->options['query']['Type'] = $request->endpointType;
$this->client($request->client);
$this->host($domain);
if (isset($request->options['timeout'])) {
$this->timeout($request->options['timeout']);
}
if (isset($request->options['connect_timeout'])) {
$this->connectTimeout($request->options['connect_timeout']);
}
}
}

View File

@ -0,0 +1,112 @@
<?php
namespace AlibabaCloud\Client;
use Composer\Script\Event;
/**
* Class Release
*
* @codeCoverageIgnore
* @package AlibabaCloud\Client
*/
class Release
{
/**
* @param Event $event
*/
public static function release(Event $event)
{
$arguments = $event->getArguments();
if (count($arguments) <= 1) {
echo 'Missing ChangeLog';
return;
}
self::updateChangelogFile($arguments[0], $arguments[1]);
self::changeVersionInCode($arguments[0]);
}
/**
* @param $version
* @param $changeLog
*/
private static function updateChangelogFile($version, $changeLog)
{
$content = preg_replace(
'/# CHANGELOG/',
'# CHANGELOG'
. "\n"
. "\n"
. "## $version - " . date('Y-m-d')
. self::log($changeLog),
self::getChangeLogContent()
);
file_put_contents(self::getChangeLogFile(), $content);
}
/**
* @param $changeLog
*
* @return string
*/
private static function log($changeLog)
{
$logs = explode('|', $changeLog);
$string = "\n";
foreach ($logs as $log) {
if ($log) {
$string .= "- $log." . "\n";
}
}
return $string;
}
/**
* @return string
*/
private static function getChangeLogContent()
{
return file_get_contents(self::getChangeLogFile());
}
/**
* @return string
*/
private static function getChangeLogFile()
{
return __DIR__ . '/../CHANGELOG.md';
}
/**
* @param $version
*/
private static function changeVersionInCode($version)
{
$content = preg_replace(
"/const VERSION = \'(.*)\';/",
"const VERSION = '" . $version . "';",
self::getCodeContent()
);
file_put_contents(self::getCodeFile(), $content);
}
/**
* @return string
*/
private static function getCodeContent()
{
return file_get_contents(self::getCodeFile());
}
/**
* @return string
*/
private static function getCodeFile()
{
return __DIR__ . '/AlibabaCloud.php';
}
}

View File

@ -0,0 +1,445 @@
<?php
namespace AlibabaCloud\Client\Request;
use Exception;
use ArrayAccess;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Uri;
use GuzzleHttp\Middleware;
use AlibabaCloud\Client\SDK;
use GuzzleHttp\HandlerStack;
use AlibabaCloud\Client\Encode;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Filter\Filter;
use AlibabaCloud\Client\Result\Result;
use Psr\Http\Message\ResponseInterface;
use GuzzleHttp\Promise\PromiseInterface;
use AlibabaCloud\Client\Filter\ApiFilter;
use AlibabaCloud\Client\Log\LogFormatter;
use AlibabaCloud\Client\Traits\HttpTrait;
use GuzzleHttp\Exception\GuzzleException;
use AlibabaCloud\Client\Filter\HttpFilter;
use AlibabaCloud\Client\Traits\RegionTrait;
use AlibabaCloud\Client\Filter\ClientFilter;
use AlibabaCloud\Client\Request\Traits\AcsTrait;
use AlibabaCloud\Client\Traits\ArrayAccessTrait;
use AlibabaCloud\Client\Traits\ObjectAccessTrait;
use AlibabaCloud\Client\Request\Traits\RetryTrait;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
use AlibabaCloud\Client\Request\Traits\ClientTrait;
use AlibabaCloud\Client\Request\Traits\DeprecatedTrait;
use AlibabaCloud\Client\Credentials\Providers\CredentialsProvider;
/**
* Class Request
*
* @package AlibabaCloud\Client\Request
*
* @method string stringToSign()
* @method string resolveParameter()
*/
abstract class Request implements ArrayAccess
{
use DeprecatedTrait;
use HttpTrait;
use RegionTrait;
use ClientTrait;
use AcsTrait;
use ArrayAccessTrait;
use ObjectAccessTrait;
use RetryTrait;
/**
* Request Connect Timeout
*/
const CONNECT_TIMEOUT = 5;
/**
* Request Timeout
*/
const TIMEOUT = 10;
/**
* @var string HTTP Method
*/
public $method = 'GET';
/**
* @var string
*/
public $format = 'JSON';
/**
* @var string HTTP Scheme
*/
protected $scheme = 'http';
/**
* @var string
*/
public $client;
/**
* @var Uri
*/
public $uri;
/**
* @var array The original parameters of the request.
*/
public $data = [];
/**
* @var array
*/
private $userAgent = [];
/**
* Request constructor.
*
* @param array $options
*
* @throws ClientException
*/
public function __construct(array $options = [])
{
$this->client = CredentialsProvider::getDefaultName();
$this->uri = new Uri();
$this->uri = $this->uri->withScheme($this->scheme);
$this->options['http_errors'] = false;
$this->options['connect_timeout'] = self::CONNECT_TIMEOUT;
$this->options['timeout'] = self::TIMEOUT;
// Turn on debug mode based on environment variable.
if (strtolower(\AlibabaCloud\Client\env('DEBUG')) === 'sdk') {
$this->options['debug'] = true;
}
// Rewrite configuration if the user has a configuration.
if ($options !== []) {
$this->options($options);
}
}
/**
* @param string $name
* @param string $value
*
* @return $this
* @throws ClientException
*/
public function appendUserAgent($name, $value)
{
$filter_name = Filter::name($name);
if (!UserAgent::isGuarded($filter_name)) {
$this->userAgent[$filter_name] = Filter::value($value);
}
return $this;
}
/**
* @param array $userAgent
*
* @return $this
*/
public function withUserAgent(array $userAgent)
{
$this->userAgent = UserAgent::clean($userAgent);
return $this;
}
/**
* Set Accept format.
*
* @param string $format
*
* @return $this
* @throws ClientException
*/
public function format($format)
{
$this->format = ApiFilter::format($format);
return $this;
}
/**
* @param $contentType
*
* @return $this
* @throws ClientException
*/
public function contentType($contentType)
{
$this->options['headers']['Content-Type'] = HttpFilter::contentType($contentType);
return $this;
}
/**
* @param string $accept
*
* @return $this
* @throws ClientException
*/
public function accept($accept)
{
$this->options['headers']['Accept'] = HttpFilter::accept($accept);
return $this;
}
/**
* Set the request body.
*
* @param string $body
*
* @return $this
* @throws ClientException
*/
public function body($body)
{
$this->options['body'] = HttpFilter::body($body);
return $this;
}
/**
* Set the json as body.
*
* @param array|object $content
*
* @return $this
* @throws ClientException
*/
public function jsonBody($content)
{
if (!\is_array($content) && !\is_object($content)) {
throw new ClientException(
'jsonBody only accepts an array or object',
SDK::INVALID_ARGUMENT
);
}
return $this->body(\json_encode($content));
}
/**
* Set the request scheme.
*
* @param string $scheme
*
* @return $this
* @throws ClientException
*/
public function scheme($scheme)
{
$this->scheme = HttpFilter::scheme($scheme);
$this->uri = $this->uri->withScheme($scheme);
return $this;
}
/**
* Set the request host.
*
* @param string $host
*
* @return $this
* @throws ClientException
*/
public function host($host)
{
$this->uri = $this->uri->withHost(HttpFilter::host($host));
return $this;
}
/**
* @param string $method
*
* @return $this
* @throws ClientException
*/
public function method($method)
{
$this->method = HttpFilter::method($method);
return $this;
}
/**
* @param string $clientName
*
* @return $this
* @throws ClientException
*/
public function client($clientName)
{
$this->client = ClientFilter::clientName($clientName);
return $this;
}
/**
* @return bool
* @throws ClientException
*/
public function isDebug()
{
if (isset($this->options['debug'])) {
return $this->options['debug'] === true;
}
if (isset($this->httpClient()->options['debug'])) {
return $this->httpClient()->options['debug'] === true;
}
return false;
}
/**
* @throws ClientException
* @throws ServerException
*/
public function resolveOption()
{
$this->options['headers']['User-Agent'] = UserAgent::toString($this->userAgent);
$this->cleanQuery();
$this->cleanFormParams();
$this->resolveHost();
$this->resolveParameter();
if (isset($this->options['form_params'])) {
$this->options['form_params'] = \GuzzleHttp\Psr7\parse_query(
Encode::create($this->options['form_params'])->toString()
);
}
$this->mergeOptionsIntoClient();
}
/**
* @return Result
* @throws ClientException
* @throws ServerException
*/
public function request()
{
$this->resolveOption();
$result = $this->response();
if ($this->shouldServerRetry($result)) {
return $this->request();
}
if (!$result->isSuccess()) {
throw new ServerException($result);
}
return $result;
}
/***
* @return PromiseInterface
* @throws Exception
*/
public function requestAsync()
{
$this->resolveOption();
return self::createClient($this)->requestAsync(
$this->method,
(string)$this->uri,
$this->options
);
}
/**
* @param Request $request
*
* @return Client
* @throws Exception
*/
public static function createClient(Request $request = null)
{
if (AlibabaCloud::hasMock()) {
$stack = HandlerStack::create(AlibabaCloud::getMock());
} else {
$stack = HandlerStack::create();
}
if (AlibabaCloud::isRememberHistory()) {
$stack->push(Middleware::history(AlibabaCloud::referenceHistory()));
}
if (AlibabaCloud::getLogger()) {
$stack->push(Middleware::log(
AlibabaCloud::getLogger(),
new LogFormatter(AlibabaCloud::getLogFormat())
));
}
$stack->push(Middleware::mapResponse(static function (ResponseInterface $response) use ($request) {
return new Result($response, $request);
}));
self::$config['handler'] = $stack;
return new Client(self::$config);
}
/**
* @throws ClientException
* @throws Exception
*/
private function response()
{
try {
return self::createClient($this)->request(
$this->method,
(string)$this->uri,
$this->options
);
} catch (GuzzleException $exception) {
if ($this->shouldClientRetry($exception)) {
return $this->response();
}
throw new ClientException(
$exception->getMessage(),
SDK::SERVER_UNREACHABLE,
$exception
);
}
}
/**
* Remove redundant Query
*
* @codeCoverageIgnore
*/
private function cleanQuery()
{
if (isset($this->options['query']) && $this->options['query'] === []) {
unset($this->options['query']);
}
}
/**
* Remove redundant Headers
*
* @codeCoverageIgnore
*/
private function cleanFormParams()
{
if (isset($this->options['form_params']) && $this->options['form_params'] === []) {
unset($this->options['form_params']);
}
}
}

View File

@ -0,0 +1,335 @@
<?php
namespace AlibabaCloud\Client\Request;
use Exception;
use Stringy\Stringy;
use RuntimeException;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\Encode;
use AlibabaCloud\Client\Accept;
use AlibabaCloud\Client\Support\Path;
use AlibabaCloud\Client\Support\Sign;
use AlibabaCloud\Client\Filter\Filter;
use AlibabaCloud\Client\Support\Arrays;
use AlibabaCloud\Client\Filter\ApiFilter;
use AlibabaCloud\Client\Credentials\StsCredential;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
use AlibabaCloud\Client\Credentials\AccessKeyCredential;
use AlibabaCloud\Client\Credentials\BearerTokenCredential;
use AlibabaCloud\Client\Request\Traits\DeprecatedRoaTrait;
/**
* RESTful ROA Request.
*
* @package AlibabaCloud\Client\Request
* @method setParameter()
*/
class RoaRequest extends Request
{
use DeprecatedRoaTrait;
/**
* @var string
*/
public $pathPattern = '/';
/**
* @var array
*/
public $pathParameters = [];
/**
* @var string
*/
private $dateTimeFormat = "D, d M Y H:i:s \G\M\T";
/**
* Resolve request parameter.
*
* @throws ClientException
* @throws Exception
*/
public function resolveParameter()
{
$this->resolveQuery();
$this->resolveHeaders();
$this->resolveBody();
$this->resolveUri();
$this->resolveSignature();
}
private function resolveQuery()
{
if (!isset($this->options['query']['Version'])) {
$this->options['query']['Version'] = $this->version;
}
}
private function resolveBody()
{
// If the body has already been specified, it will not be resolved.
if (isset($this->options['body'])) {
return;
}
if (!isset($this->options['form_params'])) {
return;
}
// Merge data, compatible with parameters set from constructor.
$params = Arrays::merge(
[
$this->data,
$this->options['form_params']
]
);
$this->encodeBody($params);
unset($this->options['form_params']);
}
/**
* Determine the body format based on the Content-Type and calculate the MD5 value.
*
* @param array $params
*/
private function encodeBody(array $params)
{
$stringy = Stringy::create($this->options['headers']['Content-Type']);
if ($stringy->contains('application/json', false)) {
$this->options['body'] = json_encode($params);
$this->options['headers']['Content-MD5'] = base64_encode(md5($this->options['body'], true));
return;
}
$this->options['body'] = Encode::create($params)->ksort()->toString();
$this->options['headers']['Content-MD5'] = base64_encode(md5($this->options['body'], true));
$this->options['headers']['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
}
/**
* @throws ClientException
* @throws ServerException
* @throws Exception
*/
private function resolveHeaders()
{
$this->options['headers']['x-acs-version'] = $this->version;
$this->options['headers']['x-acs-region-id'] = $this->realRegionId();
$this->options['headers']['Date'] = gmdate($this->dateTimeFormat);
$signature = $this->httpClient()->getSignature();
$this->options['headers']['x-acs-signature-method'] = $signature->getMethod();
$this->options['headers']['x-acs-signature-nonce'] = Sign::uuid($this->product . $this->action);
$this->options['headers']['x-acs-signature-version'] = $signature->getVersion();
if ($signature->getType()) {
$this->options['headers']['x-acs-signature-type'] = $signature->getType();
}
$this->resolveAccept();
$this->resolveContentType();
$this->resolveSecurityToken();
$this->resolveBearerToken();
}
/**
* @throws ClientException
* @throws Exception
*/
private function resolveSignature()
{
$this->options['headers']['Authorization'] = $this->signature();
}
/**
* If accept is not specified, it is determined by format.
*/
private function resolveAccept()
{
if (!isset($this->options['headers']['Accept'])) {
$this->options['headers']['Accept'] = Accept::create($this->format)->toString();
}
}
/**
* If the Content-Type is not specified, it is determined according to accept.
*/
private function resolveContentType()
{
if (!isset($this->options['headers']['Content-Type'])) {
$this->options['headers']['Content-Type'] = "{$this->options['headers']['Accept']}; charset=utf-8";
}
}
/**
* @throws ClientException
* @throws ServerException
*/
private function resolveSecurityToken()
{
if (!$this->credential() instanceof StsCredential) {
return;
}
if (!$this->credential()->getSecurityToken()) {
return;
}
$this->options['headers']['x-acs-security-token'] = $this->credential()->getSecurityToken();
}
/**
* @throws ClientException
* @throws ServerException
*/
private function resolveBearerToken()
{
if ($this->credential() instanceof BearerTokenCredential) {
$this->options['headers']['x-acs-bearer-token'] = $this->credential()->getBearerToken();
}
}
/**
* Sign the request message.
*
* @return string
* @throws ClientException
* @throws ServerException
*/
private function signature()
{
/**
* @var AccessKeyCredential $credential
*/
$credential = $this->credential();
$access_key_id = $credential->getAccessKeyId();
$signature = $this->httpClient()
->getSignature()
->sign(
$this->stringToSign(),
$credential->getAccessKeySecret()
);
return "acs $access_key_id:$signature";
}
/**
* @return void
*/
private function resolveUri()
{
$path = Path::assign($this->pathPattern, $this->pathParameters);
$this->uri = $this->uri->withPath($path)
->withQuery(
$this->queryString()
);
}
/**
* @return string
*/
public function stringToSign()
{
$request = new \GuzzleHttp\Psr7\Request(
$this->method,
$this->uri,
$this->options['headers']
);
return Sign::roaString($request);
}
/**
* @return bool|string
*/
private function queryString()
{
$query = isset($this->options['query'])
? $this->options['query']
: [];
return Encode::create($query)->ksort()->toString();
}
/**
* Set path parameter by name.
*
* @param string $name
* @param string $value
*
* @return RoaRequest
* @throws ClientException
*/
public function pathParameter($name, $value)
{
Filter::name($name);
if ($value === '') {
throw new ClientException(
'Value cannot be empty',
SDK::INVALID_ARGUMENT
);
}
$this->pathParameters[$name] = $value;
return $this;
}
/**
* Set path pattern.
*
* @param string $pattern
*
* @return self
* @throws ClientException
*/
public function pathPattern($pattern)
{
ApiFilter::pattern($pattern);
$this->pathPattern = $pattern;
return $this;
}
/**
* Magic method for set or get request parameters.
*
* @param string $name
* @param mixed $arguments
*
* @return $this
*/
public function __call($name, $arguments)
{
if (strncmp($name, 'get', 3) === 0) {
$parameter_name = \mb_strcut($name, 3);
return $this->__get($parameter_name);
}
if (strncmp($name, 'with', 4) === 0) {
$parameter_name = \mb_strcut($name, 4);
$this->__set($parameter_name, $arguments[0]);
$this->pathParameters[$parameter_name] = $arguments[0];
return $this;
}
if (strncmp($name, 'set', 3) === 0) {
$parameter_name = \mb_strcut($name, 3);
$with_method = "with$parameter_name";
throw new RuntimeException("Please use $with_method instead of $name");
}
throw new RuntimeException('Call to undefined method ' . __CLASS__ . '::' . $name . '()');
}
}

View File

@ -0,0 +1,203 @@
<?php
namespace AlibabaCloud\Client\Request;
use Exception;
use RuntimeException;
use AlibabaCloud\Client\Support\Sign;
use AlibabaCloud\Client\Support\Arrays;
use AlibabaCloud\Client\Credentials\StsCredential;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
use AlibabaCloud\Client\Credentials\BearerTokenCredential;
/**
* RESTful RPC Request.
*
* @package AlibabaCloud\Client\Request
*/
class RpcRequest extends Request
{
/**
* @var string
*/
private $dateTimeFormat = 'Y-m-d\TH:i:s\Z';
/**
* Resolve request parameter.
*
* @throws ClientException
*/
public function resolveParameter()
{
$this->resolveBoolInParameters();
$this->resolveCommonParameters();
$this->repositionParameters();
}
/**
* Convert a Boolean value to a string
*/
private function resolveBoolInParameters()
{
if (isset($this->options['query'])) {
$this->options['query'] = array_map(
static function ($value) {
return self::boolToString($value);
},
$this->options['query']
);
}
}
/**
* Convert a Boolean value to a string.
*
* @param bool|string $value
*
* @return string
*/
public static function boolToString($value)
{
if (is_bool($value)) {
return $value ? 'true' : 'false';
}
return $value;
}
/**
* Resolve Common Parameters.
*
* @throws ClientException
* @throws Exception
*/
private function resolveCommonParameters()
{
$signature = $this->httpClient()->getSignature();
$this->options['query']['RegionId'] = $this->realRegionId();
$this->options['query']['Format'] = $this->format;
$this->options['query']['SignatureMethod'] = $signature->getMethod();
$this->options['query']['SignatureVersion'] = $signature->getVersion();
$this->options['query']['SignatureNonce'] = Sign::uuid($this->product . $this->action);
$this->options['query']['Timestamp'] = gmdate($this->dateTimeFormat);
$this->options['query']['Action'] = $this->action;
if ($this->credential()->getAccessKeyId()) {
$this->options['query']['AccessKeyId'] = $this->credential()->getAccessKeyId();
}
if ($signature->getType()) {
$this->options['query']['SignatureType'] = $signature->getType();
}
if (!isset($this->options['query']['Version'])) {
$this->options['query']['Version'] = $this->version;
}
$this->resolveSecurityToken();
$this->resolveBearerToken();
$this->options['query']['Signature'] = $this->signature();
}
/**
* @throws ClientException
* @throws ServerException
*/
private function resolveSecurityToken()
{
if (!$this->credential() instanceof StsCredential) {
return;
}
if (!$this->credential()->getSecurityToken()) {
return;
}
$this->options['query']['SecurityToken'] = $this->credential()->getSecurityToken();
}
/**
* @throws ClientException
* @throws ServerException
*/
private function resolveBearerToken()
{
if ($this->credential() instanceof BearerTokenCredential) {
$this->options['query']['BearerToken'] = $this->credential()->getBearerToken();
}
}
/**
* Sign the parameters.
*
* @return mixed
* @throws ClientException
* @throws ServerException
*/
private function signature()
{
return $this->httpClient()
->getSignature()
->sign(
$this->stringToSign(),
$this->credential()->getAccessKeySecret() . '&'
);
}
/**
* @return string
*/
public function stringToSign()
{
$query = isset($this->options['query']) ? $this->options['query'] : [];
$form_params = isset($this->options['form_params']) ? $this->options['form_params'] : [];
$parameters = Arrays::merge([$query, $form_params]);
return Sign::rpcString($this->method, $parameters);
}
/**
* Adjust parameter position
*/
private function repositionParameters()
{
if ($this->method === 'POST' || $this->method === 'PUT') {
foreach ($this->options['query'] as $api_key => $api_value) {
$this->options['form_params'][$api_key] = $api_value;
}
unset($this->options['query']);
}
}
/**
* Magic method for set or get request parameters.
*
* @param string $name
* @param mixed $arguments
*
* @return $this
*/
public function __call($name, $arguments)
{
if (strncmp($name, 'get', 3) === 0) {
$parameter_name = \mb_strcut($name, 3);
return $this->__get($parameter_name);
}
if (strncmp($name, 'with', 4) === 0) {
$parameter_name = \mb_strcut($name, 4);
$this->__set($parameter_name, $arguments[0]);
$this->options['query'][$parameter_name] = $arguments[0];
return $this;
}
if (strncmp($name, 'set', 3) === 0) {
$parameter_name = \mb_strcut($name, 3);
$with_method = "with$parameter_name";
throw new RuntimeException("Please use $with_method instead of $name");
}
throw new RuntimeException('Call to undefined method ' . __CLASS__ . '::' . $name . '()');
}
}

View File

@ -0,0 +1,259 @@
<?php
namespace AlibabaCloud\Client\Request\Traits;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
use AlibabaCloud\Client\Filter\ApiFilter;
use AlibabaCloud\Client\Regions\LocationService;
use AlibabaCloud\Client\Request\Request;
use AlibabaCloud\Client\SDK;
use GuzzleHttp\Psr7\Uri;
/**
* Trait AcsTrait
*
* @package AlibabaCloud\Client\Request\Traits
* @property Uri $uri
* @mixin Request
*/
trait AcsTrait
{
/**
* @var string
*/
public $version;
/**
* @var string
*/
public $product;
/**
* @var string
*/
public $action;
/**
* @var string
*/
public $serviceCode = '';
/**
* @var string
*/
public $endpointType = 'openAPI';
/**
* @var string|null
*/
public $network = 'public';
/**
* @var array|null
*/
public $endpointMap;
/**
* @var string|null
*/
public $endpointRegional;
/**
* @var string
*/
public $endpointSuffix = '';
/**
* @param string $action
*
* @return $this
* @throws ClientException
*/
public function action($action)
{
$this->action = ApiFilter::action($action);
return $this;
}
/**
* @codeCoverageIgnore
*
* @param string $endpointSuffix
*
* @return AcsTrait
* @throws ClientException
*/
public function endpointSuffix($endpointSuffix)
{
$this->endpointSuffix = ApiFilter::endpointSuffix($endpointSuffix);
return $this;
}
/**
* @param string $network
*/
public function network($network)
{
$this->network = ApiFilter::network($network);
return $this;
}
/**
* @param string $version
*
* @return $this
* @throws ClientException
*/
public function version($version)
{
$this->version = ApiFilter::version($version);
return $this;
}
/**
* @param string $product
*
* @return $this
* @throws ClientException
*/
public function product($product)
{
$this->product = ApiFilter::product($product);
return $this;
}
/**
* @param string $endpointType
*
* @return $this
* @throws ClientException
*/
public function endpointType($endpointType)
{
$this->endpointType = ApiFilter::endpointType($endpointType);
return $this;
}
/**
* @param string $serviceCode
*
* @return $this
* @throws ClientException
*/
public function serviceCode($serviceCode)
{
$this->serviceCode = ApiFilter::serviceCode($serviceCode);
return $this;
}
/**
* Resolve Host.
*
* @throws ClientException
* @throws ServerException
*/
public function resolveHost()
{
// Return if specified
if ($this->uri->getHost() !== 'localhost') {
return;
}
$region_id = $this->realRegionId();
$host = '';
$this->resolveHostWays($host, $region_id);
if (!$host) {
throw new ClientException(
"No host found for {$this->product} in the {$region_id}, you can specify host by host() method. " .
'Like $request->host(\'xxx.xxx.aliyuncs.com\')',
SDK::HOST_NOT_FOUND
);
}
$this->uri = $this->uri->withHost($host);
}
/**
* @param string $host
* @param string $region_id
*
* @throws ClientException
* @throws ServerException
*/
private function resolveHostWays(&$host, $region_id)
{
$host = AlibabaCloud::resolveHostByStatic($this->product, $region_id);
// 1. Find host by map.
if (!$host && $this->network === 'public' && isset($this->endpointMap[$region_id])) {
$host = $this->endpointMap[$region_id];
}
if (!$host) {
$this->hostResolver($host, $region_id);
}
}
/**
* @codeCoverageIgnore
*
* @param string $host
* @param string $region_id
*
* @throws ClientException
* @throws ServerException
*/
private function hostResolver(&$host, $region_id)
{
// 2. Find host by rules.
if ($this->endpointRegional !== null) {
$host = AlibabaCloud::resolveHostByRule($this);
}
// 3. Find in the local array file.
if (!$host) {
$host = AlibabaCloud::resolveHost($this->product, $region_id);
}
// 4. Find in the Location service.
if (!$host && $this->serviceCode) {
$host = LocationService::resolveHost($this);
}
}
/**
* @return string
* @throws ClientException
*/
public function realRegionId()
{
if ($this->regionId !== null) {
return $this->regionId;
}
if ($this->httpClient()->regionId !== null) {
return $this->httpClient()->regionId;
}
if (AlibabaCloud::getDefaultRegionId() !== null) {
return AlibabaCloud::getDefaultRegionId();
}
if ($this->product && AlibabaCloud::isGlobalProduct($this->product)) {
return 'global';
}
throw new ClientException("Missing required 'RegionId' for Request", SDK::INVALID_REGION_ID);
}
}

View File

@ -0,0 +1,98 @@
<?php
namespace AlibabaCloud\Client\Request\Traits;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Clients\Client;
use AlibabaCloud\Client\Support\Arrays;
use AlibabaCloud\Client\Request\Request;
use AlibabaCloud\Client\Credentials\StsCredential;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
use AlibabaCloud\Client\Credentials\AccessKeyCredential;
use AlibabaCloud\Client\Credentials\Requests\AssumeRole;
use AlibabaCloud\Client\Credentials\CredentialsInterface;
use AlibabaCloud\Client\Credentials\BearerTokenCredential;
use AlibabaCloud\Client\Credentials\Providers\CredentialsProvider;
use AlibabaCloud\Client\Credentials\Requests\GenerateSessionAccessKey;
/**
* Trait ClientTrait
*
* @package AlibabaCloud\Client\Request\Traits
*
* @mixin Request
*/
trait ClientTrait
{
/**
* @var array
*/
private static $config = [];
/**
* @param array $config
*/
public static function config(array $config)
{
self::$config = $config;
}
/**
* Return credentials directly if it is an AssumeRole or GenerateSessionAccessKey.
*
* @return AccessKeyCredential|BearerTokenCredential|CredentialsInterface|StsCredential
* @throws ClientException
* @throws ServerException
*/
public function credential()
{
if ($this instanceof AssumeRole || $this instanceof GenerateSessionAccessKey) {
return $this->httpClient()->getCredential();
}
$timeout = isset($this->options['timeout'])
? $this->options['timeout']
: Request::TIMEOUT;
$connectTimeout = isset($this->options['connect_timeout'])
? $this->options['connect_timeout']
: Request::CONNECT_TIMEOUT;
return $this->httpClient()->getSessionCredential($timeout, $connectTimeout);
}
/**
* Get the client based on the request's settings.
*
* @return Client
* @throws ClientException
*/
public function httpClient()
{
if (!AlibabaCloud::all()) {
if (CredentialsProvider::hasCustomChain()) {
CredentialsProvider::customProvider($this->client);
} else {
CredentialsProvider::defaultProvider($this->client);
}
}
return AlibabaCloud::get($this->client);
}
/**
* Merged with the client's options, the same name will be overwritten.
*
* @throws ClientException
*/
public function mergeOptionsIntoClient()
{
$this->options = Arrays::merge(
[
$this->httpClient()->options,
$this->options
]
);
}
}

View File

@ -0,0 +1,55 @@
<?php
namespace AlibabaCloud\Client\Request\Traits;
/**
* @package AlibabaCloud\Client\Request\Traits
* @codeCoverageIgnore
*/
trait DeprecatedRoaTrait
{
/**
* @param $name
* @param $value
*
* @return $this
* @deprecated
* @codeCoverageIgnore
*/
public function putPathParameter($name, $value)
{
return $this->pathParameter($name, $value);
}
/**
* @param $pathPattern
*
* @return $this
* @deprecated
* @codeCoverageIgnore
*/
public function setUriPattern($pathPattern)
{
return $this->pathPattern($pathPattern);
}
/**
* @return string
* @deprecated
* @codeCoverageIgnore
*/
public function getUriPattern()
{
return $this->pathPattern;
}
/**
* @return array
* @deprecated
* @codeCoverageIgnore
*/
public function getPathParameters()
{
return $this->pathParameters;
}
}

View File

@ -0,0 +1,246 @@
<?php
namespace AlibabaCloud\Client\Request\Traits;
use AlibabaCloud\Client\Exception\ClientException;
use RuntimeException;
use AlibabaCloud\Client\Request\Request;
/**
* @package AlibabaCloud\Client\Request\Traits
*
* @mixin Request
*/
trait DeprecatedTrait
{
/**
* @param $content
*
* @return $this
* @throws ClientException
* @deprecated
* @codeCoverageIgnore
*/
public function setContent($content)
{
return $this->body($content);
}
/**
* @param $method
*
* @return $this
* @throws ClientException
* @deprecated
* @codeCoverageIgnore
*/
public function setMethod($method)
{
return $this->method($method);
}
/**
* @param $scheme
*
* @return $this
* @throws ClientException
* @deprecated
* @codeCoverageIgnore
*/
public function setProtocol($scheme)
{
return $this->scheme($scheme);
}
/**
* @deprecated
* @codeCoverageIgnore
*/
public function getProtocolType()
{
return $this->uri->getScheme();
}
/**
* @param $scheme
*
* @return $this
* @throws ClientException
* @deprecated
* @codeCoverageIgnore
*/
public function setProtocolType($scheme)
{
return $this->scheme($scheme);
}
/**
* @param $actionName
*
* @return $this
* @throws ClientException
* @deprecated
* @codeCoverageIgnore
*/
public function setActionName($actionName)
{
return $this->action($actionName);
}
/**
* @param $format
*
* @return $this
* @throws ClientException
* @deprecated
* @codeCoverageIgnore
*/
public function setAcceptFormat($format)
{
return $this->format($format);
}
/**
* @deprecated
* @codeCoverageIgnore
*/
public function getProtocol()
{
return $this->uri->getScheme();
}
/**
* @deprecated
* @codeCoverageIgnore
*/
public function getContent()
{
return isset($this->options['body'])
? $this->options['body']
: null;
}
/**
* @deprecated
* @codeCoverageIgnore
*/
public function getMethod()
{
return $this->method;
}
/**
* @deprecated
* @codeCoverageIgnore
*/
public function getHeaders()
{
return isset($this->options['headers'])
? $this->options['headers']
: [];
}
/**
* @param $headerKey
* @param $headerValue
*
* @return $this
* @deprecated
* @codeCoverageIgnore
*/
public function addHeader($headerKey, $headerValue)
{
$this->options['headers'][$headerKey] = $headerValue;
return $this;
}
/**
* @deprecated
* @codeCoverageIgnore
*/
public function getQueryParameters()
{
return isset($this->options['query'])
? $this->options['query']
: [];
}
/**
* @param $name
* @param $value
*
* @return $this
* @deprecated
* @codeCoverageIgnore
*/
public function setQueryParameters($name, $value)
{
$this->options['query'][$name] = $value;
return $this;
}
/**
* @deprecated
* @codeCoverageIgnore
*/
public function getDomainParameter()
{
return isset($this->options['form_params'])
? $this->options['form_params']
: [];
}
/**
* @param $name
* @param $value
*
* @return $this
* @deprecated
* @codeCoverageIgnore
*/
public function putDomainParameters($name, $value)
{
$this->options['form_params'][$name] = $value;
return $this;
}
/**
* @deprecated
* @codeCoverageIgnore
*/
public function getActionName()
{
return $this->action;
}
/**
* @deprecated
* @codeCoverageIgnore
*/
public function getAcceptFormat()
{
return $this->format;
}
/**
* @deprecated
* @codeCoverageIgnore
*/
public function getLocationEndpointType()
{
return $this->endpointType;
}
/**
* @deprecated
* @codeCoverageIgnore
*/
public function getLocationServiceCode()
{
return $this->serviceCode;
}
}

View File

@ -0,0 +1,149 @@
<?php
namespace AlibabaCloud\Client\Request\Traits;
use Exception;
use Stringy\Stringy;
use AlibabaCloud\Client\Result\Result;
use AlibabaCloud\Client\Filter\ClientFilter;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Trait RetryTrait
*
* @package AlibabaCloud\Client\Request\Traits
*/
trait RetryTrait
{
/**
* Server Retry Times
*
* @var int
*/
private $serverRetry = 0;
/**
* Server Retry Strings
*
* @var string[]
*/
private $serverRetryStrings = [];
/**
* Server Retry Codes
*
* @var int[]
*/
private $serverRetryStatusCodes = [];
/**
* Client Retry Times
*
* @var int
*/
private $clientRetry = 0;
/**
* Client Retry Strings
*
* @var string[]
*/
private $clientRetryStrings = [];
/**
* Client Retry Codes
*
* @var int[]
*/
private $clientRetryStatusCodes = [];
/**
* @param int $times
* @param array $strings
* @param array $statusCodes
*
* @return $this
* @throws ClientException
*/
public function retryByServer($times, array $strings, array $statusCodes = [])
{
$this->serverRetry = ClientFilter::retry($times);
$this->serverRetryStrings = $strings;
$this->serverRetryStatusCodes = $statusCodes;
return $this;
}
/**
* @param int $times
* @param array $strings
* @param array $codes
*
* @return $this
* @throws ClientException
*/
public function retryByClient($times, array $strings, array $codes = [])
{
$this->clientRetry = ClientFilter::retry($times);
$this->clientRetryStrings = $strings;
$this->clientRetryStatusCodes = $codes;
return $this;
}
/**
* @param Result $result
*
* @return bool
*/
private function shouldServerRetry(Result $result)
{
if ($this->serverRetry <= 0) {
return false;
}
if (in_array($result->getStatusCode(), $this->serverRetryStatusCodes)) {
$this->serverRetry--;
return true;
}
foreach ($this->serverRetryStrings as $message) {
if (Stringy::create($result->getBody())->contains($message)) {
$this->serverRetry--;
return true;
}
}
return false;
}
/**
* @param Exception $exception
*
* @return bool
*/
private function shouldClientRetry(Exception $exception)
{
if ($this->clientRetry <= 0) {
return false;
}
if (in_array($exception->getCode(), $this->clientRetryStatusCodes, true)) {
$this->clientRetry--;
return true;
}
foreach ($this->clientRetryStrings as $message) {
if (Stringy::create($exception->getMessage())->contains($message)) {
$this->clientRetry--;
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,142 @@
<?php
namespace AlibabaCloud\Client\Request;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Filter\Filter;
use AlibabaCloud\Client\Support\Arrays;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Class UserAgent
*
* @package AlibabaCloud\Client\Request
*/
class UserAgent
{
/**
* @var array
*/
private static $userAgent = [];
/**
* @var array
*/
private static $guard = [
'client',
'php',
];
/**
* @param array $append
*
* @return string
*/
public static function toString(array $append = [])
{
self::defaultFields();
$os = \PHP_OS;
$osVersion = php_uname('r');
$osMode = php_uname('m');
$userAgent = "AlibabaCloud ($os $osVersion; $osMode) ";
$newUserAgent = [];
$append = self::clean($append);
$append = Arrays::merge(
[
self::$userAgent,
$append,
]
);
foreach ($append as $key => $value) {
if ($value === null) {
$newUserAgent[] = $key;
continue;
}
$newUserAgent[] = "$key/$value";
}
return $userAgent . \implode(' ', $newUserAgent);
}
/**
* UserAgent constructor.
*/
private static function defaultFields()
{
if (self::$userAgent === []) {
self::$userAgent = [
'Client' => AlibabaCloud::VERSION,
'PHP' => \PHP_VERSION,
];
}
}
/**
* @param array $append
*
* @return array
*/
public static function clean(array $append)
{
foreach ($append as $key => $value) {
if (self::isGuarded($key)) {
unset($append[$key]);
continue;
}
}
return $append;
}
/**
* @param $name
*
* @return bool
*/
public static function isGuarded($name)
{
return in_array(strtolower($name), self::$guard, true);
}
/**
* set User Agent of Alibaba Cloud.
*
* @param string $name
* @param string $value
*
* @throws ClientException
*/
public static function append($name, $value)
{
Filter::name($name);
Filter::value($value);
self::defaultFields();
if (!self::isGuarded($name)) {
self::$userAgent[$name] = $value;
}
}
/**
* @param array $userAgent
*/
public static function with(array $userAgent)
{
self::$userAgent = self::clean($userAgent);
}
/**
* Clear all of the User Agent.
*/
public static function clear()
{
self::$userAgent = [];
}
}

View File

@ -0,0 +1,50 @@
<?php
namespace AlibabaCloud\Client\Resolver;
use ReflectionClass;
use ReflectionException;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Request\Request;
use AlibabaCloud\Client\Exception\ClientException;
/**
* @codeCoverageIgnore
* @mixin Rpc
* @mixin Roa
* @mixin Request
* @package AlibabaCloud\Client\Resolver
*/
trait ActionResolverTrait
{
/**
* Resolve Action name from class name
*/
private function resolveActionName()
{
if (!$this->action) {
$array = explode('\\', get_class($this));
$this->action = array_pop($array);
}
}
/**
* Append SDK version into User-Agent
*
* @throws ClientException
* @throws ReflectionException
*/
private function appendSdkUA()
{
if (!(new ReflectionClass(AlibabaCloud::class))->hasMethod('appendUserAgent')) {
return;
}
if (!class_exists('AlibabaCloud\Release')) {
return;
}
AlibabaCloud::appendUserAgent('SDK', \AlibabaCloud\Release::VERSION);
}
}

View File

@ -0,0 +1,113 @@
<?php
namespace AlibabaCloud\Client\Resolver;
use ReflectionObject;
use AlibabaCloud\Client\Request\Request;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Class ApiResolver
*
* @codeCoverageIgnore
* @package AlibabaCloud\Client\Resolver
*/
abstract class ApiResolver
{
/**
* @param $name
* @param $arguments
*
* @return mixed
*/
public static function __callStatic($name, $arguments)
{
return (new static())->__call($name, $arguments);
}
/**
* @param $api
* @param $arguments
*
* @return mixed
* @throws ClientException
*/
public function __call($api, $arguments)
{
$product_name = $this->getProductName();
$class = $this->getNamespace() . '\\' . \ucfirst($api);
if (\class_exists($class)) {
if (isset($arguments[0])) {
return $this->warpEndpoint(new $class($arguments[0]));
}
return $this->warpEndpoint(new $class());
}
throw new ClientException(
"{$product_name} contains no $api",
'SDK.ApiNotFound'
);
}
/**
* @param Request $request
*
* @return Request
*/
public function warpEndpoint(Request $request)
{
$reflect = new ReflectionObject($request);
$product_dir = dirname(dirname($reflect->getFileName()));
$endpoints_json = "$product_dir/endpoints.json";
if (file_exists($endpoints_json)) {
$endpoints = json_decode(file_get_contents($endpoints_json), true);
if (isset($endpoints['endpoint_map'])) {
$request->endpointMap = $endpoints['endpoint_map'];
}
if (isset($endpoints['endpoint_regional'])) {
$request->endpointRegional = $endpoints['endpoint_regional'];
}
}
return $request;
}
/**
* @return mixed
* @throws ClientException
*/
private function getProductName()
{
$array = \explode('\\', \get_class($this));
if (isset($array[3])) {
return str_replace('ApiResolver', '', $array[3]);
}
throw new ClientException(
'Service name not found.',
'SDK.ServiceNotFound'
);
}
/**
* @return string
* @throws ClientException
*/
private function getNamespace()
{
$array = \explode('\\', \get_class($this));
if (!isset($array[3])) {
throw new ClientException(
'Get namespace error.',
'SDK.ParseError'
);
}
unset($array[3]);
return \implode('\\', $array);
}
}

View File

@ -0,0 +1,67 @@
<?php
namespace AlibabaCloud\Client\Resolver;
use RuntimeException;
use ArgumentCountError;
/**
* Trait CallTrait
*
* @codeCoverageIgnore
* @package AlibabaCloud\Client\Resolver
*/
trait CallTrait
{
/**
* Magic method for set or get request parameters.
*
* @param string $name
* @param mixed $arguments
*
* @return $this
*/
public function __call($name, $arguments)
{
if (strncmp($name, 'get', 3) === 0) {
$parameter = \mb_strcut($name, 3);
return $this->__get($parameter);
}
if (strncmp($name, 'with', 4) === 0) {
$parameter = \mb_strcut($name, 4);
$value = $this->getCallArguments($name, $arguments);
$this->data[$parameter] = $value;
$this->parameterPosition()[$parameter] = $value;
return $this;
}
if (strncmp($name, 'set', 3) === 0) {
$parameter = \mb_strcut($name, 3);
$with_method = "with$parameter";
return $this->$with_method($this->getCallArguments($name, $arguments));
}
throw new RuntimeException('Call to undefined method ' . __CLASS__ . '::' . $name . '()');
}
/**
* @param string $name
* @param array $arguments
* @param int $index
*
* @return mixed
*/
private function getCallArguments($name, array $arguments, $index = 0)
{
if (!isset($arguments[$index])) {
throw new ArgumentCountError("Missing arguments to method $name");
}
return $arguments[$index];
}
}

View File

@ -0,0 +1,43 @@
<?php
namespace AlibabaCloud\Client\Resolver;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Request\RoaRequest;
use ReflectionClass;
use ReflectionException;
/**
* Class Roa
*
* @codeCoverageIgnore
* @package AlibabaCloud\Client\Resolver
*/
abstract class Roa extends RoaRequest
{
use ActionResolverTrait;
use CallTrait;
/**
* @param array $options
*
* @throws ReflectionException
* @throws ClientException
*/
public function __construct(array $options = [])
{
parent::__construct($options);
$this->resolveActionName();
$this->appendSdkUA();
}
/**
* @return mixed
*/
private function &parameterPosition()
{
return $this->pathParameters;
}
}

View File

@ -0,0 +1,41 @@
<?php
namespace AlibabaCloud\Client\Resolver;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Request\RpcRequest;
use ReflectionException;
/**
* Class Rpc
*
* @codeCoverageIgnore
* @package AlibabaCloud\Client\Resolver
*/
abstract class Rpc extends RpcRequest
{
use ActionResolverTrait;
use CallTrait;
/**
* @param array $options
*
* @throws ReflectionException
* @throws ClientException
*/
public function __construct(array $options = [])
{
parent::__construct($options);
$this->resolveActionName();
$this->appendSdkUA();
}
/**
* @return mixed
*/
private function &parameterPosition()
{
return $this->options['query'];
}
}

View File

@ -0,0 +1,74 @@
<?php
namespace AlibabaCloud\Client\Resolver;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Class VersionResolver
*
* @codeCoverageIgnore
* @package AlibabaCloud\Client\Resolver
*/
abstract class VersionResolver
{
/**
* @param string $name
* @param array $arguments
*
* @return mixed
* @throws ClientException
*/
public static function __callStatic($name, $arguments)
{
return (new static())->__call($name, $arguments);
}
/**
* @param string $version
* @param array $arguments
*
* @return mixed
* @throws ClientException
*/
public function __call($version, $arguments)
{
$version = \ucfirst($version);
$product = $this->getProductName();
$position = strpos($product, 'Version');
if ($position !== false && $position !== 0) {
$product = \str_replace('Version', '', $product);
}
$class = "AlibabaCloud\\{$product}\\$version\\{$product}ApiResolver";
if (\class_exists($class)) {
return new $class();
}
throw new ClientException(
"$product Versions contains no {$version}",
'SDK.VersionNotFound'
);
}
/**
* @return mixed
* @throws ClientException
*/
private function getProductName()
{
$array = \explode('\\', \get_class($this));
if (is_array($array) && isset($array[1])) {
return $array[1];
}
throw new ClientException(
'Service name not found.',
'SDK.ServiceNotFound'
);
}
}

View File

@ -0,0 +1,151 @@
<?php
namespace AlibabaCloud\Client\Result;
use Countable;
use Exception;
use ArrayAccess;
use IteratorAggregate;
use InvalidArgumentException;
use GuzzleHttp\Psr7\Response;
use Psr\Http\Message\ResponseInterface;
use AlibabaCloud\Client\Request\Request;
use AlibabaCloud\Client\Traits\HasDataTrait;
/**
* Result from Alibaba Cloud
*
* @property string|null RequestId
*
* @package AlibabaCloud\Client\Result
*/
class Result extends Response implements ArrayAccess, IteratorAggregate, Countable
{
use HasDataTrait;
/**
* Instance of the request.
*
* @var Request
*/
protected $request;
/**
* Result constructor.
*
* @param ResponseInterface $response
* @param Request $request
*/
public function __construct(ResponseInterface $response, Request $request = null)
{
parent::__construct(
$response->getStatusCode(),
$response->getHeaders(),
$response->getBody(),
$response->getProtocolVersion(),
$response->getReasonPhrase()
);
$this->request = $request;
$this->resolveData();
}
private function resolveData()
{
$content = $this->getBody()->getContents();
switch ($this->getRequestFormat()) {
case 'JSON':
$result_data = $this->jsonToArray($content);
break;
case 'XML':
$result_data = $this->xmlToArray($content);
break;
case 'RAW':
$result_data = $this->jsonToArray($content);
break;
default:
$result_data = $this->jsonToArray($content);
}
if (!$result_data) {
$result_data = [];
}
$this->dot($result_data);
}
/**
* @return string
*/
private function getRequestFormat()
{
return ($this->request instanceof Request)
? \strtoupper($this->request->format)
: 'JSON';
}
/**
* @param string $response
*
* @return array
*/
private function jsonToArray($response)
{
try {
return \GuzzleHttp\json_decode($response, true);
} catch (InvalidArgumentException $exception) {
return [];
}
}
/**
* @param string $string
*
* @return array
*/
private function xmlToArray($string)
{
try {
return json_decode(json_encode(simplexml_load_string($string)), true);
} catch (Exception $exception) {
return [];
}
}
/**
* @return string
*/
public function __toString()
{
return (string)$this->getBody();
}
/**
* @return Request
*/
public function getRequest()
{
return $this->request;
}
/**
* @codeCoverageIgnore
* @return Response
* @deprecated
*/
public function getResponse()
{
return $this;
}
/**
* @return bool
*/
public function isSuccess()
{
return 200 <= $this->getStatusCode()
&& 300 > $this->getStatusCode();
}
}

57
vendor/alibabacloud/client/src/SDK.php vendored Normal file
View File

@ -0,0 +1,57 @@
<?php
namespace AlibabaCloud\Client;
/**
* Class SDK
*
* @package AlibabaCloud\Client
*/
class SDK
{
/**
* Invalid credential
*/
const INVALID_CREDENTIAL = 'SDK.InvalidCredential';
/**
* Client Not Found
*/
const CLIENT_NOT_FOUND = 'SDK.ClientNotFound';
/**
* Host Not Found
*/
const HOST_NOT_FOUND = 'SDK.HostNotFound';
/**
* Server Unreachable
*/
const SERVER_UNREACHABLE = 'SDK.ServerUnreachable';
/**
* Invalid RegionId
*/
const INVALID_REGION_ID = 'SDK.InvalidRegionId';
/**
* Invalid Argument
*/
const INVALID_ARGUMENT = 'SDK.InvalidArgument';
/**
* Service Not Found
*/
const SERVICE_NOT_FOUND = 'SDK.ServiceNotFound';
/**
* Service Unknown Error
*/
const SERVICE_UNKNOWN_ERROR = 'SDK.UnknownError';
/**
* Response Empty
*/
const RESPONSE_EMPTY = 'The response is empty';
}

View File

@ -0,0 +1,47 @@
<?php
namespace AlibabaCloud\Client\Signature;
/**
* Class BearerTokenSignature
*
* @package AlibabaCloud\Signature
*/
class BearerTokenSignature extends Signature implements SignatureInterface
{
/**
* @return string
*/
public function getMethod()
{
return '';
}
/**
* @return string
*/
public function getType()
{
return 'BEARERTOKEN';
}
/**
* @return string
*/
public function getVersion()
{
return '1.0';
}
/**
* @param string $string
* @param string $accessKeySecret
*
* @return string
*/
public function sign($string, $accessKeySecret)
{
return '';
}
}

View File

@ -0,0 +1,47 @@
<?php
namespace AlibabaCloud\Client\Signature;
/**
* Class ShaHmac1Signature
*
* @package AlibabaCloud\Signature
*/
class ShaHmac1Signature extends Signature implements SignatureInterface
{
/**
* @return string
*/
public function getMethod()
{
return 'HMAC-SHA1';
}
/**
* @return string
*/
public function getType()
{
return '';
}
/**
* @return string
*/
public function getVersion()
{
return '1.0';
}
/**
* @param string $string
* @param string $accessKeySecret
*
* @return string
*/
public function sign($string, $accessKeySecret)
{
return base64_encode(hash_hmac('sha1', $string, $accessKeySecret, true));
}
}

View File

@ -0,0 +1,47 @@
<?php
namespace AlibabaCloud\Client\Signature;
/**
* Class ShaHmac256Signature
*
* @package AlibabaCloud\Signature
*/
class ShaHmac256Signature extends Signature implements SignatureInterface
{
/**
* @return string
*/
public function getMethod()
{
return 'HMAC-SHA256';
}
/**
* @return string
*/
public function getType()
{
return '';
}
/**
* @return string
*/
public function getVersion()
{
return '1.0';
}
/**
* @param string $string
* @param string $accessKeySecret
*
* @return string
*/
public function sign($string, $accessKeySecret)
{
return base64_encode(hash_hmac('sha256', $string, $accessKeySecret, true));
}
}

View File

@ -0,0 +1,67 @@
<?php
namespace AlibabaCloud\Client\Signature;
use Exception;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Class ShaHmac256WithRsaSignature
*
* @package AlibabaCloud\Signature
*/
class ShaHmac256WithRsaSignature extends Signature implements SignatureInterface
{
/**
* @return string
*/
public function getMethod()
{
return 'SHA256withRSA';
}
/**
* @return string
*/
public function getType()
{
return 'PRIVATEKEY';
}
/**
* @return string
*/
public function getVersion()
{
return '1.0';
}
/**
* @param string $string
* @param string $privateKey
*
* @return string
* @throws ClientException
*/
public function sign($string, $privateKey)
{
$binarySignature = '';
try {
openssl_sign(
$string,
$binarySignature,
$privateKey,
\OPENSSL_ALGO_SHA256
);
} catch (Exception $exception) {
throw new ClientException(
$exception->getMessage(),
SDK::INVALID_CREDENTIAL
);
}
return base64_encode($binarySignature);
}
}

View File

@ -0,0 +1,49 @@
<?php
namespace AlibabaCloud\Client\Signature;
use GuzzleHttp\Psr7\Request;
use AlibabaCloud\Client\Support\Sign;
/**
* Class Signature
*
* @package AlibabaCloud\Client\Signature
*/
abstract class Signature
{
/**
* @codeCoverageIgnore
*
* @param string $accessKeyId
* @param string $accessKeySecret
* @param Request $request
*
* @return string
*/
public function roa($accessKeyId, $accessKeySecret, Request $request)
{
$string = Sign::roaString($request);
$signature = $this->sign($string, $accessKeySecret);
return "acs $accessKeyId:$signature";
}
/**
* @codeCoverageIgnore
*
* @param string $accessKeySecret
* @param string $method
* @param array $parameters
*
* @return string
*/
public function rpc($accessKeySecret, $method, array $parameters)
{
$string = Sign::rpcString($method, $parameters);
return $this->sign($string, $accessKeySecret . '&');
}
}

View File

@ -0,0 +1,35 @@
<?php
namespace AlibabaCloud\Client\Signature;
/**
* Interface used to provide interchangeable strategies for requests
*
* @package AlibabaCloud\Signature
*/
interface SignatureInterface
{
/**
* @return string
*/
public function getMethod();
/**
* @return string
*/
public function getVersion();
/**
* @param string $string
* @param string $accessKeySecret
*
* @return string
*/
public function sign($string, $accessKeySecret);
/**
* @return string
*/
public function getType();
}

View File

@ -0,0 +1,41 @@
<?php
namespace AlibabaCloud\Client\Support;
/**
* Class Arrays
*
* @package AlibabaCloud\Client\Support
*/
class Arrays
{
/**
* @param array $arrays
*
* @return array
*/
public static function merge(array $arrays)
{
$result = [];
foreach ($arrays as $array) {
foreach ($array as $key => $value) {
if (is_int($key)) {
$result[] = $value;
continue;
}
if (isset($result[$key]) && is_array($result[$key])) {
$result[$key] = self::merge(
[$result[$key], $value]
);
continue;
}
$result[$key] = $value;
}
}
return $result;
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace AlibabaCloud\Client\Support;
/**
* Class Path
*
* @package AlibabaCloud\Client\Support
*/
class Path
{
/**
* Assign path parameters to the url.
*
* @param string $pattern
* @param array $parameters
*
* @return string
*/
public static function assign($pattern, array $parameters)
{
foreach ($parameters as $key => $value) {
$pattern = str_replace("[$key]", $value, $pattern);
}
return $pattern;
}
}

View File

@ -0,0 +1,140 @@
<?php
namespace AlibabaCloud\Client\Support;
use GuzzleHttp\Psr7\Request;
use Psr\Http\Message\UriInterface;
/**
* Class Sign
*
* @package AlibabaCloud\Client\Support
*/
class Sign
{
/**
* @var string
*/
private static $headerSeparator = "\n";
/**
* Construct standard Header for Alibaba Cloud.
*
* @param array $headers
*
* @return string
*/
private static function acsHeaderString(array $headers)
{
$array = [];
foreach ($headers as $headerKey => $headerValue) {
$key = strtolower($headerKey);
if (strncmp($key, 'x-acs-', 6) === 0) {
$array[$key] = $headerValue;
}
}
ksort($array);
$string = '';
foreach ($array as $sortMapKey => $sortMapValue) {
$string .= $sortMapKey . ':' . $sortMapValue[0] . self::$headerSeparator;
}
return $string;
}
/**
* @param UriInterface $uri
*
* @return string
*/
private static function resourceString(UriInterface $uri)
{
return $uri->getPath() . '?' . rawurldecode($uri->getQuery());
}
/**
* @param string $method
* @param array $headers
*
* @return string
*/
private static function headerString($method, array $headers)
{
$string = $method . self::$headerSeparator;
if (isset($headers['Accept'][0])) {
$string .= $headers['Accept'][0];
}
$string .= self::$headerSeparator;
if (isset($headers['Content-MD5'][0])) {
$string .= $headers['Content-MD5'][0];
}
$string .= self::$headerSeparator;
if (isset($headers['Content-Type'][0])) {
$string .= $headers['Content-Type'][0];
}
$string .= self::$headerSeparator;
if (isset($headers['Date'][0])) {
$string .= $headers['Date'][0];
}
$string .= self::$headerSeparator;
$string .= self::acsHeaderString($headers);
return $string;
}
/**
* @param string $string
*
* @return null|string|string[]
*/
private static function percentEncode($string)
{
$result = urlencode($string);
$result = str_replace(['+', '*'], ['%20', '%2A'], $result);
$result = preg_replace('/%7E/', '~', $result);
return $result;
}
/**
* @param string $method
* @param array $parameters
*
* @return string
*/
public static function rpcString($method, array $parameters)
{
ksort($parameters);
$canonicalized = '';
foreach ($parameters as $key => $value) {
$canonicalized .= '&' . self::percentEncode($key) . '=' . self::percentEncode($value);
}
return $method . '&%2F&' . self::percentEncode(substr($canonicalized, 1));
}
/**
* @param Request $request
*
* @return string
*/
public static function roaString(Request $request)
{
return self::headerString($request->getMethod(), $request->getHeaders()) .
self::resourceString($request->getUri());
}
/**
* @param string $salt
*
* @return string
*/
public static function uuid($salt)
{
return md5($salt . uniqid(md5(microtime(true)), true)) . microtime();
}
}

View File

@ -0,0 +1,57 @@
<?php
namespace AlibabaCloud\Client\Traits;
/**
* Trait ArrayAccessTrait
*
* @package AlibabaCloud\Client\Traits
*/
trait ArrayAccessTrait
{
/**
* This method returns a reference to the variable to allow for indirect
* array modification (e.g., $foo['bar']['baz'] = 'qux').
*
* @param string $offset
*
* @return mixed|null
*/
public function & offsetGet($offset)
{
if (isset($this->data[$offset])) {
return $this->data[$offset];
}
$value = null;
return $value;
}
/**
* @param string $offset
* @param string|mixed $value
*/
public function offsetSet($offset, $value)
{
$this->data[$offset] = $value;
}
/**
* @param string $offset
*
* @return bool
*/
public function offsetExists($offset)
{
return isset($this->data[$offset]);
}
/**
* @param string $offset
*/
public function offsetUnset($offset)
{
unset($this->data[$offset]);
}
}

View File

@ -0,0 +1,273 @@
<?php
namespace AlibabaCloud\Client\Traits;
use AlibabaCloud\Client\SDK;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Clients\Client;
use AlibabaCloud\Client\Clients\StsClient;
use AlibabaCloud\Client\Filter\ClientFilter;
use AlibabaCloud\Client\Clients\AccessKeyClient;
use AlibabaCloud\Client\Clients\EcsRamRoleClient;
use AlibabaCloud\Client\Clients\RamRoleArnClient;
use AlibabaCloud\Client\Clients\RsaKeyPairClient;
use AlibabaCloud\Client\Clients\BearerTokenClient;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Signature\SignatureInterface;
use AlibabaCloud\Client\Credentials\Ini\IniCredential;
use AlibabaCloud\Client\Credentials\CredentialsInterface;
use AlibabaCloud\Client\Credentials\Providers\CredentialsProvider;
/**
* Trait of the manage clients.
*
* @package AlibabaCloud\Client\Traits
*
* @mixin AlibabaCloud
*/
trait ClientTrait
{
/**
* @var array Containers of Clients
*/
protected static $clients = [];
/**
* @param string $clientName
* @param Client $client
*
* @return Client
* @throws ClientException
*/
public static function set($clientName, Client $client)
{
ClientFilter::clientName($clientName);
return self::$clients[\strtolower($clientName)] = $client;
}
/**
* Get all clients.
*
* @return array
*/
public static function all()
{
return self::$clients;
}
/**
* Delete the client by specifying name.
*
* @param string $clientName
*
* @throws ClientException
*/
public static function del($clientName)
{
ClientFilter::clientName($clientName);
unset(self::$clients[\strtolower($clientName)]);
}
/**
* Delete all clients.
*
* @return void
*/
public static function flush()
{
self::$clients = [];
self::$defaultRegionId = null;
}
/**
* @codeCoverageIgnore
* @throws ClientException
* @deprecated
*/
public static function getGlobalClient()
{
return self::getDefaultClient();
}
/**
* Get the default client.
*
* @return Client
* @throws ClientException
*/
public static function getDefaultClient()
{
return self::get(CredentialsProvider::getDefaultName());
}
/**
* Get the Client instance by name.
*
* @param string $clientName
*
* @return Client
* @throws ClientException
*/
public static function get($clientName)
{
ClientFilter::clientName($clientName);
if (self::has($clientName)) {
return self::$clients[\strtolower($clientName)];
}
throw new ClientException(
"Client '$clientName' not found",
SDK::CLIENT_NOT_FOUND
);
}
/**
* Determine whether there is a client.
*
* @param string $clientName
*
* @return bool
* @throws ClientException
*/
public static function has($clientName)
{
ClientFilter::clientName($clientName);
return isset(self::$clients[\strtolower($clientName)]);
}
/**
* A list of additional files to load.
*
* @return array
* @throws ClientException when a file has a syntax error or does not exist or is not readable
*/
public static function load()
{
if (\func_get_args() === []) {
return (new IniCredential())->load();
}
$list = [];
foreach (\func_get_args() as $filename) {
$list[$filename] = (new IniCredential($filename))->load();
}
return $list;
}
/**
* Custom Client.
*
* @param CredentialsInterface $credentials
* @param SignatureInterface $signature
*
* @return Client
*/
public static function client(CredentialsInterface $credentials, SignatureInterface $signature)
{
return new Client($credentials, $signature);
}
/**
* Use the AccessKey to complete the authentication.
*
* @param string $accessKeyId
* @param string $accessKeySecret
*
* @return AccessKeyClient
* @throws ClientException
*/
public static function accessKeyClient($accessKeyId, $accessKeySecret)
{
if (strpos($accessKeyId, ' ') !== false) {
throw new ClientException(
'AccessKey ID format is invalid',
SDK::INVALID_ARGUMENT
);
}
if (strpos($accessKeySecret, ' ') !== false) {
throw new ClientException(
'AccessKey Secret format is invalid',
SDK::INVALID_ARGUMENT
);
}
return new AccessKeyClient($accessKeyId, $accessKeySecret);
}
/**
* Use the AssumeRole of the RAM account to complete the authentication.
*
* @param string $accessKeyId
* @param string $accessKeySecret
* @param string $roleArn
* @param string $roleSessionName
* @param string|array $policy
*
* @return RamRoleArnClient
* @throws ClientException
*/
public static function ramRoleArnClient($accessKeyId, $accessKeySecret, $roleArn, $roleSessionName, $policy = '')
{
return new RamRoleArnClient($accessKeyId, $accessKeySecret, $roleArn, $roleSessionName, $policy);
}
/**
* Use the RAM role of an ECS instance to complete the authentication.
*
* @param string $roleName
*
* @return EcsRamRoleClient
* @throws ClientException
*/
public static function ecsRamRoleClient($roleName)
{
return new EcsRamRoleClient($roleName);
}
/**
* Use the Bearer Token to complete the authentication.
*
* @param string $bearerToken
*
* @return BearerTokenClient
* @throws ClientException
*/
public static function bearerTokenClient($bearerToken)
{
return new BearerTokenClient($bearerToken);
}
/**
* Use the STS Token to complete the authentication.
*
* @param string $accessKeyId Access key ID
* @param string $accessKeySecret Access Key Secret
* @param string $securityToken Security Token
*
* @return StsClient
* @throws ClientException
*/
public static function stsClient($accessKeyId, $accessKeySecret, $securityToken = '')
{
return new StsClient($accessKeyId, $accessKeySecret, $securityToken);
}
/**
* Use the RSA key pair to complete the authentication (supported only on Japanese site)
*
* @param string $publicKeyId
* @param string $privateKeyFile
*
* @return RsaKeyPairClient
* @throws ClientException
*/
public static function rsaKeyPairClient($publicKeyId, $privateKeyFile)
{
return new RsaKeyPairClient($publicKeyId, $privateKeyFile);
}
}

View File

@ -0,0 +1,66 @@
<?php
namespace AlibabaCloud\Client\Traits;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Filter\ClientFilter;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Trait DefaultRegionTrait
*
* @package AlibabaCloud\Client\Traits
*
* @mixin AlibabaCloud
*/
trait DefaultRegionTrait
{
/**
* @var string|null Default RegionId
*/
protected static $defaultRegionId;
/**
* @param $regionId
*
* @throws ClientException
* @deprecated
* @codeCoverageIgnore
*/
public static function setGlobalRegionId($regionId)
{
self::setDefaultRegionId($regionId);
}
/**
* @return string|null
* @deprecated
* @codeCoverageIgnore
*/
public static function getGlobalRegionId()
{
return self::getDefaultRegionId();
}
/**
* Get the default RegionId.
*
* @return string|null
*/
public static function getDefaultRegionId()
{
return self::$defaultRegionId;
}
/**
* Set the default RegionId.
*
* @param string $regionId
*
* @throws ClientException
*/
public static function setDefaultRegionId($regionId)
{
self::$defaultRegionId = ClientFilter::regionId($regionId);
}
}

View File

@ -0,0 +1,134 @@
<?php
namespace AlibabaCloud\Client\Traits;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Config\Config;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Filter\ApiFilter;
use AlibabaCloud\Client\Filter\ClientFilter;
use AlibabaCloud\Client\Filter\HttpFilter;
use AlibabaCloud\Client\Regions\LocationService;
use AlibabaCloud\Client\Request\Request;
use InvalidArgumentException;
/**
* Help developers set up and get host.
*
* @package AlibabaCloud\Client\Traits
*
* @mixin AlibabaCloud
*/
trait EndpointTrait
{
/**
* @var array Host cache.
*/
private static $hosts = [];
/**
* Resolve host based on product name and region.
*
* @param string $product
* @param string $regionId
*
* @return string
* @throws ClientException
*/
public static function resolveHost($product, $regionId = LocationService::GLOBAL_REGION)
{
ApiFilter::product($product);
ClientFilter::regionId($regionId);
if (isset(self::$hosts[$product][$regionId])) {
return self::$hosts[$product][$regionId];
}
$domain = Config::get("endpoints.{$product}.{$regionId}");
if (!$domain) {
$regionId = LocationService::GLOBAL_REGION;
$domain = Config::get("endpoints.{$product}.{$regionId}", '');
}
return $domain;
}
/**
* @param $productCode
*
* @return bool
*/
public static function isGlobalProduct($productCode)
{
$global = LocationService::GLOBAL_REGION;
if (self::resolveHostByStatic($productCode, $global)) {
return true;
}
$productCode = strtolower($productCode);
return (bool)Config::get("endpoints.{$productCode}.{$global}");
}
/**
* @param string $product
* @param string $regionId
*
* @return string
*/
public static function resolveHostByStatic($product, $regionId)
{
if (isset(self::$hosts[$product][$regionId])) {
return self::$hosts[$product][$regionId];
}
return '';
}
/**
* Add host based on product name and region.
*
* @param string $product
* @param string $host
* @param string $regionId
*
* @return void
* @throws ClientException
*/
public static function addHost($product, $host, $regionId = LocationService::GLOBAL_REGION)
{
ApiFilter::product($product);
HttpFilter::host($host);
ClientFilter::regionId($regionId);
self::$hosts[$product][$regionId] = $host;
LocationService::addHost($product, $host, $regionId);
}
/**
* @param Request $request
*
* @return string
* @throws ClientException
*/
public static function resolveHostByRule(Request $request)
{
$network = $request->network ?: 'public';
$suffix = $request->endpointSuffix;
if ($network === 'public') {
$network = '';
}
if ($request->endpointRegional === 'regional') {
$regionId = $request->realRegionId();
return "{$request->product}{$suffix}{$network}.{$regionId}.aliyuncs.com";
}
if ($request->endpointRegional === 'central') {
return "{$request->product}{$suffix}{$network}.aliyuncs.com";
}
throw new InvalidArgumentException('endpointRegional is invalid.');
}
}

View File

@ -0,0 +1,317 @@
<?php
namespace AlibabaCloud\Client\Traits;
use Adbar\Dot;
use ArrayIterator;
use JmesPath\Env as JmesPath;
use AlibabaCloud\Client\Result\Result;
/**
* Trait HasDataTrait
*
* @package AlibabaCloud\Client\Traits
* @mixin Result
*/
trait HasDataTrait
{
/**
* Instance of the Dot.
*
* @var Dot
*/
protected $dot;
/**
* @param string $expression
*
* @return mixed|null
*/
public function search($expression)
{
return JmesPath::search($expression, $this->dot->all());
}
/**
* Delete the contents of a given key or keys
*
* @param array|int|string|null $keys
*/
public function clear($keys = null)
{
$this->dot->clear($keys);
}
/**
* Flatten an array with the given character as a key delimiter
*
* @param string $delimiter
* @param array|null $items
* @param string $prepend
*
* @return array
*/
public function flatten($delimiter = '.', $items = null, $prepend = '')
{
return $this->dot->flatten($delimiter, $items, $prepend);
}
/**
* Return the value of a given key
*
* @param int|string|null $key
* @param mixed $default
*
* @return mixed
*/
public function get($key = null, $default = null)
{
return $this->dot->get($key, $default);
}
/**
* Set a given key / value pair or pairs
*
* @param array|int|string $keys
* @param mixed $value
*/
public function set($keys, $value = null)
{
$this->dot->set($keys, $value);
}
/**
* Check if a given key or keys are empty
*
* @param array|int|string|null $keys
*
* @return bool
*/
public function isEmpty($keys = null)
{
return $this->dot->isEmpty($keys);
}
/**
* Replace all items with a given array as a reference
*
* @param array $items
*/
public function setReference(array &$items)
{
$this->dot->setReference($items);
}
/**
* Return the value of a given key or all the values as JSON
*
* @param mixed $key
* @param int $options
*
* @return string
*/
public function toJson($key = null, $options = 0)
{
return $this->dot->toJson($key, $options);
}
/**
* @return array
*/
public function toArray()
{
return $this->dot->all();
}
/**
* Check if a given key exists
*
* @param int|string $key
*
* @return bool
*/
public function offsetExists($key)
{
return $this->dot->has($key);
}
/**
* Return the value of a given key
*
* @param int|string $key
*
* @return mixed
*/
public function offsetGet($key)
{
return $this->dot->offsetGet($key);
}
/**
* Set a given value to the given key
*
* @param int|string|null $key
* @param mixed $value
*/
public function offsetSet($key, $value)
{
$this->dot->offsetSet($key, $value);
}
/**
* Delete the given key
*
* @param int|string $key
*/
public function offsetUnset($key)
{
$this->delete($key);
}
/**
* Delete the given key or keys
*
* @param array|int|string $keys
*/
public function delete($keys)
{
$this->dot->delete($keys);
}
/*
* --------------------------------------------------------------
* ArrayAccess interface
* --------------------------------------------------------------
*/
/**
* Return the number of items in a given key
*
* @param int|string|null $key
*
* @return int
*/
public function count($key = null)
{
return $this->dot->count($key);
}
/**
* Get an iterator for the stored items
*
* @return ArrayIterator
*/
public function getIterator()
{
return $this->dot->getIterator();
}
/**
* Return items for JSON serialization
*
* @return array
*/
public function jsonSerialize()
{
return $this->dot->jsonSerialize();
}
/**
* @param string $name
*
* @return mixed|null
*/
public function __get($name)
{
if (!isset($this->all()[$name])) {
return null;
}
return \json_decode(\json_encode($this->all()))->$name;
}
/*
* --------------------------------------------------------------
* Countable interface
* --------------------------------------------------------------
*/
/**
* Return all the stored items
*
* @return array
*/
public function all()
{
return $this->dot->all();
}
/**
* @param string $name
* @param mixed $value
*/
public function __set($name, $value)
{
$this->add($name, $value);
}
/**
* Set a given key / value pair or pairs
* if the key doesn't exist already
*
* @param array|int|string $keys
* @param mixed $value
*/
public function add($keys, $value = null)
{
$this->dot->add($keys, $value);
}
/*
* --------------------------------------------------------------
* ObjectAccess
* --------------------------------------------------------------
*/
/**
* @param string $name
*
* @return bool
*/
public function __isset($name)
{
return $this->has($name);
}
/**
* Check if a given key or keys exists
*
* @param array|int|string $keys
*
* @return bool
*/
public function has($keys)
{
return $this->dot->has($keys);
}
/**
* @param $name
*
* @return void
*/
public function __unset($name)
{
$this->delete($name);
}
/**
* @param array $data
*/
protected function dot(array $data = [])
{
$this->dot = new Dot($data);
}
}

View File

@ -0,0 +1,68 @@
<?php
namespace AlibabaCloud\Client\Traits;
/**
* Trait HistoryTrait
*
* @package AlibabaCloud\Client\Traits
*/
trait HistoryTrait
{
/**
* @var array
*/
private static $history = [];
/**
* @var bool
*/
private static $isRememberHistory = false;
/**
* @return array
*/
public static function getHistory()
{
return self::$history;
}
public static function forgetHistory()
{
self::$history = [];
}
public static function notRememberHistory()
{
self::$isRememberHistory = false;
}
public static function rememberHistory()
{
self::$isRememberHistory = true;
}
/**
* @return bool
*/
public static function isRememberHistory()
{
return self::$isRememberHistory;
}
/**
* @return array
*/
public static function &referenceHistory()
{
return self::$history;
}
/**
* @return int
*/
public static function countHistory()
{
return count(self::$history);
}
}

View File

@ -0,0 +1,141 @@
<?php
namespace AlibabaCloud\Client\Traits;
use AlibabaCloud\Client\Support\Arrays;
use AlibabaCloud\Client\Filter\ClientFilter;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Trait HttpTrait
*
* @package AlibabaCloud\Client\Traits
*/
trait HttpTrait
{
/**
* @var array
*/
public $options = [];
/**
* @param int|float $seconds
*
* @return $this
* @throws ClientException
*/
public function timeout($seconds)
{
$this->options['timeout'] = ClientFilter::timeout($seconds);
return $this;
}
/**
* @param int $milliseconds
*
* @return $this
* @throws ClientException
*/
public function timeoutMilliseconds($milliseconds)
{
ClientFilter::milliseconds($milliseconds);
$seconds = $milliseconds / 1000;
return $this->timeout($seconds);
}
/**
* @param int|float $seconds
*
* @return $this
* @throws ClientException
*/
public function connectTimeout($seconds)
{
$this->options['connect_timeout'] = ClientFilter::connectTimeout($seconds);
return $this;
}
/**
* @param int $milliseconds
*
* @return $this
* @throws ClientException
*/
public function connectTimeoutMilliseconds($milliseconds)
{
ClientFilter::milliseconds($milliseconds);
$seconds = $milliseconds / 1000;
return $this->connectTimeout($seconds);
}
/**
* @param bool $debug
*
* @return $this
*/
public function debug($debug)
{
$this->options['debug'] = $debug;
return $this;
}
/**
* @codeCoverageIgnore
*
* @param array $cert
*
* @return $this
*/
public function cert($cert)
{
$this->options['cert'] = $cert;
return $this;
}
/**
* @codeCoverageIgnore
*
* @param array|string $proxy
*
* @return $this
*/
public function proxy($proxy)
{
$this->options['proxy'] = $proxy;
return $this;
}
/**
* @param mixed $verify
*
* @return $this
*/
public function verify($verify)
{
$this->options['verify'] = $verify;
return $this;
}
/**
* @param array $options
*
* @return $this
*/
public function options(array $options)
{
if ($options !== []) {
$this->options = Arrays::merge([$this->options, $options]);
}
return $this;
}
}

View File

@ -0,0 +1,64 @@
<?php
namespace AlibabaCloud\Client\Traits;
use Exception;
use Psr\Log\LoggerInterface;
/**
* Trait LogTrait
*
* @package AlibabaCloud\Client\Traits
*/
trait LogTrait
{
/**
* @var LoggerInterface
*/
private static $logger;
/**
* @var string
*/
private static $logFormat;
/**
* @return LoggerInterface
*/
public static function getLogger()
{
return self::$logger;
}
/**
* @param LoggerInterface $logger
*
* @throws Exception
*/
public static function setLogger(LoggerInterface $logger)
{
self::$logger = $logger;
}
/**
* @return string
*/
public static function getLogFormat()
{
return self::$logFormat
?: '"{method} {uri} HTTP/{version}" {code} {cost} {hostname} {pid}';
}
/**
* Apache Common Log Format.
*
* @param string $formatter
*
* @link http://httpd.apache.org/docs/2.4/logs.html#common
* @see \GuzzleHttp\MessageFormatter
*/
public static function setLogFormat($formatter)
{
self::$logFormat = $formatter;
}
}

View File

@ -0,0 +1,97 @@
<?php
namespace AlibabaCloud\Client\Traits;
use Exception;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;
use GuzzleHttp\Handler\MockHandler;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use GuzzleHttp\Exception\RequestException;
/**
* Class MockTrait
*
* @package AlibabaCloud\Client\Request\Traits
* @mixin Request
*/
trait MockTrait
{
/**
* @var array
*/
private static $mockQueue = [];
/**
* @var MockHandler
*/
private static $mock;
/**
* @param integer $status
* @param array $headers
* @param array|string|object $body
*/
public static function mockResponse($status = 200, array $headers = [], $body = null)
{
if (is_array($body) || is_object($body)) {
$body = json_encode($body);
}
self::$mockQueue[] = new Response($status, $headers, $body);
self::createHandlerStack();
}
private static function createHandlerStack()
{
self::$mock = new MockHandler(self::$mockQueue);
}
/**
* @param string $message
* @param RequestInterface $request
* @param ResponseInterface|null $response
* @param Exception|null $previous
* @param array $handlerContext
*/
public static function mockRequestException(
$message,
RequestInterface $request,
ResponseInterface $response = null,
Exception $previous = null,
array $handlerContext = []
) {
self::$mockQueue[] = new RequestException(
$message,
$request,
$response,
$previous,
$handlerContext
);
self::createHandlerStack();
}
public static function cancelMock()
{
self::$mockQueue = [];
self::$mock = null;
}
/**
* @return bool
*/
public static function hasMock()
{
return (bool)self::$mockQueue;
}
/**
* @return MockHandler
*/
public static function getMock()
{
return self::$mock;
}
}

View File

@ -0,0 +1,54 @@
<?php
namespace AlibabaCloud\Client\Traits;
/**
* Trait ObjectAccessTrait
*
* @package AlibabaCloud\Client\Traits
*/
trait ObjectAccessTrait
{
/**
* @param string $name
*
* @return mixed|null
*/
public function __get($name)
{
if (!isset($this->data[$name])) {
return null;
}
return \json_decode(\json_encode($this->data))->$name;
}
/**
* @param string $name
* @param mixed $value
*/
public function __set($name, $value)
{
$this->data[$name] = $value;
}
/**
* @param string $name
*
* @return bool
*/
public function __isset($name)
{
return isset($this->data[$name]);
}
/**
* @param $name
*
* @return void
*/
public function __unset($name)
{
unset($this->data[$name]);
}
}

View File

@ -0,0 +1,33 @@
<?php
namespace AlibabaCloud\Client\Traits;
use AlibabaCloud\Client\Filter\ClientFilter;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Trait RegionTrait
*
* @package AlibabaCloud\Client\Traits
*/
trait RegionTrait
{
/**
* @var string|null
*/
public $regionId;
/**
* @param string $regionId
*
* @return $this
* @throws ClientException
*/
public function regionId($regionId)
{
$this->regionId = ClientFilter::regionId($regionId);
return $this;
}
}

View File

@ -0,0 +1,90 @@
<?php
namespace AlibabaCloud\Client\Traits;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Filter\Filter;
use AlibabaCloud\Client\Request\UserAgent;
use AlibabaCloud\Client\Request\RpcRequest;
use AlibabaCloud\Client\Request\RoaRequest;
use AlibabaCloud\Client\Exception\ClientException;
/**
* Trait RequestTrait
*
* @package AlibabaCloud\Client\Traits
*
* @mixin AlibabaCloud
*/
trait RequestTrait
{
/**
* @param string $name
* @param string $value
*
* @throws ClientException
*/
public static function appendUserAgent($name, $value)
{
Filter::name($name);
Filter::value($value);
UserAgent::append($name, $value);
}
/**
* @param array $userAgent
*/
public static function withUserAgent(array $userAgent)
{
UserAgent::with($userAgent);
}
/**
* @param array $options
*
* @return RpcRequest
* @throws ClientException
* @deprecated
* @codeCoverageIgnore
*/
public static function rpcRequest(array $options = [])
{
return self::rpc($options);
}
/**
* @param array $options
*
* @return RpcRequest
* @throws ClientException
*/
public static function rpc(array $options = [])
{
return new RpcRequest($options);
}
/**
* @param array $options
*
* @return RoaRequest
* @throws ClientException
* @deprecated
* @codeCoverageIgnore
*/
public static function roaRequest(array $options = [])
{
return self::roa($options);
}
/**
* @param array $options
*
* @return RoaRequest
* @throws ClientException
*/
public static function roa(array $options = [])
{
return new RoaRequest($options);
}
}

View File

@ -0,0 +1,2 @@
coverage_clover: coverage.xml
json_path: coverage.json

View File

@ -0,0 +1,8 @@
vendor
composer.lock
doc
output
.idea
.buildpath
.project
.settings

Some files were not shown because too many files have changed in this diff Show More