Browse Source

更新了一些基础组件

panda 4 months ago
parent
commit
2932440070
100 changed files with 15366 additions and 0 deletions
  1. 33 0
      application/job/DemoJob.php
  2. 67 0
      application/task/Kernel.php
  3. 31 0
      application/task/time/DemoTime.php
  4. 21 0
      vendor/adbario/php-dot-notation/LICENSE.md
  5. 29 0
      vendor/adbario/php-dot-notation/composer.json
  6. 623 0
      vendor/adbario/php-dot-notation/src/Dot.php
  7. 24 0
      vendor/adbario/php-dot-notation/src/helpers.php
  8. 14 0
      vendor/alibabacloud/credentials/CHANGELOG.md
  9. 30 0
      vendor/alibabacloud/credentials/CONTRIBUTING.md
  10. 13 0
      vendor/alibabacloud/credentials/LICENSE.md
  11. 88 0
      vendor/alibabacloud/credentials/NOTICE.md
  12. 405 0
      vendor/alibabacloud/credentials/README-zh-CN.md
  13. 400 0
      vendor/alibabacloud/credentials/README.md
  14. 21 0
      vendor/alibabacloud/credentials/SECURITY.md
  15. 6 0
      vendor/alibabacloud/credentials/UPGRADING.md
  16. 107 0
      vendor/alibabacloud/credentials/composer.json
  17. 86 0
      vendor/alibabacloud/credentials/src/AccessKeyCredential.php
  18. 67 0
      vendor/alibabacloud/credentials/src/BearerTokenCredential.php
  19. 268 0
      vendor/alibabacloud/credentials/src/Credential.php
  20. 270 0
      vendor/alibabacloud/credentials/src/Credential/Config.php
  21. 125 0
      vendor/alibabacloud/credentials/src/Credential/CredentialModel.php
  22. 104 0
      vendor/alibabacloud/credentials/src/Credentials.php
  23. 32 0
      vendor/alibabacloud/credentials/src/CredentialsInterface.php
  24. 75 0
      vendor/alibabacloud/credentials/src/CredentialsProviderWrap.php
  25. 199 0
      vendor/alibabacloud/credentials/src/EcsRamRoleCredential.php
  26. 179 0
      vendor/alibabacloud/credentials/src/Providers/CLIProfileCredentialsProvider.php
  27. 188 0
      vendor/alibabacloud/credentials/src/Providers/ChainProvider.php
  28. 87 0
      vendor/alibabacloud/credentials/src/Providers/Credentials.php
  29. 24 0
      vendor/alibabacloud/credentials/src/Providers/CredentialsProvider.php
  30. 177 0
      vendor/alibabacloud/credentials/src/Providers/DefaultCredentialsProvider.php
  31. 256 0
      vendor/alibabacloud/credentials/src/Providers/EcsRamRoleCredentialsProvider.php
  32. 61 0
      vendor/alibabacloud/credentials/src/Providers/EnvironmentVariableCredentialsProvider.php
  33. 257 0
      vendor/alibabacloud/credentials/src/Providers/OIDCRoleArnCredentialsProvider.php
  34. 188 0
      vendor/alibabacloud/credentials/src/Providers/ProfileCredentialsProvider.php
  35. 310 0
      vendor/alibabacloud/credentials/src/Providers/RamRoleArnCredentialsProvider.php
  36. 193 0
      vendor/alibabacloud/credentials/src/Providers/RsaKeyPairCredentialsProvider.php
  37. 86 0
      vendor/alibabacloud/credentials/src/Providers/SessionCredentialsProvider.php
  38. 78 0
      vendor/alibabacloud/credentials/src/Providers/StaticAKCredentialsProvider.php
  39. 92 0
      vendor/alibabacloud/credentials/src/Providers/StaticSTSCredentialsProvider.php
  40. 119 0
      vendor/alibabacloud/credentials/src/Providers/URLCredentialsProvider.php
  41. 242 0
      vendor/alibabacloud/credentials/src/RamRoleArnCredential.php
  42. 167 0
      vendor/alibabacloud/credentials/src/Request/Request.php
  43. 185 0
      vendor/alibabacloud/credentials/src/RsaKeyPairCredential.php
  44. 47 0
      vendor/alibabacloud/credentials/src/Signature/BearerTokenSignature.php
  45. 47 0
      vendor/alibabacloud/credentials/src/Signature/ShaHmac1Signature.php
  46. 47 0
      vendor/alibabacloud/credentials/src/Signature/ShaHmac256Signature.php
  47. 64 0
      vendor/alibabacloud/credentials/src/Signature/ShaHmac256WithRsaSignature.php
  48. 34 0
      vendor/alibabacloud/credentials/src/Signature/SignatureInterface.php
  49. 115 0
      vendor/alibabacloud/credentials/src/StsCredential.php
  50. 233 0
      vendor/alibabacloud/credentials/src/Utils/Filter.php
  51. 251 0
      vendor/alibabacloud/credentials/src/Utils/Helper.php
  52. 120 0
      vendor/alibabacloud/credentials/src/Utils/MockTrait.php
  53. 15 0
      vendor/alibabacloud/darabonba-openapi/.gitignore
  54. 65 0
      vendor/alibabacloud/darabonba-openapi/.php_cs.dist
  55. 31 0
      vendor/alibabacloud/darabonba-openapi/README-CN.md
  56. 31 0
      vendor/alibabacloud/darabonba-openapi/README.md
  57. 15 0
      vendor/alibabacloud/darabonba-openapi/autoload.php
  58. 34 0
      vendor/alibabacloud/darabonba-openapi/composer.json
  59. 31 0
      vendor/alibabacloud/darabonba-openapi/phpunit.xml
  60. 450 0
      vendor/alibabacloud/darabonba-openapi/src/Models/Config.php
  61. 43 0
      vendor/alibabacloud/darabonba-openapi/src/Models/GlobalParameters.php
  62. 75 0
      vendor/alibabacloud/darabonba-openapi/src/Models/OpenApiRequest.php
  63. 131 0
      vendor/alibabacloud/darabonba-openapi/src/Models/Params.php
  64. 1274 0
      vendor/alibabacloud/darabonba-openapi/src/OpenApiClient.php
  65. 328 0
      vendor/alibabacloud/darabonba-openapi/tests/OpenApiClientTest.php
  66. 3 0
      vendor/alibabacloud/darabonba-openapi/tests/bootstrap.php
  67. 15 0
      vendor/alibabacloud/dysmsapi-20170525/.gitignore
  68. 65 0
      vendor/alibabacloud/dysmsapi-20170525/.php_cs.dist
  69. 89 0
      vendor/alibabacloud/dysmsapi-20170525/ChangeLog.md
  70. 201 0
      vendor/alibabacloud/dysmsapi-20170525/LICENSE
  71. 35 0
      vendor/alibabacloud/dysmsapi-20170525/README-CN.md
  72. 35 0
      vendor/alibabacloud/dysmsapi-20170525/README.md
  73. 17 0
      vendor/alibabacloud/dysmsapi-20170525/autoload.php
  74. 33 0
      vendor/alibabacloud/dysmsapi-20170525/composer.json
  75. 3049 0
      vendor/alibabacloud/dysmsapi-20170525/src/Dysmsapi.php
  76. 122 0
      vendor/alibabacloud/dysmsapi-20170525/src/Models/AddShortUrlRequest.php
  77. 71 0
      vendor/alibabacloud/dysmsapi-20170525/src/Models/AddShortUrlResponse.php
  78. 101 0
      vendor/alibabacloud/dysmsapi-20170525/src/Models/AddShortUrlResponseBody.php
  79. 84 0
      vendor/alibabacloud/dysmsapi-20170525/src/Models/AddShortUrlResponseBody/data.php
  80. 182 0
      vendor/alibabacloud/dysmsapi-20170525/src/Models/AddSmsSignRequest.php
  81. 69 0
      vendor/alibabacloud/dysmsapi-20170525/src/Models/AddSmsSignRequest/signFileList.php
  82. 71 0
      vendor/alibabacloud/dysmsapi-20170525/src/Models/AddSmsSignResponse.php
  83. 102 0
      vendor/alibabacloud/dysmsapi-20170525/src/Models/AddSmsSignResponseBody.php
  84. 144 0
      vendor/alibabacloud/dysmsapi-20170525/src/Models/AddSmsTemplateRequest.php
  85. 71 0
      vendor/alibabacloud/dysmsapi-20170525/src/Models/AddSmsTemplateResponse.php
  86. 102 0
      vendor/alibabacloud/dysmsapi-20170525/src/Models/AddSmsTemplateResponseBody.php
  87. 69 0
      vendor/alibabacloud/dysmsapi-20170525/src/Models/CheckMobilesCardSupportRequest.php
  88. 71 0
      vendor/alibabacloud/dysmsapi-20170525/src/Models/CheckMobilesCardSupportResponse.php
  89. 104 0
      vendor/alibabacloud/dysmsapi-20170525/src/Models/CheckMobilesCardSupportResponseBody.php
  90. 62 0
      vendor/alibabacloud/dysmsapi-20170525/src/Models/CheckMobilesCardSupportResponseBody/data.php
  91. 70 0
      vendor/alibabacloud/dysmsapi-20170525/src/Models/CheckMobilesCardSupportResponseBody/data/queryResult.php
  92. 105 0
      vendor/alibabacloud/dysmsapi-20170525/src/Models/ConversionDataIntlRequest.php
  93. 71 0
      vendor/alibabacloud/dysmsapi-20170525/src/Models/ConversionDataIntlResponse.php
  94. 83 0
      vendor/alibabacloud/dysmsapi-20170525/src/Models/ConversionDataIntlResponseBody.php
  95. 108 0
      vendor/alibabacloud/dysmsapi-20170525/src/Models/CreateCardSmsTemplateRequest.php
  96. 71 0
      vendor/alibabacloud/dysmsapi-20170525/src/Models/CreateCardSmsTemplateResponse.php
  97. 104 0
      vendor/alibabacloud/dysmsapi-20170525/src/Models/CreateCardSmsTemplateResponseBody.php
  98. 54 0
      vendor/alibabacloud/dysmsapi-20170525/src/Models/CreateCardSmsTemplateResponseBody/data.php
  99. 108 0
      vendor/alibabacloud/dysmsapi-20170525/src/Models/CreateCardSmsTemplateShrinkRequest.php
  100. 117 0
      vendor/alibabacloud/dysmsapi-20170525/src/Models/CreateSmartShortUrlRequest.php

+ 33 - 0
application/job/DemoJob.php

@@ -0,0 +1,33 @@
+<?php
+namespace app\job;
+
+use app\utils\LogUtil;
+use think\queue\Job;
+
+/**
+ * 任务队列 示例
+ * Class DemoJob
+ * @package app\task
+ * Author: Panda joeyoung0314@qq.com
+ * Gitee: https://gitee.com/xertao
+ */
+class DemoJob{
+    const LOG_MODULE = 'DemoJob';
+    public function __construct()
+    {
+        //日志统一写入
+        register_shutdown_function([new LogUtil, 'close']);
+        LogUtil::getInstance('Job/'); //设置日志存入通道
+    }
+
+    /**
+     * fire是消息队列默认调用的方法
+     * @param Job $job 当前的任务对象
+     * @param array|mixed $data 发布任务时自定义的数据
+     */
+    public function fire(Job $job,$data)
+    {
+        LogUtil::info('任务队列', self::LOG_MODULE,__FUNCTION__, $data);
+        $job->delete();//任务执行成功后删除
+    }
+}

+ 67 - 0
application/task/Kernel.php

@@ -0,0 +1,67 @@
+<?php
+
+namespace app\task;
+
+use app\task\time\DemoTime;
+use think\Cache;
+use think\Console;
+
+/**
+ * 定时任务管理器
+ * 业务代码执行时间过长,会造成堵塞,请合理安排执行任务
+ * Class Kernel
+ * @package app\task
+ * Author: Panda joeyoung0314@qq.com
+ * Gitee: https://gitee.com/xertao
+ */
+class Kernel{
+
+    /**
+     * 定时组
+     * 业务代码 业务代码执行时间过长,会造成堵塞,请合理安排执行任务。
+     * 过于复杂的业务需求建议搭配异步进行处理,定时任务作为触发功能使用。
+     * $this->command('DemoTime','10:08','at');// 每天指定时间点触发
+     * $this->command('DemoTime','1','minute');// 默认间隔1分钟触发 daily 单位分钟
+     * @return void
+     */
+    public function schedule()
+    {
+//        $this->command('DemoTime','1','minute');// 默认间隔1分钟触发 daily 单位分钟
+    }
+
+    /**
+     * 定时任务触发时间
+     * @param string $class
+     * @param string $daily
+     * @param string $type
+     * @return false|\think\console\Output
+     */
+    private function command(string $class,string $daily = '',string $type = 'minute')
+    {
+        // 按分钟、按每天指定点数
+        if (!in_array($type,['minute','at'])) {
+            return false;
+        }
+
+        if (!empty($daily)) {
+            switch ($type){
+                case 'minute':
+                    $run_time = Cache::get("task_{$class}_{$type}_{$daily}");
+                    if (ceil((time() - $run_time) / 60) < $daily){
+                        return false;
+                    }
+                    Cache::set("task_{$class}_{$type}_{$daily}",time());
+                    break;
+                case 'at':
+                    if (date('H:i') != $daily){
+                        return false;
+                    }
+                    break;
+                default:
+                    return false;
+            }
+        }
+
+        return Console::call($class);
+    }
+}

+ 31 - 0
application/task/time/DemoTime.php

@@ -0,0 +1,31 @@
+<?php
+
+namespace app\task\time;
+
+use app\job\DemoJob;
+use app\task\Kernel;
+use app\utils\Queue;
+use think\console\Command;
+use think\console\Input;
+use think\console\Output;
+
+/**
+ * 定时任务管理器
+ * 业务代码执行时间过长,会造成堵塞,请合理安排执行任务
+ * Class Kernel
+ * @package app\task
+ */
+class DemoTime extends Command{
+
+    protected function configure()
+    {
+        $this->setName('DemoTime')->setDescription('Here is the remark ');
+    }
+
+    // 业务代码 业务代码执行时间过长,会造成堵塞,请合理安排执行任务
+    protected function execute(Input $input, Output $output)
+    {
+        Queue::work(DemoJob::class,['a' => 1]);
+        return 0;
+    }
+}

+ 21 - 0
vendor/adbario/php-dot-notation/LICENSE.md

@@ -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.

+ 29 - 0
vendor/adbario/php-dot-notation/composer.json

@@ -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 || ^7.0 || ^8.0",
+        "ext-json": "*"
+    },
+    "require-dev": {
+        "phpunit/phpunit": "^4.8|^5.7|^6.6|^7.5|^8.5|^9.5",
+        "squizlabs/php_codesniffer": "^3.6"
+    },
+    "autoload": {
+        "files": [
+            "src/helpers.php"
+        ],
+        "psr-4": {
+            "Adbar\\": "src"
+        }
+    }
+}

+ 623 - 0
vendor/adbario/php-dot-notation/src/Dot.php

@@ -0,0 +1,623 @@
+<?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 = [];
+
+
+    /**
+     * The delimiter (alternative to a '.') to be used.
+     *
+     * @var string
+     */
+    protected $delimiter = '.';
+
+
+    /**
+     * Create a new Dot instance
+     *
+     * @param mixed $items
+     * @param string $delimiter
+     */
+    public function __construct($items = [], $delimiter = '.')
+    {
+        $this->items = $this->getArrayItems($items);
+        $this->delimiter = strlen($delimiter) ? $delimiter : '.';
+    }
+
+    /**
+     * 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($this->delimiter, $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;
+        }
+
+        if (!func_num_args()) {
+            $delimiter = $this->delimiter;
+        }
+
+        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, $this->delimiter) === false) {
+            return $default;
+        }
+
+        $items = $this->items;
+
+        foreach (explode($this->delimiter, $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($this->delimiter, $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($this->delimiter, $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
+     */
+    #[\ReturnTypeWillChange]
+    public function offsetExists($key)
+    {
+        return $this->has($key);
+    }
+
+    /**
+     * Return the value of a given key
+     *
+     * @param  int|string $key
+     * @return mixed
+     */
+    #[\ReturnTypeWillChange]
+    public function offsetGet($key)
+    {
+        return $this->get($key);
+    }
+
+    /**
+     * Set a given value to the given key
+     *
+     * @param int|string|null $key
+     * @param mixed           $value
+     */
+    #[\ReturnTypeWillChange]
+    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
+     */
+    #[\ReturnTypeWillChange]
+    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
+     */
+    #[\ReturnTypeWillChange]
+    public function count($key = null)
+    {
+        return count($this->get($key));
+    }
+
+    /*
+     * --------------------------------------------------------------
+     * IteratorAggregate interface
+     * --------------------------------------------------------------
+     */
+
+     /**
+     * Get an iterator for the stored items
+     *
+     * @return \ArrayIterator
+     */
+    #[\ReturnTypeWillChange]
+    public function getIterator()
+    {
+        return new ArrayIterator($this->items);
+    }
+
+    /*
+     * --------------------------------------------------------------
+     * JsonSerializable interface
+     * --------------------------------------------------------------
+     */
+
+    /**
+     * Return items for JSON serialization
+     *
+     * @return array
+     */
+    #[\ReturnTypeWillChange]
+    public function jsonSerialize()
+    {
+        return $this->items;
+    }
+}

+ 24 - 0
vendor/adbario/php-dot-notation/src/helpers.php

@@ -0,0 +1,24 @@
+<?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 and optional delimiter
+     *
+     * @param  mixed  $items
+     * @param  string $delimiter
+     * @return \Adbar\Dot
+     */
+    function dot($items, $delimiter = '.')
+    {
+        return new Dot($items, $delimiter);
+    }
+}

+ 14 - 0
vendor/alibabacloud/credentials/CHANGELOG.md

@@ -0,0 +1,14 @@
+# CHANGELOG
+
+## 1.1.3 - 2020-12-24
+
+- Require guzzle ^6.3|^7.0
+
+## 1.0.2 - 2020-02-14
+- Update Tea.
+
+## 1.0.1 - 2019-12-30
+- Supported get `Role Name` automatically.
+
+## 1.0.0 - 2019-09-01
+- Initial release of the Alibaba Cloud Credentials for PHP Version 1.0.0 on Packagist See <https://github.com/aliyun/credentials-php> for more information.

+ 30 - 0
vendor/alibabacloud/credentials/CONTRIBUTING.md

@@ -0,0 +1,30 @@
+# CONTRIBUTING
+
+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/credentials-php/issues
+[pull-requests]: https://github.com/aliyun/credentials-php/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/credentials-php/blob/master/README.md

+ 13 - 0
vendor/alibabacloud/credentials/LICENSE.md

@@ -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 - 0
vendor/alibabacloud/credentials/NOTICE.md

@@ -0,0 +1,88 @@
+# NOTICE
+
+<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.

+ 405 - 0
vendor/alibabacloud/credentials/README-zh-CN.md

@@ -0,0 +1,405 @@
+[English](/README.md) | 简体中文
+
+![](https://aliyunsdk-pages.alicdn.com/icons/AlibabaCloud.svg)
+
+# Alibaba Cloud Credentials for PHP
+
+[![PHP CI](https://github.com/aliyun/credentials-php/actions/workflows/ci.yml/badge.svg)](https://github.com/aliyun/credentials-php/actions/workflows/ci.yml)
+[![codecov](https://codecov.io/gh/aliyun/credentials-php/graph/badge.svg?token=YIkSjtfKbB)](https://codecov.io/gh/aliyun/credentials-php)
+[![Latest Stable Version](https://poser.pugx.org/alibabacloud/credentials/v/stable)](https://packagist.org/packages/alibabacloud/credentials)
+[![composer.lock](https://poser.pugx.org/alibabacloud/credentials/composerlock)](https://packagist.org/packages/alibabacloud/credentials)
+[![Total Downloads](https://poser.pugx.org/alibabacloud/credentials/downloads)](https://packagist.org/packages/alibabacloud/credentials)
+[![License](https://poser.pugx.org/alibabacloud/credentials/license)](https://packagist.org/packages/alibabacloud/credentials)
+
+Alibaba Cloud Credentials for PHP 是帮助 PHP 开发者管理凭据的工具。
+
+## 先决条件
+
+您的系统需要满足[先决条件](/docs/zh-CN/0-Prerequisites.md),包括 PHP> = 5.6。 我们强烈建议使用cURL扩展,并使用TLS后端编译cURL 7.16.2+。
+
+## 安装依赖
+
+如果已在系统上[全局安装 Composer](https://getcomposer.org/doc/00-intro.md#globally),请直接在项目目录中运行以下内容来安装 Alibaba Cloud Credentials for PHP 作为依赖项:
+
+```sh
+composer require alibabacloud/credentials
+```
+
+> 一些用户可能由于网络问题无法安装,可以使用[阿里云 Composer 全量镜像](https://developer.aliyun.com/composer)。
+
+请看[安装](/docs/zh-CN/1-Installation.md)有关通过 Composer 和其他方式安装的详细信息。
+
+## 快速使用
+
+在您开始之前,您需要注册阿里云帐户并获取您的[凭证](https://usercenter.console.aliyun.com/#/manage/ak)。
+
+### 凭证类型
+
+#### 使用默认凭据链
+当您在初始化凭据客户端不传入任何参数时,Credentials工具会使用默认凭据链方式初始化客户端。默认凭据的读取逻辑请参见[默认凭据链](#默认凭证提供程序链)。
+
+```php
+<?php
+
+use AlibabaCloud\Credentials\Credential;
+
+// Chain Provider if no Parameter
+$client = new Credential();
+
+$credential = $client->getCredential();
+$credential->getAccessKeyId();
+$credential->getAccessKeySecret();
+$credential->getSecurityToken();
+```
+
+#### AccessKey
+
+通过[用户信息管理][ak]设置 access_key,它们具有该账户完全的权限,请妥善保管。有时出于安全考虑,您不能把具有完全访问权限的主账户 AccessKey 交于一个项目的开发者使用,您可以[创建RAM子账户][ram]并为子账户[授权][permissions],使用RAM子用户的 AccessKey 来进行API调用。
+
+```php
+<?php
+
+use AlibabaCloud\Credentials\Credential;
+namespace AlibabaCloud\Credentials\Credential\Config;
+
+// Access Key
+$config = new Config([
+    'type'            => 'access_key',
+    'accessKeyId'     => '<access_key_id>',
+    'accessKeySecret' => '<access_key_secret>',
+]);
+$client = new Credential($config);
+
+$credential = $client->getCredential();
+$credential->getAccessKeyId();
+$credential->getAccessKeySecret();
+```
+
+#### STS
+
+通过安全令牌服务(Security Token Service,简称 STS),申请临时安全凭证(Temporary Security Credentials,简称 TSC),创建临时安全凭证。
+
+```php
+<?php
+
+use AlibabaCloud\Credentials\Credential;
+namespace AlibabaCloud\Credentials\Credential\Config;
+
+$config = new Config([
+    'type'            => 'sts',
+    'accessKeyId'     => '<access_key_id>',
+    'accessKeySecret' => '<access_key_secret>',
+    'securityToken'   => '<security_token>',
+]);
+$client = new Credential($config);
+
+$credential = $client->getCredential();
+$credential->getAccessKeyId();
+$credential->getAccessKeySecret();
+$credential->getSecurityToken();
+```
+
+#### RamRoleArn
+
+通过指定RAM角色的ARN(Alibabacloud Resource Name),Credentials工具可以帮助开发者前往STS换取STS Token。您也可以通过为 `Policy` 赋值来限制RAM角色到一个更小的权限集合。
+
+```php
+<?php
+
+use AlibabaCloud\Credentials\Credential;
+namespace AlibabaCloud\Credentials\Credential\Config;
+
+$config = new Config([
+    'type'                  => 'ram_role_arn',
+    'accessKeyId'           => '<access_key_id>',
+    'accessKeySecret'       => '<access_key_secret>',
+    // 要扮演的RAM角色ARN,示例值:acs:ram::123456789012****:role/adminrole,可以通过环境变量ALIBABA_CLOUD_ROLE_ARN设置role_arn
+    'roleArn'               => '<role_arn>',
+    // 角色会话名称,可以通过环境变量ALIBABA_CLOUD_ROLE_SESSION_NAME设置role_session_name
+    'roleSessionName'       => '<role_session_name>',
+    // 设置更小的权限策略,非必填。示例值:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}
+    'policy'                => '',
+    # 设置session过期时间
+    'roleSessionExpiration' => 3600,
+]);
+$client = new Credential($config);
+
+$credential = $client->getCredential();
+$credential->getAccessKeyId();
+$credential->getAccessKeySecret();
+$credential->getSecurityToken();
+```
+
+#### EcsRamRole
+
+Credentials工具会自动获取ECS实例绑定的RAM角色,调用ECS的元数据服务(Meta Data Server)换取STS Token,完成凭据客户端初始化。ECI实例,容器服务 Kubernetes 版的Worker节点均支持绑定实例RAM角色。
+
+```php
+<?php
+
+use AlibabaCloud\Credentials\Credential;
+namespace AlibabaCloud\Credentials\Credential\Config;
+
+$config = new Config([
+    'type'         => 'ecs_ram_role',
+    // 选填,该ECS角色的角色名称,不填会自动获取,但是建议加上以减少请求次数,可以通过环境变量ALIBABA_CLOUD_ECS_METADATA设置role_name
+    'roleName'     => '<role_name>',
+]);
+$client = new Credential($config);
+
+$credential = $client->getCredential();
+$credential->getAccessKeyId();
+$credential->getAccessKeySecret();
+$credential->getSecurityToken();
+```
+
+#### OIDCRoleArn
+
+在容器服务 Kubernetes 版中设置了Worker节点RAM角色后,对应节点内的Pod中的应用也就可以像ECS上部署的应用一样,通过元数据服务(Meta Data Server)获取关联角色的STS Token。但如果容器集群上部署的是不可信的应用(比如部署您的客户提交的应用,代码也没有对您开放),您可能并不希望它们能通过元数据服务获取Worker节点关联实例RAM角色的STS Token。为了避免影响云上资源的安全,同时又能让这些不可信的应用安全地获取所需的 STS Token,实现应用级别的权限最小化,您可以使用RRSA(RAM Roles for Service Account)功能。阿里云容器集群会为不同的应用Pod创建和挂载相应的服务账户OIDC Token文件,并将相关配置信息注入到环境变量中,Credentials工具通过获取环境变量的配置信息,调用STS服务的AssumeRoleWithOIDC - OIDC角色SSO时获取扮演角色的临时身份凭证接口换取绑定角色的STS Token。详情请参见[通过RRSA配置ServiceAccount的RAM权限实现Pod权限隔离](https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/use-rrsa-to-authorize-pods-to-access-different-cloud-services#task-2142941)。
+
+```php
+<?php
+
+use AlibabaCloud\Credentials\Credential;
+namespace AlibabaCloud\Credentials\Credential\Config;
+
+$config = new Config([
+    'type'                  => 'oidc_role_arn',
+    // OIDC提供商ARN,可以通过环境变量ALIBABA_CLOUD_OIDC_PROVIDER_ARN设置oidc_provider_arn
+    'oidcProviderArn'       => '<oidc_provider_arn>',
+    // OIDC Token文件路径,可以通过环境变量ALIBABA_CLOUD_OIDC_TOKEN_FILE设置oidc_token_file_path
+    'oidcTokenFilePath'     => '<oidc_token_file_path>',
+    // 要扮演的RAM角色ARN,示例值:acs:ram::123456789012****:role/adminrole,可以通过环境变量ALIBABA_CLOUD_ROLE_ARN设置role_arn
+    'roleArn'               => '<role_arn>',
+    // 角色会话名称,可以通过环境变量ALIBABA_CLOUD_ROLE_SESSION_NAME设置role_session_name
+    'roleSessionName'       => '<role_session_name>',
+    // 设置更小的权限策略,非必填。示例值:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}
+    'policy'                => '',
+    # 设置session过期时间
+    'roleSessionExpiration' => 3600,
+]);
+$client = new Credential($config);
+
+$credential = $client->getCredential();
+$credential->getAccessKeyId();
+$credential->getAccessKeySecret();
+$credential->getSecurityToken();
+```
+
+#### Credentials URI
+
+通过指定提供凭证的自定义网络服务地址,让凭证自动申请维护 STS Token。
+
+```php
+<?php
+
+use AlibabaCloud\Credentials\Credential;
+namespace AlibabaCloud\Credentials\Credential\Config;
+
+$config = new Config([
+    'type'               => 'credentials_uri',
+    // 凭证的 URI,格式为http://local_or_remote_uri/,可以通过环境变量ALIBABA_CLOUD_CREDENTIALS_URI设置credentials_uri
+    'credentialsURI'     => '<credentials_uri>',
+]);
+$client = new Credential($config);
+
+$credential = $client->getCredential();
+$credential->getBearerToken();
+```
+
+#### Bearer Token
+
+目前只有云呼叫中心 CCC 这款产品支持 Bearer Token 的凭据初始化方式。
+
+```php
+<?php
+
+use AlibabaCloud\Credentials\Credential;
+namespace AlibabaCloud\Credentials\Credential\Config;
+
+$config = new Config([
+    'type'            => 'bearer',
+    // 填入您的Bearer Token
+    'bearerToken'     => '<bearer_token>',
+]);
+$client = new Credential($config);
+
+$credential = $client->getCredential();
+$credential->getBearerToken();
+```
+
+## 默认凭证提供程序链
+
+当您的程序开发环境和生产环境采用不同的凭据类型,常见做法是在代码中获取当前环境信息,编写获取不同凭据的分支代码。借助Credentials工具的默认凭据链,您可以用同一套代码,通过程序之外的配置来控制不同环境下的凭据获取方式。当您在不传入参数的情况下,直接使用$credential = new Credential();初始化凭据客户端时,阿里云SDK将会尝试按照如下顺序查找相关凭据信息。
+
+### 1. 使用环境变量
+
+Credentials工具会优先在环境变量中获取凭据信息。
+
+- 如果系统环境变量 `ALIBABA_CLOUD_ACCESS_KEY_ID`(密钥Key) 和 `ALIBABA_CLOUD_ACCESS_KEY_SECRET`(密钥Value) 不为空,Credentials工具会优先使用它们作为默认凭据。
+
+- 如果系统环境变量 `ALIBABA_CLOUD_ACCESS_KEY_ID`(密钥Key)、`ALIBABA_CLOUD_ACCESS_KEY_SECRET`(密钥Value)、`ALIBABA_CLOUD_SECURITY_TOKEN`(Token)均不为空,Credentials工具会优先使用STS Token作为默认凭据。
+
+### 2. 使用OIDC RAM角色
+若不存在优先级更高的凭据信息,Credentials工具会在环境变量中获取如下内容:
+
+`ALIBABA_CLOUD_ROLE_ARN`:RAM角色名称ARN;
+
+`ALIBABA_CLOUD_OIDC_PROVIDER_ARN`:OIDC提供商ARN;
+
+`ALIBABA_CLOUD_OIDC_TOKEN_FILE`:OIDC Token文件路径;
+
+若以上三个环境变量都已设置内容,Credentials将会使用变量内容调用STS服务的[AssumeRoleWithOIDC - OIDC角色SSO时获取扮演角色的临时身份凭证](https://help.aliyun.com/zh/ram/developer-reference/api-sts-2015-04-01-assumerolewithoidc)接口换取STS Token作为默认凭据。
+
+### 3. 使用 Aliyun CLI 工具的 config.json 配置文件
+
+若不存在优先级更高的凭据信息,Credentials工具会优先在如下位置查找 `config.json` 文件是否存在:
+Linux系统:`~/.aliyun/config.json`
+Windows系统: `C:\Users\USER_NAME\.aliyun\config.json`
+如果文件存在,程序将会使用配置文件中 `current` 指定的凭据信息初始化凭据客户端。当然,您也可以通过环境变量 `ALIBABA_CLOUD_PROFILE` 来指定凭据信息,例如设置 `ALIBABA_CLOUD_PROFILE` 的值为 `AK`。
+
+在config.json配置文件中每个module的值代表了不同的凭据信息获取方式:
+
+- AK:使用用户的Access Key作为凭据信息;
+- RamRoleArn:使用RAM角色的ARN来获取凭据信息;
+- EcsRamRole:利用ECS绑定的RAM角色来获取凭据信息;
+- OIDC:通过OIDC ARN和OIDC Token来获取凭据信息;
+- ChainableRamRoleArn:采用角色链的方式,通过指定JSON文件中的其他凭据,以重新获取新的凭据信息。
+
+配置示例信息如下:
+
+```json
+{
+    "current": "AK",
+    "profiles": [
+        {
+            "name": "AK",
+            "mode": "AK",
+            "access_key_id": "access_key_id",
+            "access_key_secret": "access_key_secret"
+        },
+        {
+            "name": "RamRoleArn",
+            "mode": "RamRoleArn",
+            "access_key_id": "access_key_id",
+            "access_key_secret": "access_key_secret",
+            "ram_role_arn": "ram_role_arn",
+            "ram_session_name": "ram_session_name",
+            "expired_seconds": 3600,
+            "sts_region": "cn-hangzhou"
+        },
+        {
+            "name": "EcsRamRole",
+            "mode": "EcsRamRole",
+            "ram_role_name": "ram_role_name"
+        },
+        {
+            "name": "OIDC",
+            "mode": "OIDC",
+            "ram_role_arn": "ram_role_arn",
+            "oidc_token_file": "path/to/oidc/file",
+            "oidc_provider_arn": "oidc_provider_arn",
+            "ram_session_name": "ram_session_name",
+            "expired_seconds": 3600,
+            "sts_region": "cn-hangzhou"
+        },
+        {
+            "name": "ChainableRamRoleArn",
+            "mode": "ChainableRamRoleArn",
+            "source_profile": "AK",
+            "ram_role_arn": "ram_role_arn",
+            "ram_session_name": "ram_session_name",
+            "expired_seconds": 3600,
+            "sts_region": "cn-hangzhou"
+        }
+    ]
+}
+```
+
+### 4. 使用配置文件
+>
+> 如果用户主目录存在默认文件 `~/.alibabacloud/credentials` (Windows 为 `C:\Users\USER_NAME\.alibabacloud\credentials`),程序会自动创建指定类型和名称的凭证。您也可通过环境变量 `ALIBABA_CLOUD_CREDENTIALS_FILE` 指定配置文件路径。如果文件存在,程序将会使用配置文件中 default 指定的凭据信息初始化凭据客户端。当然,您也可以通过环境变量 `ALIBABA_CLOUD_PROFILE` 来指定凭据信息,例如设置 `ALIBABA_CLOUD_PROFILE` 的值为 `client1`。
+
+配置示例信息如下:
+
+```ini
+[default]
+type = access_key                  # 认证方式为 access_key
+access_key_id = foo                # Key
+access_key_secret = bar            # Secret
+
+[project1]
+type = ecs_ram_role                # 认证方式为 ecs_ram_role
+role_name = EcsRamRoleTest         # Role Name,非必填,不填则自动获取,建议设置,可以减少网络请求。
+
+[project2]
+type = ram_role_arn                # 认证方式为 ram_role_arn
+access_key_id = foo
+access_key_secret = bar
+role_arn = role_arn
+role_session_name = session_name
+
+[project3]
+type=oidc_role_arn                 # 认证方式为 oidc_role_arn
+oidc_provider_arn=oidc_provider_arn
+oidc_token_file_path=oidc_token_file_path
+role_arn=role_arn
+role_session_name=session_name
+```
+
+### 5. 使用 ECS 实例RAM角色
+
+如果定义了环境变量 `ALIBABA_CLOUD_ECS_METADATA` 且不为空,程序会将该环境变量的值作为角色名称,请求 `http://100.100.100.200/latest/meta-data/ram/security-credentials/` 获取临时安全凭证作为默认凭证。
+
+### 6. 使用外部服务 Credentials URI
+
+若不存在优先级更高的凭据信息,Credentials工具会在环境变量中获取ALIBABA_CLOUD_CREDENTIALS_URI,若存在,程序将请求该URI地址,获取临时安全凭证作为默认凭据信息。
+
+外部服务响应结构应如下:
+
+```json
+{
+  "Code": "Success",
+  "AccessKeyId": "AccessKeyId",
+  "AccessKeySecret": "AccessKeySecret",
+  "SecurityToken": "SecurityToken",
+  "Expiration": "2024-10-26T03:46:38Z"
+}
+```
+
+## 文档
+
+* [先决条件](/docs/zh-CN/0-Prerequisites.md)
+* [安装](/docs/zh-CN/1-Installation.md)
+
+## 问题
+
+[提交 Issue](https://github.com/aliyun/credentials-php/issues/new/choose),不符合指南的问题可能会立即关闭。
+
+## 发行说明
+
+每个版本的详细更改记录在[发行说明](/CHANGELOG.md)中。
+
+## 贡献
+
+提交 Pull Request 之前请阅读[贡献指南](/CONTRIBUTING.md)。
+
+## 相关
+
+* [OpenAPI 开发者门户][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.
+
+[open-api]: https://api.aliyun.com
+[latest-release]: https://github.com/aliyun/credentials-php
+[guzzle-docs]: https://guzzle-cn.readthedocs.io/zh_CN/latest/request-options.html
+[composer]: https://getcomposer.org
+[packagist]: https://packagist.org/packages/alibabacloud/credentials

+ 400 - 0
vendor/alibabacloud/credentials/README.md

@@ -0,0 +1,400 @@
+English | [简体中文](/README-zh-CN.md)
+
+![](https://aliyunsdk-pages.alicdn.com/icons/AlibabaCloud.svg)
+
+# Alibaba Cloud Credentials for PHP
+
+[![PHP CI](https://github.com/aliyun/credentials-php/actions/workflows/ci.yml/badge.svg)](https://github.com/aliyun/credentials-php/actions/workflows/ci.yml)
+[![codecov](https://codecov.io/gh/aliyun/credentials-php/graph/badge.svg?token=YIkSjtfKbB)](https://codecov.io/gh/aliyun/credentials-php)
+[![Latest Stable Version](https://poser.pugx.org/alibabacloud/credentials/v/stable)](https://packagist.org/packages/alibabacloud/credentials)
+[![composer.lock](https://poser.pugx.org/alibabacloud/credentials/composerlock)](https://packagist.org/packages/alibabacloud/credentials)
+[![Total Downloads](https://poser.pugx.org/alibabacloud/credentials/downloads)](https://packagist.org/packages/alibabacloud/credentials)
+[![License](https://poser.pugx.org/alibabacloud/credentials/license)](https://packagist.org/packages/alibabacloud/credentials)
+
+Alibaba Cloud Credentials for PHP is a tool that helps PHP developers manage their credentials.
+
+## Prerequisites
+
+Your system needs to meet [Prerequisites](/docs/zh-CN/0-Prerequisites.md), including PHP> = 5.6. We strongly recommend using the cURL extension and compiling cURL 7.16.2+ using the TLS backend.
+
+## Installation
+
+If you have [Globally Install Composer](https://getcomposer.org/doc/00-intro.md#globally) on your system, install Alibaba Cloud Credentials for PHP as a dependency by running the following directly in the project directory:
+
+```sh
+composer require alibabacloud/credentials
+```
+
+> Some users may not be able to install due to network problems, you can switch to the [Alibaba Cloud Composer Mirror](https://developer.aliyun.com/composer).
+
+See [Installation](/docs/zh-CN/1-Installation.md) for details on installing 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).
+
+### Credential Type
+
+#### Default credential provider chain
+
+If you do not specify a method to initialize a Credentials client, the default credential provider chain is used. For more information, see the Default credential provider chain section of this topic.
+
+```php
+<?php
+
+use AlibabaCloud\Credentials\Credential;
+
+// Chain Provider if no Parameter
+// Do not specify a method to initialize a Credentials client.
+$client = new Credential();
+
+$credential = $client->getCredential();
+$credential->getAccessKeyId();
+$credential->getAccessKeySecret();
+$credential->getSecurityToken();
+```
+
+#### AccessKey
+
+Setup access_key credential through [User Information Management][ak], it have full authority over the account, please keep it safe. Sometimes for security reasons, you cannot hand over a primary account AccessKey with full access to the developer of a project. You may create a sub-account [RAM Sub-account][ram] , grant its [authorization][permissions],and use the AccessKey of RAM Sub-account.
+
+```php
+<?php
+
+use AlibabaCloud\Credentials\Credential;
+namespace AlibabaCloud\Credentials\Credential\Config;
+
+// Access Key
+$config = new Config([
+    'type'            => 'access_key',
+    'accessKeyId'     => '<access_key_id>',
+    'accessKeySecret' => '<access_key_secret>',
+]);
+$client = new Credential($config);
+
+$credential = $client->getCredential();
+$credential->getAccessKeyId();
+$credential->getAccessKeySecret();
+```
+
+#### STS
+
+Create a temporary security credential by applying Temporary Security Credentials (TSC) through the Security Token Service (STS).
+
+```php
+<?php
+
+use AlibabaCloud\Credentials\Credential;
+namespace AlibabaCloud\Credentials\Credential\Config;
+
+$config = new Config([
+    'type'            => 'sts',
+    'accessKeyId'     => '<access_key_id>',
+    'accessKeySecret' => '<access_key_secret>',
+    'securityToken'   => '<security_token>',
+]);
+$client = new Credential($config);
+
+$credential = $client->getCredential();
+$credential->getAccessKeyId();
+$credential->getAccessKeySecret();
+$credential->getSecurityToken();
+```
+
+#### RamRoleArn
+
+By specifying [RAM Role][RAM Role], the credential will be able to automatically request maintenance of STS Token. If you want to limit the permissions([How to make a policy][policy]) of STS Token, you can assign value for `Policy`.
+
+```php
+<?php
+
+use AlibabaCloud\Credentials\Credential;
+namespace AlibabaCloud\Credentials\Credential\Config;
+
+$config = new Config([
+    'type'                  => 'ram_role_arn',
+    'accessKeyId'           => '<access_key_id>',
+    'accessKeySecret'       => '<access_key_secret>',
+    // Specify the ARN of the RAM role to be assumed. Example: acs:ram::123456789012****:role/adminrole.
+    'roleArn'               => '<role_arn>',
+    // Specify the name of the role session.
+    'roleSessionName'       => '<role_session_name>',
+    // Optional. Specify limited permissions for the RAM role. Example: {"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}.
+    'policy'                => '',
+    # Specify the expiration of the session
+    'roleSessionExpiration' => 3600,
+]);
+$client = new Credential($config);
+
+$credential = $client->getCredential();
+$credential->getAccessKeyId();
+$credential->getAccessKeySecret();
+$credential->getSecurityToken();
+```
+
+#### EcsRamRole
+
+The Credentials tool automatically obtains the RAM role attached to an ECS instance and uses the metadata server of ECS to obtain an STS token. The STS token is then used to initialize a Credentials client. You can also attach a RAM role to an elastic container instance or a worker node in an Alibaba Cloud Container Service for Kubernetes (ACK) cluster.
+
+```php
+<?php
+
+use AlibabaCloud\Credentials\Credential;
+namespace AlibabaCloud\Credentials\Credential\Config;
+
+$config = new Config([
+    'type'         => 'ecs_ram_role',
+    // Optional. Specify the name of the RAM role of the ECS instance. If you do not specify this parameter, its value is automatically obtained. To reduce the number of requests, we recommend that you specify this parameter.
+    'roleName'     => '<role_name>',
+]);
+$client = new Credential($config);
+
+$credential = $client->getCredential();
+$credential->getAccessKeyId();
+$credential->getAccessKeySecret();
+$credential->getSecurityToken();
+```
+
+#### OIDCRoleArn
+
+After you attach a RAM role to a worker node in an Container Service for Kubernetes, applications in the pods on the worker node can use the metadata server to obtain an STS token the same way in which applications on ECS instances do. However, if an untrusted application is deployed on the worker node, such as an application that is submitted by your customer and whose code is unavailable to you, you may not want the application to use the metadata server to obtain an STS token of the RAM role attached to the worker node. To ensure the security of cloud resources and enable untrusted applications to securely obtain required STS tokens, you can use the RAM Roles for Service Accounts (RRSA) feature to grant minimum necessary permissions to an application. In this case, the ACK cluster creates a service account OpenID Connect (OIDC) token file, associates the token file with a pod, and then injects relevant environment variables into the pod. Then, the Credentials tool uses the environment variables to call the AssumeRoleWithOIDC operation of STS and obtains an STS token of the RAM role. For more information about the RRSA feature, see [Use RRSA to authorize different pods to access different cloud services](https://www.alibabacloud.com/help/en/ack/ack-managed-and-ack-dedicated/user-guide/use-rrsa-to-authorize-pods-to-access-different-cloud-services#task-2142941).
+
+```php
+<?php
+
+use AlibabaCloud\Credentials\Credential;
+namespace AlibabaCloud\Credentials\Credential\Config;
+
+$config = new Config([
+    'type'                  => 'oidc_role_arn',
+    // Specify the ARN of the OIDC IdP by specifying the ALIBABA_CLOUD_OIDC_PROVIDER_ARN environment variable.
+    'oidcProviderArn'       => '<oidc_provider_arn>',
+    // Specify the path of the OIDC token file by specifying the ALIBABA_CLOUD_OIDC_TOKEN_FILE environment variable.
+    'oidcTokenFilePath'     => '<oidc_token_file_path>',
+    // Specify the ARN of the RAM role by specifying the ALIBABA_CLOUD_ROLE_ARN environment variable.
+    'roleArn'               => '<role_arn>',
+    // Specify the role session name by specifying the ALIBABA_CLOUD_ROLE_SESSION_NAME environment variable.
+    'roleSessionName'       => '<role_session_name>',
+    // Optional. Specify limited permissions for the RAM role. Example: {"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}.
+    'policy'                => '',
+    // Optional. Specify the validity period of the session.
+    'roleSessionExpiration' => 3600,
+]);
+$client = new Credential($config);
+
+$credential = $client->getCredential();
+$credential->getAccessKeyId();
+$credential->getAccessKeySecret();
+$credential->getSecurityToken();
+```
+
+#### Credentials URI
+
+By specifying the url, the credential will be able to automatically request maintenance of STS Token.
+
+```php
+<?php
+
+use AlibabaCloud\Credentials\Credential;
+namespace AlibabaCloud\Credentials\Credential\Config;
+
+$config = new Config([
+    'type'               => 'credentials_uri',
+    // Format: http url. `credentialsURI` can be replaced by setting environment variable: ALIBABA_CLOUD_CREDENTIALS_URI
+    'credentialsURI'     => '<credentials_uri>',
+]);
+$client = new Credential($config);
+
+$credential = $client->getCredential();
+$credential->getBearerToken();
+```
+
+#### Bearer Token
+
+If credential is required by the Cloud Call Centre (CCC), please apply for Bearer Token maintenance by yourself.
+
+```php
+<?php
+
+use AlibabaCloud\Credentials\Credential;
+
+$bearerToken = new Credential([
+    'type'         => 'bearer',
+    'bearer_token' => '<bearer_token>',
+]);
+$bearerToken->getBearerToken();
+```
+
+## Default credential provider chain
+
+If you want to use different types of credentials in the development and production environments of your application, you generally need to obtain the environment information from the code and write code branches to obtain different credentials for the development and production environments. The default credential provider chain of the Credentials tool allows you to use the same code to obtain credentials for different environments based on configurations independent of the application. If you use $credential = new Credential(); to initialize a Credentials client without specifying an initialization method, the Credentials tool obtains the credential information in the following order:
+
+### 1. Environmental certificate
+
+Look for environment credentials in environment variable.
+- If the `ALIBABA_CLOUD_ACCESS_KEY_ID` and `ALIBABA_CLOUD_ACCESS_KEY_SECRET` environment variables are defined and are not empty, the program will use them to create default credentials.
+- If the `ALIBABA_CLOUD_ACCESS_KEY_ID`, `ALIBABA_CLOUD_ACCESS_KEY_SECRET` and `ALIBABA_CLOUD_SECURITY_TOKEN` environment variables are defined and are not empty, the program will use them to create temporary security credentials(STS). Note: This token has an expiration time, it is recommended to use it in a temporary environment.
+
+### 2. The RAM role of an OIDC IdP
+
+If no credentials are found in the previous step, the Credentials tool obtains the values of the following environment variables:
+
+`ALIBABA_CLOUD_ROLE_ARN`: the ARN of the RAM role.
+
+`ALIBABA_CLOUD_OIDC_PROVIDER_ARN`: the ARN of the OIDC IdP.
+
+`ALIBABA_CLOUD_OIDC_TOKEN_FILE`: the path of the OIDC token file.
+
+If the preceding three environment variables are specified, the Credentials tool uses the environment variables to call the [AssumeRoleWithOIDC](https://www.alibabacloud.com/help/en/ram/developer-reference/api-sts-2015-04-01-assumerolewithoidc) operation of STS to obtain an STS token as the default credential.
+
+### 3. Using the config.json Configuration File of Aliyun CLI Tool
+If there is no higher-priority credential information, the Credentials tool will first check the following locations to see if the config.json file exists:
+
+Linux system: `~/.aliyun/config.json`
+Windows system: `C:\Users\USER_NAME\.aliyun\config.json`
+If the file exists, the program will use the credential information specified by `current` in the configuration file to initialize the credentials client. Of course, you can also use the environment variable `ALIBABA_CLOUD_PROFILE` to specify the credential information, for example by setting the value of `ALIBABA_CLOUD_PROFILE` to `AK`.
+
+In the config.json configuration file, the value of each module represents different ways to obtain credential information:
+
+- AK: Use the Access Key of the user as credential information;
+- RamRoleArn: Use the ARN of the RAM role to obtain credential information;
+- EcsRamRole: Use the RAM role bound to the ECS to obtain credential information;
+- OIDC: Obtain credential information through OIDC ARN and OIDC Token;
+- ChainableRamRoleArn: Use the role chaining method to obtain new credential information by specifying other credentials in the JSON file.
+
+The configuration example information is as follows:
+
+```json
+{
+    "current": "AK",
+    "profiles": [
+        {
+            "name": "AK",
+            "mode": "AK",
+            "access_key_id": "access_key_id",
+            "access_key_secret": "access_key_secret"
+        },
+        {
+            "name": "RamRoleArn",
+            "mode": "RamRoleArn",
+            "access_key_id": "access_key_id",
+            "access_key_secret": "access_key_secret",
+            "ram_role_arn": "ram_role_arn",
+            "ram_session_name": "ram_session_name",
+            "expired_seconds": 3600,
+            "sts_region": "cn-hangzhou"
+        },
+        {
+            "name": "EcsRamRole",
+            "mode": "EcsRamRole",
+            "ram_role_name": "ram_role_name"
+        },
+        {
+            "name": "OIDC",
+            "mode": "OIDC",
+            "ram_role_arn": "ram_role_arn",
+            "oidc_token_file": "path/to/oidc/file",
+            "oidc_provider_arn": "oidc_provider_arn",
+            "ram_session_name": "ram_session_name",
+            "expired_seconds": 3600,
+            "sts_region": "cn-hangzhou"
+        },
+        {
+            "name": "ChainableRamRoleArn",
+            "mode": "ChainableRamRoleArn",
+            "source_profile": "AK",
+            "ram_role_arn": "ram_role_arn",
+            "ram_session_name": "ram_session_name",
+            "expired_seconds": 3600,
+            "sts_region": "cn-hangzhou"
+        }
+    ]
+}
+```
+
+### 4. Configuration file
+>
+> If the user's home directory has the default file `~/.alibabacloud/credentials` (Windows is `C:\Users\USER_NAME\.alibabacloud\credentials`), the program will automatically create credentials with the specified type and name. You can also specify the configuration file path by configuring the `ALIBABA_CLOUD_CREDENTIALS_FILE` environment variable. If the configuration file exists, the application initializes a Credentials client by using the credential information that is specified by default in the configuration file. You can also configure the `ALIBABA_CLOUD_PROFILE` environment variable to modify the default credential information that is read.
+
+Configuration example:
+```ini
+[default]
+type = access_key                  # Authentication method is access_key
+access_key_id = foo                # Key
+access_key_secret = bar            # Secret
+
+[project1]
+type = ecs_ram_role                # Authentication method is ecs_ram_role
+role_name = EcsRamRoleTest         # Role name, optional. It will be retrieved automatically if not set. It is highly recommended to set it up to reduce requests.
+
+[project2]
+type = ram_role_arn                # Authentication method is ram_role_arn
+access_key_id = foo
+access_key_secret = bar
+role_arn = role_arn
+role_session_name = session_name
+
+[project3]
+type=oidc_role_arn                 # Authentication method is oidc_role_arn
+oidc_provider_arn=oidc_provider_arn
+oidc_token_file_path=oidc_token_file_path
+role_arn=role_arn
+role_session_name=session_name
+```
+
+### 5. Instance RAM role
+
+If the environment variable `ALIBABA_CLOUD_ECS_METADATA` is defined and not empty, the program will take the value of the environment variable as the role name and request `http://100.100.100.200/latest/meta-data/ram/security-credentials/` to get the temporary Security credentials are used as default credentials.
+
+### 6. Using External Service Credentials URI
+
+If there are no higher-priority credential information, the Credentials tool will obtain the `ALIBABA_CLOUD_CREDENTIALS_URI` from the environment variables. If it exists, the program will request the URI address to obtain temporary security credentials as the default credential information.
+
+The external service response structure should be as follows:
+
+```json
+{
+  "Code": "Success",
+  "AccessKeyId": "AccessKeyId",
+  "AccessKeySecret": "AccessKeySecret",
+  "SecurityToken": "SecurityToken",
+  "Expiration": "2024-10-26T03:46:38Z"
+}
+```
+
+## Documentation
+
+* [Prerequisites](/docs/zh-CN/0-Prerequisites.md)
+* [Installation](/docs/zh-CN/1-Installation.md)
+
+## Issue
+
+[Submit Issue](https://github.com/aliyun/credentials-php/issues/new/choose), Problems that do not meet the guidelines may close immediately.
+
+## Release notes
+
+Detailed changes for each version are recorded in the [Release Notes](/CHANGELOG.md).
+
+## Contribution
+
+Please read the [Contribution Guide](/CONTRIBUTING.md) before submitting a Pull Request.
+
+## Related
+
+* [OpenAPI Developer Portal][open-api]
+* [Packagist][packagist]
+* [Composer][composer]
+* [Guzzle Doc][guzzle-docs]
+* [Latest Release][latest-release]
+
+## License
+
+[Apache-2.0](/LICENSE.md)
+
+Copyright (c) 2009-present, Alibaba Cloud All rights reserved.
+
+[open-api]: https://api.alibabacloud.com
+[latest-release]: https://github.com/aliyun/credentials-php
+[guzzle-docs]: http://docs.guzzlephp.org/en/stable/request-options.html
+[composer]: https://getcomposer.org
+[packagist]: https://packagist.org/packages/alibabacloud/credentials

+ 21 - 0
vendor/alibabacloud/credentials/SECURITY.md

@@ -0,0 +1,21 @@
+# Security Policy
+
+## Supported Versions
+
+Use this section to tell people about which versions of your project are
+currently being supported with security updates.
+
+| Version | Supported          |
+| ------- | ------------------ |
+| 5.1.x   | :white_check_mark: |
+| 5.0.x   | :x:                |
+| 4.0.x   | :white_check_mark: |
+| < 4.0   | :x:                |
+
+## Reporting a Vulnerability
+
+Use this section to tell people how to report a vulnerability.
+
+Tell them where to go, how often they can expect to get an update on a
+reported vulnerability, what to expect if the vulnerability is accepted or
+declined, etc.

+ 6 - 0
vendor/alibabacloud/credentials/UPGRADING.md

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

+ 107 - 0
vendor/alibabacloud/credentials/composer.json

@@ -0,0 +1,107 @@
+{
+    "name": "alibabacloud/credentials",
+    "homepage": "https://www.alibabacloud.com/",
+    "description": "Alibaba Cloud Credentials for PHP",
+    "keywords": [
+        "sdk",
+        "tool",
+        "cloud",
+        "client",
+        "aliyun",
+        "library",
+        "alibaba",
+        "Credentials",
+        "alibabacloud"
+    ],
+    "type": "library",
+    "license": "Apache-2.0",
+    "support": {
+        "source": "https://github.com/aliyun/credentials-php",
+        "issues": "https://github.com/aliyun/credentials-php/issues"
+    },
+    "authors": [
+        {
+            "name": "Alibaba Cloud SDK",
+            "email": "sdk-team@alibabacloud.com",
+            "homepage": "http://www.alibabacloud.com"
+        }
+    ],
+    "require": {
+        "php": ">=5.6",
+        "ext-curl": "*",
+        "ext-json": "*",
+        "ext-libxml": "*",
+        "ext-openssl": "*",
+        "ext-mbstring": "*",
+        "ext-simplexml": "*",
+        "ext-xmlwriter": "*",
+        "guzzlehttp/guzzle": "^6.3|^7.0",
+        "adbario/php-dot-notation": "^2.2",
+        "alibabacloud/tea": "^3.0"
+    },
+    "require-dev": {
+        "ext-spl": "*",
+        "ext-dom": "*",
+        "ext-pcre": "*",
+        "psr/cache": "^1.0",
+        "ext-sockets": "*",
+        "drupal/coder": "^8.3",
+        "symfony/dotenv": "^3.4",
+        "phpunit/phpunit": "^5.7|^6.6|^9.3",
+        "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\\Credentials\\": "src"
+        }
+    },
+    "autoload-dev": {
+        "psr-4": {
+            "AlibabaCloud\\Credentials\\Tests\\": "tests/"
+        }
+    },
+    "config": {
+        "preferred-install": "dist",
+        "optimize-autoloader": true,
+        "allow-plugins": {
+            "dealerdirect/phpcodesniffer-composer-installer": 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/*"
+    }
+}

+ 86 - 0
vendor/alibabacloud/credentials/src/AccessKeyCredential.php

@@ -0,0 +1,86 @@
+<?php
+
+namespace AlibabaCloud\Credentials;
+
+use AlibabaCloud\Credentials\Utils\Filter;
+use AlibabaCloud\Credentials\Credential\CredentialModel;
+use AlibabaCloud\Credentials\Signature\ShaHmac1Signature;
+
+/**
+ * @deprecated
+ * Use the AccessKey to complete the authentication.
+ */
+class AccessKeyCredential implements CredentialsInterface
+{
+    /**
+     * @var string
+     */
+    private $accessKeyId;
+
+    /**
+     * @var string
+     */
+    private $accessKeySecret;
+
+    /**
+     * AccessKeyCredential constructor.
+     *
+     * @param string $access_key_id     Access key ID
+     * @param string $access_key_secret Access Key Secret
+     */
+    public function __construct($access_key_id, $access_key_secret)
+    {
+        Filter::accessKey($access_key_id, $access_key_secret);
+
+        $this->accessKeyId = $access_key_id;
+        $this->accessKeySecret = $access_key_secret;
+    }
+
+    /**
+     * @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";
+    }
+
+    /**
+     * @return ShaHmac1Signature
+     */
+    public function getSignature()
+    {
+        return new ShaHmac1Signature();
+    }
+
+    public function getSecurityToken()
+    {
+        return '';
+    }
+    /**
+     * @inheritDoc
+     */
+    public function getCredential()
+    {
+        return new CredentialModel([
+            'accessKeyId' => $this->accessKeyId,
+            'accessKeySecret' => $this->accessKeySecret,
+            'type' => 'access_key',
+        ]);
+    }
+}

+ 67 - 0
vendor/alibabacloud/credentials/src/BearerTokenCredential.php

@@ -0,0 +1,67 @@
+<?php
+
+namespace AlibabaCloud\Credentials;
+
+use AlibabaCloud\Credentials\Utils\Filter;
+use AlibabaCloud\Credentials\Credential\CredentialModel;
+use AlibabaCloud\Credentials\Signature\BearerTokenSignature;
+
+/**
+ * Class BearerTokenCredential
+ */
+class BearerTokenCredential implements CredentialsInterface
+{
+
+    /**
+     * @var string
+     */
+    private $bearerToken;
+
+    /**
+     * BearerTokenCredential constructor.
+     *
+     * @param $bearer_token
+     */
+    public function __construct($bearer_token)
+    {
+        Filter::bearerToken($bearer_token);
+
+        $this->bearerToken = $bearer_token;
+    }
+
+    /**
+     * @return string
+     */
+    public function getBearerToken()
+    {
+        return $this->bearerToken;
+    }
+
+    /**
+     * @return string
+     */
+    public function __toString()
+    {
+        return "bearerToken#$this->bearerToken";
+    }
+
+    /**
+     * @return BearerTokenSignature
+     */
+    public function getSignature()
+    {
+        return new BearerTokenSignature();
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function getCredential()
+    {
+        return new CredentialModel([
+            'bearerToken' => $this->bearerToken,
+            'type' => 'bearer',
+        ]);
+    }
+
+}

+ 268 - 0
vendor/alibabacloud/credentials/src/Credential.php

@@ -0,0 +1,268 @@
+<?php
+
+namespace AlibabaCloud\Credentials;
+
+use AlibabaCloud\Credentials\Credential\Config;
+use AlibabaCloud\Credentials\Credential\CredentialModel;
+use AlibabaCloud\Credentials\Providers\DefaultCredentialsProvider;
+use AlibabaCloud\Credentials\Providers\EcsRamRoleCredentialsProvider;
+use AlibabaCloud\Credentials\Providers\OIDCRoleArnCredentialsProvider;
+use AlibabaCloud\Credentials\Providers\RamRoleArnCredentialsProvider;
+use AlibabaCloud\Credentials\Providers\RsaKeyPairCredentialsProvider;
+use AlibabaCloud\Credentials\Providers\StaticAKCredentialsProvider;
+use AlibabaCloud\Credentials\Providers\StaticSTSCredentialsProvider;
+use AlibabaCloud\Credentials\Providers\URLCredentialsProvider;
+use AlibabaCloud\Credentials\Utils\Helper;
+use GuzzleHttp\Exception\GuzzleException;
+use InvalidArgumentException;
+use RuntimeException;
+
+/**
+ * Class Credential
+ *
+ * @package AlibabaCloud\Credentials
+ *
+ */
+class Credential
+{
+
+    /**
+     * Version of the Client
+     */
+    const VERSION = '1.1.5';
+
+    /**
+     * @var Config
+     */
+    protected $config;
+
+    /**
+     * @var CredentialsInterface
+     */
+    protected $credential;
+
+    /**
+     * Credential constructor.
+     *
+     * @param array|Config $config
+     */
+    public function __construct($config = [])
+    {
+        if (\is_array($config)) {
+            if (empty($config)) {
+                $this->config = null;
+            } else {
+                $this->config = new Config($this->parseConfig($config));
+            }
+        } else {
+            $this->config = $config;
+        }
+        $this->credential = $this->getCredentials($this->config);
+    }
+
+    /**
+     * @param array $config
+     *
+     * @return array
+     */
+    private function parseConfig($config)
+    {
+        $res = [];
+        foreach (\array_change_key_case($config) as $key => $value) {
+            $res[Helper::snakeToCamelCase($key)] = $value;
+        }
+        return $res;
+    }
+
+
+
+    /**
+     * Credentials getter.
+     *
+     * @param Config $config
+     * @return CredentialsInterface
+     *
+     */
+    private function getCredentials($config)
+    {
+        if (is_null($config)) {
+            return new CredentialsProviderWrap('default', new DefaultCredentialsProvider());
+        }
+        switch ($config->type) {
+            case 'access_key':
+                $provider = new StaticAKCredentialsProvider([
+                    'accessKeyId' => $config->accessKeyId,
+                    'accessKeySecret' => $config->accessKeySecret,
+                ]);
+                return new CredentialsProviderWrap('access_key', $provider);
+            case 'sts':
+                $provider = new StaticSTSCredentialsProvider([
+                    'accessKeyId' => $config->accessKeyId,
+                    'accessKeySecret' => $config->accessKeySecret,
+                    'securityToken' => $config->securityToken,
+                ]);
+                return new CredentialsProviderWrap('sts', $provider);
+            case 'bearer':
+                return new BearerTokenCredential($config->bearerToken);
+            case 'ram_role_arn':
+                if (!is_null($config->securityToken) && $config->securityToken !== '') {
+                    $innerProvider = new StaticSTSCredentialsProvider([
+                        'accessKeyId' => $config->accessKeyId,
+                        'accessKeySecret' => $config->accessKeySecret,
+                        'securityToken' => $config->securityToken,
+                    ]);
+                } else {
+                    $innerProvider = new StaticAKCredentialsProvider([
+                        'accessKeyId' => $config->accessKeyId,
+                        'accessKeySecret' => $config->accessKeySecret,
+                    ]);
+                }
+                $provider = new RamRoleArnCredentialsProvider([
+                    'credentialsProvider' => $innerProvider,
+                    'roleArn' => $config->roleArn,
+                    'roleSessionName' => $config->roleSessionName,
+                    'policy' => $config->policy,
+                    'durationSeconds' => $config->roleSessionExpiration,
+                    'externalId' => $config->externalId,
+                    'stsEndpoint' => $config->STSEndpoint,
+                ], [
+                    'connectTimeout' => $config->connectTimeout,
+                    'readTimeout' => $config->readTimeout,
+                ]);
+                return new CredentialsProviderWrap('ram_role_arn', $provider);
+            case 'rsa_key_pair':
+                $provider = new RsaKeyPairCredentialsProvider([
+                    'publicKeyId' => $config->publicKeyId,
+                    'privateKeyFile' => $config->privateKeyFile,
+                    'durationSeconds' => $config->roleSessionExpiration,
+                    'stsEndpoint' => $config->STSEndpoint,
+                ], [
+                    'connectTimeout' => $config->connectTimeout,
+                    'readTimeout' => $config->readTimeout,
+                ]);
+                return new CredentialsProviderWrap('rsa_key_pair', $provider);
+            case 'ecs_ram_role':
+                $provider = new EcsRamRoleCredentialsProvider([
+                    'roleName' => $config->roleName,
+                    'disableIMDSv1' => $config->disableIMDSv1,
+                ], [
+                    'connectTimeout' => $config->connectTimeout,
+                    'readTimeout' => $config->readTimeout,
+                ]);
+                return new CredentialsProviderWrap('ecs_ram_role', $provider);
+            case 'oidc_role_arn':
+                $provider = new OIDCRoleArnCredentialsProvider([
+                    'roleArn' => $config->roleArn,
+                    'oidcProviderArn' => $config->oidcProviderArn,
+                    'oidcTokenFilePath' => $config->oidcTokenFilePath,
+                    'roleSessionName' => $config->roleSessionName,
+                    'policy' => $config->policy,
+                    'durationSeconds' => $config->roleSessionExpiration,
+                    'stsEndpoint' => $config->STSEndpoint,
+                ], [
+                    'connectTimeout' => $config->connectTimeout,
+                    'readTimeout' => $config->readTimeout,
+                ]);
+                return new CredentialsProviderWrap('oidc_role_arn', $provider);
+            case "credentials_uri":
+                $provider = new URLCredentialsProvider([
+                    'credentialsURI' => $config->credentialsURI,
+                ], [
+                    'connectTimeout' => $config->connectTimeout,
+                    'readTimeout' => $config->readTimeout,
+                ]);
+                return new CredentialsProviderWrap('credentials_uri', $provider);
+            default:
+                throw new InvalidArgumentException('Unsupported credential type option: ' . $config->type . ', support: access_key, sts, bearer, ecs_ram_role, ram_role_arn, rsa_key_pair, oidc_role_arn, credentials_uri');
+        }
+    }
+
+    /**
+     * @return CredentialModel
+     * @throws RuntimeException
+     * @throws GuzzleException
+     */
+    public function getCredential()
+    {
+        return $this->credential->getCredential();
+    }
+
+    /**
+     * @return array
+     */
+    public function getConfig()
+    {
+        return $this->config->toMap();
+    }
+
+    /**
+     * @deprecated use getCredential() instead
+     *
+     * @return string
+     * @throws RuntimeException
+     * @throws GuzzleException
+     */
+    public function getType()
+    {
+        return $this->credential->getCredential()->getType();
+    }
+
+    /**
+     * @deprecated use getCredential() instead
+     * 
+     * @return string
+     * @throws RuntimeException
+     * @throws GuzzleException
+     */
+    public function getAccessKeyId()
+    {
+        return $this->credential->getCredential()->getAccessKeyId();
+    }
+
+    /**
+     * @deprecated use getCredential() instead
+     * 
+     * @return string
+     * @throws RuntimeException
+     * @throws GuzzleException
+     */
+    public function getAccessKeySecret()
+    {
+        return $this->credential->getCredential()->getAccessKeySecret();
+    }
+
+    /**
+     * @deprecated use getCredential() instead
+     * 
+     * @return string
+     * @throws RuntimeException
+     * @throws GuzzleException
+     */
+    public function getSecurityToken()
+    {
+        return $this->credential->getCredential()->getSecurityToken();
+    }
+
+    /**
+     * @deprecated use getCredential() instead
+     * 
+     * @return string
+     * @throws RuntimeException
+     * @throws GuzzleException
+     */
+    public function getBearerToken()
+    {
+        return $this->credential->getCredential()->getBearerToken();
+    }
+
+    /**
+     * @param string $name
+     * @param array  $arguments
+     *
+     * @return mixed
+     */
+    public function __call($name, $arguments)
+    {
+        return $this->credential->$name($arguments);
+    }
+}

+ 270 - 0
vendor/alibabacloud/credentials/src/Credential/Config.php

@@ -0,0 +1,270 @@
+<?php
+
+namespace AlibabaCloud\Credentials\Credential;
+
+use AlibabaCloud\Tea\Model;
+
+class Config extends Model
+{
+    public function validate()
+    {
+    }
+    public function toMap()
+    {
+        $res = [];
+        if (null !== $this->accessKeyId) {
+            $res['accessKeyId'] = $this->accessKeyId;
+        }
+        if (null !== $this->accessKeySecret) {
+            $res['accessKeySecret'] = $this->accessKeySecret;
+        }
+        if (null !== $this->securityToken) {
+            $res['securityToken'] = $this->securityToken;
+        }
+        if (null !== $this->bearerToken) {
+            $res['bearerToken'] = $this->bearerToken;
+        }
+        if (null !== $this->durationSeconds) {
+            $res['durationSeconds'] = $this->durationSeconds;
+        }
+        if (null !== $this->roleArn) {
+            $res['roleArn'] = $this->roleArn;
+        }
+        if (null !== $this->policy) {
+            $res['policy'] = $this->policy;
+        }
+        if (null !== $this->roleSessionExpiration) {
+            $res['roleSessionExpiration'] = $this->roleSessionExpiration;
+        }
+        if (null !== $this->roleSessionName) {
+            $res['roleSessionName'] = $this->roleSessionName;
+        }
+        if (null !== $this->publicKeyId) {
+            $res['publicKeyId'] = $this->publicKeyId;
+        }
+        if (null !== $this->privateKeyFile) {
+            $res['privateKeyFile'] = $this->privateKeyFile;
+        }
+        if (null !== $this->roleName) {
+            $res['roleName'] = $this->roleName;
+        }
+        if (null !== $this->credentialsURI) {
+            $res['credentialsURI'] = $this->credentialsURI;
+        }
+        if (null !== $this->type) {
+            $res['type'] = $this->type;
+        }
+        if (null !== $this->STSEndpoint) {
+            $res['STSEndpoint'] = $this->STSEndpoint;
+        }
+        if (null !== $this->externalId) {
+            $res['externalId'] = $this->externalId;
+        }
+        return $res;
+    }
+    /**
+     * @param array $map
+     * @return Config
+     */
+    public static function fromMap($map = [])
+    {
+        $model = new self();
+        if (isset($map['accessKeyId'])) {
+            $model->accessKeyId = $map['accessKeyId'];
+        }
+        if (isset($map['accessKeySecret'])) {
+            $model->accessKeySecret = $map['accessKeySecret'];
+        }
+        if (isset($map['securityToken'])) {
+            $model->securityToken = $map['securityToken'];
+        }
+        if (isset($map['bearerToken'])) {
+            $model->bearerToken = $map['bearerToken'];
+        }
+        if (isset($map['durationSeconds'])) {
+            $model->durationSeconds = $map['durationSeconds'];
+        }
+        if (isset($map['roleArn'])) {
+            $model->roleArn = $map['roleArn'];
+        }
+        if (isset($map['policy'])) {
+            $model->policy = $map['policy'];
+        }
+        if (isset($map['roleSessionExpiration'])) {
+            $model->roleSessionExpiration = $map['roleSessionExpiration'];
+        }
+        if (isset($map['roleSessionName'])) {
+            $model->roleSessionName = $map['roleSessionName'];
+        }
+        if (isset($map['publicKeyId'])) {
+            $model->publicKeyId = $map['publicKeyId'];
+        }
+        if (isset($map['privateKeyFile'])) {
+            $model->privateKeyFile = $map['privateKeyFile'];
+        }
+        if (isset($map['roleName'])) {
+            $model->roleName = $map['roleName'];
+        }
+        if (isset($map['credentialsURI'])) {
+            $model->credentialsURI = $map['credentialsURI'];
+        }
+        if (isset($map['type'])) {
+            $model->type = $map['type'];
+        }
+        if (isset($map['STSEndpoint'])) {
+            $model->STSEndpoint = $map['STSEndpoint'];
+        }
+        if (isset($map['externalId'])) {
+            $model->externalId = $map['externalId'];
+        }
+        return $model;
+    }
+    /**
+     * @description credential type
+     * @example access_key
+     * @var string
+     */
+    public $type = 'default';
+
+    /**
+     * @description accesskey id
+     * @var string
+     */
+    public $accessKeyId;
+
+    /**
+     * @description accesskey secret
+     * @var string
+     */
+    public $accessKeySecret;
+
+    /**
+     * @description security token
+     * @var string
+     */
+    public $securityToken;
+
+    /**
+     * @description bearer token
+     * @var string
+     */
+    public $bearerToken;
+
+    /**
+     * @description role name
+     * @var string
+     */
+    public $roleName;
+
+    /**
+     * @description role arn
+     * @var string
+     */
+    public $roleArn;
+
+    /**
+     * @description oidc provider arn
+     * @var string
+     */
+    public $oidcProviderArn;
+
+    /**
+     * @description oidc token file path
+     * @var string
+     */
+    public $oidcTokenFilePath;
+
+    /**
+     * @description role session expiration
+     * @example 3600
+     * @var int
+     */
+    public $roleSessionExpiration;
+
+    /**
+     * @description role session name
+     * @var string
+     */
+    public $roleSessionName;
+
+    /**
+     * @description role arn policy
+     * @var string
+     */
+    public $policy;
+
+    /**
+     * @description external id for ram role arn
+     * @var string
+     */
+    public $externalId;
+
+    /**
+     * @description sts endpoint
+     * @var string
+     */
+    public $STSEndpoint;
+
+    public $publicKeyId;
+
+    public $privateKeyFile;
+
+    /**
+     * @description read timeout
+     * @var int
+     */
+    public $readTimeout;
+
+    /**
+     * @description connection timeout
+     * @var int
+     */
+    public $connectTimeout;
+
+    /**
+     * @description disable IMDS v1
+     * @var bool
+     */
+    public $disableIMDSv1;
+
+    /**
+     * @description credentials URI
+     * @var string
+     */
+    public $credentialsURI;
+
+    /**
+     * @deprecated
+     */
+    public $metadataTokenDuration;
+
+    /**
+     * @deprecated
+     */
+    public $durationSeconds;
+
+    /**
+     * @deprecated
+     */
+    public $host;
+
+    /**
+     * @deprecated
+     */
+    public $expiration;
+
+    /**
+     * @deprecated
+     */
+    public $certFile = "";
+
+    /**
+     * @deprecated
+     */
+    public $certPassword = "";
+
+    /**
+     * @internal
+     */
+    public $proxy;
+}

+ 125 - 0
vendor/alibabacloud/credentials/src/Credential/CredentialModel.php

@@ -0,0 +1,125 @@
+<?php
+
+// This file is auto-generated, don't edit it. Thanks.
+namespace AlibabaCloud\Credentials\Credential;
+
+use AlibabaCloud\Tea\Model;
+
+class CredentialModel extends Model
+{
+    public function validate()
+    {
+    }
+    public function toMap()
+    {
+        $res = [];
+        if (null !== $this->accessKeyId) {
+            $res['accessKeyId'] = $this->accessKeyId;
+        }
+        if (null !== $this->accessKeySecret) {
+            $res['accessKeySecret'] = $this->accessKeySecret;
+        }
+        if (null !== $this->securityToken) {
+            $res['securityToken'] = $this->securityToken;
+        }
+        if (null !== $this->bearerToken) {
+            $res['bearerToken'] = $this->bearerToken;
+        }
+        if (null !== $this->type) {
+            $res['type'] = $this->type;
+        }
+        return $res;
+    }
+    /**
+     * @param array $map
+     * @return CredentialModel
+     */
+    public static function fromMap($map = [])
+    {
+        $model = new self();
+        if (isset($map['accessKeyId'])) {
+            $model->accessKeyId = $map['accessKeyId'];
+        }
+        if (isset($map['accessKeySecret'])) {
+            $model->accessKeySecret = $map['accessKeySecret'];
+        }
+        if (isset($map['securityToken'])) {
+            $model->securityToken = $map['securityToken'];
+        }
+        if (isset($map['bearerToken'])) {
+            $model->bearerToken = $map['bearerToken'];
+        }
+        if (isset($map['type'])) {
+            $model->type = $map['type'];
+        }
+        return $model;
+    }
+    /**
+     * @description accesskey id
+     * @var string
+     */
+    public $accessKeyId;
+
+    /**
+     * @description accesskey secret
+     * @var string
+     */
+    public $accessKeySecret;
+
+    /**
+     * @description security token
+     * @var string
+     */
+    public $securityToken;
+
+    /**
+     * @description bearer token
+     * @var string
+     */
+    public $bearerToken;
+
+    /**
+     * @description type
+     * @example access_key
+     * @var string
+     */
+    public $type;
+
+    /**
+     * @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 getBearerToken()
+    {
+        return $this->bearerToken;
+    }
+
+    public function getType()
+    {
+        return $this->type;
+    }
+
+}

+ 104 - 0
vendor/alibabacloud/credentials/src/Credentials.php

@@ -0,0 +1,104 @@
+<?php
+
+namespace AlibabaCloud\Credentials;
+
+use AlibabaCloud\Credentials\Providers\ChainProvider;
+use AlibabaCloud\Credentials\Utils\Filter;
+use AlibabaCloud\Credentials\Utils\MockTrait;
+use ReflectionException;
+use RuntimeException;
+
+/**
+ * Class Credentials
+ *
+ * @package AlibabaCloud\Credentials
+ */
+class Credentials
+{
+    use MockTrait;
+
+    /**
+     * @var array|CredentialsInterface[] containers of credentials
+     */
+    protected static $credentials = [];
+
+    /**
+     * Get the credential instance by name.
+     *
+     * @param string $name
+     *
+     * @return Credential
+     * @throws ReflectionException
+     */
+    public static function get($name = null)
+    {
+        if ($name !== null) {
+            Filter::credentialName($name);
+        } else {
+            $name = ChainProvider::getDefaultName();
+        }
+
+        self::load();
+
+        if (self::has($name)) {
+            return new Credential(self::$credentials[\strtolower($name)]);
+        }
+
+        throw new RuntimeException("Credential '$name' not found");
+    }
+
+    private static function load()
+    {
+        if (self::$credentials) {
+            return;
+        }
+
+        if (ChainProvider::hasCustomChain()) {
+            ChainProvider::customProvider(ChainProvider::getDefaultName());
+        } else {
+            ChainProvider::defaultProvider(ChainProvider::getDefaultName());
+        }
+    }
+
+    /**
+     * Determine whether there is a credential.
+     *
+     * @param string $name
+     *
+     * @return bool
+     */
+    public static function has($name)
+    {
+        Filter::credentialName($name);
+
+        return isset(self::$credentials[\strtolower($name)]);
+    }
+
+    public static function flush()
+    {
+        self::$credentials = [];
+    }
+
+    /**
+     * Get all credentials.
+     *
+     * @return array
+     */
+    public static function all()
+    {
+        self::load();
+
+        return self::$credentials;
+    }
+
+    /**
+     * @param string $name
+     * @param array  $credential
+     */
+    public static function set($name, array $credential)
+    {
+        Filter::credentialName($name);
+
+        self::$credentials[\strtolower($name)] = \array_change_key_case($credential);
+    }
+}

+ 32 - 0
vendor/alibabacloud/credentials/src/CredentialsInterface.php

@@ -0,0 +1,32 @@
+<?php
+
+namespace AlibabaCloud\Credentials;
+
+use AlibabaCloud\Credentials\Credential\CredentialModel;
+use AlibabaCloud\Credentials\Signature\SignatureInterface;
+
+/**
+ * @internal This class is intended for internal use within the package. 
+ * Interface CredentialsInterface
+ *
+ * @codeCoverageIgnore
+ */
+interface CredentialsInterface
+{
+    /**
+     * @deprecated
+     * @return string
+     */
+    public function __toString();
+
+    /**
+     * @deprecated
+     * @return SignatureInterface
+     */
+    public function getSignature();
+
+    /**
+     * @return CredentialModel
+     */
+    public function getCredential();
+}

+ 75 - 0
vendor/alibabacloud/credentials/src/CredentialsProviderWrap.php

@@ -0,0 +1,75 @@
+<?php
+
+namespace AlibabaCloud\Credentials;
+
+use AlibabaCloud\Credentials\Credential\CredentialModel;
+use AlibabaCloud\Credentials\Providers\CredentialsProvider;
+
+/**
+ * @internal This class is intended for internal use within the package. 
+ * Class CredentialsProviderWrap
+ * 
+ * @package AlibabaCloud\Credentials
+ */
+class CredentialsProviderWrap implements CredentialsInterface
+{
+    /**
+     * @var string
+     */
+    private $typeName;
+
+    /**
+     * @var CredentialsProvider
+     */
+    private $credentialsProvider;
+
+    /**
+     * CLIProfileCredentialsProvider constructor.
+     *
+     * @param string $typeName
+     * @param CredentialsProvider $credentialsProvider
+     */
+    public function __construct($typeName, $credentialsProvider)
+    {
+        $this->typeName = $typeName;
+        $this->credentialsProvider = $credentialsProvider;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function getCredential()
+    {
+        $credentials = $this->credentialsProvider->getCredentials();
+        return new CredentialModel([
+            'accessKeyId' => $credentials->getAccessKeyId(),
+            'accessKeySecret' => $credentials->getAccessKeySecret(),
+            'securityToken' => $credentials->getSecurityToken(),
+            'type' => $this->typeName,
+        ]);
+    }
+
+    /**
+     * @param string $name
+     * @param array  $arguments
+     *
+     * @return mixed
+     */
+    public function __call($name, $arguments)
+    {
+        return $this->credentialsProvider->$name($arguments);
+    }
+
+    public function __toString()
+    {
+        return "credentialsProviderWrap#$this->typeName";
+    }
+
+    /**
+     * @return ShaHmac1Signature
+     */
+    public function getSignature()
+    {
+        return null;
+    }
+}

+ 199 - 0
vendor/alibabacloud/credentials/src/EcsRamRoleCredential.php

@@ -0,0 +1,199 @@
+<?php
+
+namespace AlibabaCloud\Credentials;
+
+use AlibabaCloud\Credentials\Providers\EcsRamRoleCredentialsProvider;
+use AlibabaCloud\Credentials\Credential\CredentialModel;
+use AlibabaCloud\Credentials\Signature\ShaHmac1Signature;
+use AlibabaCloud\Credentials\Request\Request;
+use AlibabaCloud\Credentials\Utils\Filter;
+use Exception;
+use GuzzleHttp\Exception\GuzzleException;
+use InvalidArgumentException;
+use RuntimeException;
+
+/**
+ * @deprecated
+ * Use the RAM role of an ECS instance to complete the authentication.
+ */
+class EcsRamRoleCredential implements CredentialsInterface
+{
+
+    /**
+     * @var string
+     */
+    private $roleName;
+
+    /**
+     * @var boolean
+     */
+    private $disableIMDSv1;
+
+    /**
+     * @var int
+     */
+    private $metadataTokenDuration;
+
+
+    /**
+     * EcsRamRoleCredential constructor.
+     *
+     * @param $role_name
+     */
+    public function __construct($role_name = null, $disable_imdsv1 = false, $metadata_token_duration = 21600)
+    {
+        Filter::roleName($role_name);
+
+        $this->roleName = $role_name;
+
+        Filter::disableIMDSv1($disable_imdsv1);
+
+        $this->disableIMDSv1 = $disable_imdsv1;
+
+        $this->metadataTokenDuration = $metadata_token_duration;
+    }
+
+    /**
+     * @return string
+     * @throws GuzzleException
+     * @throws Exception
+     */
+    public function getRoleName()
+    {
+        if ($this->roleName !== null) {
+            return $this->roleName;
+        }
+
+        $this->roleName = $this->getRoleNameFromMeta();
+
+        return $this->roleName;
+    }
+
+    /**
+     * @return string
+     * @throws Exception
+     */
+    public function getRoleNameFromMeta()
+    {
+        $options = [
+            'http_errors' => false,
+            'timeout' => 1,
+            'connect_timeout' => 1,
+        ];
+
+        $result = Request::createClient()->request(
+            'GET',
+            'http://100.100.100.200/latest/meta-data/ram/security-credentials/',
+            $options
+        );
+
+        if ($result->getStatusCode() === 404) {
+            throw new InvalidArgumentException('The role name was not found in the instance');
+        }
+
+        if ($result->getStatusCode() !== 200) {
+            throw new RuntimeException('Error retrieving credentials from result: ' . $result->getBody());
+        }
+
+        $role_name = (string) $result;
+        if (!$role_name) {
+            throw new RuntimeException('Error retrieving credentials from result is empty');
+        }
+
+        return $role_name;
+    }
+
+    /**
+     * @return string
+     */
+    public function __toString()
+    {
+        return "roleName#$this->roleName";
+    }
+
+    /**
+     * @return ShaHmac1Signature
+     */
+    public function getSignature()
+    {
+        return new ShaHmac1Signature();
+    }
+
+    /**
+     * @return string
+     * @throws Exception
+     * @throws GuzzleException
+     */
+    public function getAccessKeyId()
+    {
+        return $this->getSessionCredential()->getAccessKeyId();
+    }
+
+    /**
+     * @return AlibabaCloud\Credentials\Providers\Credentials
+     * @throws Exception
+     * @throws GuzzleException
+     */
+    protected function getSessionCredential()
+    {
+        $params = [
+            "roleName" => $this->roleName,
+            'disableIMDSv1' => $this->disableIMDSv1,
+            'metadataTokenDuration' => $this->metadataTokenDuration,
+        ];
+        return (new EcsRamRoleCredentialsProvider($params))->getCredentials();
+    }
+
+    /**
+     * @return string
+     * @throws Exception
+     * @throws GuzzleException
+     */
+    public function getAccessKeySecret()
+    {
+        return $this->getSessionCredential()->getAccessKeySecret();
+    }
+
+    /**
+     * @return string
+     * @throws Exception
+     * @throws GuzzleException
+     */
+    public function getSecurityToken()
+    {
+        return $this->getSessionCredential()->getSecurityToken();
+    }
+
+    /**
+     * @return int
+     * @throws Exception
+     * @throws GuzzleException
+     */
+    public function getExpiration()
+    {
+        return $this->getSessionCredential()->getExpiration();
+    }
+
+    /**
+     * @return bool
+     */
+    public function isDisableIMDSv1()
+    {
+        return $this->disableIMDSv1;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function getCredential()
+    {
+        $credentials = $this->getSessionCredential();
+        return new CredentialModel([
+            'accessKeyId' => $credentials->getAccessKeyId(),
+            'accessKeySecret' => $credentials->getAccessKeySecret(),
+            'securityToken' => $credentials->getSecurityToken(),
+            'type' => 'ecs_ram_role',
+        ]);
+    }
+
+}

+ 179 - 0
vendor/alibabacloud/credentials/src/Providers/CLIProfileCredentialsProvider.php

@@ -0,0 +1,179 @@
+<?php
+
+namespace AlibabaCloud\Credentials\Providers;
+
+use AlibabaCloud\Credentials\Utils\Helper;
+use RuntimeException;
+
+/**
+ * @internal This class is intended for internal use within the package. 
+ * Class CLIProfileCredentialsProvider
+ *
+ * @package AlibabaCloud\Credentials\Providers
+ */
+class CLIProfileCredentialsProvider implements CredentialsProvider
+{
+
+    /**
+     * @var string
+     */
+    private $profileName;
+
+    /**
+     * @var CredentialsProvider
+     */
+    private $credentialsProvider;
+
+
+    /**
+     * CLIProfileCredentialsProvider constructor.
+     *
+     * @param array $params
+     */
+    public function __construct(array $params = [])
+    {
+        $this->filterProfileName($params);
+    }
+
+    private function filterProfileName(array $params)
+    {
+        if (Helper::envNotEmpty('ALIBABA_CLOUD_PROFILE')) {
+            $this->profileName = Helper::env('ALIBABA_CLOUD_PROFILE');
+        }
+
+        if (isset($params['profileName'])) {
+            $this->profileName = $params['profileName'];
+        }
+    }
+
+    /**
+     * @return bool
+     */
+    private function shouldReloadCredentialsProvider()
+    {
+        if (is_null($this->credentialsProvider)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * @return CredentialsProvider
+     */
+    protected function reloadCredentialsProvider($profileFile, $profileName)
+    {
+        if (!Helper::inOpenBasedir($profileFile)) {
+            throw new RuntimeException('Unable to open credentials file: ' . $profileFile);
+        }
+
+        if (!\is_readable($profileFile) || !\is_file($profileFile)) {
+            throw new RuntimeException('Credentials file is not readable: ' . $profileFile);
+        }
+
+        $jsonContent = \file_get_contents($profileFile);
+        $fileArray = json_decode($jsonContent, true);
+
+        if (\is_array($fileArray) && !empty($fileArray)) {
+            if (is_null($profileName) || $profileName === '') {
+                $profileName = $fileArray['current'];
+            }
+            if (isset($fileArray['profiles'])) {
+                foreach ($fileArray['profiles'] as $profile) {
+                    if (Helper::unsetReturnNull($profile, 'name') === $profileName) {
+                        switch (Helper::unsetReturnNull($profile, 'mode')) {
+                            case 'AK':
+                                return new StaticAKCredentialsProvider([
+                                    'accessKeyId' => Helper::unsetReturnNull($profile, 'access_key_id'),
+                                    'accessKeySecret' => Helper::unsetReturnNull($profile, 'access_key_secret'),
+                                ]);
+                            case 'RamRoleArn':
+                                $innerProvider = new StaticAKCredentialsProvider([
+                                    'accessKeyId' => Helper::unsetReturnNull($profile, 'access_key_id'),
+                                    'accessKeySecret' => Helper::unsetReturnNull($profile, 'access_key_secret'),
+                                ]);
+                                return new RamRoleArnCredentialsProvider([
+                                    'credentialsProvider' => $innerProvider,
+                                    'roleArn' => Helper::unsetReturnNull($profile, 'ram_role_arn'),
+                                    'roleSessionName' => Helper::unsetReturnNull($profile, 'ram_session_name'),
+                                    'durationSeconds' => Helper::unsetReturnNull($profile, 'expired_seconds'),
+                                    'stsRegionId' => Helper::unsetReturnNull($profile, 'sts_region'),
+                                ]);
+                            case 'EcsRamRole':
+                                return new EcsRamRoleCredentialsProvider([
+                                    'roleName' => Helper::unsetReturnNull($profile, 'ram_role_name'),
+                                ]);
+                            case 'OIDC':
+                                return new OIDCRoleArnCredentialsProvider([
+                                    'roleArn' => Helper::unsetReturnNull($profile, 'ram_role_arn'),
+                                    'oidcProviderArn' => Helper::unsetReturnNull($profile, 'oidc_provider_arn'),
+                                    'oidcTokenFilePath' => Helper::unsetReturnNull($profile, 'oidc_token_file'),
+                                    'roleSessionName' => Helper::unsetReturnNull($profile, 'ram_session_name'),
+                                    'durationSeconds' => Helper::unsetReturnNull($profile, 'expired_seconds'),
+                                    'stsRegionId' => Helper::unsetReturnNull($profile, 'sts_region'),
+                                ]);
+                            case 'ChainableRamRoleArn':
+                                $previousProvider = $this->reloadCredentialsProvider($profileFile, Helper::unsetReturnNull($profile, 'source_profile'));
+                                return new RamRoleArnCredentialsProvider([
+                                    'credentialsProvider' => $previousProvider,
+                                    'roleArn' => Helper::unsetReturnNull($profile, 'ram_role_arn'),
+                                    'roleSessionName' => Helper::unsetReturnNull($profile, 'ram_session_name'),
+                                    'durationSeconds' => Helper::unsetReturnNull($profile, 'expired_seconds'),
+                                    'stsRegionId' => Helper::unsetReturnNull($profile, 'sts_region'),
+                                ]);
+                            default:
+                                throw new RuntimeException('Unsupported credential mode from CLI credentials file: ' . Helper::unsetReturnNull($profile, 'mode'));
+                        }
+                    }
+                }
+            }
+        }
+        throw new RuntimeException('Failed to get credential from CLI credentials file: ' . $profileFile);
+    }
+    /**
+     * Get credential.
+     *
+     * @return Credentials
+     * @throws RuntimeException
+     */
+    public function getCredentials()
+    {
+        if (Helper::envNotEmpty('ALIBABA_CLOUD_CLI_PROFILE_DISABLED') && Helper::env('ALIBABA_CLOUD_CLI_PROFILE_DISABLED') === true) {
+            throw new RuntimeException('CLI credentials file is disabled');
+        }
+        $cliProfileFile = self::getDefaultFile();
+        if ($this->shouldReloadCredentialsProvider()) {
+            $this->credentialsProvider = $this->reloadCredentialsProvider($cliProfileFile, $this->profileName);
+        }
+
+        $credentials = $this->credentialsProvider->getCredentials();
+        return new Credentials([
+            'accessKeyId' => $credentials->getAccessKeyId(),
+            'accessKeySecret' => $credentials->getAccessKeySecret(),
+            'securityToken' => $credentials->getSecurityToken(),
+            'providerName' => $this->getProviderName() . '/' . $this->credentialsProvider->getProviderName(),
+        ]);
+    }
+
+    /**
+     * Get the default credential file.
+     *
+     * @return string
+     */
+    private function getDefaultFile()
+    {
+        return Helper::getHomeDirectory() .
+            DIRECTORY_SEPARATOR .
+            '.aliyun' .
+            DIRECTORY_SEPARATOR .
+            'config.json';
+    }
+
+    /**
+     * @return string
+     */
+    public function getProviderName()
+    {
+        return 'cli_profile';
+    }
+}

+ 188 - 0
vendor/alibabacloud/credentials/src/Providers/ChainProvider.php

@@ -0,0 +1,188 @@
+<?php
+
+namespace AlibabaCloud\Credentials\Providers;
+
+use AlibabaCloud\Credentials\Credentials;
+use AlibabaCloud\Credentials\Utils\Helper;
+use Closure;
+use InvalidArgumentException;
+use RuntimeException;
+
+/**
+ * @deprecated
+ * Class ChainProvider
+ *
+ * @package AlibabaCloud\Credentials\Providers
+ */
+class ChainProvider
+{
+    /**
+     * @var array
+     */
+    private static $customChains;
+
+    /**
+     * @param callable ...$providers
+     */
+    public static function set(...$providers)
+    {
+        if (empty($providers)) {
+            throw new InvalidArgumentException('No providers in chain');
+        }
+
+        foreach ($providers as $provider) {
+            if (!$provider instanceof Closure) {
+                throw new InvalidArgumentException('Providers must all be Closures');
+            }
+        }
+
+        self::$customChains = $providers;
+    }
+
+    /**
+     * @return bool
+     */
+    public static function hasCustomChain()
+    {
+        return (bool)self::$customChains;
+    }
+
+    public static function flush()
+    {
+        self::$customChains = [];
+    }
+
+    /**
+     * @param string $name
+     */
+    public static function customProvider($name)
+    {
+        foreach (self::$customChains as $provider) {
+            $provider();
+
+            if (Credentials::has($name)) {
+                break;
+            }
+        }
+    }
+
+    /**
+     * @param string $name
+     */
+    public static function defaultProvider($name)
+    {
+        $providers = [
+            self::env(),
+            self::ini(),
+            self::instance(),
+        ];
+
+        foreach ($providers as $provider) {
+            $provider();
+
+            if (Credentials::has($name)) {
+                break;
+            }
+        }
+    }
+
+    /**
+     * @return Closure
+     */
+    public static function env()
+    {
+        return static function () {
+            $accessKeyId     = Helper::envNotEmpty('ALIBABA_CLOUD_ACCESS_KEY_ID');
+            $accessKeySecret = Helper::envNotEmpty('ALIBABA_CLOUD_ACCESS_KEY_SECRET');
+
+            if ($accessKeyId && $accessKeySecret) {
+                Credentials::set(
+                    self::getDefaultName(),
+                    [
+                        'type'              => 'access_key',
+                        'access_key_id'     => $accessKeyId,
+                        'access_key_secret' => $accessKeySecret,
+                    ]
+                );
+            }
+        };
+    }
+
+    /**
+     * @return string
+     */
+    public static function getDefaultName()
+    {
+        $name = Helper::envNotEmpty('ALIBABA_CLOUD_PROFILE');
+
+        if ($name) {
+            return $name;
+        }
+
+        return 'default';
+    }
+
+    /**
+     * @return Closure
+     */
+    public static function ini()
+    {
+        return static function () {
+            $filename = Helper::envNotEmpty('ALIBABA_CLOUD_CREDENTIALS_FILE');
+            if (!$filename) {
+                $filename = self::getDefaultFile();
+            }
+
+            if (!Helper::inOpenBasedir($filename)) {
+                return;
+            }
+
+            if ($filename !== self::getDefaultFile() && (!\is_readable($filename) || !\is_file($filename))) {
+                throw new RuntimeException(
+                    'Credentials file is not readable: ' . $filename
+                );
+            }
+
+            $file_array = \parse_ini_file($filename, true);
+
+            if (\is_array($file_array) && !empty($file_array)) {
+                foreach (\array_change_key_case($file_array) as $name => $configures) {
+                    Credentials::set($name, $configures);
+                }
+            }
+        };
+    }
+
+    /**
+     * Get the default credential file.
+     *
+     * @return string
+     */
+    public static function getDefaultFile()
+    {
+        return Helper::getHomeDirectory() .
+               DIRECTORY_SEPARATOR .
+               '.alibabacloud' .
+               DIRECTORY_SEPARATOR .
+               'credentials';
+    }
+
+    /**
+     * @return Closure
+     */
+    public static function instance()
+    {
+        return static function () {
+            $instance = Helper::envNotEmpty('ALIBABA_CLOUD_ECS_METADATA');
+            if ($instance) {
+                Credentials::set(
+                    self::getDefaultName(),
+                    [
+                        'type'      => 'ecs_ram_role',
+                        'role_name' => $instance,
+                    ]
+                );
+            }
+        };
+    }
+}

+ 87 - 0
vendor/alibabacloud/credentials/src/Providers/Credentials.php

@@ -0,0 +1,87 @@
+<?php
+
+namespace AlibabaCloud\Credentials\Providers;
+
+/**
+ * @internal This class is intended for internal use within the package. 
+ * Class Credentials
+ *
+ * @package AlibabaCloud\Credentials\Providers
+ */
+class Credentials
+{
+
+    /**
+     * @var string
+     */
+    private $accessKeyId;
+
+    /**
+     * @var string
+     */
+    private $accessKeySecret;
+
+    /**
+     * @var string
+     */
+    private $securityToken;
+
+    /**
+     * @var int
+     */
+    private $expiration;
+
+    /**
+     * @var int
+     */
+    private $providerName;
+
+    public function __construct($config = [])
+    {
+        if (!empty($config)) {
+            foreach ($config as $k => $v) {
+                $this->{$k} = $v;
+            }
+        }
+    }
+
+    /**
+     * @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 int
+     */
+    public function getExpiration()
+    {
+        return $this->expiration;
+    }
+
+    /**
+     * @return string
+     */
+    public function getProviderName()
+    {
+        return $this->providerName;
+    }
+}

+ 24 - 0
vendor/alibabacloud/credentials/src/Providers/CredentialsProvider.php

@@ -0,0 +1,24 @@
+<?php
+
+namespace AlibabaCloud\Credentials\Providers;
+
+
+/**
+ * @internal This class is intended for internal use within the package. 
+ * Interface CredentialsInterface
+ *
+ * @codeCoverageIgnore
+ */
+interface CredentialsProvider
+{
+
+    /**
+     * @return Credentials
+     */
+    public function getCredentials();
+
+    /**
+     * @return string
+     */
+    public function getProviderName();
+}

+ 177 - 0
vendor/alibabacloud/credentials/src/Providers/DefaultCredentialsProvider.php

@@ -0,0 +1,177 @@
+<?php
+
+namespace AlibabaCloud\Credentials\Providers;
+
+use AlibabaCloud\Credentials\Utils\Filter;
+use AlibabaCloud\Credentials\Utils\Helper;
+use InvalidArgumentException;
+use RuntimeException;
+use Exception;
+
+/**
+ * @internal This class is intended for internal use within the package. 
+ * Class DefaultCredentialsProvider
+ *
+ * @package AlibabaCloud\Credentials\Providers
+ */
+class DefaultCredentialsProvider implements CredentialsProvider
+{
+
+    /**
+     * @var array
+     */
+    private static $defaultProviders = [];
+
+    /**
+     * @var bool
+     */
+    private $reuseLastProviderEnabled;
+
+    /**
+     * @var CredentialsProvider
+     */
+    private $lastUsedCredentialsProvider;
+
+    /**
+     * @var array
+     */
+    private static $customChain = [];
+
+    /**
+     * DefaultCredentialsProvider constructor.
+     * @param array $params
+     */
+    public function __construct(array $params = [])
+    {
+        $this->filterReuseLastProviderEnabled($params);
+        $this->createDefaultChain();
+        Filter::reuseLastProviderEnabled($this->reuseLastProviderEnabled);
+    }
+
+    private function filterReuseLastProviderEnabled(array $params)
+    {
+        $this->reuseLastProviderEnabled = true;
+        if (isset($params['reuseLastProviderEnabled'])) {
+            $this->reuseLastProviderEnabled = $params['reuseLastProviderEnabled'];
+        }
+    }
+
+    private function createDefaultChain()
+    {
+        self::$defaultProviders = [
+            new EnvironmentVariableCredentialsProvider(),
+        ];
+        if (
+            Helper::envNotEmpty('ALIBABA_CLOUD_ROLE_ARN')
+            && Helper::envNotEmpty('ALIBABA_CLOUD_OIDC_PROVIDER_ARN')
+            && Helper::envNotEmpty('ALIBABA_CLOUD_OIDC_TOKEN_FILE')
+        ) {
+            array_push(
+                self::$defaultProviders,
+                new OIDCRoleArnCredentialsProvider()
+            );
+        }
+        array_push(
+            self::$defaultProviders,
+            new CLIProfileCredentialsProvider()
+        );
+        array_push(
+            self::$defaultProviders,
+            new ProfileCredentialsProvider()
+        );
+        if (Helper::envNotEmpty('ALIBABA_CLOUD_ECS_METADATA')) {
+            array_push(
+                self::$defaultProviders,
+                new EcsRamRoleCredentialsProvider()
+            );
+        }
+        if (Helper::envNotEmpty('ALIBABA_CLOUD_CREDENTIALS_URI')) {
+            array_push(
+                self::$defaultProviders,
+                new URLCredentialsProvider()
+            );
+        }
+    }
+
+    /**
+     * @param CredentialsProvider ...$providers
+     */
+    public static function set(...$providers)
+    {
+        if (empty($providers)) {
+            throw new InvalidArgumentException('No providers in chain');
+        }
+
+        foreach ($providers as $provider) {
+            if (!$provider instanceof CredentialsProvider) {
+                throw new InvalidArgumentException('Providers must all be CredentialsProvider');
+            }
+        }
+
+        self::$customChain = $providers;
+    }
+
+    /**
+     * @return bool
+     */
+    public static function hasCustomChain()
+    {
+        return (bool) self::$customChain;
+    }
+
+    public static function flush()
+    {
+        self::$customChain = [];
+    }
+
+    /**
+     * Get credential.
+     *
+     * @return Credentials
+     * @throws RuntimeException
+     */
+    public function getCredentials()
+    {
+        if ($this->reuseLastProviderEnabled && !is_null($this->lastUsedCredentialsProvider)) {
+            $credentials = $this->lastUsedCredentialsProvider->getCredentials();
+            return new Credentials([
+                'accessKeyId' => $credentials->getAccessKeyId(),
+                'accessKeySecret' => $credentials->getAccessKeySecret(),
+                'securityToken' => $credentials->getSecurityToken(),
+                'providerName' => $this->getProviderName() . '/' . $this->lastUsedCredentialsProvider->getProviderName(),
+            ]);
+        }
+
+        $providerChain = array_merge(
+            self::$customChain,
+            self::$defaultProviders
+        );
+
+        $exceptionMessages = [];
+
+        foreach ($providerChain as $provider) {
+            try {
+                $credentials = $provider->getCredentials();
+                $this->lastUsedCredentialsProvider = $provider;
+                return new Credentials([
+                    'accessKeyId' => $credentials->getAccessKeyId(),
+                    'accessKeySecret' => $credentials->getAccessKeySecret(),
+                    'securityToken' => $credentials->getSecurityToken(),
+                    'providerName' => $this->getProviderName() . '/' . $provider->getProviderName(),
+                ]);
+            } catch (Exception $exception) {
+                array_push($exceptionMessages, basename(str_replace('\\', '/', get_class($provider))) . ': ' . $exception->getMessage());
+            }
+        }
+        throw new RuntimeException('Unable to load credentials from any of the providers in the chain: ' . implode(', ', $exceptionMessages));
+
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function getProviderName()
+    {
+        return "default";
+    }
+}

+ 256 - 0
vendor/alibabacloud/credentials/src/Providers/EcsRamRoleCredentialsProvider.php

@@ -0,0 +1,256 @@
+<?php
+
+namespace AlibabaCloud\Credentials\Providers;
+
+use AlibabaCloud\Credentials\Utils\Helper;
+use AlibabaCloud\Credentials\Utils\Filter;
+use AlibabaCloud\Credentials\Request\Request;
+use GuzzleHttp\Exception\GuzzleException;
+use InvalidArgumentException;
+use RuntimeException;
+
+/**
+ * @internal This class is intended for internal use within the package. 
+ * Class EcsRamRoleCredentialsProvider
+ *
+ * @package AlibabaCloud\Credentials\Providers
+ */
+class EcsRamRoleCredentialsProvider extends SessionCredentialsProvider
+{
+
+    /**
+     * @var string
+     */
+    private $metadataHost = 'http://100.100.100.200';
+
+    /**
+     * @var string
+     */
+    private $ecsUri = '/latest/meta-data/ram/security-credentials/';
+
+    /**
+     * @var string
+     */
+    private $metadataTokenUri = '/latest/api/token';
+
+    /**
+     * @var string
+     */
+    private $roleName;
+
+    /**
+     * @var boolean
+     */
+    private $disableIMDSv1 = false;
+
+    /**
+     * @var int
+     */
+    private $metadataTokenDuration = 21600;
+
+    /**
+     * @var int
+     */
+    private $connectTimeout = 5;
+
+    /**
+     * @var int
+     */
+    private $readTimeout = 5;
+
+
+    /**
+     * EcsRamRoleCredentialsProvider constructor.
+     *
+     * @param array $params
+     * @param array $options
+     */
+    public function __construct(array $params = [], array $options = [])
+    {
+        $this->filterOptions($options);
+        $this->filterRoleName($params);
+        $this->filterDisableECSIMDSv1($params);
+        Filter::roleName($this->roleName);
+        Filter::disableIMDSv1($this->disableIMDSv1);
+    }
+
+    private function filterOptions(array $options)
+    {
+        if (isset($options['connectTimeout'])) {
+            $this->connectTimeout = $options['connectTimeout'];
+        }
+
+        if (isset($options['readTimeout'])) {
+            $this->readTimeout = $options['readTimeout'];
+        }
+
+        Filter::timeout($this->connectTimeout, $this->readTimeout);
+    }
+
+    private function filterRoleName(array $params)
+    {
+        if (Helper::envNotEmpty('ALIBABA_CLOUD_ECS_METADATA')) {
+            $this->roleName = Helper::env('ALIBABA_CLOUD_ECS_METADATA');
+        }
+
+        if (isset($params['roleName'])) {
+            $this->roleName = $params['roleName'];
+        }
+
+        if (is_null($this->roleName) || $this->roleName === '') {
+            $this->roleName = $this->getRoleNameFromMeta();
+        }
+    }
+
+    private function filterDisableECSIMDSv1($params)
+    {
+        if (Helper::envNotEmpty('ALIBABA_CLOUD_IMDSV1_DISABLED')) {
+            $this->disableIMDSv1 = Helper::env('ALIBABA_CLOUD_IMDSV1_DISABLED') === true ? true : false;
+        }
+
+        if (isset($params['disableIMDSv1'])) {
+            $this->disableIMDSv1 = $params['disableIMDSv1'];
+        }
+    }
+
+    /**
+     * Get credentials by request.
+     *
+     * @return array
+     * @throws InvalidArgumentException
+     * @throws RuntimeException
+     * @throws GuzzleException
+     */
+    public function refreshCredentials()
+    {
+        $url = $this->metadataHost . $this->ecsUri . $this->roleName;
+        $options = Request::commonOptions();
+        $options['read_timeout'] = $this->readTimeout;
+        $options['connect_timeout'] = $this->connectTimeout;
+
+        $metadataToken = $this->getMetadataToken();
+        if (!is_null($metadataToken)) {
+            $options['headers']['X-aliyun-ecs-metadata-token'] = $metadataToken;
+        }
+
+        $result = Request::createClient()->request('GET', $url, $options);
+
+        if ($result->getStatusCode() === 404) {
+            throw new InvalidArgumentException('The role was not found in the instance' . (string) $result);
+        }
+
+        if ($result->getStatusCode() !== 200) {
+            throw new RuntimeException('Error refreshing credentials from IMDS, statusCode: ' . $result->getStatusCode() . ', result: ' . (string) $result);
+        }
+
+        $credentials = $result->toArray();
+
+        if (!isset($credentials['AccessKeyId']) || !isset($credentials['AccessKeySecret']) || !isset($credentials['SecurityToken'])) {
+            throw new RuntimeException('Error retrieving credentials from IMDS result:' . $result->toJson());
+        }
+
+        if (!isset($credentials['Code']) || $credentials['Code'] !== 'Success') {
+            throw new RuntimeException('Error retrieving credentials from IMDS result, Code is not Success:' . $result->toJson());
+        }
+
+        return $credentials;
+    }
+
+    /**
+     * @return string
+     * @throws InvalidArgumentException
+     * @throws RuntimeException
+     * @throws GuzzleException
+     */
+    private function getRoleNameFromMeta()
+    {
+        $options = Request::commonOptions();
+        $options['read_timeout'] = $this->readTimeout;
+        $options['connect_timeout'] = $this->connectTimeout;
+
+        $metadataToken = $this->getMetadataToken();
+        if (!is_null($metadataToken)) {
+            $options['headers']['X-aliyun-ecs-metadata-token'] = $metadataToken;
+        }
+
+        $result = Request::createClient()->request(
+            'GET',
+            'http://100.100.100.200/latest/meta-data/ram/security-credentials/',
+            $options
+        );
+
+        if ($result->getStatusCode() === 404) {
+            throw new InvalidArgumentException('The role name was not found in the instance' . (string) $result);
+        }
+
+        if ($result->getStatusCode() !== 200) {
+            throw new RuntimeException('Error retrieving role name from result: ' . (string) $result);
+        }
+
+        $role_name = (string) $result;
+        if (!$role_name) {
+            throw new RuntimeException('Error retrieving role name from result is empty');
+        }
+
+        return $role_name;
+    }
+
+    /**
+     * Get metadata token by request.
+     *
+     * @return string
+     * @throws RuntimeException
+     * @throws GuzzleException
+     */
+    private function getMetadataToken()
+    {
+        $url = $this->metadataHost . $this->metadataTokenUri;
+        $options = Request::commonOptions();
+        $options['read_timeout'] = $this->readTimeout;
+        $options['connect_timeout'] = $this->connectTimeout;
+        $options['headers']['X-aliyun-ecs-metadata-token-ttl-seconds'] = $this->metadataTokenDuration;
+
+        $result = Request::createClient()->request('PUT', $url, $options);
+
+        if ($result->getStatusCode() != 200) {
+            if ($this->disableIMDSv1) {
+                throw new RuntimeException('Failed to get token from ECS Metadata Service. HttpCode= ' . $result->getStatusCode());
+            }
+            return null;
+        }
+        return (string) $result;
+    }
+
+
+    /**
+     * @return string
+     */
+    public function key()
+    {
+        return 'ecs_ram_role#roleName#' . $this->roleName;
+    }
+
+    /**
+     * @return string
+     */
+    public function getProviderName()
+    {
+        return 'ecs_ram_role';
+    }
+
+    /**
+     * @return string
+     */
+    public function getRoleName()
+    {
+        return $this->roleName;
+    }
+
+    /**
+     * @return bool
+     */
+    public function isDisableIMDSv1()
+    {
+        return $this->disableIMDSv1;
+    }
+}

+ 61 - 0
vendor/alibabacloud/credentials/src/Providers/EnvironmentVariableCredentialsProvider.php

@@ -0,0 +1,61 @@
+<?php
+
+namespace AlibabaCloud\Credentials\Providers;
+
+use AlibabaCloud\Credentials\Utils\Helper;
+use InvalidArgumentException;
+
+/**
+ * @internal This class is intended for internal use within the package. 
+ * Class EnvironmentVariableCredentialsProvider
+ *
+ * @package AlibabaCloud\Credentials\Providers
+ */
+class EnvironmentVariableCredentialsProvider implements CredentialsProvider
+{
+    /**
+     * EnvironmentVariableCredentialsProvider constructor.
+     */
+    public function __construct()
+    {
+    }
+
+    /**
+     * Get credential.
+     *
+     * @return Credentials
+     * @throws InvalidArgumentException
+     */
+    public function getCredentials()
+    {
+        if (Helper::envNotEmpty('ALIBABA_CLOUD_ACCESS_KEY_ID')) {
+            $accessKeyId = Helper::env('ALIBABA_CLOUD_ACCESS_KEY_ID');
+        } else {
+            throw new InvalidArgumentException('Access key ID must be specified via environment variable (ALIBABA_CLOUD_ACCESS_KEY_ID)');
+        }
+
+        if (Helper::envNotEmpty('ALIBABA_CLOUD_ACCESS_KEY_SECRET')) {
+            $accessKeySecret = Helper::env('ALIBABA_CLOUD_ACCESS_KEY_SECRET');
+        } else {
+            throw new InvalidArgumentException('Access key Secret must be specified via environment variable (ALIBABA_CLOUD_ACCESS_KEY_SECRET)');
+        }
+
+        if (Helper::envNotEmpty('ALIBABA_CLOUD_SECURITY_TOKEN')) {
+            $securityToken = Helper::env('ALIBABA_CLOUD_SECURITY_TOKEN');
+        }
+        return new Credentials([
+            'accessKeyId' => $accessKeyId,
+            'accessKeySecret' => $accessKeySecret,
+            'securityToken' => $securityToken,
+            'providerName' => $this->getProviderName(),
+        ]);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function getProviderName()
+    {
+        return "env";
+    }
+}

+ 257 - 0
vendor/alibabacloud/credentials/src/Providers/OIDCRoleArnCredentialsProvider.php

@@ -0,0 +1,257 @@
+<?php
+
+namespace AlibabaCloud\Credentials\Providers;
+
+use AlibabaCloud\Credentials\Utils\Helper;
+use AlibabaCloud\Credentials\Utils\Filter;
+use AlibabaCloud\Credentials\Request\Request;
+use GuzzleHttp\Psr7\Uri;
+use GuzzleHttp\Exception\GuzzleException;
+use InvalidArgumentException;
+use RuntimeException;
+use Exception;
+
+/**
+ * @internal This class is intended for internal use within the package. 
+ * Class OIDCRoleArnCredentialsProvider
+ *
+ * @package AlibabaCloud\Credentials\Providers
+ */
+class OIDCRoleArnCredentialsProvider extends SessionCredentialsProvider
+{
+
+    /**
+     * @var string
+     */
+    private $roleArn;
+
+    /**
+     * @var string
+     */
+    private $oidcProviderArn;
+
+    /**
+     * @var string
+     */
+    private $oidcTokenFilePath;
+
+    /**
+     * @var string
+     */
+    private $roleSessionName;
+
+    /**
+     * @description role session expiration
+     * @example 3600
+     * @var int
+     */
+    private $durationSeconds = 3600;
+
+    /**
+     * @var string
+     */
+    private $policy;
+
+    /**
+     * @var string
+     */
+    private $stsEndpoint;
+
+    /**
+     * @var int
+     */
+    private $connectTimeout = 5;
+
+    /**
+     * @var int
+     */
+    private $readTimeout = 5;
+
+    /**
+     * OIDCRoleArnCredentialsProvider constructor.
+     *
+     * @param array $params
+     * @param array $options
+     */
+    public function __construct(array $params = [], array $options = [])
+    {
+        $this->filterOptions($options);
+        $this->filterRoleArn($params);
+        $this->filterOIDCProviderArn($params);
+        $this->filterOIDCTokenFilePath($params);
+        $this->filterRoleSessionName($params);
+        $this->filterDurationSeconds($params);
+        $this->filterPolicy($params);
+        $this->filterSTSEndpoint($params);
+    }
+
+    private function filterRoleArn(array $params)
+    {
+        if (Helper::envNotEmpty('ALIBABA_CLOUD_ROLE_ARN')) {
+            $this->roleArn = Helper::env('ALIBABA_CLOUD_ROLE_ARN');
+        }
+
+        if (isset($params['roleArn'])) {
+            $this->roleArn = $params['roleArn'];
+        }
+
+        Filter::roleArn($this->roleArn);
+    }
+
+    private function filterOIDCProviderArn(array $params)
+    {
+        if (Helper::envNotEmpty('ALIBABA_CLOUD_OIDC_PROVIDER_ARN')) {
+            $this->oidcProviderArn = Helper::env('ALIBABA_CLOUD_OIDC_PROVIDER_ARN');
+        }
+
+        if (isset($params['oidcProviderArn'])) {
+            $this->oidcProviderArn = $params['oidcProviderArn'];
+        }
+
+        Filter::oidcProviderArn($this->oidcProviderArn);
+    }
+
+    private function filterOIDCTokenFilePath(array $params)
+    {
+        if (Helper::envNotEmpty('ALIBABA_CLOUD_OIDC_TOKEN_FILE')) {
+            $this->oidcTokenFilePath = Helper::env('ALIBABA_CLOUD_OIDC_TOKEN_FILE');
+        }
+
+        if (isset($params['oidcTokenFilePath'])) {
+            $this->oidcTokenFilePath = $params['oidcTokenFilePath'];
+        }
+
+        Filter::oidcTokenFilePath($this->oidcTokenFilePath);
+    }
+
+    private function filterRoleSessionName(array $params)
+    {
+        if (Helper::envNotEmpty('ALIBABA_CLOUD_ROLE_SESSION_NAME')) {
+            $this->roleSessionName = Helper::env('ALIBABA_CLOUD_ROLE_SESSION_NAME');
+        }
+
+        if (isset($params['roleSessionName'])) {
+            $this->roleSessionName = $params['roleSessionName'];
+        }
+
+        if (is_null($this->roleSessionName) || $this->roleSessionName === '') {
+            $this->roleSessionName = 'phpSdkRoleSessionName';
+        }
+    }
+
+    private function filterDurationSeconds(array $params)
+    {
+        if (isset($params['durationSeconds'])) {
+            if (is_int($params['durationSeconds'])) {
+                $this->durationSeconds = $params['durationSeconds'];
+            }
+        }
+        if ($this->durationSeconds < 900) {
+            throw new InvalidArgumentException('Role session expiration should be in the range of 900s - max session duration');
+        }
+    }
+
+    private function filterPolicy(array $params)
+    {
+        if (isset($params['policy'])) {
+            if (is_string($params['policy'])) {
+                $this->policy = $params['policy'];
+            }
+
+            if (is_array($params['policy'])) {
+                $this->policy = json_encode($params['policy']);
+            }
+        }
+    }
+
+    private function filterSTSEndpoint(array $params)
+    {
+        if (Helper::envNotEmpty('ALIBABA_CLOUD_STS_REGION')) {
+            $this->stsEndpoint = 'sts' . Helper::env('ALIBABA_CLOUD_STS_REGION') . '.aliyuncs.com';
+        }
+
+        if (isset($params['stsRegionId'])) {
+            $this->stsEndpoint = 'sts' . $params['stsRegionId'] . '.aliyuncs.com';
+        }
+
+        if (isset($params['stsEndpoint'])) {
+            $this->stsEndpoint = $params['stsEndpoint'];
+        }
+
+        if (is_null($this->stsEndpoint) || $this->stsEndpoint === '') {
+            $this->stsEndpoint = 'sts.aliyuncs.com';
+        }
+    }
+
+    private function filterOptions(array $options)
+    {
+        if (isset($options['connectTimeout'])) {
+            $this->connectTimeout = $options['connectTimeout'];
+        }
+
+        if (isset($options['readTimeout'])) {
+            $this->readTimeout = $options['readTimeout'];
+        }
+
+        Filter::timeout($this->connectTimeout, $this->readTimeout);
+    }
+
+    /**
+     * Get credentials by request.
+     *
+     * @return array
+     * @throws RuntimeException
+     * @throws GuzzleException
+     */
+    public function refreshCredentials()
+    {
+        $options = Request::commonOptions();
+        $options['read_timeout'] = $this->readTimeout;
+        $options['connect_timeout'] = $this->connectTimeout;
+
+        $options['query']['Action'] = 'AssumeRoleWithOIDC';
+        $options['query']['Version'] = '2015-04-01';
+        $options['query']['Format'] = 'JSON';
+        $options['query']['Timestamp'] = gmdate('Y-m-d\TH:i:s\Z');
+        $options['query']['RoleArn'] = $this->roleArn;
+        $options['query']['OIDCProviderArn'] = $this->oidcProviderArn;
+        try {
+            $oidcToken = file_get_contents($this->oidcTokenFilePath);
+            $options['query']['OIDCToken'] = $oidcToken;
+        } catch (Exception $exception) {
+            throw new InvalidArgumentException($exception->getMessage());
+        }
+        $options['query']['RoleSessionName'] = $this->roleSessionName;
+        $options['query']['DurationSeconds'] = (string) $this->durationSeconds;
+        if (!is_null($this->policy)) {
+            $options['query']['Policy'] = $this->policy;
+        }
+
+        $url = (new Uri())->withScheme('https')->withHost($this->stsEndpoint);
+
+        $result = Request::createClient()->request('POST', $url, $options);
+
+        if ($result->getStatusCode() !== 200) {
+            throw new RuntimeException('Error refreshing credentials from OIDC, statusCode: ' . $result->getStatusCode() . ', result: ' . (string) $result);
+        }
+
+        $json = $result->toArray();
+        $credentials = $json['Credentials'];
+
+        if (!isset($credentials['AccessKeyId']) || !isset($credentials['AccessKeySecret']) || !isset($credentials['SecurityToken'])) {
+            throw new RuntimeException('Error retrieving credentials from OIDC result:' . $result->toJson());
+        }
+
+        return $credentials;
+    }
+
+    public function key()
+    {
+        return 'oidc_role_arn#roleArn#' . $this->roleArn . '#oidcProviderArn#' . $this->oidcProviderArn . '#roleSessionName#' . $this->roleSessionName;
+    }
+
+    public function getProviderName()
+    {
+        return 'oidc_role_arn';
+    }
+}

+ 188 - 0
vendor/alibabacloud/credentials/src/Providers/ProfileCredentialsProvider.php

@@ -0,0 +1,188 @@
+<?php
+
+namespace AlibabaCloud\Credentials\Providers;
+
+use AlibabaCloud\Credentials\Utils\Helper;
+use RuntimeException;
+
+/**
+ * @internal This class is intended for internal use within the package. 
+ * Class ProfileCredentialsProvider
+ *
+ * @package AlibabaCloud\Credentials\Providers
+ */
+class ProfileCredentialsProvider implements CredentialsProvider
+{
+
+    /**
+     * @var string
+     */
+    private $profileName;
+
+    /**
+     * @var string
+     */
+    private $profileFile;
+
+    /**
+     * @var CredentialsProvider
+     */
+    private $credentialsProvider;
+
+
+    /**
+     * ProfileCredentialsProvider constructor.
+     *
+     * @param array $params
+     */
+    public function __construct(array $params = [])
+    {
+        $this->filterProfileName($params);
+        $this->filterProfileFile();
+    }
+
+    private function filterProfileName(array $params)
+    {
+        if (Helper::envNotEmpty('ALIBABA_CLOUD_PROFILE')) {
+            $this->profileName = Helper::env('ALIBABA_CLOUD_PROFILE');
+        }
+
+        if (isset($params['profileName'])) {
+            $this->profileName = $params['profileName'];
+        }
+
+        if (is_null($this->profileName) || $this->profileName === '') {
+            $this->profileName = 'default';
+        }
+    }
+
+    private function filterProfileFile()
+    {
+        $this->profileFile = Helper::envNotEmpty('ALIBABA_CLOUD_CREDENTIALS_FILE');
+
+        if (!$this->profileFile) {
+            $this->profileFile = self::getDefaultFile();
+        }
+    }
+
+    /**
+     * @return bool
+     */
+    private function shouldReloadCredentialsProvider()
+    {
+        if (is_null($this->credentialsProvider)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * @return CredentialsProvider
+     */
+    private function reloadCredentialsProvider($profileFile, $profileName)
+    {
+        if (!Helper::inOpenBasedir($profileFile)) {
+            throw new RuntimeException('Unable to open credentials file: ' . $profileFile);
+        }
+
+        if (!\is_readable($profileFile) || !\is_file($profileFile)) {
+            throw new RuntimeException('Credentials file is not readable: ' . $profileFile);
+        }
+
+        $fileArray = \parse_ini_file($profileFile, true);
+
+        if (\is_array($fileArray) && !empty($fileArray)) {
+            $credentialsConfigures = [];
+            foreach (\array_change_key_case($fileArray) as $name => $configures) {
+                if ($name === $profileName) {
+                    $credentialsConfigures = $configures;
+                    break;
+                }
+            }
+            if (\is_array($credentialsConfigures) && !empty($credentialsConfigures)) {
+                switch (Helper::unsetReturnNull($credentialsConfigures, 'type')) {
+                    case 'access_key':
+                        return new StaticAKCredentialsProvider([
+                            'accessKeyId' => Helper::unsetReturnNull($credentialsConfigures, 'access_key_id'),
+                            'accessKeySecret' => Helper::unsetReturnNull($credentialsConfigures, 'access_key_secret'),
+                        ]);
+                    case 'ram_role_arn':
+                        $innerProvider = new StaticAKCredentialsProvider([
+                            'accessKeyId' => Helper::unsetReturnNull($credentialsConfigures, 'access_key_id'),
+                            'accessKeySecret' => Helper::unsetReturnNull($credentialsConfigures, 'access_key_secret'),
+                        ]);
+                        return new RamRoleArnCredentialsProvider([
+                            'credentialsProvider' => $innerProvider,
+                            'roleArn' => Helper::unsetReturnNull($credentialsConfigures, 'role_arn'),
+                            'roleSessionName' => Helper::unsetReturnNull($credentialsConfigures, 'role_session_name'),
+                            'policy' => Helper::unsetReturnNull($credentialsConfigures, 'policy'),
+                        ]);
+                    case 'ecs_ram_role':
+                        return new EcsRamRoleCredentialsProvider([
+                            'roleName' => Helper::unsetReturnNull($credentialsConfigures, 'role_name'),
+                        ]);
+                    case 'oidc_role_arn':
+                        return new OIDCRoleArnCredentialsProvider([
+                            'roleArn' => Helper::unsetReturnNull($credentialsConfigures, 'role_arn'),
+                            'oidcProviderArn' => Helper::unsetReturnNull($credentialsConfigures, 'oidc_provider_arn'),
+                            'oidcTokenFilePath' => Helper::unsetReturnNull($credentialsConfigures, 'oidc_token_file_path'),
+                            'roleSessionName' => Helper::unsetReturnNull($credentialsConfigures, 'role_session_name'),
+                            'policy' => Helper::unsetReturnNull($credentialsConfigures, 'policy'),
+                        ]);
+                    case 'rsa_key_pair':
+                        return new RsaKeyPairCredentialsProvider([
+                            'publicKeyId' => Helper::unsetReturnNull($credentialsConfigures, 'public_key_id'),
+                            'privateKeyFile' => Helper::unsetReturnNull($credentialsConfigures, 'private_key_file'),
+                        ]);
+                    default:
+                        throw new RuntimeException('Unsupported credential type from credentials file: ' . Helper::unsetReturnNull($credentialsConfigures, 'type'));
+                }
+            }
+        }
+        throw new RuntimeException('Failed to get credential from credentials file: ' . $profileFile);
+    }
+    /**
+     * Get credential.
+     *
+     * @return Credentials
+     * @throws RuntimeException
+     */
+    public function getCredentials()
+    {
+        if ($this->shouldReloadCredentialsProvider()) {
+            $this->credentialsProvider = $this->reloadCredentialsProvider($this->profileFile, $this->profileName);
+        }
+
+        $credentials = $this->credentialsProvider->getCredentials();
+        return new Credentials([
+            'accessKeyId' => $credentials->getAccessKeyId(),
+            'accessKeySecret' => $credentials->getAccessKeySecret(),
+            'securityToken' => $credentials->getSecurityToken(),
+            'providerName' => $this->getProviderName() . '/' . $this->credentialsProvider->getProviderName(),
+        ]);
+
+    }
+
+    /**
+     * Get the default credential file.
+     *
+     * @return string
+     */
+    private function getDefaultFile()
+    {
+        return Helper::getHomeDirectory() .
+            DIRECTORY_SEPARATOR .
+            '.alibabacloud' .
+            DIRECTORY_SEPARATOR .
+            'credentials';
+    }
+
+    /**
+     * @return string
+     */
+    public function getProviderName()
+    {
+        return 'profile';
+    }
+}

+ 310 - 0
vendor/alibabacloud/credentials/src/Providers/RamRoleArnCredentialsProvider.php

@@ -0,0 +1,310 @@
+<?php
+
+namespace AlibabaCloud\Credentials\Providers;
+
+use AlibabaCloud\Credentials\Utils\Helper;
+use AlibabaCloud\Credentials\Utils\Filter;
+use AlibabaCloud\Credentials\Request\Request;
+use GuzzleHttp\Psr7\Uri;
+use GuzzleHttp\Exception\GuzzleException;
+use InvalidArgumentException;
+use RuntimeException;
+
+/**
+ * @internal This class is intended for internal use within the package. 
+ * Class RamRoleArnCredentialsProvider
+ *
+ * @package AlibabaCloud\Credentials\Providers
+ */
+class RamRoleArnCredentialsProvider extends SessionCredentialsProvider
+{
+
+    /**
+     * @var CredentialsProvider
+     */
+    private $credentialsProvider;
+
+    /**
+     * @var string
+     */
+    private $roleArn;
+
+    /**
+     * @var string
+     */
+    private $roleSessionName;
+
+    /**
+     * @description role session expiration
+     * @example 3600
+     * @var int
+     */
+    private $durationSeconds = 3600;
+
+    /**
+     * @var string
+     */
+    private $externalId;
+
+    /**
+     * @var string
+     */
+    private $policy;
+
+    /**
+     * @var string
+     */
+    private $stsEndpoint;
+
+    /**
+     * @var int
+     */
+    private $connectTimeout = 5;
+
+    /**
+     * @var int
+     */
+    private $readTimeout = 5;
+
+    /**
+     * RamRoleArnCredentialsProvider constructor.
+     *
+     * @param array $params
+     * @param array $options
+     */
+    public function __construct(array $params = [], array $options = [])
+    {
+        $this->filterOptions($options);
+        $this->filterCredentials($params);
+        $this->filterRoleArn($params);
+        $this->filterRoleSessionName($params);
+        $this->filterDurationSeconds($params);
+        $this->filterPolicy($params);
+        $this->filterExternalId($params);
+        $this->filterSTSEndpoint($params);
+    }
+
+    private function filterRoleArn(array $params)
+    {
+        if (Helper::envNotEmpty('ALIBABA_CLOUD_ROLE_ARN')) {
+            $this->roleArn = Helper::env('ALIBABA_CLOUD_ROLE_ARN');
+        }
+
+        if (isset($params['roleArn'])) {
+            $this->roleArn = $params['roleArn'];
+        }
+
+        Filter::roleArn($this->roleArn);
+    }
+
+    private function filterRoleSessionName(array $params)
+    {
+        if (Helper::envNotEmpty('ALIBABA_CLOUD_ROLE_SESSION_NAME')) {
+            $this->roleSessionName = Helper::env('ALIBABA_CLOUD_ROLE_SESSION_NAME');
+        }
+
+        if (isset($params['roleSessionName'])) {
+            $this->roleSessionName = $params['roleSessionName'];
+        }
+
+        if (is_null($this->roleSessionName) || $this->roleSessionName === '') {
+            $this->roleSessionName = 'phpSdkRoleSessionName';
+        }
+    }
+
+    private function filterDurationSeconds(array $params)
+    {
+        if (isset($params['durationSeconds'])) {
+            if (is_int($params['durationSeconds'])) {
+                $this->durationSeconds = $params['durationSeconds'];
+            }
+        }
+        if ($this->durationSeconds < 900) {
+            throw new InvalidArgumentException('Role session expiration should be in the range of 900s - max session duration');
+        }
+    }
+
+    private function filterPolicy(array $params)
+    {
+        if (isset($params['policy'])) {
+            if (is_string($params['policy'])) {
+                $this->policy = $params['policy'];
+            }
+
+            if (is_array($params['policy'])) {
+                $this->policy = json_encode($params['policy']);
+            }
+        }
+    }
+
+    private function filterExternalId(array $params)
+    {
+        if (isset($params['externalId'])) {
+            if (is_string($params['externalId'])) {
+                $this->externalId = $params['externalId'];
+            }
+        }
+    }
+
+    private function filterSTSEndpoint(array $params)
+    {
+        if (Helper::envNotEmpty('ALIBABA_CLOUD_STS_REGION')) {
+            $this->stsEndpoint = 'sts.' . Helper::env('ALIBABA_CLOUD_STS_REGION') . '.aliyuncs.com';
+        }
+
+        if (isset($params['stsRegionId'])) {
+            $this->stsEndpoint = 'sts.' . $params['stsRegionId'] . '.aliyuncs.com';
+        }
+
+        if (isset($params['stsEndpoint'])) {
+            $this->stsEndpoint = $params['stsEndpoint'];
+        }
+
+        if (is_null($this->stsEndpoint) || $this->stsEndpoint === '') {
+            $this->stsEndpoint = 'sts.aliyuncs.com';
+        }
+    }
+
+    private function filterCredentials(array $params)
+    {
+        if (isset($params['credentialsProvider'])) {
+            if (!($params['credentialsProvider'] instanceof CredentialsProvider)) {
+                throw new InvalidArgumentException('Invalid credentialsProvider option for ram_role_arn');
+            }
+            $this->credentialsProvider = $params['credentialsProvider'];
+        } else if (isset($params['accessKeyId']) && isset($params['accessKeySecret']) && isset($params['securityToken'])) {
+            Filter::accessKey($params['accessKeyId'], $params['accessKeySecret']);
+            Filter::securityToken($params['securityToken']);
+            $this->credentialsProvider = new StaticSTSCredentialsProvider($params);
+        } else if (isset($params['accessKeyId']) && isset($params['accessKeySecret'])) {
+            Filter::accessKey($params['accessKeyId'], $params['accessKeySecret']);
+            $this->credentialsProvider = new StaticAKCredentialsProvider($params);
+        } else {
+            throw new InvalidArgumentException('Missing required credentials option for ram_role_arn');
+        }
+    }
+
+    private function filterOptions(array $options)
+    {
+        if (isset($options['connectTimeout'])) {
+            $this->connectTimeout = $options['connectTimeout'];
+        }
+
+        if (isset($options['readTimeout'])) {
+            $this->readTimeout = $options['readTimeout'];
+        }
+
+        Filter::timeout($this->connectTimeout, $this->readTimeout);
+    }
+
+    /**
+     * Get credentials by request.
+     *
+     * @return array
+     * @throws RuntimeException
+     * @throws GuzzleException
+     */
+    public function refreshCredentials()
+    {
+        $options = Request::commonOptions();
+        $options['read_timeout'] = $this->readTimeout;
+        $options['connect_timeout'] = $this->connectTimeout;
+
+        $options['query']['Action'] = 'AssumeRole';
+        $options['query']['Version'] = '2015-04-01';
+        $options['query']['Format'] = 'JSON';
+        $options['query']['Timestamp'] = gmdate('Y-m-d\TH:i:s\Z');
+        $options['query']['SignatureMethod'] = 'HMAC-SHA1';
+        $options['query']['SignatureVersion'] = '1.0';
+        $options['query']['SignatureNonce'] = Request::uuid(json_encode($options['query']));
+        $options['query']['RoleArn'] = $this->roleArn;
+        $options['query']['RoleSessionName'] = $this->roleSessionName;
+        $options['query']['DurationSeconds'] = (string) $this->durationSeconds;
+        if (!is_null($this->policy) && $this->policy !== '') {
+            $options['query']['Policy'] = $this->policy;
+        }
+        if (!is_null($this->externalId) && $this->externalId !== '') {
+            $options['query']['ExternalId'] = $this->externalId;
+        }
+
+        $sessionCredentials = $this->credentialsProvider->getCredentials();
+        $options['query']['AccessKeyId'] = $sessionCredentials->getAccessKeyId();
+        if (!is_null($sessionCredentials->getSecurityToken())) {
+            $options['query']['SecurityToken'] = $sessionCredentials->getSecurityToken();
+        }
+        $options['query']['Signature'] = Request::shaHmac1sign(
+            Request::signString('GET', $options['query']),
+            $sessionCredentials->getAccessKeySecret() . '&'
+        );
+
+        $url = (new Uri())->withScheme('https')->withHost($this->stsEndpoint);
+
+        $result = Request::createClient()->request('GET', $url, $options);
+
+        if ($result->getStatusCode() !== 200) {
+            throw new RuntimeException('Error refreshing credentials from RamRoleArn, statusCode: ' . $result->getStatusCode() . ', result: ' . (string) $result);
+        }
+
+        $json = $result->toArray();
+        $credentials = $json['Credentials'];
+
+        if (!isset($credentials['AccessKeyId']) || !isset($credentials['AccessKeySecret']) || !isset($credentials['SecurityToken'])) {
+            throw new RuntimeException('Error retrieving credentials from RamRoleArn result:' . $result->toJson());
+        }
+
+        return $credentials;
+    }
+
+    public function key()
+    {
+        $credentials = $this->credentialsProvider->getCredentials();
+        return 'ram_role_arn#credential#' . $credentials->getAccessKeyId() . '#roleArn#' . $this->roleArn . '#roleSessionName#' . $this->roleSessionName;
+    }
+
+    public function getProviderName()
+    {
+        return 'ram_role_arn/' . $this->credentialsProvider->getProviderName();
+    }
+
+    /**
+     * @return string
+     */
+    public function getRoleArn()
+    {
+        return $this->roleArn;
+    }
+
+    /**
+     * @return string
+     */
+    public function getRoleSessionName()
+    {
+        return $this->roleSessionName;
+    }
+
+    /**
+     * @return string
+     */
+    public function getPolicy()
+    {
+        return $this->policy;
+    }
+
+    /**
+     * @deprecated
+     * @return string
+     */
+    public function getOriginalAccessKeyId()
+    {
+        return $this->credentialsProvider->getCredentials()->getAccessKeyId();
+    }
+
+    /**
+     * @deprecated
+     * @return string
+     */
+    public function getOriginalAccessKeySecret()
+    {
+        return $this->credentialsProvider->getCredentials()->getAccessKeySecret();
+    }
+}

+ 193 - 0
vendor/alibabacloud/credentials/src/Providers/RsaKeyPairCredentialsProvider.php

@@ -0,0 +1,193 @@
+<?php
+
+namespace AlibabaCloud\Credentials\Providers;
+
+use AlibabaCloud\Credentials\Utils\Helper;
+use AlibabaCloud\Credentials\Utils\Filter;
+use AlibabaCloud\Credentials\Request\Request;
+use GuzzleHttp\Psr7\Uri;
+use GuzzleHttp\Exception\GuzzleException;
+
+use InvalidArgumentException;
+use RuntimeException;
+use Exception;
+
+/**
+ * @internal This class is intended for internal use within the package.
+ * Class RsaKeyPairCredentialsProvider
+ *
+ * @package AlibabaCloud\Credentials\Providers
+ */
+class RsaKeyPairCredentialsProvider extends SessionCredentialsProvider
+{
+
+    /**
+     * @var string
+     */
+    private $publicKeyId;
+
+    /**
+     * @var string
+     */
+    private $privateKey;
+
+    /**
+     * @description role session expiration
+     * @example 3600
+     * @var int
+     */
+    private $durationSeconds = 3600;
+
+    /**
+     * @var string
+     */
+    private $stsEndpoint;
+
+    /**
+     * @var int
+     */
+    private $connectTimeout = 5;
+
+    /**
+     * @var int
+     */
+    private $readTimeout = 5;
+
+    /**
+     * RsaKeyPairCredentialsProvider constructor.
+     *
+     * @param array $params
+     * @param array $options
+     */
+    public function __construct(array $params = [], array $options = [])
+    {
+        $this->filterOptions($options);
+        $this->filterDurationSeconds($params);
+        $this->filterSTSEndpoint($params);
+        $this->publicKeyId = isset($params['publicKeyId']) ? $params['publicKeyId'] : null;
+        $privateKeyFile = isset($params['privateKeyFile']) ? $params['privateKeyFile'] : null;
+        Filter::publicKeyId($this->publicKeyId);
+        Filter::privateKeyFile($privateKeyFile);
+
+        try {
+            $this->privateKey = file_get_contents($privateKeyFile);
+        } catch (Exception $exception) {
+            throw new InvalidArgumentException($exception->getMessage());
+        }
+    }
+
+    private function filterOptions(array $options)
+    {
+        if (isset($options['connectTimeout'])) {
+            $this->connectTimeout = $options['connectTimeout'];
+        }
+
+        if (isset($options['readTimeout'])) {
+            $this->readTimeout = $options['readTimeout'];
+        }
+
+        Filter::timeout($this->connectTimeout, $this->readTimeout);
+    }
+
+    private function filterDurationSeconds(array $params)
+    {
+        if (isset($params['durationSeconds'])) {
+            if (is_int($params['durationSeconds'])) {
+                $this->durationSeconds = $params['durationSeconds'];
+            }
+        }
+        if ($this->durationSeconds < 900) {
+            throw new InvalidArgumentException('Role session expiration should be in the range of 900s - max session duration');
+        }
+    }
+
+    private function filterSTSEndpoint(array $params)
+    {
+        if (isset($params['stsEndpoint'])) {
+            $this->stsEndpoint = $params['stsEndpoint'];
+        }
+
+        if (is_null($this->stsEndpoint) || $this->stsEndpoint === '') {
+            $this->stsEndpoint = 'sts.ap-northeast-1.aliyuncs.com';
+        }
+    }
+
+
+    /**
+     * Get credentials by request.
+     *
+     * @return array
+     * @throws RuntimeException
+     * @throws GuzzleException
+     */
+    public function refreshCredentials()
+    {
+        $options = Request::commonOptions();
+        $options['read_timeout'] = $this->readTimeout;
+        $options['connect_timeout'] = $this->connectTimeout;
+
+        $options['query']['Action'] = 'GenerateSessionAccessKey';
+        $options['query']['Version'] = '2015-04-01';
+        $options['query']['Format'] = 'JSON';
+        $options['query']['Timestamp'] = gmdate('Y-m-d\TH:i:s\Z');
+        $options['query']['SignatureMethod'] = 'SHA256withRSA';
+        $options['query']['SignatureType'] = 'PRIVATEKEY';
+        $options['query']['SignatureVersion'] = '1.0';
+        $options['query']['SignatureNonce'] = Request::uuid(json_encode($options['query']));
+        $options['query']['DurationSeconds'] = (string) $this->durationSeconds;
+        $options['query']['AccessKeyId'] = $this->publicKeyId;
+        $options['query']['Signature'] = Request::shaHmac256WithRsasign(
+            Request::signString('GET', $options['query']),
+            $this->privateKey
+        );
+
+        $url = (new Uri())->withScheme('https')->withHost($this->stsEndpoint);
+
+        $result = Request::createClient()->request('GET', $url, $options);
+
+        if ($result->getStatusCode() !== 200) {
+            throw new RuntimeException('Error refreshing credentials from RsaKeyPair, statusCode: ' . $result->getStatusCode() . ', result: ' . (string) $result);
+        }
+
+        $json = $result->toArray();
+
+        if (!isset($json['SessionAccessKey']['SessionAccessKeyId']) || !isset($json['SessionAccessKey']['SessionAccessKeySecret'])) {
+            throw new RuntimeException('Error retrieving credentials from RsaKeyPair result:' . $result->toJson());
+        }
+
+        $credentials = [];
+        $credentials['AccessKeyId'] = $json['SessionAccessKey']['SessionAccessKeyId'];
+        $credentials['AccessKeySecret'] = $json['SessionAccessKey']['SessionAccessKeySecret'];
+        $credentials['Expiration'] = $json['SessionAccessKey']['Expiration'];
+        $credentials['SecurityToken'] = null;
+
+
+        return $credentials;
+    }
+
+    public function key()
+    {
+        return 'rsa_key_pair#publicKeyId#' . $this->publicKeyId;
+    }
+
+    public function getProviderName()
+    {
+        return 'rsa_key_pair';
+    }
+
+    /**
+     * @return string
+     */
+    public function getPublicKeyId()
+    {
+        return $this->publicKeyId;
+    }
+
+    /**
+     * @return mixed
+     */
+    public function getPrivateKey()
+    {
+        return $this->privateKey;
+    }
+}

+ 86 - 0
vendor/alibabacloud/credentials/src/Providers/SessionCredentialsProvider.php

@@ -0,0 +1,86 @@
+<?php
+
+namespace AlibabaCloud\Credentials\Providers;
+
+abstract class SessionCredentialsProvider implements CredentialsProvider
+{
+    /**
+     * @var array
+     */
+    protected static $credentialsCache = [];
+
+    /**
+     * Expiration time slot for temporary security credentials.
+     *
+     * @var int
+     */
+    protected $expirationSlot = 180;
+
+    /**
+     * @var string
+     */
+    protected $error = 'Result contains no credentials';
+
+    /**
+     * Get the credentials from the cache in the validity period.
+     *
+     * @return array|null
+     */
+    protected function getCredentialsInCache()
+    {
+        if (isset(self::$credentialsCache[$this->key()])) {
+            $result = self::$credentialsCache[$this->key()];
+            if (\strtotime($result['Expiration']) - \time() >= $this->expirationSlot) {
+                return $result;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Cache credentials.
+     *
+     * @param array $credential
+     */
+    protected function cache(array $credential)
+    {
+        self::$credentialsCache[$this->key()] = $credential;
+    }
+
+    /**
+     * Get credential.
+     *
+     * @return Credentials
+     */
+    public function getCredentials()
+    {
+        $credentials = $this->getCredentialsInCache();
+
+        if ($credentials === null) {
+            $credentials = $this->refreshCredentials();
+            $this->cache($credentials);
+        }
+
+        return new Credentials([
+            'accessKeyId' => $credentials['AccessKeyId'],
+            'accessKeySecret' => $credentials['AccessKeySecret'],
+            'securityToken' => $credentials['SecurityToken'],
+            'expiration' => \strtotime($credentials['Expiration']),
+            'providerName' => $this->getProviderName(),
+        ]);
+    }
+
+
+    /**
+     * @return array
+     */
+    abstract function refreshCredentials();
+
+    /**
+     * Get the toString of the credentials provider as the key.
+     *
+     * @return string
+     */
+    abstract function key();
+}

+ 78 - 0
vendor/alibabacloud/credentials/src/Providers/StaticAKCredentialsProvider.php

@@ -0,0 +1,78 @@
+<?php
+
+namespace AlibabaCloud\Credentials\Providers;
+
+use AlibabaCloud\Credentials\Utils\Helper;
+use AlibabaCloud\Credentials\Utils\Filter;
+
+/**
+ * @internal This class is intended for internal use within the package. 
+ * Class StaticAKCredentialsProvider
+ *
+ * @package AlibabaCloud\Credentials\Providers
+ */
+class StaticAKCredentialsProvider implements CredentialsProvider
+{
+
+    /**
+     * @var string
+     */
+    private $accessKeyId;
+
+    /**
+     * @var string
+     */
+    private $accessKeySecret;
+
+    /**
+     * StaticAKCredentialsProvider constructor.
+     *
+     * @param array $params
+     */
+    public function __construct(array $params = [])
+    {
+        $this->filterAK($params);
+    }
+
+    private function filterAK(array $params)
+    {
+        if (Helper::envNotEmpty('ALIBABA_CLOUD_ACCESS_KEY_ID')) {
+            $this->accessKeyId =  Helper::env('ALIBABA_CLOUD_ACCESS_KEY_ID');
+        }
+
+        if (Helper::envNotEmpty('ALIBABA_CLOUD_ACCESS_KEY_SECRET')) {
+            $this->accessKeySecret =  Helper::env('ALIBABA_CLOUD_ACCESS_KEY_SECRET');
+        }
+
+        if (isset($params['accessKeyId'])) {
+            $this->accessKeyId = $params['accessKeyId'];
+        }
+        if (isset($params['accessKeySecret'])) {
+            $this->accessKeySecret = $params['accessKeySecret'];
+        }
+
+        Filter::accessKey($this->accessKeyId, $this->accessKeySecret);
+    }
+
+    /**
+     * Get credential.
+     *
+     * @return Credentials
+     */
+    public function getCredentials()
+    {
+        return new Credentials([
+            'accessKeyId' => $this->accessKeyId,
+            'accessKeySecret' => $this->accessKeySecret,
+            'providerName' => $this->getProviderName(),
+        ]);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function getProviderName()
+    {
+        return "static_ak";
+    }
+}

+ 92 - 0
vendor/alibabacloud/credentials/src/Providers/StaticSTSCredentialsProvider.php

@@ -0,0 +1,92 @@
+<?php
+
+namespace AlibabaCloud\Credentials\Providers;
+
+use AlibabaCloud\Credentials\Utils\Helper;
+use AlibabaCloud\Credentials\Utils\Filter;
+
+/**
+ * @internal This class is intended for internal use within the package. 
+ * Class StaticSTSCredentialsProvider
+ *
+ * @package AlibabaCloud\Credentials\Providers
+ */
+class StaticSTSCredentialsProvider implements CredentialsProvider
+{
+
+    /**
+     * @var string
+     */
+    private $accessKeyId;
+
+    /**
+     * @var string
+     */
+    private $accessKeySecret;
+
+    /**
+     * @var string
+     */
+    private $securityToken;
+
+    /**
+     * StaticSTSCredentialsProvider constructor.
+     *
+     * @param array $params
+     */
+    public function __construct(array $params = [])
+    {
+        $this->filterSTS($params);
+    }
+
+    private function filterSTS(array $params)
+    {
+        if (Helper::envNotEmpty('ALIBABA_CLOUD_ACCESS_KEY_ID')) {
+            $this->accessKeyId = Helper::env('ALIBABA_CLOUD_ACCESS_KEY_ID');
+        }
+
+        if (Helper::envNotEmpty('ALIBABA_CLOUD_ACCESS_KEY_SECRET')) {
+            $this->accessKeySecret = Helper::env('ALIBABA_CLOUD_ACCESS_KEY_SECRET');
+        }
+
+        if (Helper::envNotEmpty('ALIBABA_CLOUD_SECURITY_TOKEN')) {
+            $this->securityToken = Helper::env('ALIBABA_CLOUD_SECURITY_TOKEN');
+        }
+
+        if (isset($params['accessKeyId'])) {
+            $this->accessKeyId = $params['accessKeyId'];
+        }
+        if (isset($params['accessKeySecret'])) {
+            $this->accessKeySecret = $params['accessKeySecret'];
+        }
+        if (isset($params['securityToken'])) {
+            $this->securityToken = $params['securityToken'];
+        }
+
+        Filter::accessKey($this->accessKeyId, $this->accessKeySecret);
+        Filter::securityToken($this->securityToken);
+    }
+
+    /**
+     * Get credential.
+     *
+     * @return Credentials
+     */
+    public function getCredentials()
+    {
+        return new Credentials([
+            'accessKeyId' => $this->accessKeyId,
+            'accessKeySecret' => $this->accessKeySecret,
+            'securityToken' => $this->securityToken,
+            'providerName' => $this->getProviderName(),
+        ]);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function getProviderName()
+    {
+        return "static_sts";
+    }
+}

+ 119 - 0
vendor/alibabacloud/credentials/src/Providers/URLCredentialsProvider.php

@@ -0,0 +1,119 @@
+<?php
+
+namespace AlibabaCloud\Credentials\Providers;
+
+use AlibabaCloud\Credentials\Utils\Helper;
+use AlibabaCloud\Credentials\Utils\Filter;
+use AlibabaCloud\Credentials\Request\Request;
+use GuzzleHttp\Exception\GuzzleException;
+use InvalidArgumentException;
+use RuntimeException;
+
+/**
+ * @internal This class is intended for internal use within the package. 
+ * Class URLCredentialsProvider
+ *
+ * @package AlibabaCloud\Credentials\Providers
+ */
+class URLCredentialsProvider extends SessionCredentialsProvider
+{
+
+    /**
+     * @var string
+     */
+    private $credentialsURI;
+
+    /**
+     * @var int
+     */
+    private $connectTimeout = 5;
+
+    /**
+     * @var int
+     */
+    private $readTimeout = 5;
+
+    /**
+     * URLCredentialsProvider constructor.
+     *
+     * @param array $params
+     * @param array $options
+     */
+    public function __construct(array $params = [], array $options = [])
+    {
+        $this->filterOptions($options);
+        $this->filterCredentialsURI($params);
+    }
+
+    private function filterOptions(array $options)
+    {
+        if (isset($options['connectTimeout'])) {
+            $this->connectTimeout = $options['connectTimeout'];
+        }
+
+        if (isset($options['readTimeout'])) {
+            $this->readTimeout = $options['readTimeout'];
+        }
+
+        Filter::timeout($this->connectTimeout, $this->readTimeout);
+    }
+
+    private function filterCredentialsURI(array $params)
+    {
+        if (Helper::envNotEmpty('ALIBABA_CLOUD_CREDENTIALS_URI')) {
+            $this->credentialsURI = Helper::env('ALIBABA_CLOUD_CREDENTIALS_URI');
+        }
+
+        if (isset($params['credentialsURI'])) {
+            $this->credentialsURI = $params['credentialsURI'];
+        }
+
+        Filter::credentialsURI($this->credentialsURI);
+    }
+
+    /**
+     * Get credentials by request.
+     *
+     * @return array
+     * @throws InvalidArgumentException
+     * @throws RuntimeException
+     * @throws GuzzleException
+     */
+    public function refreshCredentials()
+    {
+        $options = Request::commonOptions();
+        $options['read_timeout'] = $this->readTimeout;
+        $options['connect_timeout'] = $this->connectTimeout;
+
+        $result = Request::createClient()->request('GET', $this->credentialsURI, $options);
+
+        if ($result->getStatusCode() !== 200) {
+            throw new RuntimeException('Error refreshing credentials from credentialsURI, statusCode: ' . $result->getStatusCode() . ', result: ' . (string) $result);
+        }
+
+        $credentials = $result->toArray();
+
+        if (!isset($credentials['AccessKeyId']) || !isset($credentials['AccessKeySecret']) || !isset($credentials['SecurityToken']) || !isset($credentials['Expiration'])) {
+            throw new RuntimeException('Error retrieving credentials from credentialsURI result:' . $result->toJson());
+        }
+
+        return $credentials;
+    }
+
+
+    /**
+     * @return string
+     */
+    public function key()
+    {
+        return 'credential_uri#' . $this->credentialsURI;
+    }
+
+    /**
+     * @return string
+     */
+    public function getProviderName()
+    {
+        return 'credential_uri';
+    }
+}

+ 242 - 0
vendor/alibabacloud/credentials/src/RamRoleArnCredential.php

@@ -0,0 +1,242 @@
+<?php
+
+namespace AlibabaCloud\Credentials;
+
+use AlibabaCloud\Credentials\Providers\RamRoleArnCredentialsProvider;
+use AlibabaCloud\Credentials\Credential\CredentialModel;
+use AlibabaCloud\Credentials\Signature\ShaHmac1Signature;
+use AlibabaCloud\Credentials\Utils\Filter;
+use Exception;
+use GuzzleHttp\Exception\GuzzleException;
+use InvalidArgumentException;
+
+/**
+ * @deprecated
+ * Use the AssumeRole of the RAM account to complete  the authentication.
+ */
+class RamRoleArnCredential implements CredentialsInterface
+{
+
+    /**
+     * @var string
+     */
+    private $accessKeyId;
+
+    /**
+     * @var string
+     */
+    private $accessKeySecret;
+
+    /**
+     * @var string
+     */
+    private $roleArn;
+
+    /**
+     * @var string
+     */
+    private $roleSessionName;
+
+    /**
+     * @var string
+     */
+    private $policy;
+
+    /**
+     * @var array
+     */
+    private $config;
+
+    /**
+     * RamRoleArnCredential constructor.
+     *
+     * @param array $credential
+     * @param array $config
+     */
+    public function __construct(array $credential = [], array $config = [])
+    {
+        $this->filterParameters($credential);
+        $this->filterPolicy($credential);
+
+        Filter::accessKey($credential['access_key_id'], $credential['access_key_secret']);
+
+        $this->config = $config;
+        $this->accessKeyId = $credential['access_key_id'];
+        $this->accessKeySecret = $credential['access_key_secret'];
+        $this->roleArn = $credential['role_arn'];
+        $this->roleSessionName = $credential['role_session_name'];
+    }
+
+    /**
+     * @param array $credential
+     */
+    private function filterParameters(array $credential)
+    {
+        if (!isset($credential['access_key_id'])) {
+            throw new InvalidArgumentException('Missing required access_key_id option in config for ram_role_arn');
+        }
+
+        if (!isset($credential['access_key_secret'])) {
+            throw new InvalidArgumentException('Missing required access_key_secret option in config for ram_role_arn');
+        }
+
+        if (!isset($credential['role_arn'])) {
+            throw new InvalidArgumentException('Missing required role_arn option in config for ram_role_arn');
+        }
+
+        if (!isset($credential['role_session_name'])) {
+            throw new InvalidArgumentException('Missing required role_session_name option in config for ram_role_arn');
+        }
+    }
+
+    /**
+     * @param array $credential
+     */
+    private function filterPolicy(array $credential)
+    {
+        if (isset($credential['policy'])) {
+            if (is_string($credential['policy'])) {
+                $this->policy = $credential['policy'];
+            }
+
+            if (is_array($credential['policy'])) {
+                $this->policy = json_encode($credential['policy']);
+            }
+        }
+    }
+
+    /**
+     * @return array
+     */
+    public function getConfig()
+    {
+        return $this->config;
+    }
+
+    /**
+     * @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";
+    }
+
+    /**
+     * @return ShaHmac1Signature
+     */
+    public function getSignature()
+    {
+        return new ShaHmac1Signature();
+    }
+
+    /**
+     * @return string
+     */
+    public function getOriginalAccessKeyId()
+    {
+        return $this->accessKeyId;
+    }
+
+    /**
+     * @return string
+     */
+    public function getOriginalAccessKeySecret()
+    {
+        return $this->accessKeySecret;
+    }
+
+    /**
+     * @return string
+     * @throws Exception
+     * @throws GuzzleException
+     */
+    public function getAccessKeyId()
+    {
+        return $this->getSessionCredential()->getAccessKeyId();
+    }
+
+    /**
+     * @return AlibabaCloud\Credentials\Providers\Credentials
+     * @throws Exception
+     * @throws GuzzleException
+     */
+    protected function getSessionCredential()
+    {
+        $params = [
+            'accessKeyId' => $this->accessKeyId,
+            'accessKeySecret' => $this->accessKeyId,
+            'roleArn' => $this->roleArn,
+            'roleSessionName' => $this->roleSessionName,
+            'policy' => $this->policy,
+        ];
+        return (new RamRoleArnCredentialsProvider($params))->getCredentials();
+    }
+
+    /**
+     * @return string
+     * @throws Exception
+     * @throws GuzzleException
+     */
+    public function getAccessKeySecret()
+    {
+        return $this->getSessionCredential()->getAccessKeySecret();
+    }
+
+    /**
+     * @return string
+     * @throws Exception
+     * @throws GuzzleException
+     */
+    public function getSecurityToken()
+    {
+        return $this->getSessionCredential()->getSecurityToken();
+    }
+
+    /**
+     * @return string
+     * @throws Exception
+     * @throws GuzzleException
+     */
+    public function getExpiration()
+    {
+        return $this->getSessionCredential()->getExpiration();
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function getCredential()
+    {
+        $credentials = $this->getSessionCredential();
+        return new CredentialModel([
+            'accessKeyId' => $credentials->getAccessKeyId(),
+            'accessKeySecret' => $credentials->getAccessKeySecret(),
+            'securityToken' => $credentials->getSecurityToken(),
+            'type' => 'ram_role_arn',
+        ]);
+    }
+}

+ 167 - 0
vendor/alibabacloud/credentials/src/Request/Request.php

@@ -0,0 +1,167 @@
+<?php
+
+namespace AlibabaCloud\Credentials\Request;
+
+use AlibabaCloud\Credentials\Credentials;
+use AlibabaCloud\Credentials\Utils\Helper;
+use GuzzleHttp\Client;
+use GuzzleHttp\HandlerStack;
+use GuzzleHttp\Middleware;
+use AlibabaCloud\Tea\Response;
+use Psr\Http\Message\ResponseInterface;
+
+use Exception;
+use InvalidArgumentException;
+
+/**
+ * RESTful RPC Request.
+ */
+class Request
+{
+
+    /**
+     * Request Connect Timeout
+     */
+    const CONNECT_TIMEOUT = 5;
+
+    /**
+     * Request Read Timeout
+     */
+    const READ_TIMEOUT = 5;
+
+    /**
+     * @var array
+     */
+    private static $config = [];
+
+
+    /**
+     *
+     * @return array
+     */
+    public static function commonOptions()
+    {
+        $options = [];
+        $options['http_errors'] = false;
+        $options['connect_timeout'] = self::CONNECT_TIMEOUT;
+        $options['read_timeout'] = self::READ_TIMEOUT;
+        $options['headers']['User-Agent'] = Helper::getUserAgent();
+
+        // Turn on debug mode based on environment variable.
+        if (strtolower(Helper::env('DEBUG')) === 'sdk') {
+            $options['debug'] = true;
+        }
+        return $options;
+    }
+
+    /**
+     * @param string $salt
+     *
+     * @return string
+     */
+    public static function uuid($salt)
+    {
+        return md5($salt . uniqid(md5(microtime(true)), true));
+    }
+
+    /**
+     * @param string $method
+     * @param array  $parameters
+     *
+     * @return string
+     */
+    public static function signString($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 string $string
+     * @param string $accessKeySecret
+     *
+     * @return string
+     */
+    public static function shaHmac1sign($string, $accessKeySecret)
+    {
+        return base64_encode(hash_hmac('sha1', $string, $accessKeySecret, true));
+    }
+
+    /**
+     * @param string $string
+     * @param string $accessKeySecret
+     *
+     * @return string
+     */
+    public static function shaHmac256sign($string, $accessKeySecret)
+    {
+        return base64_encode(hash_hmac('sha256', $string, $accessKeySecret, true));
+    }
+
+    /**
+     * @param string $string
+     * @param string $privateKey
+     *
+     * @return string
+     */
+    public static function shaHmac256WithRsasign($string, $privateKey)
+    {
+        $binarySignature = '';
+        try {
+            openssl_sign(
+                $string,
+                $binarySignature,
+                $privateKey,
+                \OPENSSL_ALGO_SHA256
+            );
+        } catch (Exception $exception) {
+            throw new InvalidArgumentException(
+                $exception->getMessage()
+            );
+        }
+
+        return base64_encode($binarySignature);
+    }
+
+    /**
+     * @param string $string
+     *
+     * @return null|string|string[]
+     */
+    private static function percentEncode($string)
+    {
+        $result = rawurlencode($string);
+        $result = str_replace(['+', '*'], ['%20', '%2A'], $result);
+        $result = preg_replace('/%7E/', '~', $result);
+
+        return $result;
+    }
+
+    /**
+     * @return Client
+     * @throws Exception
+     */
+    public static function createClient()
+    {
+        if (Credentials::hasMock()) {
+            $stack = HandlerStack::create(Credentials::getMock());
+            $history = Credentials::getHandlerHistory();
+            $stack->push($history);
+        } else {
+            $stack = HandlerStack::create();
+        }
+
+        $stack->push(Middleware::mapResponse(static function (ResponseInterface $response) {
+            return new Response($response);
+        }));
+
+        self::$config['handler'] = $stack;
+
+        return new Client(self::$config);
+    }
+}

+ 185 - 0
vendor/alibabacloud/credentials/src/RsaKeyPairCredential.php

@@ -0,0 +1,185 @@
+<?php
+
+namespace AlibabaCloud\Credentials;
+
+use AlibabaCloud\Credentials\Providers\RsaKeyPairCredentialsProvider;
+use AlibabaCloud\Credentials\Credential\CredentialModel;
+use AlibabaCloud\Credentials\Signature\ShaHmac1Signature;
+use AlibabaCloud\Credentials\Utils\Filter;
+use Exception;
+use GuzzleHttp\Exception\GuzzleException;
+use InvalidArgumentException;
+
+/**
+ * @deprecated
+ * Use the RSA key pair to complete the authentication (supported only on Japanese site)
+ */
+class RsaKeyPairCredential implements CredentialsInterface
+{
+
+    /**
+     * @var string
+     */
+    private $publicKeyId;
+
+    /**
+     * @var string
+     */
+    private $privateKeyFile;
+
+    /**
+     * @var string
+     */
+    private $privateKey;
+
+    /**
+     * @var array
+     */
+    private $config;
+
+    /**
+     * RsaKeyPairCredential constructor.
+     *
+     * @param string $public_key_id
+     * @param string $private_key_file
+     * @param array  $config
+     */
+    public function __construct($public_key_id, $private_key_file, array $config = [])
+    {
+        Filter::publicKeyId($public_key_id);
+        Filter::privateKeyFile($private_key_file);
+
+        $this->publicKeyId = $public_key_id;
+        $this->privateKeyFile = $private_key_file;
+        $this->config = $config;
+        try {
+            $this->privateKey = file_get_contents($private_key_file);
+        } catch (Exception $exception) {
+            throw new InvalidArgumentException($exception->getMessage());
+        }
+    }
+
+    /**
+     * @return array
+     */
+    public function getConfig()
+    {
+        return $this->config;
+    }
+
+    /**
+     * @return string
+     */
+    public function getOriginalAccessKeyId()
+    {
+        return $this->getPublicKeyId();
+    }
+
+    /**
+     * @return string
+     */
+    public function getPublicKeyId()
+    {
+        return $this->publicKeyId;
+    }
+
+    /**
+     * @return string
+     */
+    public function getOriginalAccessKeySecret()
+    {
+        return $this->getPrivateKey();
+    }
+
+    /**
+     * @return mixed
+     */
+    public function getPrivateKey()
+    {
+        return $this->privateKey;
+    }
+
+    /**
+     * @return string
+     */
+    public function __toString()
+    {
+        return "publicKeyId#$this->publicKeyId";
+    }
+
+    /**
+     * @return ShaHmac1Signature
+     */
+    public function getSignature()
+    {
+        return new ShaHmac1Signature();
+    }
+
+    /**
+     * @return string
+     * @throws Exception
+     * @throws GuzzleException
+     */
+    public function getAccessKeyId()
+    {
+        return $this->getSessionCredential()->getAccessKeyId();
+    }
+
+    /**
+     * @return AlibabaCloud\Credentials\Providers\Credentials
+     * @throws Exception
+     * @throws GuzzleException
+     */
+    protected function getSessionCredential()
+    {
+        $params = [
+            'publicKeyId' => $this->publicKeyId,
+            'privateKeyFile' => $this->privateKeyFile,
+        ];
+        return (new RsaKeyPairCredentialsProvider($params))->getCredentials();
+    }
+
+    /**
+     * @return string
+     * @throws Exception
+     * @throws GuzzleException
+     */
+    public function getAccessKeySecret()
+    {
+        return $this->getSessionCredential()->getAccessKeySecret();
+    }
+
+    /**
+     * @return string
+     * @throws Exception
+     * @throws GuzzleException
+     */
+    public function getSecurityToken()
+    {
+        return $this->getSessionCredential()->getSecurityToken();
+    }
+
+    /**
+     * @return int
+     * @throws Exception
+     * @throws GuzzleException
+     */
+    public function getExpiration()
+    {
+        return $this->getSessionCredential()->getExpiration();
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function getCredential()
+    {
+        $credentials = $this->getSessionCredential();
+        return new CredentialModel([
+            'accessKeyId' => $credentials->getAccessKeyId(),
+            'accessKeySecret' => $credentials->getAccessKeySecret(),
+            'securityToken' => $credentials->getSecurityToken(),
+            'type' => 'rsa_key_pair',
+        ]);
+    }
+}

+ 47 - 0
vendor/alibabacloud/credentials/src/Signature/BearerTokenSignature.php

@@ -0,0 +1,47 @@
+<?php
+
+namespace AlibabaCloud\Credentials\Signature;
+
+/**
+ * Class BearerTokenSignature
+ *
+ * @package AlibabaCloud\Credentials\Signature
+ */
+class BearerTokenSignature 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 '';
+    }
+}

+ 47 - 0
vendor/alibabacloud/credentials/src/Signature/ShaHmac1Signature.php

@@ -0,0 +1,47 @@
+<?php
+
+namespace AlibabaCloud\Credentials\Signature;
+
+/**
+ * Class ShaHmac1Signature
+ *
+ * @package AlibabaCloud\Credentials\Signature
+ */
+class ShaHmac1Signature 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));
+    }
+}

+ 47 - 0
vendor/alibabacloud/credentials/src/Signature/ShaHmac256Signature.php

@@ -0,0 +1,47 @@
+<?php
+
+namespace AlibabaCloud\Credentials\Signature;
+
+/**
+ * Class ShaHmac256Signature
+ *
+ * @package AlibabaCloud\Credentials\Signature
+ */
+class ShaHmac256Signature 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));
+    }
+}

+ 64 - 0
vendor/alibabacloud/credentials/src/Signature/ShaHmac256WithRsaSignature.php

@@ -0,0 +1,64 @@
+<?php
+
+namespace AlibabaCloud\Credentials\Signature;
+
+use Exception;
+use InvalidArgumentException;
+
+/**
+ * Class ShaHmac256WithRsaSignature
+ *
+ * @package AlibabaCloud\Credentials\Signature
+ */
+class ShaHmac256WithRsaSignature 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
+     */
+    public function sign($string, $privateKey)
+    {
+        $binarySignature = '';
+        try {
+            openssl_sign(
+                $string,
+                $binarySignature,
+                $privateKey,
+                \OPENSSL_ALGO_SHA256
+            );
+        } catch (Exception $exception) {
+            throw  new InvalidArgumentException(
+                $exception->getMessage()
+            );
+        }
+
+        return base64_encode($binarySignature);
+    }
+}

+ 34 - 0
vendor/alibabacloud/credentials/src/Signature/SignatureInterface.php

@@ -0,0 +1,34 @@
+<?php
+
+namespace AlibabaCloud\Credentials\Signature;
+
+/**
+ * Interface SignatureInterface
+ *
+ * @package AlibabaCloud\Credentials\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();
+}

+ 115 - 0
vendor/alibabacloud/credentials/src/StsCredential.php

@@ -0,0 +1,115 @@
+<?php
+
+namespace AlibabaCloud\Credentials;
+
+use AlibabaCloud\Credentials\Utils\Filter;
+use AlibabaCloud\Credentials\Credential\CredentialModel;
+use AlibabaCloud\Credentials\Signature\ShaHmac1Signature;
+
+/**
+ * @deprecated
+ * Use the STS Token to complete the authentication.
+ */
+class StsCredential implements CredentialsInterface
+{
+
+    /**
+     * @var string
+     */
+    private $accessKeyId;
+
+    /**
+     * @var string
+     */
+    private $accessKeySecret;
+
+    /**
+     * @var string
+     */
+    private $securityToken;
+
+    /**
+     * @var int
+     */
+    private $expiration;
+
+    /**
+     * StsCredential constructor.
+     *
+     * @param string $access_key_id     Access key ID
+     * @param string $access_key_secret Access Key Secret
+     * @param int    $expiration
+     * @param string $security_token    Security Token
+     */
+    public function __construct($access_key_id, $access_key_secret, $expiration, $security_token = '')
+    {
+        Filter::accessKey($access_key_id, $access_key_secret);
+        Filter::expiration($expiration);
+        $this->accessKeyId = $access_key_id;
+        $this->accessKeySecret = $access_key_secret;
+        $this->expiration = $expiration;
+        $this->securityToken = $security_token;
+    }
+
+    /**
+     * @return int
+     */
+    public function getExpiration()
+    {
+        return $this->expiration;
+    }
+
+    /**
+     * @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";
+    }
+
+    /**
+     * @return ShaHmac1Signature
+     */
+    public function getSignature()
+    {
+        return new ShaHmac1Signature();
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function getCredential()
+    {
+        return new CredentialModel([
+            'accessKeyId' => $this->accessKeyId,
+            'accessKeySecret' => $this->accessKeySecret,
+            'securityToken' => $this->securityToken,
+            'type' => 'sts',
+        ]);
+    }
+
+}

+ 233 - 0
vendor/alibabacloud/credentials/src/Utils/Filter.php

@@ -0,0 +1,233 @@
+<?php
+
+namespace AlibabaCloud\Credentials\Utils;
+
+use InvalidArgumentException;
+
+/**
+ * Class Filter
+ *
+ * @package AlibabaCloud\Credentials\Utils
+ */
+class Filter
+{
+
+    /**
+     * @param $name
+     *
+     * @codeCoverageIgnore
+     * @return string
+     */
+    public static function credentialName($name)
+    {
+        if (!is_string($name)) {
+            throw new InvalidArgumentException('Name must be a string');
+        }
+
+        if ($name === '') {
+            throw new InvalidArgumentException('Name cannot be empty');
+        }
+
+        return $name;
+    }
+
+    /**
+     * @param $bearerToken
+     *
+     * @return mixed
+     * @throws InvalidArgumentException
+     */
+    public static function bearerToken($bearerToken)
+    {
+        if (!is_string($bearerToken)) {
+            throw new InvalidArgumentException('bearerToken must be a string');
+        }
+
+        if ($bearerToken === '') {
+            throw new InvalidArgumentException('bearerToken cannot be empty');
+        }
+
+        return $bearerToken;
+    }
+
+    /**
+     * @param $publicKeyId
+     *
+     * @return mixed
+     */
+    public static function publicKeyId($publicKeyId)
+    {
+        if (!is_string($publicKeyId)) {
+            throw new InvalidArgumentException('publicKeyId must be a string');
+        }
+
+        if ($publicKeyId === '') {
+            throw new InvalidArgumentException('publicKeyId cannot be empty');
+        }
+
+        return $publicKeyId;
+    }
+
+    /**
+     * @param $privateKeyFile
+     *
+     * @return mixed
+     */
+    public static function privateKeyFile($privateKeyFile)
+    {
+        if (!is_string($privateKeyFile)) {
+            throw new InvalidArgumentException('privateKeyFile must be a string');
+        }
+
+        if ($privateKeyFile === '') {
+            throw new InvalidArgumentException('privateKeyFile cannot be empty');
+        }
+
+        return $privateKeyFile;
+    }
+
+    /**
+     * @param string|null $roleName
+     */
+    public static function roleName($roleName)
+    {
+        if ($roleName === null) {
+            return;
+        }
+
+        if (!is_string($roleName)) {
+            throw new InvalidArgumentException('roleName must be a string');
+        }
+
+        if ($roleName === '') {
+            throw new InvalidArgumentException('roleName cannot be empty');
+        }
+    }
+
+    /**
+     * @param boolean|null $disableIMDSv1
+     */
+    public static function disableIMDSv1($disableIMDSv1)
+    {
+        if (!is_bool($disableIMDSv1)) {
+            throw new InvalidArgumentException('disableIMDSv1 must be a boolean');
+        }
+    }
+
+
+    /**
+     * @param string|null $roleArn
+     */
+    public static function roleArn($roleArn)
+    {
+        if (is_null($roleArn) || $roleArn === '') {
+            throw new InvalidArgumentException('roleArn cannot be empty');
+        }
+    }
+
+    /**
+     * @param string|null $roleArn
+     */
+    public static function oidcProviderArn($oidcProviderArn)
+    {
+        if (is_null($oidcProviderArn) || $oidcProviderArn === '') {
+            throw new InvalidArgumentException('oidcProviderArn cannot be empty');
+        }
+    }
+
+    /**
+     * @param string|null $roleArn
+     */
+    public static function oidcTokenFilePath($oidcTokenFilePath)
+    {
+        if (is_null($oidcTokenFilePath) || $oidcTokenFilePath === '') {
+            throw new InvalidArgumentException('oidcTokenFilePath cannot be empty');
+        }
+    }
+
+    /**
+     * @param string $accessKeyId
+     * @param string $accessKeySecret
+     */
+    public static function accessKey($accessKeyId, $accessKeySecret)
+    {
+        if (!is_string($accessKeyId)) {
+            throw new InvalidArgumentException('accessKeyId must be a string');
+        }
+
+        if ($accessKeyId === '') {
+            throw new InvalidArgumentException('accessKeyId cannot be empty');
+        }
+
+        if (!is_string($accessKeySecret)) {
+            throw new InvalidArgumentException('accessKeySecret must be a string');
+        }
+
+        if ($accessKeySecret === '') {
+            throw new InvalidArgumentException('accessKeySecret cannot be empty');
+        }
+    }
+
+    /**
+     * @param string $securityToken
+     */
+    public static function securityToken($securityToken)
+    {
+        if (!is_string($securityToken)) {
+            throw new InvalidArgumentException('securityToken must be a string');
+        }
+
+        if ($securityToken === '') {
+            throw new InvalidArgumentException('securityToken cannot be empty');
+        }
+    }
+
+    /**
+     * @param int $expiration
+     */
+    public static function expiration($expiration)
+    {
+        if (!is_int($expiration)) {
+            throw new InvalidArgumentException('expiration must be a int');
+        }
+    }
+
+    /**
+     * @param int $connectTimeout
+     * @param int $readTimeout
+     */
+    public static function timeout($connectTimeout, $readTimeout)
+    {
+        if (!is_int($connectTimeout)) {
+            throw new InvalidArgumentException('connectTimeout must be a int');
+        }
+
+        if (!is_int($readTimeout)) {
+            throw new InvalidArgumentException('readTimeout must be a int');
+        }
+    }
+
+    /**
+     * @param string|null $credentialsURI
+     */
+    public static function credentialsURI($credentialsURI)
+    {
+        if (!is_string($credentialsURI)) {
+            throw new InvalidArgumentException('credentialsURI must be a string');
+        }
+
+        if ($credentialsURI === '') {
+            throw new InvalidArgumentException('credentialsURI cannot be empty');
+        }
+    }
+
+    /**
+     * @param boolean|null $reuseLastProviderEnabled
+     */
+    public static function reuseLastProviderEnabled($reuseLastProviderEnabled)
+    {
+        if (!is_bool($reuseLastProviderEnabled)) {
+            throw new InvalidArgumentException('reuseLastProviderEnabled must be a boolean');
+        }
+    }
+}

+ 251 - 0
vendor/alibabacloud/credentials/src/Utils/Helper.php

@@ -0,0 +1,251 @@
+<?php
+
+namespace AlibabaCloud\Credentials\Utils;
+
+use AlibabaCloud\Credentials\Credential;
+use org\bovigo\vfs\vfsStream;
+use Closure;
+
+/**
+ * Class Helper
+ *
+ * @package AlibabaCloud\Credentials\Utils
+ */
+class Helper
+{
+    /**
+     * @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;
+    }
+
+    /**
+     * @param      $filename
+     *
+     * @return bool
+     */
+    public static function inOpenBasedir($filename)
+    {
+        $open_basedir = ini_get('open_basedir');
+        if (!$open_basedir) {
+            return true;
+        }
+        if (0 === strpos($filename, vfsStream::SCHEME)) {
+            // 虚拟文件忽略
+            return true;
+        }
+
+        $dirs = explode(PATH_SEPARATOR, $open_basedir);
+
+        return empty($dirs) || self::inDir($filename, $dirs);
+    }
+
+    /**
+     * @param string $filename
+     * @param array  $dirs
+     *
+     * @return bool
+     */
+    public static function inDir($filename, array $dirs)
+    {
+        foreach ($dirs as $dir) {
+            if ($dir[strlen($dir) - 1] !== DIRECTORY_SEPARATOR) {
+                $dir .= DIRECTORY_SEPARATOR;
+            }
+
+            if (0 === strpos($filename, $dir)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * @return bool
+     */
+    public static function isWindows()
+    {
+        return PATH_SEPARATOR === ';';
+    }
+
+    /**
+     * @param $key
+     *
+     * @return bool|mixed
+     */
+    public static function envNotEmpty($key)
+    {
+        $value = self::env($key, false);
+        if ($value) {
+            return $value;
+        }
+
+        return false;
+    }
+
+    /**
+     * Gets the value of an environment variable.
+     *
+     * @param string $key
+     * @param mixed  $default
+     *
+     * @return mixed
+     */
+    public static function env($key, $default = null)
+    {
+        $value = getenv($key);
+
+        if ($value === false) {
+            return self::value($default);
+        }
+
+        if (self::envSubstr($value)) {
+            return substr($value, 1, -1);
+        }
+
+        return self::envConversion($value);
+    }
+
+    /**
+     * Return the default value of the given value.
+     *
+     * @param mixed $value
+     *
+     * @return mixed
+     */
+    public static function value($value)
+    {
+        return $value instanceof Closure ? $value() : $value;
+    }
+
+    /**
+     * @param $value
+     *
+     * @return bool
+     */
+    public static function envSubstr($value)
+    {
+        return ($valueLength = strlen($value)) > 1
+            && strpos($value, '"') === 0
+            && $value[$valueLength - 1] === '"';
+    }
+
+    /**
+     * @param $value
+     *
+     * @return bool|string|null
+     */
+    public static 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;
+    }
+
+    /**
+     * Gets the environment's HOME directory.
+     *
+     * @return null|string
+     */
+    public static function getHomeDirectory()
+    {
+        if (getenv('HOME')) {
+            return getenv('HOME');
+        }
+
+        return (getenv('HOMEDRIVE') && getenv('HOMEPATH'))
+            ? getenv('HOMEDRIVE') . getenv('HOMEPATH')
+            : null;
+    }
+
+    /**
+     * @param mixed ...$parameters
+     *
+     * @codeCoverageIgnore
+     */
+    public static function dd(...$parameters)
+    {
+        dump(...$parameters);
+        exit;
+    }
+
+    /**
+     * Snake to camel case.
+     *
+     * @param string $str
+     *
+     * @return string
+     */
+    public static function snakeToCamelCase($str)
+    {
+        $components = explode('_', $str);
+        $camelCaseStr = $components[0];
+        for ($i = 1; $i < count($components); $i++) {
+            $camelCaseStr .= ucfirst($components[$i]);
+        }
+        return $camelCaseStr;
+    }
+
+    /**
+     * Get user agent.
+     *
+     * @param string $userAgent
+     *
+     * @return string
+     */
+    public static function getUserAgent()
+    {
+        return sprintf('AlibabaCloud (%s; %s) PHP/%s Credentials/%s TeaDSL/1', PHP_OS, \PHP_SAPI, PHP_VERSION, Credential::VERSION);
+    }
+
+    /**
+     * @param array $arrays
+     * @param string $key
+     *
+     * @return mix
+     */
+    public static function unsetReturnNull(array $arrays, $key)
+    {
+        if(isset($arrays[$key])) {
+            return $arrays[$key];
+        }
+        return null;
+    }
+}

+ 120 - 0
vendor/alibabacloud/credentials/src/Utils/MockTrait.php

@@ -0,0 +1,120 @@
+<?php
+
+namespace AlibabaCloud\Credentials\Utils;
+
+use Exception;
+use GuzzleHttp\Exception\RequestException;
+use GuzzleHttp\Handler\MockHandler;
+use GuzzleHttp\Psr7\Response;
+use GuzzleHttp\Middleware;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+
+/**
+ * Trait MockTrait
+ *
+ * @package AlibabaCloud\Credentials\Utils
+ */
+trait MockTrait
+{
+    /**
+     * @var array
+     */
+    private static $mockQueue = [];
+
+    /**
+     * @var array
+     */
+    private static $history = [];
+
+    /**
+     * @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);
+    }
+
+    /**
+     * @return MockHandler
+     */
+    public static function getHandlerHistory()
+    {
+         return Middleware::history(self::$history);
+    }
+
+    /**
+     * @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();
+    }
+
+    /**
+     * @return void
+     */
+    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;
+    }
+
+    /**
+     * @return array
+     */
+    public static function getHistroy()
+    {
+        return self::$history;
+    }
+}

+ 15 - 0
vendor/alibabacloud/darabonba-openapi/.gitignore

@@ -0,0 +1,15 @@
+composer.phar
+/vendor/
+
+# Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control
+# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
+composer.lock
+
+.vscode/
+.idea
+.DS_Store
+
+cache/
+*.cache
+runtime/
+.php_cs.cache

+ 65 - 0
vendor/alibabacloud/darabonba-openapi/.php_cs.dist

@@ -0,0 +1,65 @@
+<?php
+/*
+ * This document has been generated with
+ * https://mlocati.github.io/php-cs-fixer-configurator/#version:2.15|configurator
+ * you can change this configuration by importing this file.
+ */
+
+return PhpCsFixer\Config::create()
+    ->setRiskyAllowed(true)
+    ->setIndent('    ')
+    ->setRules([
+        '@PSR2'                                       => true,
+        '@PhpCsFixer'                                 => true,
+        '@Symfony:risky'                              => true,
+        'concat_space'                                => ['spacing' => 'one'],
+        'array_syntax'                                => ['syntax' => 'short'],
+        'array_indentation'                           => true,
+        'combine_consecutive_unsets'                  => true,
+        'method_separation'                           => true,
+        'single_quote'                                => true,
+        'declare_equal_normalize'                     => true,
+        'function_typehint_space'                     => true,
+        'hash_to_slash_comment'                       => true,
+        'include'                                     => true,
+        'lowercase_cast'                              => true,
+        'no_multiline_whitespace_before_semicolons'   => true,
+        'no_leading_import_slash'                     => true,
+        'no_multiline_whitespace_around_double_arrow' => true,
+        'no_spaces_around_offset'                     => true,
+        'no_unneeded_control_parentheses'             => true,
+        'no_unused_imports'                           => true,
+        'no_whitespace_before_comma_in_array'         => true,
+        'no_whitespace_in_blank_line'                 => true,
+        'object_operator_without_whitespace'          => true,
+        'single_blank_line_before_namespace'          => true,
+        'single_class_element_per_statement'          => true,
+        'space_after_semicolon'                       => true,
+        'standardize_not_equals'                      => true,
+        'ternary_operator_spaces'                     => true,
+        'trailing_comma_in_multiline_array'           => true,
+        'trim_array_spaces'                           => true,
+        'unary_operator_spaces'                       => true,
+        'whitespace_after_comma_in_array'             => true,
+        'no_extra_consecutive_blank_lines'            => [
+            'curly_brace_block',
+            'extra',
+            'parenthesis_brace_block',
+            'square_brace_block',
+            'throw',
+            'use',
+        ],
+        'binary_operator_spaces'       => [
+            'align_double_arrow' => true,
+            'align_equals'       => true,
+        ],
+        'braces'                                    => [
+            'allow_single_line_closure' => true,
+        ],
+    ])
+    ->setFinder(
+        PhpCsFixer\Finder::create()
+            ->exclude('vendor')
+            ->exclude('tests')
+            ->in(__DIR__)
+  );

+ 31 - 0
vendor/alibabacloud/darabonba-openapi/README-CN.md

@@ -0,0 +1,31 @@
+[English](README.md) | 简体中文
+
+![](https://aliyunsdk-pages.alicdn.com/icons/AlibabaCloud.svg)
+
+## Alibaba Cloud OpenApi Client
+
+## 安装
+
+### Composer
+
+```bash
+composer require alibabacloud/darabonba-openapi
+```
+
+## 问题
+
+[提交 Issue](https://github.com/aliyun/darabonba-openapi/issues/new),不符合指南的问题可能会立即关闭。
+
+## 发行说明
+
+每个版本的详细更改记录在[发行说明](./ChangeLog.txt)中。
+
+## 相关
+
+* [最新源码](https://github.com/aliyun/darabonba-openapi)
+
+## 许可证
+
+[Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0)
+
+Copyright (c) 2009-present, Alibaba Cloud All rights reserved.

+ 31 - 0
vendor/alibabacloud/darabonba-openapi/README.md

@@ -0,0 +1,31 @@
+English | [简体中文](README-CN.md)
+
+![](https://aliyunsdk-pages.alicdn.com/icons/AlibabaCloud.svg)
+
+## Alibaba Cloud OpenApi Client
+
+## Installation
+
+### Composer
+
+```bash
+composer require alibabacloud/darabonba-openapi
+```
+
+## Issues
+
+[Opening an Issue](https://github.com/aliyun/darabonba-openapi/issues/new), Issues not conforming to the guidelines may be closed immediately.
+
+## Changelog
+
+Detailed changes for each release are documented in the [release notes](./ChangeLog.txt).
+
+## References
+
+* [Latest Release](https://github.com/aliyun/darabonba-openapi)
+
+## License
+
+[Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0)
+
+Copyright (c) 2009-present, Alibaba Cloud All rights reserved.

+ 15 - 0
vendor/alibabacloud/darabonba-openapi/autoload.php

@@ -0,0 +1,15 @@
+<?php
+
+if (file_exists(__DIR__ . \DIRECTORY_SEPARATOR . 'vendor' . \DIRECTORY_SEPARATOR . 'autoload.php')) {
+    require_once __DIR__ . \DIRECTORY_SEPARATOR . 'vendor' . \DIRECTORY_SEPARATOR . 'autoload.php';
+}
+
+spl_autoload_register(function ($class) {
+    $name = str_replace('Darabonba\\OpenApi\\', '', $class);
+    $file = __DIR__ . \DIRECTORY_SEPARATOR . 'src' . \DIRECTORY_SEPARATOR . str_replace('\\', \DIRECTORY_SEPARATOR, $name) . '.php';
+    if (file_exists($file)) {
+        require_once $file;
+        return true;
+    }
+    return false;
+});

+ 34 - 0
vendor/alibabacloud/darabonba-openapi/composer.json

@@ -0,0 +1,34 @@
+{
+  "name": "alibabacloud/darabonba-openapi",
+  "description": "Alibaba Cloud OpenApi Client",
+  "type": "library",
+  "license": "Apache-2.0",
+  "authors": [
+    {
+      "name": "Alibaba Cloud SDK",
+      "email": "sdk-team@alibabacloud.com"
+    }
+  ],
+  "require": {
+    "php": ">5.5",
+    "alibabacloud/tea-utils": "^0.2.21",
+    "alibabacloud/credentials": "^1.1",
+    "alibabacloud/openapi-util": "^0.1.10|^0.2.1",
+    "alibabacloud/gateway-spi": "^1",
+    "alibabacloud/tea-xml": "^0.2"
+  },
+  "autoload": {
+    "psr-4": {
+      "Darabonba\\OpenApi\\": "src"
+    }
+  },
+  "scripts": {
+    "fixer": "php-cs-fixer fix ./"
+  },
+  "config": {
+    "sort-packages": true,
+    "preferred-install": "dist",
+    "optimize-autoloader": true
+  },
+  "prefer-stable": true
+}

+ 31 - 0
vendor/alibabacloud/darabonba-openapi/phpunit.xml

@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit bootstrap="./tests/bootstrap.php" colors="true" processIsolation="false" stopOnFailure="false"
+         convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true"
+         testSuiteLoaderFile="phpunit/src/Runner/StandardTestSuiteLoader.php">
+
+    <testsuites>
+        <testsuite name="All">
+            <directory>tests</directory>
+        </testsuite>
+        <testsuite name="Unit">
+            <directory suffix="Test.php">./tests/Unit</directory>
+        </testsuite>
+    </testsuites>
+
+    <groups>
+        <exclude>
+            <group>integration</group>
+        </exclude>
+    </groups>
+
+    <logging>
+        <log type="coverage-html" target="cache/coverage" lowUpperBound="35" highLowerBound="70"/>
+        <log type="coverage-clover" target="cache/coverage.clover"/>
+    </logging>
+
+    <filter>
+        <whitelist processUncoveredFilesFromWhitelist="true">
+            <directory suffix=".php">./src</directory>
+        </whitelist>
+    </filter>
+</phpunit>

+ 450 - 0
vendor/alibabacloud/darabonba-openapi/src/Models/Config.php

@@ -0,0 +1,450 @@
+<?php
+
+// This file is auto-generated, don't edit it. Thanks.
+namespace Darabonba\OpenApi\Models;
+
+use AlibabaCloud\Tea\Model;
+use AlibabaCloud\Credentials\Credential;
+
+use Darabonba\OpenApi\Models\GlobalParameters;
+
+/**
+ * Model for initing client
+ */
+class Config extends Model
+{
+    protected $_default = [
+        'accessKeyId' => '',
+        'accessKeySecret' => '',
+        'securityToken' => '',
+        'bearerToken' => '',
+        'protocol' => 'http',
+        'method' => '',
+        'regionId' => '',
+        'readTimeout' => '',
+        'connectTimeout' => '',
+        'httpProxy' => '',
+        'httpsProxy' => '',
+        'credential' => '',
+        'endpoint' => '',
+        'noProxy' => '',
+        'maxIdleConns' => '',
+        'network' => '',
+        'userAgent' => '',
+        'suffix' => '',
+        'socks5Proxy' => '',
+        'socks5NetWork' => '',
+        'endpointType' => '',
+        'openPlatformEndpoint' => '',
+        'type' => '',
+        'signatureVersion' => '',
+        'signatureAlgorithm' => '',
+        'key' => '',
+        'cert' => '',
+        'ca' => '',
+    ];
+    public function validate()
+    {
+    }
+    public function toMap()
+    {
+        $res = [];
+        if (null !== $this->accessKeyId) {
+            $res['accessKeyId'] = $this->accessKeyId;
+        }
+        if (null !== $this->accessKeySecret) {
+            $res['accessKeySecret'] = $this->accessKeySecret;
+        }
+        if (null !== $this->securityToken) {
+            $res['securityToken'] = $this->securityToken;
+        }
+        if (null !== $this->bearerToken) {
+            $res['bearerToken'] = $this->bearerToken;
+        }
+        if (null !== $this->protocol) {
+            $res['protocol'] = $this->protocol;
+        }
+        if (null !== $this->method) {
+            $res['method'] = $this->method;
+        }
+        if (null !== $this->regionId) {
+            $res['regionId'] = $this->regionId;
+        }
+        if (null !== $this->readTimeout) {
+            $res['readTimeout'] = $this->readTimeout;
+        }
+        if (null !== $this->connectTimeout) {
+            $res['connectTimeout'] = $this->connectTimeout;
+        }
+        if (null !== $this->httpProxy) {
+            $res['httpProxy'] = $this->httpProxy;
+        }
+        if (null !== $this->httpsProxy) {
+            $res['httpsProxy'] = $this->httpsProxy;
+        }
+        if (null !== $this->credential) {
+            $res['credential'] = null !== $this->credential ? $this->credential->toMap() : null;
+        }
+        if (null !== $this->endpoint) {
+            $res['endpoint'] = $this->endpoint;
+        }
+        if (null !== $this->noProxy) {
+            $res['noProxy'] = $this->noProxy;
+        }
+        if (null !== $this->maxIdleConns) {
+            $res['maxIdleConns'] = $this->maxIdleConns;
+        }
+        if (null !== $this->network) {
+            $res['network'] = $this->network;
+        }
+        if (null !== $this->userAgent) {
+            $res['userAgent'] = $this->userAgent;
+        }
+        if (null !== $this->suffix) {
+            $res['suffix'] = $this->suffix;
+        }
+        if (null !== $this->socks5Proxy) {
+            $res['socks5Proxy'] = $this->socks5Proxy;
+        }
+        if (null !== $this->socks5NetWork) {
+            $res['socks5NetWork'] = $this->socks5NetWork;
+        }
+        if (null !== $this->endpointType) {
+            $res['endpointType'] = $this->endpointType;
+        }
+        if (null !== $this->openPlatformEndpoint) {
+            $res['openPlatformEndpoint'] = $this->openPlatformEndpoint;
+        }
+        if (null !== $this->type) {
+            $res['type'] = $this->type;
+        }
+        if (null !== $this->signatureVersion) {
+            $res['signatureVersion'] = $this->signatureVersion;
+        }
+        if (null !== $this->signatureAlgorithm) {
+            $res['signatureAlgorithm'] = $this->signatureAlgorithm;
+        }
+        if (null !== $this->globalParameters) {
+            $res['globalParameters'] = null !== $this->globalParameters ? $this->globalParameters->toMap() : null;
+        }
+        if (null !== $this->key) {
+            $res['key'] = $this->key;
+        }
+        if (null !== $this->cert) {
+            $res['cert'] = $this->cert;
+        }
+        if (null !== $this->ca) {
+            $res['ca'] = $this->ca;
+        }
+        if (null !== $this->disableHttp2) {
+            $res['disableHttp2'] = $this->disableHttp2;
+        }
+        return $res;
+    }
+    /**
+     * @param array $map
+     * @return Config
+     */
+    public static function fromMap($map = [])
+    {
+        $model = new self();
+        if (isset($map['accessKeyId'])) {
+            $model->accessKeyId = $map['accessKeyId'];
+        }
+        if (isset($map['accessKeySecret'])) {
+            $model->accessKeySecret = $map['accessKeySecret'];
+        }
+        if (isset($map['securityToken'])) {
+            $model->securityToken = $map['securityToken'];
+        }
+        if (isset($map['bearerToken'])) {
+            $model->bearerToken = $map['bearerToken'];
+        }
+        if (isset($map['protocol'])) {
+            $model->protocol = $map['protocol'];
+        }
+        if (isset($map['method'])) {
+            $model->method = $map['method'];
+        }
+        if (isset($map['regionId'])) {
+            $model->regionId = $map['regionId'];
+        }
+        if (isset($map['readTimeout'])) {
+            $model->readTimeout = $map['readTimeout'];
+        }
+        if (isset($map['connectTimeout'])) {
+            $model->connectTimeout = $map['connectTimeout'];
+        }
+        if (isset($map['httpProxy'])) {
+            $model->httpProxy = $map['httpProxy'];
+        }
+        if (isset($map['httpsProxy'])) {
+            $model->httpsProxy = $map['httpsProxy'];
+        }
+        if (isset($map['credential'])) {
+            $model->credential = Credential::fromMap($map['credential']);
+        }
+        if (isset($map['endpoint'])) {
+            $model->endpoint = $map['endpoint'];
+        }
+        if (isset($map['noProxy'])) {
+            $model->noProxy = $map['noProxy'];
+        }
+        if (isset($map['maxIdleConns'])) {
+            $model->maxIdleConns = $map['maxIdleConns'];
+        }
+        if (isset($map['network'])) {
+            $model->network = $map['network'];
+        }
+        if (isset($map['userAgent'])) {
+            $model->userAgent = $map['userAgent'];
+        }
+        if (isset($map['suffix'])) {
+            $model->suffix = $map['suffix'];
+        }
+        if (isset($map['socks5Proxy'])) {
+            $model->socks5Proxy = $map['socks5Proxy'];
+        }
+        if (isset($map['socks5NetWork'])) {
+            $model->socks5NetWork = $map['socks5NetWork'];
+        }
+        if (isset($map['endpointType'])) {
+            $model->endpointType = $map['endpointType'];
+        }
+        if (isset($map['openPlatformEndpoint'])) {
+            $model->openPlatformEndpoint = $map['openPlatformEndpoint'];
+        }
+        if (isset($map['type'])) {
+            $model->type = $map['type'];
+        }
+        if (isset($map['signatureVersion'])) {
+            $model->signatureVersion = $map['signatureVersion'];
+        }
+        if (isset($map['signatureAlgorithm'])) {
+            $model->signatureAlgorithm = $map['signatureAlgorithm'];
+        }
+        if (isset($map['globalParameters'])) {
+            $model->globalParameters = GlobalParameters::fromMap($map['globalParameters']);
+        }
+        if (isset($map['key'])) {
+            $model->key = $map['key'];
+        }
+        if (isset($map['cert'])) {
+            $model->cert = $map['cert'];
+        }
+        if (isset($map['ca'])) {
+            $model->ca = $map['ca'];
+        }
+        if (isset($map['disableHttp2'])) {
+            $model->disableHttp2 = $map['disableHttp2'];
+        }
+        return $model;
+    }
+    /**
+     * @description accesskey id
+     * @var string
+     */
+    public $accessKeyId;
+
+    /**
+     * @description accesskey secret
+     * @var string
+     */
+    public $accessKeySecret;
+
+    /**
+     * @description security token
+     * @example a.txt
+     * @var string
+     */
+    public $securityToken;
+
+    /**
+     * @description bearer token
+     * @example the-bearer-token
+     * @var string
+     */
+    public $bearerToken;
+
+    /**
+     * @description http protocol
+     * @example http
+     * @var string
+     */
+    public $protocol;
+
+    /**
+     * @description http method
+     * @example GET
+     * @var string
+     */
+    public $method;
+
+    /**
+     * @description region id
+     * @example cn-hangzhou
+     * @var string
+     */
+    public $regionId;
+
+    /**
+     * @description read timeout
+     * @example 10
+     * @var int
+     */
+    public $readTimeout;
+
+    /**
+     * @description connect timeout
+     * @example 10
+     * @var int
+     */
+    public $connectTimeout;
+
+    /**
+     * @description http proxy
+     * @example http://localhost
+     * @var string
+     */
+    public $httpProxy;
+
+    /**
+     * @description https proxy
+     * @example https://localhost
+     * @var string
+     */
+    public $httpsProxy;
+
+    /**
+     * @description credential
+     * @example 
+     * @var Credential
+     */
+    public $credential;
+
+    /**
+     * @description endpoint
+     * @example cs.aliyuncs.com
+     * @var string
+     */
+    public $endpoint;
+
+    /**
+     * @description proxy white list
+     * @example http://localhost
+     * @var string
+     */
+    public $noProxy;
+
+    /**
+     * @description max idle conns
+     * @example 3
+     * @var int
+     */
+    public $maxIdleConns;
+
+    /**
+     * @description network for endpoint
+     * @example public
+     * @var string
+     */
+    public $network;
+
+    /**
+     * @description user agent
+     * @example Alibabacloud/1
+     * @var string
+     */
+    public $userAgent;
+
+    /**
+     * @description suffix for endpoint
+     * @example aliyun
+     * @var string
+     */
+    public $suffix;
+
+    /**
+     * @description socks5 proxy
+     * @var string
+     */
+    public $socks5Proxy;
+
+    /**
+     * @description socks5 network
+     * @example TCP
+     * @var string
+     */
+    public $socks5NetWork;
+
+    /**
+     * @description endpoint type
+     * @example internal
+     * @var string
+     */
+    public $endpointType;
+
+    /**
+     * @description OpenPlatform endpoint
+     * @example openplatform.aliyuncs.com
+     * @var string
+     */
+    public $openPlatformEndpoint;
+
+    /**
+     * @description credential type
+     * @example access_key
+     * @deprecated
+     * @var string
+     */
+    public $type;
+
+    /**
+     * @description Signature Version
+     * @example v1
+     * @var string
+     */
+    public $signatureVersion;
+
+    /**
+     * @description Signature Algorithm
+     * @example ACS3-HMAC-SHA256
+     * @var string
+     */
+    public $signatureAlgorithm;
+
+    /**
+     * @description Global Parameters
+     * @var GlobalParameters
+     */
+    public $globalParameters;
+
+    /**
+     * @description privite key for client certificate
+     * @example MIIEvQ
+     * @var string
+     */
+    public $key;
+
+    /**
+     * @description client certificate
+     * @example -----BEGIN CERTIFICATE-----xxx-----END CERTIFICATE-----
+     * @var string
+     */
+    public $cert;
+
+    /**
+     * @description server certificate
+     * @example -----BEGIN CERTIFICATE-----xxx-----END CERTIFICATE-----
+     * @var string
+     */
+    public $ca;
+
+    /**
+     * @description disable HTTP/2
+     * @example false
+     * @var bool
+     */
+    public $disableHttp2;
+
+}

+ 43 - 0
vendor/alibabacloud/darabonba-openapi/src/Models/GlobalParameters.php

@@ -0,0 +1,43 @@
+<?php
+
+// This file is auto-generated, don't edit it. Thanks.
+namespace Darabonba\OpenApi\Models;
+
+use AlibabaCloud\Tea\Model;
+
+class GlobalParameters extends Model
+{
+    public function validate()
+    {
+    }
+    public function toMap()
+    {
+        $res = [];
+        if (null !== $this->headers) {
+            $res['headers'] = $this->headers;
+        }
+        if (null !== $this->queries) {
+            $res['queries'] = $this->queries;
+        }
+        return $res;
+    }
+    /**
+     * @param array $map
+     * @return GlobalParameters
+     */
+    public static function fromMap($map = [])
+    {
+        $model = new self();
+        if (isset($map['headers'])) {
+            $model->headers = $map['headers'];
+        }
+        if (isset($map['queries'])) {
+            $model->queries = $map['queries'];
+        }
+        return $model;
+    }
+    public $headers;
+
+    public $queries;
+
+}

+ 75 - 0
vendor/alibabacloud/darabonba-openapi/src/Models/OpenApiRequest.php

@@ -0,0 +1,75 @@
+<?php
+
+// This file is auto-generated, don't edit it. Thanks.
+namespace Darabonba\OpenApi\Models;
+
+use AlibabaCloud\Tea\Model;
+
+class OpenApiRequest extends Model
+{
+    public function validate()
+    {
+    }
+    public function toMap()
+    {
+        $res = [];
+        if (null !== $this->headers) {
+            $res['headers'] = $this->headers;
+        }
+        if (null !== $this->query) {
+            $res['query'] = $this->query;
+        }
+        if (null !== $this->body) {
+            $res['body'] = $this->body;
+        }
+        if (null !== $this->stream) {
+            $res['stream'] = $this->stream;
+        }
+        if (null !== $this->hostMap) {
+            $res['hostMap'] = $this->hostMap;
+        }
+        if (null !== $this->endpointOverride) {
+            $res['endpointOverride'] = $this->endpointOverride;
+        }
+        return $res;
+    }
+    /**
+     * @param array $map
+     * @return OpenApiRequest
+     */
+    public static function fromMap($map = [])
+    {
+        $model = new self();
+        if (isset($map['headers'])) {
+            $model->headers = $map['headers'];
+        }
+        if (isset($map['query'])) {
+            $model->query = $map['query'];
+        }
+        if (isset($map['body'])) {
+            $model->body = $map['body'];
+        }
+        if (isset($map['stream'])) {
+            $model->stream = $map['stream'];
+        }
+        if (isset($map['hostMap'])) {
+            $model->hostMap = $map['hostMap'];
+        }
+        if (isset($map['endpointOverride'])) {
+            $model->endpointOverride = $map['endpointOverride'];
+        }
+        return $model;
+    }
+    public $headers;
+
+    public $query;
+
+    public $body;
+
+    public $stream;
+
+    public $hostMap;
+
+    public $endpointOverride;
+
+}

+ 131 - 0
vendor/alibabacloud/darabonba-openapi/src/Models/Params.php

@@ -0,0 +1,131 @@
+<?php
+
+// This file is auto-generated, don't edit it. Thanks.
+namespace Darabonba\OpenApi\Models;
+
+use AlibabaCloud\Tea\Model;
+
+class Params extends Model
+{
+    public function validate()
+    {
+        Model::validateRequired('action', $this->action, true);
+        Model::validateRequired('version', $this->version, true);
+        Model::validateRequired('protocol', $this->protocol, true);
+        Model::validateRequired('pathname', $this->pathname, true);
+        Model::validateRequired('method', $this->method, true);
+        Model::validateRequired('authType', $this->authType, true);
+        Model::validateRequired('bodyType', $this->bodyType, true);
+        Model::validateRequired('reqBodyType', $this->reqBodyType, true);
+    }
+    public function toMap()
+    {
+        $res = [];
+        if (null !== $this->action) {
+            $res['action'] = $this->action;
+        }
+        if (null !== $this->version) {
+            $res['version'] = $this->version;
+        }
+        if (null !== $this->protocol) {
+            $res['protocol'] = $this->protocol;
+        }
+        if (null !== $this->pathname) {
+            $res['pathname'] = $this->pathname;
+        }
+        if (null !== $this->method) {
+            $res['method'] = $this->method;
+        }
+        if (null !== $this->authType) {
+            $res['authType'] = $this->authType;
+        }
+        if (null !== $this->bodyType) {
+            $res['bodyType'] = $this->bodyType;
+        }
+        if (null !== $this->reqBodyType) {
+            $res['reqBodyType'] = $this->reqBodyType;
+        }
+        if (null !== $this->style) {
+            $res['style'] = $this->style;
+        }
+        return $res;
+    }
+    /**
+     * @param array $map
+     * @return Params
+     */
+    public static function fromMap($map = [])
+    {
+        $model = new self();
+        if (isset($map['action'])) {
+            $model->action = $map['action'];
+        }
+        if (isset($map['version'])) {
+            $model->version = $map['version'];
+        }
+        if (isset($map['protocol'])) {
+            $model->protocol = $map['protocol'];
+        }
+        if (isset($map['pathname'])) {
+            $model->pathname = $map['pathname'];
+        }
+        if (isset($map['method'])) {
+            $model->method = $map['method'];
+        }
+        if (isset($map['authType'])) {
+            $model->authType = $map['authType'];
+        }
+        if (isset($map['bodyType'])) {
+            $model->bodyType = $map['bodyType'];
+        }
+        if (isset($map['reqBodyType'])) {
+            $model->reqBodyType = $map['reqBodyType'];
+        }
+        if (isset($map['style'])) {
+            $model->style = $map['style'];
+        }
+        return $model;
+    }
+    /**
+     * @var string
+     */
+    public $action;
+
+    /**
+     * @var string
+     */
+    public $version;
+
+    /**
+     * @var string
+     */
+    public $protocol;
+
+    /**
+     * @var string
+     */
+    public $pathname;
+
+    /**
+     * @var string
+     */
+    public $method;
+
+    /**
+     * @var string
+     */
+    public $authType;
+
+    /**
+     * @var string
+     */
+    public $bodyType;
+
+    /**
+     * @var string
+     */
+    public $reqBodyType;
+
+    public $style;
+
+}

+ 1274 - 0
vendor/alibabacloud/darabonba-openapi/src/OpenApiClient.php

@@ -0,0 +1,1274 @@
+<?php
+
+// This file is auto-generated, don't edit it. Thanks.
+namespace Darabonba\OpenApi;
+
+use AlibabaCloud\Tea\Utils\Utils;
+use AlibabaCloud\Tea\Exception\TeaError;
+use AlibabaCloud\Credentials\Credential;
+use \Exception;
+use AlibabaCloud\Tea\Exception\TeaUnableRetryError;
+use AlibabaCloud\Tea\Tea;
+use AlibabaCloud\Tea\Request;
+use AlibabaCloud\OpenApiUtil\OpenApiUtilClient;
+use AlibabaCloud\Tea\XML\XML;
+use Darabonba\GatewaySpi\Client;
+
+use AlibabaCloud\Credentials\Credential\Config;
+use Darabonba\OpenApi\Models\OpenApiRequest;
+use AlibabaCloud\Tea\Utils\Utils\RuntimeOptions;
+use Darabonba\OpenApi\Models\Params;
+use Darabonba\GatewaySpi\Models\InterceptorContext\configuration;
+use Darabonba\GatewaySpi\Models\InterceptorContext;
+use Darabonba\GatewaySpi\Models\AttributeMap;
+use Darabonba\GatewaySpi\Models\InterceptorContext\response;
+
+/**
+ * This is for OpenApi SDK
+ */
+class OpenApiClient
+{
+    protected $_endpoint;
+
+    protected $_regionId;
+
+    protected $_protocol;
+
+    protected $_method;
+
+    protected $_userAgent;
+
+    protected $_endpointRule;
+
+    protected $_endpointMap;
+
+    protected $_suffix;
+
+    protected $_readTimeout;
+
+    protected $_connectTimeout;
+
+    protected $_httpProxy;
+
+    protected $_httpsProxy;
+
+    protected $_socks5Proxy;
+
+    protected $_socks5NetWork;
+
+    protected $_noProxy;
+
+    protected $_network;
+
+    protected $_productId;
+
+    protected $_maxIdleConns;
+
+    protected $_endpointType;
+
+    protected $_openPlatformEndpoint;
+
+    protected $_credential;
+
+    protected $_signatureVersion;
+
+    protected $_signatureAlgorithm;
+
+    protected $_headers;
+
+    protected $_spi;
+
+    protected $_globalParameters;
+
+    protected $_key;
+
+    protected $_cert;
+
+    protected $_ca;
+
+    protected $_disableHttp2;
+
+    /**
+     * Init client with Config
+     * @param config config contains the necessary information to create a client
+     */
+    public function __construct($config)
+    {
+        if (Utils::isUnset($config)) {
+            throw new TeaError([
+                "code" => "ParameterMissing",
+                "message" => "'config' can not be unset"
+            ]);
+        }
+        if (!Utils::empty_($config->accessKeyId) && !Utils::empty_($config->accessKeySecret)) {
+            if (!Utils::empty_($config->securityToken)) {
+                $config->type = "sts";
+            } else {
+                $config->type = "access_key";
+            }
+            $credentialConfig = new Config([
+                "accessKeyId" => $config->accessKeyId,
+                "type" => $config->type,
+                "accessKeySecret" => $config->accessKeySecret
+            ]);
+            $credentialConfig->securityToken = $config->securityToken;
+            $this->_credential = new Credential($credentialConfig);
+        } else if (!Utils::empty_($config->bearerToken)) {
+            $cc = new Config([
+                "type" => "bearer",
+                "bearerToken" => $config->bearerToken
+            ]);
+            $this->_credential = new Credential($cc);
+        } else if (!Utils::isUnset($config->credential)) {
+            $this->_credential = $config->credential;
+        }
+        $this->_endpoint = $config->endpoint;
+        $this->_endpointType = $config->endpointType;
+        $this->_network = $config->network;
+        $this->_suffix = $config->suffix;
+        $this->_protocol = $config->protocol;
+        $this->_method = $config->method;
+        $this->_regionId = $config->regionId;
+        $this->_userAgent = $config->userAgent;
+        $this->_readTimeout = $config->readTimeout;
+        $this->_connectTimeout = $config->connectTimeout;
+        $this->_httpProxy = $config->httpProxy;
+        $this->_httpsProxy = $config->httpsProxy;
+        $this->_noProxy = $config->noProxy;
+        $this->_socks5Proxy = $config->socks5Proxy;
+        $this->_socks5NetWork = $config->socks5NetWork;
+        $this->_maxIdleConns = $config->maxIdleConns;
+        $this->_signatureVersion = $config->signatureVersion;
+        $this->_signatureAlgorithm = $config->signatureAlgorithm;
+        $this->_globalParameters = $config->globalParameters;
+        $this->_key = $config->key;
+        $this->_cert = $config->cert;
+        $this->_ca = $config->ca;
+        $this->_disableHttp2 = $config->disableHttp2;
+    }
+
+    /**
+     * Encapsulate the request and invoke the network
+     * @param string $action api name
+     * @param string $version product version
+     * @param string $protocol http or https
+     * @param string $method e.g. GET
+     * @param string $authType authorization type e.g. AK
+     * @param string $bodyType response body type e.g. String
+     * @param OpenApiRequest $request object of OpenApiRequest
+     * @param RuntimeOptions $runtime which controls some details of call api, such as retry times
+     * @return array the response
+     * @throws TeaError
+     * @throws Exception
+     * @throws TeaUnableRetryError
+     */
+    public function doRPCRequest($action, $version, $protocol, $method, $authType, $bodyType, $request, $runtime)
+    {
+        $request->validate();
+        $runtime->validate();
+        $_runtime = [
+            "timeouted" => "retry",
+            "key" => Utils::defaultString($runtime->key, $this->_key),
+            "cert" => Utils::defaultString($runtime->cert, $this->_cert),
+            "ca" => Utils::defaultString($runtime->ca, $this->_ca),
+            "readTimeout" => Utils::defaultNumber($runtime->readTimeout, $this->_readTimeout),
+            "connectTimeout" => Utils::defaultNumber($runtime->connectTimeout, $this->_connectTimeout),
+            "httpProxy" => Utils::defaultString($runtime->httpProxy, $this->_httpProxy),
+            "httpsProxy" => Utils::defaultString($runtime->httpsProxy, $this->_httpsProxy),
+            "noProxy" => Utils::defaultString($runtime->noProxy, $this->_noProxy),
+            "socks5Proxy" => Utils::defaultString($runtime->socks5Proxy, $this->_socks5Proxy),
+            "socks5NetWork" => Utils::defaultString($runtime->socks5NetWork, $this->_socks5NetWork),
+            "maxIdleConns" => Utils::defaultNumber($runtime->maxIdleConns, $this->_maxIdleConns),
+            "retry" => [
+                "retryable" => $runtime->autoretry,
+                "maxAttempts" => Utils::defaultNumber($runtime->maxAttempts, 3)
+            ],
+            "backoff" => [
+                "policy" => Utils::defaultString($runtime->backoffPolicy, "no"),
+                "period" => Utils::defaultNumber($runtime->backoffPeriod, 1)
+            ],
+            "ignoreSSL" => $runtime->ignoreSSL
+        ];
+        $_lastRequest = null;
+        $_lastException = null;
+        $_now = time();
+        $_retryTimes = 0;
+        while (Tea::allowRetry(@$_runtime["retry"], $_retryTimes, $_now)) {
+            if ($_retryTimes > 0) {
+                $_backoffTime = Tea::getBackoffTime(@$_runtime["backoff"], $_retryTimes);
+                if ($_backoffTime > 0) {
+                    Tea::sleep($_backoffTime);
+                }
+            }
+            $_retryTimes = $_retryTimes + 1;
+            try {
+                $_request = new Request();
+                $_request->protocol = Utils::defaultString($this->_protocol, $protocol);
+                $_request->method = $method;
+                $_request->pathname = "/";
+                $globalQueries = [];
+                $globalHeaders = [];
+                if (!Utils::isUnset($this->_globalParameters)) {
+                    $globalParams = $this->_globalParameters;
+                    if (!Utils::isUnset($globalParams->queries)) {
+                        $globalQueries = $globalParams->queries;
+                    }
+                    if (!Utils::isUnset($globalParams->headers)) {
+                        $globalHeaders = $globalParams->headers;
+                    }
+                }
+                $extendsHeaders = [];
+                $extendsQueries = [];
+                if (!Utils::isUnset($runtime->extendsParameters)) {
+                    $extendsParameters = $runtime->extendsParameters;
+                    if (!Utils::isUnset($extendsParameters->headers)) {
+                        $extendsHeaders = $extendsParameters->headers;
+                    }
+                    if (!Utils::isUnset($extendsParameters->queries)) {
+                        $extendsQueries = $extendsParameters->queries;
+                    }
+                }
+                $_request->query = Tea::merge([
+                    "Action" => $action,
+                    "Format" => "json",
+                    "Version" => $version,
+                    "Timestamp" => OpenApiUtilClient::getTimestamp(),
+                    "SignatureNonce" => Utils::getNonce()
+                ], $globalQueries, $extendsQueries, $request->query);
+                $headers = $this->getRpcHeaders();
+                if (Utils::isUnset($headers)) {
+                    // endpoint is setted in product client
+                    $_request->headers = Tea::merge([
+                        "host" => $this->_endpoint,
+                        "x-acs-version" => $version,
+                        "x-acs-action" => $action,
+                        "user-agent" => $this->getUserAgent()
+                    ], $globalHeaders, $extendsHeaders);
+                } else {
+                    $_request->headers = Tea::merge([
+                        "host" => $this->_endpoint,
+                        "x-acs-version" => $version,
+                        "x-acs-action" => $action,
+                        "user-agent" => $this->getUserAgent()
+                    ], $globalHeaders, $extendsHeaders, $headers);
+                }
+                if (!Utils::isUnset($request->body)) {
+                    $m = Utils::assertAsMap($request->body);
+                    $tmp = Utils::anyifyMapValue(OpenApiUtilClient::query($m));
+                    $_request->body = Utils::toFormString($tmp);
+                    $_request->headers["content-type"] = "application/x-www-form-urlencoded";
+                }
+                if (!Utils::equalString($authType, "Anonymous")) {
+                    $credentialType = $this->getType();
+                    if (Utils::equalString($credentialType, "bearer")) {
+                        $bearerToken = $this->getBearerToken();
+                        $_request->query["BearerToken"] = $bearerToken;
+                        $_request->query["SignatureType"] = "BEARERTOKEN";
+                    } else {
+                        $accessKeyId = $this->getAccessKeyId();
+                        $accessKeySecret = $this->getAccessKeySecret();
+                        $securityToken = $this->getSecurityToken();
+                        if (!Utils::empty_($securityToken)) {
+                            $_request->query["SecurityToken"] = $securityToken;
+                        }
+                        $_request->query["SignatureMethod"] = "HMAC-SHA1";
+                        $_request->query["SignatureVersion"] = "1.0";
+                        $_request->query["AccessKeyId"] = $accessKeyId;
+                        $t = null;
+                        if (!Utils::isUnset($request->body)) {
+                            $t = Utils::assertAsMap($request->body);
+                        }
+                        $signedParam = Tea::merge($_request->query, OpenApiUtilClient::query($t));
+                        $_request->query["Signature"] = OpenApiUtilClient::getRPCSignature($signedParam, $_request->method, $accessKeySecret);
+                    }
+                }
+                $_lastRequest = $_request;
+                $_response = Tea::send($_request, $_runtime);
+                if (Utils::is4xx($_response->statusCode) || Utils::is5xx($_response->statusCode)) {
+                    $_res = Utils::readAsJSON($_response->body);
+                    $err = Utils::assertAsMap($_res);
+                    $requestId = self::defaultAny(@$err["RequestId"], @$err["requestId"]);
+                    @$err["statusCode"] = $_response->statusCode;
+                    throw new TeaError([
+                        "code" => "" . (string) (self::defaultAny(@$err["Code"], @$err["code"])) . "",
+                        "message" => "code: " . (string) ($_response->statusCode) . ", " . (string) (self::defaultAny(@$err["Message"], @$err["message"])) . " request id: " . (string) ($requestId) . "",
+                        "data" => $err,
+                        "description" => "" . (string) (self::defaultAny(@$err["Description"], @$err["description"])) . "",
+                        "accessDeniedDetail" => self::defaultAny(@$err["AccessDeniedDetail"], @$err["accessDeniedDetail"])
+                    ]);
+                }
+                if (Utils::equalString($bodyType, "binary")) {
+                    $resp = [
+                        "body" => $_response->body,
+                        "headers" => $_response->headers,
+                        "statusCode" => $_response->statusCode
+                    ];
+                    return $resp;
+                } else if (Utils::equalString($bodyType, "byte")) {
+                    $byt = Utils::readAsBytes($_response->body);
+                    return [
+                        "body" => $byt,
+                        "headers" => $_response->headers,
+                        "statusCode" => $_response->statusCode
+                    ];
+                } else if (Utils::equalString($bodyType, "string")) {
+                    $str = Utils::readAsString($_response->body);
+                    return [
+                        "body" => $str,
+                        "headers" => $_response->headers,
+                        "statusCode" => $_response->statusCode
+                    ];
+                } else if (Utils::equalString($bodyType, "json")) {
+                    $obj = Utils::readAsJSON($_response->body);
+                    $res = Utils::assertAsMap($obj);
+                    return [
+                        "body" => $res,
+                        "headers" => $_response->headers,
+                        "statusCode" => $_response->statusCode
+                    ];
+                } else if (Utils::equalString($bodyType, "array")) {
+                    $arr = Utils::readAsJSON($_response->body);
+                    return [
+                        "body" => $arr,
+                        "headers" => $_response->headers,
+                        "statusCode" => $_response->statusCode
+                    ];
+                } else {
+                    return [
+                        "headers" => $_response->headers,
+                        "statusCode" => $_response->statusCode
+                    ];
+                }
+            } catch (Exception $e) {
+                if (!($e instanceof TeaError)) {
+                    $e = new TeaError([], $e->getMessage(), $e->getCode(), $e);
+                }
+                if (Tea::isRetryable($e)) {
+                    $_lastException = $e;
+                    continue;
+                }
+                throw $e;
+            }
+        }
+        throw new TeaUnableRetryError($_lastRequest, $_lastException);
+    }
+
+    /**
+     * Encapsulate the request and invoke the network
+     * @param string $action api name
+     * @param string $version product version
+     * @param string $protocol http or https
+     * @param string $method e.g. GET
+     * @param string $authType authorization type e.g. AK
+     * @param string $pathname pathname of every api
+     * @param string $bodyType response body type e.g. String
+     * @param OpenApiRequest $request object of OpenApiRequest
+     * @param RuntimeOptions $runtime which controls some details of call api, such as retry times
+     * @return array the response
+     * @throws TeaError
+     * @throws Exception
+     * @throws TeaUnableRetryError
+     */
+    public function doROARequest($action, $version, $protocol, $method, $authType, $pathname, $bodyType, $request, $runtime)
+    {
+        $request->validate();
+        $runtime->validate();
+        $_runtime = [
+            "timeouted" => "retry",
+            "key" => Utils::defaultString($runtime->key, $this->_key),
+            "cert" => Utils::defaultString($runtime->cert, $this->_cert),
+            "ca" => Utils::defaultString($runtime->ca, $this->_ca),
+            "readTimeout" => Utils::defaultNumber($runtime->readTimeout, $this->_readTimeout),
+            "connectTimeout" => Utils::defaultNumber($runtime->connectTimeout, $this->_connectTimeout),
+            "httpProxy" => Utils::defaultString($runtime->httpProxy, $this->_httpProxy),
+            "httpsProxy" => Utils::defaultString($runtime->httpsProxy, $this->_httpsProxy),
+            "noProxy" => Utils::defaultString($runtime->noProxy, $this->_noProxy),
+            "socks5Proxy" => Utils::defaultString($runtime->socks5Proxy, $this->_socks5Proxy),
+            "socks5NetWork" => Utils::defaultString($runtime->socks5NetWork, $this->_socks5NetWork),
+            "maxIdleConns" => Utils::defaultNumber($runtime->maxIdleConns, $this->_maxIdleConns),
+            "retry" => [
+                    "retryable" => $runtime->autoretry,
+                    "maxAttempts" => Utils::defaultNumber($runtime->maxAttempts, 3)
+                ],
+            "backoff" => [
+                    "policy" => Utils::defaultString($runtime->backoffPolicy, "no"),
+                    "period" => Utils::defaultNumber($runtime->backoffPeriod, 1)
+                ],
+            "ignoreSSL" => $runtime->ignoreSSL
+        ];
+        $_lastRequest = null;
+        $_lastException = null;
+        $_now = time();
+        $_retryTimes = 0;
+        while (Tea::allowRetry(@$_runtime["retry"], $_retryTimes, $_now)) {
+            if ($_retryTimes > 0) {
+                $_backoffTime = Tea::getBackoffTime(@$_runtime["backoff"], $_retryTimes);
+                if ($_backoffTime > 0) {
+                    Tea::sleep($_backoffTime);
+                }
+            }
+            $_retryTimes = $_retryTimes + 1;
+            try {
+                $_request = new Request();
+                $_request->protocol = Utils::defaultString($this->_protocol, $protocol);
+                $_request->method = $method;
+                $_request->pathname = $pathname;
+                $globalQueries = [];
+                $globalHeaders = [];
+                if (!Utils::isUnset($this->_globalParameters)) {
+                    $globalParams = $this->_globalParameters;
+                    if (!Utils::isUnset($globalParams->queries)) {
+                        $globalQueries = $globalParams->queries;
+                    }
+                    if (!Utils::isUnset($globalParams->headers)) {
+                        $globalHeaders = $globalParams->headers;
+                    }
+                }
+                $extendsHeaders = [];
+                $extendsQueries = [];
+                if (!Utils::isUnset($runtime->extendsParameters)) {
+                    $extendsParameters = $runtime->extendsParameters;
+                    if (!Utils::isUnset($extendsParameters->headers)) {
+                        $extendsHeaders = $extendsParameters->headers;
+                    }
+                    if (!Utils::isUnset($extendsParameters->queries)) {
+                        $extendsQueries = $extendsParameters->queries;
+                    }
+                }
+                $_request->headers = Tea::merge([
+                    "date" => Utils::getDateUTCString(),
+                    "host" => $this->_endpoint,
+                    "accept" => "application/json",
+                    "x-acs-signature-nonce" => Utils::getNonce(),
+                    "x-acs-signature-method" => "HMAC-SHA1",
+                    "x-acs-signature-version" => "1.0",
+                    "x-acs-version" => $version,
+                    "x-acs-action" => $action,
+                    "user-agent" => Utils::getUserAgent($this->_userAgent)
+                ], $globalHeaders, $extendsHeaders, $request->headers);
+                if (!Utils::isUnset($request->body)) {
+                    $_request->body = Utils::toJSONString($request->body);
+                    $_request->headers["content-type"] = "application/json; charset=utf-8";
+                }
+                $_request->query = Tea::merge($globalQueries, $extendsQueries);
+                if (!Utils::isUnset($request->query)) {
+                    $_request->query = Tea::merge($_request->query, $request->query);
+                }
+                if (!Utils::equalString($authType, "Anonymous")) {
+                    $credentialType = $this->getType();
+                    if (Utils::equalString($credentialType, "bearer")) {
+                        $bearerToken = $this->getBearerToken();
+                        $_request->headers["x-acs-bearer-token"] = $bearerToken;
+                        $_request->headers["x-acs-signature-type"] = "BEARERTOKEN";
+                    } else {
+                        $accessKeyId = $this->getAccessKeyId();
+                        $accessKeySecret = $this->getAccessKeySecret();
+                        $securityToken = $this->getSecurityToken();
+                        if (!Utils::empty_($securityToken)) {
+                            $_request->headers["x-acs-accesskey-id"] = $accessKeyId;
+                            $_request->headers["x-acs-security-token"] = $securityToken;
+                        }
+                        $stringToSign = OpenApiUtilClient::getStringToSign($_request);
+                        $_request->headers["authorization"] = "acs " . $accessKeyId . ":" . OpenApiUtilClient::getROASignature($stringToSign, $accessKeySecret) . "";
+                    }
+                }
+                $_lastRequest = $_request;
+                $_response = Tea::send($_request, $_runtime);
+                if (Utils::equalNumber($_response->statusCode, 204)) {
+                    return [
+                        "headers" => $_response->headers
+                    ];
+                }
+                if (Utils::is4xx($_response->statusCode) || Utils::is5xx($_response->statusCode)) {
+                    $_res = Utils::readAsJSON($_response->body);
+                    $err = Utils::assertAsMap($_res);
+                    $requestId = self::defaultAny(@$err["RequestId"], @$err["requestId"]);
+                    $requestId = self::defaultAny($requestId, @$err["requestid"]);
+                    @$err["statusCode"] = $_response->statusCode;
+                    throw new TeaError([
+                        "code" => "" . (string) (self::defaultAny(@$err["Code"], @$err["code"])) . "",
+                        "message" => "code: " . (string) ($_response->statusCode) . ", " . (string) (self::defaultAny(@$err["Message"], @$err["message"])) . " request id: " . (string) ($requestId) . "",
+                        "data" => $err,
+                        "description" => "" . (string) (self::defaultAny(@$err["Description"], @$err["description"])) . "",
+                        "accessDeniedDetail" => self::defaultAny(@$err["AccessDeniedDetail"], @$err["accessDeniedDetail"])
+                    ]);
+                }
+                if (Utils::equalString($bodyType, "binary")) {
+                    $resp = [
+                        "body" => $_response->body,
+                        "headers" => $_response->headers,
+                        "statusCode" => $_response->statusCode
+                    ];
+                    return $resp;
+                } else if (Utils::equalString($bodyType, "byte")) {
+                    $byt = Utils::readAsBytes($_response->body);
+                    return [
+                        "body" => $byt,
+                        "headers" => $_response->headers,
+                        "statusCode" => $_response->statusCode
+                    ];
+                } else if (Utils::equalString($bodyType, "string")) {
+                    $str = Utils::readAsString($_response->body);
+                    return [
+                        "body" => $str,
+                        "headers" => $_response->headers,
+                        "statusCode" => $_response->statusCode
+                    ];
+                } else if (Utils::equalString($bodyType, "json")) {
+                    $obj = Utils::readAsJSON($_response->body);
+                    $res = Utils::assertAsMap($obj);
+                    return [
+                        "body" => $res,
+                        "headers" => $_response->headers,
+                        "statusCode" => $_response->statusCode
+                    ];
+                } else if (Utils::equalString($bodyType, "array")) {
+                    $arr = Utils::readAsJSON($_response->body);
+                    return [
+                        "body" => $arr,
+                        "headers" => $_response->headers,
+                        "statusCode" => $_response->statusCode
+                    ];
+                } else {
+                    return [
+                        "headers" => $_response->headers,
+                        "statusCode" => $_response->statusCode
+                    ];
+                }
+            } catch (Exception $e) {
+                if (!($e instanceof TeaError)) {
+                    $e = new TeaError([], $e->getMessage(), $e->getCode(), $e);
+                }
+                if (Tea::isRetryable($e)) {
+                    $_lastException = $e;
+                    continue;
+                }
+                throw $e;
+            }
+        }
+        throw new TeaUnableRetryError($_lastRequest, $_lastException);
+    }
+
+    /**
+     * Encapsulate the request and invoke the network with form body
+     * @param string $action api name
+     * @param string $version product version
+     * @param string $protocol http or https
+     * @param string $method e.g. GET
+     * @param string $authType authorization type e.g. AK
+     * @param string $pathname pathname of every api
+     * @param string $bodyType response body type e.g. String
+     * @param OpenApiRequest $request object of OpenApiRequest
+     * @param RuntimeOptions $runtime which controls some details of call api, such as retry times
+     * @return array the response
+     * @throws TeaError
+     * @throws Exception
+     * @throws TeaUnableRetryError
+     */
+    public function doROARequestWithForm($action, $version, $protocol, $method, $authType, $pathname, $bodyType, $request, $runtime)
+    {
+        $request->validate();
+        $runtime->validate();
+        $_runtime = [
+            "timeouted" => "retry",
+            "key" => Utils::defaultString($runtime->key, $this->_key),
+            "cert" => Utils::defaultString($runtime->cert, $this->_cert),
+            "ca" => Utils::defaultString($runtime->ca, $this->_ca),
+            "readTimeout" => Utils::defaultNumber($runtime->readTimeout, $this->_readTimeout),
+            "connectTimeout" => Utils::defaultNumber($runtime->connectTimeout, $this->_connectTimeout),
+            "httpProxy" => Utils::defaultString($runtime->httpProxy, $this->_httpProxy),
+            "httpsProxy" => Utils::defaultString($runtime->httpsProxy, $this->_httpsProxy),
+            "noProxy" => Utils::defaultString($runtime->noProxy, $this->_noProxy),
+            "socks5Proxy" => Utils::defaultString($runtime->socks5Proxy, $this->_socks5Proxy),
+            "socks5NetWork" => Utils::defaultString($runtime->socks5NetWork, $this->_socks5NetWork),
+            "maxIdleConns" => Utils::defaultNumber($runtime->maxIdleConns, $this->_maxIdleConns),
+            "retry" => [
+                "retryable" => $runtime->autoretry,
+                "maxAttempts" => Utils::defaultNumber($runtime->maxAttempts, 3)
+            ],
+            "backoff" => [
+                    "policy" => Utils::defaultString($runtime->backoffPolicy, "no"),
+                    "period" => Utils::defaultNumber($runtime->backoffPeriod, 1)
+                ],
+            "ignoreSSL" => $runtime->ignoreSSL
+        ];
+        $_lastRequest = null;
+        $_lastException = null;
+        $_now = time();
+        $_retryTimes = 0;
+        while (Tea::allowRetry(@$_runtime["retry"], $_retryTimes, $_now)) {
+            if ($_retryTimes > 0) {
+                $_backoffTime = Tea::getBackoffTime(@$_runtime["backoff"], $_retryTimes);
+                if ($_backoffTime > 0) {
+                    Tea::sleep($_backoffTime);
+                }
+            }
+            $_retryTimes = $_retryTimes + 1;
+            try {
+                $_request = new Request();
+                $_request->protocol = Utils::defaultString($this->_protocol, $protocol);
+                $_request->method = $method;
+                $_request->pathname = $pathname;
+                $globalQueries = [];
+                $globalHeaders = [];
+                if (!Utils::isUnset($this->_globalParameters)) {
+                    $globalParams = $this->_globalParameters;
+                    if (!Utils::isUnset($globalParams->queries)) {
+                        $globalQueries = $globalParams->queries;
+                    }
+                    if (!Utils::isUnset($globalParams->headers)) {
+                        $globalHeaders = $globalParams->headers;
+                    }
+                }
+                $extendsHeaders = [];
+                $extendsQueries = [];
+                if (!Utils::isUnset($runtime->extendsParameters)) {
+                    $extendsParameters = $runtime->extendsParameters;
+                    if (!Utils::isUnset($extendsParameters->headers)) {
+                        $extendsHeaders = $extendsParameters->headers;
+                    }
+                    if (!Utils::isUnset($extendsParameters->queries)) {
+                        $extendsQueries = $extendsParameters->queries;
+                    }
+                }
+                $_request->headers = Tea::merge([
+                    "date" => Utils::getDateUTCString(),
+                    "host" => $this->_endpoint,
+                    "accept" => "application/json",
+                    "x-acs-signature-nonce" => Utils::getNonce(),
+                    "x-acs-signature-method" => "HMAC-SHA1",
+                    "x-acs-signature-version" => "1.0",
+                    "x-acs-version" => $version,
+                    "x-acs-action" => $action,
+                    "user-agent" => Utils::getUserAgent($this->_userAgent)
+                ], $globalHeaders, $extendsHeaders, $request->headers);
+                if (!Utils::isUnset($request->body)) {
+                    $m = Utils::assertAsMap($request->body);
+                    $_request->body = OpenApiUtilClient::toForm($m);
+                    $_request->headers["content-type"] = "application/x-www-form-urlencoded";
+                }
+                $_request->query = Tea::merge($globalQueries, $extendsQueries);
+                if (!Utils::isUnset($request->query)) {
+                    $_request->query = Tea::merge($_request->query, $request->query);
+                }
+                if (!Utils::equalString($authType, "Anonymous")) {
+                    $credentialType = $this->getType();
+                    if (Utils::equalString($credentialType, "bearer")) {
+                        $bearerToken = $this->getBearerToken();
+                        $_request->headers["x-acs-bearer-token"] = $bearerToken;
+                        $_request->headers["x-acs-signature-type"] = "BEARERTOKEN";
+                    } else {
+                        $accessKeyId = $this->getAccessKeyId();
+                        $accessKeySecret = $this->getAccessKeySecret();
+                        $securityToken = $this->getSecurityToken();
+                        if (!Utils::empty_($securityToken)) {
+                            $_request->headers["x-acs-accesskey-id"] = $accessKeyId;
+                            $_request->headers["x-acs-security-token"] = $securityToken;
+                        }
+                        $stringToSign = OpenApiUtilClient::getStringToSign($_request);
+                        $_request->headers["authorization"] = "acs " . $accessKeyId . ":" . OpenApiUtilClient::getROASignature($stringToSign, $accessKeySecret) . "";
+                    }
+                }
+                $_lastRequest = $_request;
+                $_response = Tea::send($_request, $_runtime);
+                if (Utils::equalNumber($_response->statusCode, 204)) {
+                    return [
+                        "headers" => $_response->headers
+                    ];
+                }
+                if (Utils::is4xx($_response->statusCode) || Utils::is5xx($_response->statusCode)) {
+                    $_res = Utils::readAsJSON($_response->body);
+                    $err = Utils::assertAsMap($_res);
+                    @$err["statusCode"] = $_response->statusCode;
+                    throw new TeaError([
+                        "code" => "" . (string) (self::defaultAny(@$err["Code"], @$err["code"])) . "",
+                        "message" => "code: " . (string) ($_response->statusCode) . ", " . (string) (self::defaultAny(@$err["Message"], @$err["message"])) . " request id: " . (string) (self::defaultAny(@$err["RequestId"], @$err["requestId"])) . "",
+                        "data" => $err,
+                        "description" => "" . (string) (self::defaultAny(@$err["Description"], @$err["description"])) . "",
+                        "accessDeniedDetail" => self::defaultAny(@$err["AccessDeniedDetail"], @$err["accessDeniedDetail"])
+                    ]);
+                }
+                if (Utils::equalString($bodyType, "binary")) {
+                    $resp = [
+                        "body" => $_response->body,
+                        "headers" => $_response->headers,
+                        "statusCode" => $_response->statusCode
+                    ];
+                    return $resp;
+                } else if (Utils::equalString($bodyType, "byte")) {
+                    $byt = Utils::readAsBytes($_response->body);
+                    return [
+                        "body" => $byt,
+                        "headers" => $_response->headers,
+                        "statusCode" => $_response->statusCode
+                    ];
+                } else if (Utils::equalString($bodyType, "string")) {
+                    $str = Utils::readAsString($_response->body);
+                    return [
+                        "body" => $str,
+                        "headers" => $_response->headers,
+                        "statusCode" => $_response->statusCode
+                    ];
+                } else if (Utils::equalString($bodyType, "json")) {
+                    $obj = Utils::readAsJSON($_response->body);
+                    $res = Utils::assertAsMap($obj);
+                    return [
+                        "body" => $res,
+                        "headers" => $_response->headers,
+                        "statusCode" => $_response->statusCode
+                    ];
+                } else if (Utils::equalString($bodyType, "array")) {
+                    $arr = Utils::readAsJSON($_response->body);
+                    return [
+                        "body" => $arr,
+                        "headers" => $_response->headers,
+                        "statusCode" => $_response->statusCode
+                    ];
+                } else {
+                    return [
+                        "headers" => $_response->headers,
+                        "statusCode" => $_response->statusCode
+                    ];
+                }
+            } catch (Exception $e) {
+                if (!($e instanceof TeaError)) {
+                    $e = new TeaError([], $e->getMessage(), $e->getCode(), $e);
+                }
+                if (Tea::isRetryable($e)) {
+                    $_lastException = $e;
+                    continue;
+                }
+                throw $e;
+            }
+        }
+        throw new TeaUnableRetryError($_lastRequest, $_lastException);
+    }
+
+    /**
+     * Encapsulate the request and invoke the network
+     * @param Params $params
+     * @param OpenApiRequest $request object of OpenApiRequest
+     * @param RuntimeOptions $runtime which controls some details of call api, such as retry times
+     * @return array the response
+     * @throws TeaError
+     * @throws Exception
+     * @throws TeaUnableRetryError
+     */
+    public function doRequest($params, $request, $runtime)
+    {
+        $params->validate();
+        $request->validate();
+        $runtime->validate();
+        $_runtime = [
+            "timeouted" => "retry",
+            "key" => Utils::defaultString($runtime->key, $this->_key),
+            "cert" => Utils::defaultString($runtime->cert, $this->_cert),
+            "ca" => Utils::defaultString($runtime->ca, $this->_ca),
+            "readTimeout" => Utils::defaultNumber($runtime->readTimeout, $this->_readTimeout),
+            "connectTimeout" => Utils::defaultNumber($runtime->connectTimeout, $this->_connectTimeout),
+            "httpProxy" => Utils::defaultString($runtime->httpProxy, $this->_httpProxy),
+            "httpsProxy" => Utils::defaultString($runtime->httpsProxy, $this->_httpsProxy),
+            "noProxy" => Utils::defaultString($runtime->noProxy, $this->_noProxy),
+            "socks5Proxy" => Utils::defaultString($runtime->socks5Proxy, $this->_socks5Proxy),
+            "socks5NetWork" => Utils::defaultString($runtime->socks5NetWork, $this->_socks5NetWork),
+            "maxIdleConns" => Utils::defaultNumber($runtime->maxIdleConns, $this->_maxIdleConns),
+            "retry" => [
+                "retryable" => $runtime->autoretry,
+                "maxAttempts" => Utils::defaultNumber($runtime->maxAttempts, 3)
+            ],
+            "backoff" => [
+                "policy" => Utils::defaultString($runtime->backoffPolicy, "no"),
+                "period" => Utils::defaultNumber($runtime->backoffPeriod, 1)
+            ],
+            "ignoreSSL" => $runtime->ignoreSSL
+        ];
+        $_lastRequest = null;
+        $_lastException = null;
+        $_now = time();
+        $_retryTimes = 0;
+        while (Tea::allowRetry(@$_runtime["retry"], $_retryTimes, $_now)) {
+            if ($_retryTimes > 0) {
+                $_backoffTime = Tea::getBackoffTime(@$_runtime["backoff"], $_retryTimes);
+                if ($_backoffTime > 0) {
+                    Tea::sleep($_backoffTime);
+                }
+            }
+            $_retryTimes = $_retryTimes + 1;
+            try {
+                $_request = new Request();
+                $_request->protocol = Utils::defaultString($this->_protocol, $params->protocol);
+                $_request->method = $params->method;
+                $_request->pathname = $params->pathname;
+                $globalQueries = [];
+                $globalHeaders = [];
+                if (!Utils::isUnset($this->_globalParameters)) {
+                    $globalParams = $this->_globalParameters;
+                    if (!Utils::isUnset($globalParams->queries)) {
+                        $globalQueries = $globalParams->queries;
+                    }
+                    if (!Utils::isUnset($globalParams->headers)) {
+                        $globalHeaders = $globalParams->headers;
+                    }
+                }
+                $extendsHeaders = [];
+                $extendsQueries = [];
+                if (!Utils::isUnset($runtime->extendsParameters)) {
+                    $extendsParameters = $runtime->extendsParameters;
+                    if (!Utils::isUnset($extendsParameters->headers)) {
+                        $extendsHeaders = $extendsParameters->headers;
+                    }
+                    if (!Utils::isUnset($extendsParameters->queries)) {
+                        $extendsQueries = $extendsParameters->queries;
+                    }
+                }
+                $_request->query = Tea::merge($globalQueries, $extendsQueries, $request->query);
+                // endpoint is setted in product client
+                $_request->headers = Tea::merge([
+                    "host" => $this->_endpoint,
+                    "x-acs-version" => $params->version,
+                    "x-acs-action" => $params->action,
+                    "user-agent" => $this->getUserAgent(),
+                    "x-acs-date" => OpenApiUtilClient::getTimestamp(),
+                    "x-acs-signature-nonce" => Utils::getNonce(),
+                    "accept" => "application/json"
+                ], $globalHeaders, $extendsHeaders, $request->headers);
+                if (Utils::equalString($params->style, "RPC")) {
+                    $headers = $this->getRpcHeaders();
+                    if (!Utils::isUnset($headers)) {
+                        $_request->headers = Tea::merge($_request->headers, $headers);
+                    }
+                }
+                $signatureAlgorithm = Utils::defaultString($this->_signatureAlgorithm, "ACS3-HMAC-SHA256");
+                $hashedRequestPayload = OpenApiUtilClient::hexEncode(OpenApiUtilClient::hash(Utils::toBytes(""), $signatureAlgorithm));
+                if (!Utils::isUnset($request->stream)) {
+                    $tmp = Utils::readAsBytes($request->stream);
+                    $hashedRequestPayload = OpenApiUtilClient::hexEncode(OpenApiUtilClient::hash($tmp, $signatureAlgorithm));
+                    $_request->body = $tmp;
+                    $_request->headers["content-type"] = "application/octet-stream";
+                } else {
+                    if (!Utils::isUnset($request->body)) {
+                        if (Utils::equalString($params->reqBodyType, "byte")) {
+                            $byteObj = Utils::assertAsBytes($request->body);
+                            $hashedRequestPayload = OpenApiUtilClient::hexEncode(OpenApiUtilClient::hash($byteObj, $signatureAlgorithm));
+                            $_request->body = $byteObj;
+                        } else if (Utils::equalString($params->reqBodyType, "json")) {
+                            $jsonObj = Utils::toJSONString($request->body);
+                            $hashedRequestPayload = OpenApiUtilClient::hexEncode(OpenApiUtilClient::hash(Utils::toBytes($jsonObj), $signatureAlgorithm));
+                            $_request->body = $jsonObj;
+                            $_request->headers["content-type"] = "application/json; charset=utf-8";
+                        } else {
+                            $m = Utils::assertAsMap($request->body);
+                            $formObj = OpenApiUtilClient::toForm($m);
+                            $hashedRequestPayload = OpenApiUtilClient::hexEncode(OpenApiUtilClient::hash(Utils::toBytes($formObj), $signatureAlgorithm));
+                            $_request->body = $formObj;
+                            $_request->headers["content-type"] = "application/x-www-form-urlencoded";
+                        }
+                    }
+                }
+                $_request->headers["x-acs-content-sha256"] = $hashedRequestPayload;
+                if (!Utils::equalString($params->authType, "Anonymous")) {
+                    $authType = $this->getType();
+                    if (Utils::equalString($authType, "bearer")) {
+                        $bearerToken = $this->getBearerToken();
+                        $_request->headers["x-acs-bearer-token"] = $bearerToken;
+                        if (Utils::equalString($params->style, "RPC")) {
+                            $_request->query["SignatureType"] = "BEARERTOKEN";
+                        } else {
+                            $_request->headers["x-acs-signature-type"] = "BEARERTOKEN";
+                        }
+                    } else {
+                        $accessKeyId = $this->getAccessKeyId();
+                        $accessKeySecret = $this->getAccessKeySecret();
+                        $securityToken = $this->getSecurityToken();
+                        if (!Utils::empty_($securityToken)) {
+                            $_request->headers["x-acs-accesskey-id"] = $accessKeyId;
+                            $_request->headers["x-acs-security-token"] = $securityToken;
+                        }
+                        $_request->headers["Authorization"] = OpenApiUtilClient::getAuthorization($_request, $signatureAlgorithm, $hashedRequestPayload, $accessKeyId, $accessKeySecret);
+                    }
+                }
+                $_lastRequest = $_request;
+                $_response = Tea::send($_request, $_runtime);
+                if (Utils::is4xx($_response->statusCode) || Utils::is5xx($_response->statusCode)) {
+                    $_res = Utils::readAsJSON($_response->body);
+                    $err = Utils::assertAsMap($_res);
+                    @$err["statusCode"] = $_response->statusCode;
+                    throw new TeaError([
+                        "code" => "" . (string) (self::defaultAny(@$err["Code"], @$err["code"])) . "",
+                        "message" => "code: " . (string) ($_response->statusCode) . ", " . (string) (self::defaultAny(@$err["Message"], @$err["message"])) . " request id: " . (string) (self::defaultAny(@$err["RequestId"], @$err["requestId"])) . "",
+                        "data" => $err,
+                        "description" => "" . (string) (self::defaultAny(@$err["Description"], @$err["description"])) . "",
+                        "accessDeniedDetail" => self::defaultAny(@$err["AccessDeniedDetail"], @$err["accessDeniedDetail"])
+                    ]);
+                }
+                if (Utils::equalString($params->bodyType, "binary")) {
+                    $resp = [
+                        "body" => $_response->body,
+                        "headers" => $_response->headers,
+                        "statusCode" => $_response->statusCode
+                    ];
+                    return $resp;
+                } else if (Utils::equalString($params->bodyType, "byte")) {
+                    $byt = Utils::readAsBytes($_response->body);
+                    return [
+                        "body" => $byt,
+                        "headers" => $_response->headers,
+                        "statusCode" => $_response->statusCode
+                    ];
+                } else if (Utils::equalString($params->bodyType, "string")) {
+                    $str = Utils::readAsString($_response->body);
+                    return [
+                        "body" => $str,
+                        "headers" => $_response->headers,
+                        "statusCode" => $_response->statusCode
+                    ];
+                } else if (Utils::equalString($params->bodyType, "json")) {
+                    $obj = Utils::readAsJSON($_response->body);
+                    $res = Utils::assertAsMap($obj);
+                    return [
+                        "body" => $res,
+                        "headers" => $_response->headers,
+                        "statusCode" => $_response->statusCode
+                    ];
+                } else if (Utils::equalString($params->bodyType, "array")) {
+                    $arr = Utils::readAsJSON($_response->body);
+                    return [
+                        "body" => $arr,
+                        "headers" => $_response->headers,
+                        "statusCode" => $_response->statusCode
+                    ];
+                } else {
+                    $anything = Utils::readAsString($_response->body);
+                    return [
+                        "body" => $anything,
+                        "headers" => $_response->headers,
+                        "statusCode" => $_response->statusCode
+                    ];
+                }
+            } catch (Exception $e) {
+                if (!($e instanceof TeaError)) {
+                    $e = new TeaError([], $e->getMessage(), $e->getCode(), $e);
+                }
+                if (Tea::isRetryable($e)) {
+                    $_lastException = $e;
+                    continue;
+                }
+                throw $e;
+            }
+        }
+        throw new TeaUnableRetryError($_lastRequest, $_lastException);
+    }
+
+    /**
+     * Encapsulate the request and invoke the network
+     * @param Params $params
+     * @param OpenApiRequest $request object of OpenApiRequest
+     * @param RuntimeOptions $runtime which controls some details of call api, such as retry times
+     * @return array the response
+     * @throws TeaError
+     * @throws Exception
+     * @throws TeaUnableRetryError
+     */
+    public function execute($params, $request, $runtime)
+    {
+        $params->validate();
+        $request->validate();
+        $runtime->validate();
+        $_runtime = [
+            "timeouted" => "retry",
+            "key" => Utils::defaultString($runtime->key, $this->_key),
+            "cert" => Utils::defaultString($runtime->cert, $this->_cert),
+            "ca" => Utils::defaultString($runtime->ca, $this->_ca),
+            "readTimeout" => Utils::defaultNumber($runtime->readTimeout, $this->_readTimeout),
+            "connectTimeout" => Utils::defaultNumber($runtime->connectTimeout, $this->_connectTimeout),
+            "httpProxy" => Utils::defaultString($runtime->httpProxy, $this->_httpProxy),
+            "httpsProxy" => Utils::defaultString($runtime->httpsProxy, $this->_httpsProxy),
+            "noProxy" => Utils::defaultString($runtime->noProxy, $this->_noProxy),
+            "socks5Proxy" => Utils::defaultString($runtime->socks5Proxy, $this->_socks5Proxy),
+            "socks5NetWork" => Utils::defaultString($runtime->socks5NetWork, $this->_socks5NetWork),
+            "maxIdleConns" => Utils::defaultNumber($runtime->maxIdleConns, $this->_maxIdleConns),
+            "retry" => [
+                "retryable" => $runtime->autoretry,
+                "maxAttempts" => Utils::defaultNumber($runtime->maxAttempts, 3)
+            ],
+            "backoff" => [
+                "policy" => Utils::defaultString($runtime->backoffPolicy, "no"),
+                "period" => Utils::defaultNumber($runtime->backoffPeriod, 1)
+            ],
+            "ignoreSSL" => $runtime->ignoreSSL,
+            "disableHttp2" => self::defaultAny($this->_disableHttp2, false)
+        ];
+        $_lastRequest = null;
+        $_lastException = null;
+        $_now = time();
+        $_retryTimes = 0;
+        while (Tea::allowRetry(@$_runtime["retry"], $_retryTimes, $_now)) {
+            if ($_retryTimes > 0) {
+                $_backoffTime = Tea::getBackoffTime(@$_runtime["backoff"], $_retryTimes);
+                if ($_backoffTime > 0) {
+                    Tea::sleep($_backoffTime);
+                }
+            }
+            $_retryTimes = $_retryTimes + 1;
+            try {
+                $_request = new Request();
+                // spi = new Gateway();//Gateway implements SPI,这一步在产品 SDK 中实例化
+                $headers = $this->getRpcHeaders();
+                $globalQueries = [];
+                $globalHeaders = [];
+                if (!Utils::isUnset($this->_globalParameters)) {
+                    $globalParams = $this->_globalParameters;
+                    if (!Utils::isUnset($globalParams->queries)) {
+                        $globalQueries = $globalParams->queries;
+                    }
+                    if (!Utils::isUnset($globalParams->headers)) {
+                        $globalHeaders = $globalParams->headers;
+                    }
+                }
+                $extendsHeaders = [];
+                $extendsQueries = [];
+                if (!Utils::isUnset($runtime->extendsParameters)) {
+                    $extendsParameters = $runtime->extendsParameters;
+                    if (!Utils::isUnset($extendsParameters->headers)) {
+                        $extendsHeaders = $extendsParameters->headers;
+                    }
+                    if (!Utils::isUnset($extendsParameters->queries)) {
+                        $extendsQueries = $extendsParameters->queries;
+                    }
+                }
+                $requestContext = new \Darabonba\GatewaySpi\Models\InterceptorContext\request([
+                    "headers" => Tea::merge($globalHeaders, $extendsHeaders, $request->headers, $headers),
+                    "query" => Tea::merge($globalQueries, $extendsQueries, $request->query),
+                    "body" => $request->body,
+                    "stream" => $request->stream,
+                    "hostMap" => $request->hostMap,
+                    "pathname" => $params->pathname,
+                    "productId" => $this->_productId,
+                    "action" => $params->action,
+                    "version" => $params->version,
+                    "protocol" => Utils::defaultString($this->_protocol, $params->protocol),
+                    "method" => Utils::defaultString($this->_method, $params->method),
+                    "authType" => $params->authType,
+                    "bodyType" => $params->bodyType,
+                    "reqBodyType" => $params->reqBodyType,
+                    "style" => $params->style,
+                    "credential" => $this->_credential,
+                    "signatureVersion" => $this->_signatureVersion,
+                    "signatureAlgorithm" => $this->_signatureAlgorithm,
+                    "userAgent" => $this->getUserAgent()
+                ]);
+                $configurationContext = new configuration([
+                    "regionId" => $this->_regionId,
+                    "endpoint" => Utils::defaultString($request->endpointOverride, $this->_endpoint),
+                    "endpointRule" => $this->_endpointRule,
+                    "endpointMap" => $this->_endpointMap,
+                    "endpointType" => $this->_endpointType,
+                    "network" => $this->_network,
+                    "suffix" => $this->_suffix
+                ]);
+                $interceptorContext = new InterceptorContext([
+                    "request" => $requestContext,
+                    "configuration" => $configurationContext
+                ]);
+                $attributeMap = new AttributeMap([]);
+                // 1. spi.modifyConfiguration(context: SPI.InterceptorContext, attributeMap: SPI.AttributeMap);
+                $this->_spi->modifyConfiguration($interceptorContext, $attributeMap);
+                // 2. spi.modifyRequest(context: SPI.InterceptorContext, attributeMap: SPI.AttributeMap);
+                $this->_spi->modifyRequest($interceptorContext, $attributeMap);
+                $_request->protocol = $interceptorContext->request->protocol;
+                $_request->method = $interceptorContext->request->method;
+                $_request->pathname = $interceptorContext->request->pathname;
+                $_request->query = $interceptorContext->request->query;
+                $_request->body = $interceptorContext->request->stream;
+                $_request->headers = $interceptorContext->request->headers;
+                $_lastRequest = $_request;
+                $_response = Tea::send($_request, $_runtime);
+                $responseContext = new response([
+                    "statusCode" => $_response->statusCode,
+                    "headers" => $_response->headers,
+                    "body" => $_response->body
+                ]);
+                $interceptorContext->response = $responseContext;
+                // 3. spi.modifyResponse(context: SPI.InterceptorContext, attributeMap: SPI.AttributeMap);
+                $this->_spi->modifyResponse($interceptorContext, $attributeMap);
+                return [
+                    "headers" => $interceptorContext->response->headers,
+                    "statusCode" => $interceptorContext->response->statusCode,
+                    "body" => $interceptorContext->response->deserializedBody
+                ];
+            } catch (Exception $e) {
+                if (!($e instanceof TeaError)) {
+                    $e = new TeaError([], $e->getMessage(), $e->getCode(), $e);
+                }
+                if (Tea::isRetryable($e)) {
+                    $_lastException = $e;
+                    continue;
+                }
+                throw $e;
+            }
+        }
+        throw new TeaUnableRetryError($_lastRequest, $_lastException);
+    }
+
+    /**
+     * @param Params $params
+     * @param OpenApiRequest $request
+     * @param RuntimeOptions $runtime
+     * @return array
+     * @throws TeaError
+     */
+    public function callApi($params, $request, $runtime)
+    {
+        if (Utils::isUnset($params)) {
+            throw new TeaError([
+                "code" => "ParameterMissing",
+                "message" => "'params' can not be unset"
+            ]);
+        }
+        if (Utils::isUnset($this->_signatureAlgorithm) || !Utils::equalString($this->_signatureAlgorithm, "v2")) {
+            return $this->doRequest($params, $request, $runtime);
+        } else if (Utils::equalString($params->style, "ROA") && Utils::equalString($params->reqBodyType, "json")) {
+            return $this->doROARequest($params->action, $params->version, $params->protocol, $params->method, $params->authType, $params->pathname, $params->bodyType, $request, $runtime);
+        } else if (Utils::equalString($params->style, "ROA")) {
+            return $this->doROARequestWithForm($params->action, $params->version, $params->protocol, $params->method, $params->authType, $params->pathname, $params->bodyType, $request, $runtime);
+        } else {
+            return $this->doRPCRequest($params->action, $params->version, $params->protocol, $params->method, $params->authType, $params->bodyType, $request, $runtime);
+        }
+    }
+
+    /**
+     * Get user agent
+     * @return string user agent
+     */
+    public function getUserAgent()
+    {
+        $userAgent = Utils::getUserAgent($this->_userAgent);
+        return $userAgent;
+    }
+
+    /**
+     * Get accesskey id by using credential
+     * @return string accesskey id
+     */
+    public function getAccessKeyId()
+    {
+        if (Utils::isUnset($this->_credential)) {
+            return '';
+        }
+        $accessKeyId = $this->_credential->getAccessKeyId();
+        return $accessKeyId;
+    }
+
+    /**
+     * Get accesskey secret by using credential
+     * @return string accesskey secret
+     */
+    public function getAccessKeySecret()
+    {
+        if (Utils::isUnset($this->_credential)) {
+            return '';
+        }
+        $secret = $this->_credential->getAccessKeySecret();
+        return $secret;
+    }
+
+    /**
+     * Get security token by using credential
+     * @return string security token
+     */
+    public function getSecurityToken()
+    {
+        if (Utils::isUnset($this->_credential)) {
+            return '';
+        }
+        $token = $this->_credential->getSecurityToken();
+        return $token;
+    }
+
+    /**
+     * Get bearer token by credential
+     * @return string bearer token
+     */
+    public function getBearerToken()
+    {
+        if (Utils::isUnset($this->_credential)) {
+            return '';
+        }
+        $token = $this->_credential->getBearerToken();
+        return $token;
+    }
+
+    /**
+     * Get credential type by credential
+     * @return string credential type e.g. access_key
+     */
+    public function getType()
+    {
+        if (Utils::isUnset($this->_credential)) {
+            return '';
+        }
+        $authType = $this->_credential->getType();
+        return $authType;
+    }
+
+    /**
+     * If inputValue is not null, return it or return defaultValue
+     * @param mixed $inputValue  users input value
+     * @param mixed $defaultValue default value
+     * @return any the final result
+     */
+    public static function defaultAny($inputValue, $defaultValue)
+    {
+        if (Utils::isUnset($inputValue)) {
+            return $defaultValue;
+        }
+        return $inputValue;
+    }
+
+    /**
+     * If the endpointRule and config.endpoint are empty, throw error
+     * @param \Darabonba\OpenApi\Models\Config $config config contains the necessary information to create a client
+     * @return void
+     * @throws TeaError
+     */
+    public function checkConfig($config)
+    {
+        if (Utils::empty_($this->_endpointRule) && Utils::empty_($config->endpoint)) {
+            throw new TeaError([
+                "code" => "ParameterMissing",
+                "message" => "'config.endpoint' can not be empty"
+            ]);
+        }
+    }
+
+    /**
+     * set gateway client
+     * @param Client $spi
+     * @return void
+     */
+    public function setGatewayClient($spi)
+    {
+        $this->_spi = $spi;
+    }
+
+    /**
+     * set RPC header for debug
+     * @param string[] $headers headers for debug, this header can be used only once.
+     * @return void
+     */
+    public function setRpcHeaders($headers)
+    {
+        $this->_headers = $headers;
+    }
+
+    /**
+     * get RPC header for debug
+     * @return array
+     */
+    public function getRpcHeaders()
+    {
+        $headers = $this->_headers;
+        $this->_headers = null;
+        return $headers;
+    }
+}

+ 328 - 0
vendor/alibabacloud/darabonba-openapi/tests/OpenApiClientTest.php

@@ -0,0 +1,328 @@
+<?php
+
+namespace Darabonba\OpenApi\Tests;
+
+use Darabonba\OpenApi\OpenApiClient;
+use AlibabaCloud\Tea\Model;
+use AlibabaCloud\Tea\Request;
+use AlibabaCloud\Tea\Utils\Utils;
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @internal
+ * @coversNothing
+ */
+class OpenApiClientTest extends TestCase
+{
+    public function testConfig(){
+        $globalParameters = new GlobalParameters([
+            "headers" => [
+                "global-key" => "global-value"
+            ],
+            "queries" => [
+                "global-query" => "global-value"
+            ]
+        ]);
+        $config = new Config([
+            "endpoint" => "config.endpoint",
+            "endpointType" => "regional",
+            "network" => "config.network",
+            "suffix" => "config.suffix",
+            "protocol" => "config.protocol",
+            "method" => "config.method",
+            "regionId" => "config.regionId",
+            "userAgent" => "config.userAgent",
+            "readTimeout" => 3000,
+            "connectTimeout" => 3000,
+            "httpProxy" => "config.httpProxy",
+            "httpsProxy" => "config.httpsProxy",
+            "noProxy" => "config.noProxy",
+            "socks5Proxy" => "config.socks5Proxy",
+            "socks5NetWork" => "config.socks5NetWork",
+            "maxIdleConns" => 128,
+            "signatureVersion" => "config.signatureVersion",
+            "signatureAlgorithm" => "config.signatureAlgorithm",
+            "globalParameters" => $globalParameters
+        ]);
+        $creConfig = new \AlibabaCloud\Credentials\Credential\Config([
+            "accessKeyId" => "accessKeyId",
+            "accessKeySecret" => "accessKeySecret",
+            "securityToken" => "securityToken",
+            "type" => "sts"
+        ]);
+        $credential = new Credential($creConfig);
+        $config->credential = $credential;
+        $client = new OpenApiClient($config);
+        $config->accessKeyId = "ak";
+        $config->accessKeySecret = "secret";
+        $config->securityToken = "token";
+        $config->type = "sts";
+        $client = new OpenApiClient($config);
+    }
+
+    /**
+     * @return Config
+     */
+    public static function createConfig(){
+        $globalParameters = new GlobalParameters([
+            "headers" => [
+                "global-key" => "global-value"
+            ],
+            "queries" => [
+                "global-query" => "global-value"
+            ]
+        ]);
+        $config = new Config([
+            "accessKeyId" => "ak",
+            "accessKeySecret" => "secret",
+            "securityToken" => "token",
+            "type" => "sts",
+            "userAgent" => "config.userAgent",
+            "readTimeout" => 3000,
+            "connectTimeout" => 3000,
+            "maxIdleConns" => 128,
+            "signatureVersion" => "config.signatureVersion",
+            "signatureAlgorithm" => "ACS3-HMAC-SHA256",
+            "globalParameters" => $globalParameters
+        ]);
+        return $config;
+    }
+
+    /**
+     * @return RuntimeOptions
+     */
+    public static function createRuntimeOptions(){
+        $runtime = new RuntimeOptions([
+            "readTimeout" => 4000,
+            "connectTimeout" => 4000,
+            "maxIdleConns" => 100,
+            "autoretry" => true,
+            "maxAttempts" => 1,
+            "backoffPolicy" => "no",
+            "backoffPeriod" => 1,
+            "ignoreSSL" => true
+        ]);
+        return $runtime;
+    }
+
+    /**
+     * @return OpenApiRequest
+     */
+    public static function createOpenApiRequest(){
+        $query = [];
+        $query["key1"] = "value";
+        $query["key2"] = 1;
+        $query["key3"] = true;
+        $body = [];
+        $body["key1"] = "value";
+        $body["key2"] = 1;
+        $body["key3"] = true;
+        $headers = [
+            "for-test" => "sdk"
+        ];
+        $req = new OpenApiRequest([
+            "headers" => $headers,
+            "query" => OpenApiUtilClient::query($query),
+            "body" => OpenApiUtilClient::parseToMap($body)
+        ]);
+        return $req;
+    }
+
+    public function testCallApiForRPCWithV2Sign_AK_Form(){
+        $config = self::createConfig();
+        $runtime = self::createRuntimeOptions();
+        $config->protocol = "HTTP";
+        $config->signatureAlgorithm = "v2";
+        $config->endpoint = "test.aliyuncs.com";
+        $client = new OpenApiClient($config);
+        $request = self::createOpenApiRequest();
+        $params = new Params([
+            "action" => "TestAPI",
+            "version" => "2022-06-01",
+            "protocol" => "HTTPS",
+            "pathname" => "/",
+            "method" => "POST",
+            "authType" => "AK",
+            "style" => "RPC",
+            "reqBodyType" => "formData",
+            "bodyType" => "json"
+        ]);
+        $client->callApi($params, $request, $runtime);
+    }
+
+    public function testCallApiForRPCWithV2Sign_Anonymous_JSON(){
+        $config = self::createConfig();
+        $runtime = self::createRuntimeOptions();
+        $config->protocol = "HTTP";
+        $config->signatureAlgorithm = "v2";
+        $config->endpoint = "test.aliyuncs.com";
+        $client = new OpenApiClient($config);
+        $request = self::createOpenApiRequest();
+        $params = new Params([
+            "action" => "TestAPI",
+            "version" => "2022-06-01",
+            "protocol" => "HTTPS",
+            "pathname" => "/",
+            "method" => "POST",
+            "authType" => "Anonymous",
+            "style" => "RPC",
+            "reqBodyType" => "json",
+            "bodyType" => "json"
+        ]);
+        $client->callApi($params, $request, $runtime);
+    }
+
+    public function testCallApiForROAWithV2Sign_HTTPS_AK_Form(){
+        $config = self::createConfig();
+        $runtime = self::createRuntimeOptions();
+        $config->signatureAlgorithm = "v2";
+        $config->endpoint = "test.aliyuncs.com";
+        $client = new OpenApiClient($config);
+        $request = self::createOpenApiRequest();
+        $params = new Params([
+            "action" => "TestAPI",
+            "version" => "2022-06-01",
+            "protocol" => "HTTPS",
+            "pathname" => "/test",
+            "method" => "POST",
+            "authType" => "AK",
+            "style" => "ROA",
+            "reqBodyType" => "formData",
+            "bodyType" => "json"
+        ]);
+        $client->callApi($params, $request, $runtime);
+    }
+
+    public function testCallApiForROAWithV2Sign_Anonymous_JSON(){
+        $config = self::createConfig();
+        $runtime = self::createRuntimeOptions();
+        $config->protocol = "HTTP";
+        $config->signatureAlgorithm = "v2";
+        $config->endpoint = "test.aliyuncs.com";
+        $client = new OpenApiClient($config);
+        $request = self::createOpenApiRequest();
+        $params = new Params([
+            "action" => "TestAPI",
+            "version" => "2022-06-01",
+            "protocol" => "HTTPS",
+            "pathname" => "/test",
+            "method" => "POST",
+            "authType" => "Anonymous",
+            "style" => "ROA",
+            "reqBodyType" => "json",
+            "bodyType" => "json"
+        ]);
+        $client->callApi($params, $request, $runtime);
+    }
+
+    public function testCallApiForRPCWithV3Sign_AK_Form(){
+        $config = self::createConfig();
+        $runtime = self::createRuntimeOptions();
+        $config->protocol = "HTTP";
+        $config->endpoint = "test.aliyuncs.com";
+        $client = new OpenApiClient($config);
+        $request = self::createOpenApiRequest();
+        $params = new Params([
+            "action" => "TestAPI",
+            "version" => "2022-06-01",
+            "protocol" => "HTTPS",
+            "pathname" => "/",
+            "method" => "POST",
+            "authType" => "AK",
+            "style" => "RPC",
+            "reqBodyType" => "formData",
+            "bodyType" => "json"
+        ]);
+        $client->callApi($params, $request, $runtime);
+    }
+
+    public function testCallApiForRPCWithV3Sign_Anonymous_JSON(){
+        $config = self::createConfig();
+        $runtime = self::createRuntimeOptions();
+        $config->protocol = "HTTP";
+        $config->endpoint = "test.aliyuncs.com";
+        $client = new OpenApiClient($config);
+        $request = self::createOpenApiRequest();
+        $params = new Params([
+            "action" => "TestAPI",
+            "version" => "2022-06-01",
+            "protocol" => "HTTPS",
+            "pathname" => "/",
+            "method" => "POST",
+            "authType" => "Anonymous",
+            "style" => "RPC",
+            "reqBodyType" => "json",
+            "bodyType" => "json"
+        ]);
+        $client->callApi($params, $request, $runtime);
+    }
+
+    public function testCallApiForROAWithV3Sign_AK_Form(){
+        $config = self::createConfig();
+        $runtime = self::createRuntimeOptions();
+        $config->protocol = "HTTP";
+        $config->endpoint = "test.aliyuncs.com";
+        $client = new OpenApiClient($config);
+        $request = self::createOpenApiRequest();
+        $params = new Params([
+            "action" => "TestAPI",
+            "version" => "2022-06-01",
+            "protocol" => "HTTPS",
+            "pathname" => "/test",
+            "method" => "POST",
+            "authType" => "AK",
+            "style" => "ROA",
+            "reqBodyType" => "formData",
+            "bodyType" => "json"
+        ]);
+        $client->callApi($params, $request, $runtime);
+    }
+
+    public function testCallApiForROAWithV3Sign_Anonymous_JSON(){
+        $config = self::createConfig();
+        $runtime = self::createRuntimeOptions();
+        $config->protocol = "HTTP";
+        $config->endpoint = "test.aliyuncs.com";
+        $client = new OpenApiClient($config);
+        $request = self::createOpenApiRequest();
+        $params = new Params([
+            "action" => "TestAPI",
+            "version" => "2022-06-01",
+            "protocol" => "HTTPS",
+            "pathname" => "/test",
+            "method" => "POST",
+            "authType" => "Anonymous",
+            "style" => "ROA",
+            "reqBodyType" => "json",
+            "bodyType" => "json"
+        ]);
+        $client->callApi($params, $request, $runtime);
+    }
+
+    public function testResponseBodyType(){
+        $config = self::createConfig();
+        $runtime = self::createRuntimeOptions();
+        $config->protocol = "HTTP";
+        $config->endpoint = "test.aliyuncs.com";
+        $client = new OpenApiClient($config);
+        $request = self::createOpenApiRequest();
+        $params = new Params([
+            "action" => "TestAPI",
+            "version" => "2022-06-01",
+            "protocol" => "HTTPS",
+            "pathname" => "/test",
+            "method" => "POST",
+            "authType" => "AK",
+            "style" => "ROA",
+            "reqBodyType" => "formData",
+            "bodyType" => "json"
+        ]);
+        $client->callApi($params, $request, $runtime);
+        $params->bodyType = "array";
+        $client->callApi($params, $request, $runtime);
+        $params->bodyType = "string";
+        $client->callApi($params, $request, $runtime);
+        $params->bodyType = "byte";
+        $client->callApi($params, $request, $runtime);
+    }
+}

+ 3 - 0
vendor/alibabacloud/darabonba-openapi/tests/bootstrap.php

@@ -0,0 +1,3 @@
+<?php
+
+require dirname(__DIR__) . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php';

+ 15 - 0
vendor/alibabacloud/dysmsapi-20170525/.gitignore

@@ -0,0 +1,15 @@
+composer.phar
+/vendor/
+
+# Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control
+# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
+composer.lock
+
+.vscode/
+.idea
+.DS_Store
+
+cache/
+*.cache
+runtime/
+.php_cs.cache

+ 65 - 0
vendor/alibabacloud/dysmsapi-20170525/.php_cs.dist

@@ -0,0 +1,65 @@
+<?php
+/*
+ * This document has been generated with
+ * https://mlocati.github.io/php-cs-fixer-configurator/#version:2.15|configurator
+ * you can change this configuration by importing this file.
+ */
+
+return PhpCsFixer\Config::create()
+    ->setRiskyAllowed(true)
+    ->setIndent('    ')
+    ->setRules([
+        '@PSR2'                                       => true,
+        '@PhpCsFixer'                                 => true,
+        '@Symfony:risky'                              => true,
+        'concat_space'                                => ['spacing' => 'one'],
+        'array_syntax'                                => ['syntax' => 'short'],
+        'array_indentation'                           => true,
+        'combine_consecutive_unsets'                  => true,
+        'method_separation'                           => true,
+        'single_quote'                                => true,
+        'declare_equal_normalize'                     => true,
+        'function_typehint_space'                     => true,
+        'hash_to_slash_comment'                       => true,
+        'include'                                     => true,
+        'lowercase_cast'                              => true,
+        'no_multiline_whitespace_before_semicolons'   => true,
+        'no_leading_import_slash'                     => true,
+        'no_multiline_whitespace_around_double_arrow' => true,
+        'no_spaces_around_offset'                     => true,
+        'no_unneeded_control_parentheses'             => true,
+        'no_unused_imports'                           => true,
+        'no_whitespace_before_comma_in_array'         => true,
+        'no_whitespace_in_blank_line'                 => true,
+        'object_operator_without_whitespace'          => true,
+        'single_blank_line_before_namespace'          => true,
+        'single_class_element_per_statement'          => true,
+        'space_after_semicolon'                       => true,
+        'standardize_not_equals'                      => true,
+        'ternary_operator_spaces'                     => true,
+        'trailing_comma_in_multiline_array'           => true,
+        'trim_array_spaces'                           => true,
+        'unary_operator_spaces'                       => true,
+        'whitespace_after_comma_in_array'             => true,
+        'no_extra_consecutive_blank_lines'            => [
+            'curly_brace_block',
+            'extra',
+            'parenthesis_brace_block',
+            'square_brace_block',
+            'throw',
+            'use',
+        ],
+        'binary_operator_spaces'       => [
+            'align_double_arrow' => true,
+            'align_equals'       => true,
+        ],
+        'braces'                                    => [
+            'allow_single_line_closure' => true,
+        ],
+    ])
+    ->setFinder(
+        PhpCsFixer\Finder::create()
+            ->exclude('vendor')
+            ->exclude('tests')
+            ->in(__DIR__)
+  );

+ 89 - 0
vendor/alibabacloud/dysmsapi-20170525/ChangeLog.md

@@ -0,0 +1,89 @@
+2024-06-25 Version: 3.0.0
+- Support API CreateSmsSign.
+- Support API CreateSmsTemplate.
+- Support API GetOSSInfoForUploadFile.
+- Support API GetSmsSign.
+- Support API GetSmsTemplate.
+- Support API UpdateSmsSign.
+- Support API UpdateSmsTemplate.
+- Update API CreateSmartShortUrl: add param OutId.
+- Update API CreateSmartShortUrl: delete param Expiration.
+- Update API CreateSmartShortUrl: delete param SourceName.
+- Update API CreateSmartShortUrl: update param PhoneNumbers.
+- Update API CreateSmartShortUrl: update param SourceUrl.
+- Update API QueryPageSmartShortUrlLog: delete param ClickState.
+- Update API QueryPageSmartShortUrlLog: delete param EndId.
+- Update API QueryPageSmartShortUrlLog: delete param ShortName.
+- Update API QueryPageSmartShortUrlLog: delete param StartId.
+- Update API QueryPageSmartShortUrlLog: update param CreateDateEnd.
+- Update API QueryPageSmartShortUrlLog: update param CreateDateStart.
+- Update API QueryPageSmartShortUrlLog: update param PageNo.
+- Update API QueryPageSmartShortUrlLog: update param PageSize.
+
+
+2023-07-04 Version: 2.0.24
+- Add CreateSmartShortUrl api.
+
+2022-11-29 Version: 2.0.23
+- Add custom content for QueryCardSmsTemplateReport.
+
+2022-10-11 Version: 2.0.22
+- Add custom content for QueryCardSmsTemplateReport.
+
+2022-09-30 Version: 2.0.21
+- Add custom content for SendBatchSms.
+
+2022-09-29 Version: 2.0.20
+- Add outId for SendBatchSms.
+
+2022-09-28 Version: 2.0.19
+- Upgrade formdata for CheckMobilesCardTemplateSupport.
+
+2022-08-11 Version: 2.0.18
+- Upgrade formdata for SendBatchSms.
+
+2022-08-03 Version: 2.0.17
+- Upgrade Service for SmsStatistics.
+
+2022-07-14 Version: 2.0.16
+- Upgrade Service for SmsTemplate.
+
+2022-07-06 Version: 2.0.15
+- Upgrade Service for SmsSign.
+
+2022-07-06 Version: 2.0.14
+- Upgrade Service for SmsSign.
+
+2022-07-04 Version: 2.0.13
+- Upgrade Service for CardSms.
+
+2022-06-29 Version: 2.0.12
+- Upgrade Service for Template and Sign.
+
+2022-06-17 Version: 2.0.10
+- Upgrade Service for CARDSMS.
+
+2022-01-24 Version: 2.0.9
+- Generated php 2017-05-25 for Dysmsapi.
+
+2021-11-29 Version: 2.0.8
+- Upgrade Service for SMS.
+
+2021-11-16 Version: 2.0.7
+- Upgrade Service for SMS.
+
+2021-10-26 Version: 2.0.6
+- Support Short Url for SMS.
+
+2021-09-01 Version: 1.0.3
+- Generated php 2017-05-25 for Dysmsapi.
+
+2021-07-15 Version: 1.0.2
+- Generated php 2017-05-25 for Dysmsapi.
+
+2021-01-04 Version: 1.0.1
+- AMP Version Change.
+
+2020-12-29 Version: 1.0.0
+- AMP Version Change.
+

+ 201 - 0
vendor/alibabacloud/dysmsapi-20170525/LICENSE

@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   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.

+ 35 - 0
vendor/alibabacloud/dysmsapi-20170525/README-CN.md

@@ -0,0 +1,35 @@
+[English](README.md) | 简体中文
+
+![](https://aliyunsdk-pages.alicdn.com/icons/AlibabaCloud.svg)
+
+# Alibaba Cloud Dysmsapi SDK for PHP
+
+## 安装
+
+### Composer
+
+```bash
+composer require alibabacloud/dysmsapi-20170525
+```
+
+## 问题
+
+[提交 Issue](https://github.com/aliyun/alibabacloud-php-sdk/issues/new),不符合指南的问题可能会立即关闭。
+
+## 使用说明
+
+[快速使用](https://github.com/aliyun/alibabacloud-php-sdk/blob/master/docs/0-Examples-CN.md#%E5%BF%AB%E9%80%9F%E4%BD%BF%E7%94%A8)
+
+## 发行说明
+
+每个版本的详细更改记录在[发行说明](./ChangeLog.txt)中。
+
+## 相关
+
+* [最新源码](https://github.com/aliyun/alibabacloud-php-sdk/)
+
+## 许可证
+
+[Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0)
+
+Copyright (c) 2009-present, Alibaba Cloud All rights reserved.

+ 35 - 0
vendor/alibabacloud/dysmsapi-20170525/README.md

@@ -0,0 +1,35 @@
+English | [简体中文](README-CN.md)
+
+![](https://aliyunsdk-pages.alicdn.com/icons/AlibabaCloud.svg)
+
+# Alibaba Cloud Dysmsapi SDK for PHP
+
+## Installation
+
+### Composer
+
+```bash
+composer require alibabacloud/dysmsapi-20170525
+```
+
+## Issues
+
+[Opening an Issue](https://github.com/aliyun/alibabacloud-php-sdk/issues/new), Issues not conforming to the guidelines may be closed immediately.
+
+## Usage
+
+[Quick Examples](https://github.com/aliyun/alibabacloud-php-sdk/blob/master/docs/0-Examples-EN.md#quick-examples)
+
+## Changelog
+
+Detailed changes for each release are documented in the [release notes](./ChangeLog.txt).
+
+## References
+
+* [Latest Release](https://github.com/aliyun/alibabacloud-php-sdk/)
+
+## License
+
+[Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0)
+
+Copyright (c) 2009-present, Alibaba Cloud All rights reserved.

+ 17 - 0
vendor/alibabacloud/dysmsapi-20170525/autoload.php

@@ -0,0 +1,17 @@
+<?php
+
+if (file_exists(__DIR__ . \DIRECTORY_SEPARATOR . 'vendor' . \DIRECTORY_SEPARATOR . 'autoload.php')) {
+    require_once __DIR__ . \DIRECTORY_SEPARATOR . 'vendor' . \DIRECTORY_SEPARATOR . 'autoload.php';
+}
+
+spl_autoload_register(function ($class) {
+    $name = str_replace('AlibabaCloud\\SDK\\Dysmsapi\\V20170525\\', '', $class);
+    $file = __DIR__ . \DIRECTORY_SEPARATOR . 'src' . \DIRECTORY_SEPARATOR . str_replace('\\', \DIRECTORY_SEPARATOR, $name) . '.php';
+    if (file_exists($file)) {
+        require_once $file;
+
+        return true;
+    }
+
+    return false;
+});

+ 33 - 0
vendor/alibabacloud/dysmsapi-20170525/composer.json

@@ -0,0 +1,33 @@
+{
+  "name": "alibabacloud/dysmsapi-20170525",
+  "description": "Alibaba Cloud Dysmsapi (20170525) SDK Library for PHP",
+  "type": "library",
+  "license": "Apache-2.0",
+  "authors": [
+    {
+      "name": "Alibaba Cloud SDK",
+      "email": "sdk-team@alibabacloud.com"
+    }
+  ],
+  "require": {
+    "php": ">5.5",
+    "alibabacloud/tea-utils": "^0.2.20",
+    "alibabacloud/darabonba-openapi": "^0.2.12",
+    "alibabacloud/openapi-util": "^0.1.10|^0.2.1",
+    "alibabacloud/endpoint-util": "^0.1.0"
+  },
+  "autoload": {
+    "psr-4": {
+      "AlibabaCloud\\SDK\\Dysmsapi\\V20170525\\": "src"
+    }
+  },
+  "scripts": {
+    "fixer": "php-cs-fixer fix ./"
+  },
+  "config": {
+    "sort-packages": true,
+    "preferred-install": "dist",
+    "optimize-autoloader": true
+  },
+  "prefer-stable": true
+}

+ 3049 - 0
vendor/alibabacloud/dysmsapi-20170525/src/Dysmsapi.php

@@ -0,0 +1,3049 @@
+<?php
+
+// This file is auto-generated, don't edit it. Thanks.
+
+namespace AlibabaCloud\SDK\Dysmsapi\V20170525;
+
+use AlibabaCloud\Endpoint\Endpoint;
+use AlibabaCloud\OpenApiUtil\OpenApiUtilClient;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\AddShortUrlRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\AddShortUrlResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\AddSmsSignRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\AddSmsSignResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\AddSmsTemplateRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\AddSmsTemplateResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\CheckMobilesCardSupportRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\CheckMobilesCardSupportResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\ConversionDataIntlRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\ConversionDataIntlResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\CreateCardSmsTemplateRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\CreateCardSmsTemplateResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\CreateCardSmsTemplateShrinkRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\CreateSmartShortUrlRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\CreateSmartShortUrlResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\CreateSmsSignRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\CreateSmsSignResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\CreateSmsSignShrinkRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\CreateSmsTemplateRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\CreateSmsTemplateResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\CreateSmsTemplateShrinkRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\DeleteShortUrlRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\DeleteShortUrlResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\DeleteSmsSignRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\DeleteSmsSignResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\DeleteSmsTemplateRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\DeleteSmsTemplateResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\GetCardSmsLinkRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\GetCardSmsLinkResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\GetMediaResourceIdRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\GetMediaResourceIdResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\GetOSSInfoForCardTemplateResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\GetOSSInfoForUploadFileRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\GetOSSInfoForUploadFileResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\GetSmsSignRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\GetSmsSignResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\GetSmsTemplateRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\GetSmsTemplateResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\ListTagResourcesRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\ListTagResourcesResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\ModifySmsSignRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\ModifySmsSignResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\ModifySmsTemplateRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\ModifySmsTemplateResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\QueryCardSmsTemplateReportRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\QueryCardSmsTemplateReportResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\QueryCardSmsTemplateRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\QueryCardSmsTemplateResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\QueryMobilesCardSupportRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\QueryMobilesCardSupportResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\QueryMobilesCardSupportShrinkRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\QueryPageSmartShortUrlLogRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\QueryPageSmartShortUrlLogResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\QuerySendDetailsRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\QuerySendDetailsResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\QuerySendStatisticsRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\QuerySendStatisticsResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\QueryShortUrlRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\QueryShortUrlResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\QuerySmsSignListRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\QuerySmsSignListResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\QuerySmsSignRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\QuerySmsSignResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\QuerySmsTemplateListRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\QuerySmsTemplateListResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\QuerySmsTemplateRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\QuerySmsTemplateResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\SendBatchCardSmsRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\SendBatchCardSmsResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\SendBatchSmsRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\SendBatchSmsResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\SendCardSmsRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\SendCardSmsResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\SendSmsRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\SendSmsResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\SmsConversionIntlRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\SmsConversionIntlResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\TagResourcesRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\TagResourcesResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\UntagResourcesRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\UntagResourcesResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\UpdateSmsSignRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\UpdateSmsSignResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\UpdateSmsSignShrinkRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\UpdateSmsTemplateRequest;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\UpdateSmsTemplateResponse;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\UpdateSmsTemplateShrinkRequest;
+use AlibabaCloud\Tea\Utils\Utils;
+use AlibabaCloud\Tea\Utils\Utils\RuntimeOptions;
+use Darabonba\OpenApi\Models\OpenApiRequest;
+use Darabonba\OpenApi\Models\Params;
+use Darabonba\OpenApi\OpenApiClient;
+
+class Dysmsapi extends OpenApiClient
+{
+    public function __construct($config)
+    {
+        parent::__construct($config);
+        $this->_endpointRule = 'central';
+        $this->_endpointMap  = [
+            'ap-southeast-1' => 'dysmsapi.ap-southeast-1.aliyuncs.com',
+            'ap-southeast-5' => 'dysmsapi.ap-southeast-5.aliyuncs.com',
+            'cn-beijing'     => 'dysmsapi-proxy.cn-beijing.aliyuncs.com',
+            'cn-hongkong'    => 'dysmsapi-xman.cn-hongkong.aliyuncs.com',
+            'eu-central-1'   => 'dysmsapi.eu-central-1.aliyuncs.com',
+            'us-east-1'      => 'dysmsapi.us-east-1.aliyuncs.com',
+        ];
+        $this->checkConfig($config);
+        $this->_endpoint = $this->getEndpoint('dysmsapi', $this->_regionId, $this->_endpointRule, $this->_network, $this->_suffix, $this->_endpointMap, $this->_endpoint);
+    }
+
+    /**
+     * @param string   $productId
+     * @param string   $regionId
+     * @param string   $endpointRule
+     * @param string   $network
+     * @param string   $suffix
+     * @param string[] $endpointMap
+     * @param string   $endpoint
+     *
+     * @return string
+     */
+    public function getEndpoint($productId, $regionId, $endpointRule, $network, $suffix, $endpointMap, $endpoint)
+    {
+        if (!Utils::empty_($endpoint)) {
+            return $endpoint;
+        }
+        if (!Utils::isUnset($endpointMap) && !Utils::empty_(@$endpointMap[$regionId])) {
+            return @$endpointMap[$regionId];
+        }
+
+        return Endpoint::getEndpointRules($productId, $regionId, $endpointRule, $network, $suffix);
+    }
+
+    /**
+     * @summary Creates a short URL.
+     *  *
+     * @description *   Before you call this operation, you must register the primary domain name of the source URL in the Short Message Service (SMS) console. After the domain name is registered, you can call this operation to create a short URL. For more information, see [Domain name registration](https://help.aliyun.com/document_detail/302325.html#title-mau-zdh-hd0).
+     * *   You can create up to 3,000 short URLs within a natural day.
+     * *   After a short URL is generated, a security review is required. Generally, the review takes 10 minutes to 2 hours to complete. Before the security review is passed, the short URL cannot be directly accessed.
+     *  *
+     * @param AddShortUrlRequest $request AddShortUrlRequest
+     * @param RuntimeOptions     $runtime runtime options for this request RuntimeOptions
+     *
+     * @return AddShortUrlResponse AddShortUrlResponse
+     */
+    public function addShortUrlWithOptions($request, $runtime)
+    {
+        Utils::validateModel($request);
+        $query = [];
+        if (!Utils::isUnset($request->ownerId)) {
+            $query['OwnerId'] = $request->ownerId;
+        }
+        if (!Utils::isUnset($request->resourceOwnerAccount)) {
+            $query['ResourceOwnerAccount'] = $request->resourceOwnerAccount;
+        }
+        if (!Utils::isUnset($request->resourceOwnerId)) {
+            $query['ResourceOwnerId'] = $request->resourceOwnerId;
+        }
+        $body = [];
+        if (!Utils::isUnset($request->effectiveDays)) {
+            $body['EffectiveDays'] = $request->effectiveDays;
+        }
+        if (!Utils::isUnset($request->shortUrlName)) {
+            $body['ShortUrlName'] = $request->shortUrlName;
+        }
+        if (!Utils::isUnset($request->sourceUrl)) {
+            $body['SourceUrl'] = $request->sourceUrl;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+            'body'  => OpenApiUtilClient::parseToMap($body),
+        ]);
+        $params = new Params([
+            'action'      => 'AddShortUrl',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return AddShortUrlResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary Creates a short URL.
+     *  *
+     * @description *   Before you call this operation, you must register the primary domain name of the source URL in the Short Message Service (SMS) console. After the domain name is registered, you can call this operation to create a short URL. For more information, see [Domain name registration](https://help.aliyun.com/document_detail/302325.html#title-mau-zdh-hd0).
+     * *   You can create up to 3,000 short URLs within a natural day.
+     * *   After a short URL is generated, a security review is required. Generally, the review takes 10 minutes to 2 hours to complete. Before the security review is passed, the short URL cannot be directly accessed.
+     *  *
+     * @param AddShortUrlRequest $request AddShortUrlRequest
+     *
+     * @return AddShortUrlResponse AddShortUrlResponse
+     */
+    public function addShortUrl($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->addShortUrlWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary Creates a signature.
+     *  *
+     * @description You can call the AddSmsSign operation or use the [Short Message Service (SMS) console](https://dysms.console.aliyun.com/dysms.htm#/overview) to create an SMS signature. The signature must comply with the [SMS signature specifications](https://help.aliyun.com/document_detail/108076.html). You can call the QuerySmsSign operation or use the SMS console to query the review status of the signature.
+     * For more information, see [Usage notes](https://help.aliyun.com/document_detail/55324.html).
+     * ### QPS limit
+     * You can call this operation only once per second. If the number of calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     * >
+     * *   You cannot cancel the review of a signature.
+     * *   Individual users can create only one verification code signature, and can create only one general-purpose signature within a natural day. If you need to apply for multiple signatures, we recommend that you upgrade your account to an enterprise user.
+     * *   If you need to use the same signature for messages sent to recipients both in and outside the Chinese mainland, the signature must be a general-purpose signature.
+     * *   If you apply for a signature or message template, you must specify the signature scenario or template type. You must also provide the information of your services, such as a website URL, a domain name with an ICP filing, an application download URL, or the name of your WeChat official account or mini program. For sign-in scenarios, you must also provide an account and password for tests. A detailed description can improve the review efficiency of signatures and templates.
+     * *   An SMS signature must undergo a thorough review process before it can be approved for use.
+     *  *
+     * @param AddSmsSignRequest $request AddSmsSignRequest
+     * @param RuntimeOptions    $runtime runtime options for this request RuntimeOptions
+     *
+     * @return AddSmsSignResponse AddSmsSignResponse
+     */
+    public function addSmsSignWithOptions($request, $runtime)
+    {
+        Utils::validateModel($request);
+        $query = [];
+        if (!Utils::isUnset($request->ownerId)) {
+            $query['OwnerId'] = $request->ownerId;
+        }
+        if (!Utils::isUnset($request->remark)) {
+            $query['Remark'] = $request->remark;
+        }
+        if (!Utils::isUnset($request->resourceOwnerAccount)) {
+            $query['ResourceOwnerAccount'] = $request->resourceOwnerAccount;
+        }
+        if (!Utils::isUnset($request->resourceOwnerId)) {
+            $query['ResourceOwnerId'] = $request->resourceOwnerId;
+        }
+        if (!Utils::isUnset($request->signName)) {
+            $query['SignName'] = $request->signName;
+        }
+        if (!Utils::isUnset($request->signSource)) {
+            $query['SignSource'] = $request->signSource;
+        }
+        if (!Utils::isUnset($request->signType)) {
+            $query['SignType'] = $request->signType;
+        }
+        $body = [];
+        if (!Utils::isUnset($request->signFileList)) {
+            $body['SignFileList'] = $request->signFileList;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+            'body'  => OpenApiUtilClient::parseToMap($body),
+        ]);
+        $params = new Params([
+            'action'      => 'AddSmsSign',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return AddSmsSignResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary Creates a signature.
+     *  *
+     * @description You can call the AddSmsSign operation or use the [Short Message Service (SMS) console](https://dysms.console.aliyun.com/dysms.htm#/overview) to create an SMS signature. The signature must comply with the [SMS signature specifications](https://help.aliyun.com/document_detail/108076.html). You can call the QuerySmsSign operation or use the SMS console to query the review status of the signature.
+     * For more information, see [Usage notes](https://help.aliyun.com/document_detail/55324.html).
+     * ### QPS limit
+     * You can call this operation only once per second. If the number of calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     * >
+     * *   You cannot cancel the review of a signature.
+     * *   Individual users can create only one verification code signature, and can create only one general-purpose signature within a natural day. If you need to apply for multiple signatures, we recommend that you upgrade your account to an enterprise user.
+     * *   If you need to use the same signature for messages sent to recipients both in and outside the Chinese mainland, the signature must be a general-purpose signature.
+     * *   If you apply for a signature or message template, you must specify the signature scenario or template type. You must also provide the information of your services, such as a website URL, a domain name with an ICP filing, an application download URL, or the name of your WeChat official account or mini program. For sign-in scenarios, you must also provide an account and password for tests. A detailed description can improve the review efficiency of signatures and templates.
+     * *   An SMS signature must undergo a thorough review process before it can be approved for use.
+     *  *
+     * @param AddSmsSignRequest $request AddSmsSignRequest
+     *
+     * @return AddSmsSignResponse AddSmsSignResponse
+     */
+    public function addSmsSign($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->addSmsSignWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary Creates a message template.
+     *  *
+     * @description You can call the operation or use the [Alibaba Cloud SMS console](https://dysms.console.aliyun.com/dysms.htm#/overview) to apply for a message template. The template must comply with the [message template specifications](https://help.aliyun.com/document_detail/108253.html). You can call the [QuerySmsTemplate](https://help.aliyun.com/document_detail/419289.html) operation or use the Alibaba Cloud SMS console to check whether the message template is approved.
+     * >
+     * *   Message templates pending approval can be withdrawn. You can withdraw a message template pending approval on the Message Templates tab in the [Alibaba Cloud SMS console](https://dysms.console.aliyun.com/dysms.htm#/overview).
+     * *   Message templates that have been approved can be deleted, and cannot be modified. You can delete a message template pending approval on the Message Templates tab in the [Alibaba Cloud SMS console](https://dysms.console.aliyun.com/dysms.htm#/overview).
+     * *   If you call the AddSmsTemplate operation, you can apply for a maximum of 100 message templates in a calendar day. After you apply for a message template, we recommend that you wait for at least 30 seconds before you apply for another one. If you use the Alibaba Cloud SMS console, you can apply for an unlimited number of message templates.
+     * *   Messages sent to the Chinese mainland and messages sent to countries or regions outside the Chinese mainland use separate message templates. Create message templates based on your needs.
+     * *   If you apply for a signature or message template, you must specify the signature scenario or template type. You must also provide the information of your services, such as a website URL, a domain name with an ICP filing, an application download URL, or the name of your WeChat official account or mini program. For sign-in scenarios, you must also provide an account and password for tests. A detailed description can improve the review efficiency of signatures and templates.
+     * *   A signature must undergo a thorough review process before it can be approved for use. For more information, see [Usage notes](https://help.aliyun.com/document_detail/55324.html).
+     * ### QPS limits
+     * You can call this operation up to 1,000 times per second per account. If the number of calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param AddSmsTemplateRequest $request AddSmsTemplateRequest
+     * @param RuntimeOptions        $runtime runtime options for this request RuntimeOptions
+     *
+     * @return AddSmsTemplateResponse AddSmsTemplateResponse
+     */
+    public function addSmsTemplateWithOptions($request, $runtime)
+    {
+        Utils::validateModel($request);
+        $query = [];
+        if (!Utils::isUnset($request->ownerId)) {
+            $query['OwnerId'] = $request->ownerId;
+        }
+        if (!Utils::isUnset($request->remark)) {
+            $query['Remark'] = $request->remark;
+        }
+        if (!Utils::isUnset($request->resourceOwnerAccount)) {
+            $query['ResourceOwnerAccount'] = $request->resourceOwnerAccount;
+        }
+        if (!Utils::isUnset($request->resourceOwnerId)) {
+            $query['ResourceOwnerId'] = $request->resourceOwnerId;
+        }
+        if (!Utils::isUnset($request->templateContent)) {
+            $query['TemplateContent'] = $request->templateContent;
+        }
+        if (!Utils::isUnset($request->templateName)) {
+            $query['TemplateName'] = $request->templateName;
+        }
+        if (!Utils::isUnset($request->templateType)) {
+            $query['TemplateType'] = $request->templateType;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+        ]);
+        $params = new Params([
+            'action'      => 'AddSmsTemplate',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return AddSmsTemplateResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary Creates a message template.
+     *  *
+     * @description You can call the operation or use the [Alibaba Cloud SMS console](https://dysms.console.aliyun.com/dysms.htm#/overview) to apply for a message template. The template must comply with the [message template specifications](https://help.aliyun.com/document_detail/108253.html). You can call the [QuerySmsTemplate](https://help.aliyun.com/document_detail/419289.html) operation or use the Alibaba Cloud SMS console to check whether the message template is approved.
+     * >
+     * *   Message templates pending approval can be withdrawn. You can withdraw a message template pending approval on the Message Templates tab in the [Alibaba Cloud SMS console](https://dysms.console.aliyun.com/dysms.htm#/overview).
+     * *   Message templates that have been approved can be deleted, and cannot be modified. You can delete a message template pending approval on the Message Templates tab in the [Alibaba Cloud SMS console](https://dysms.console.aliyun.com/dysms.htm#/overview).
+     * *   If you call the AddSmsTemplate operation, you can apply for a maximum of 100 message templates in a calendar day. After you apply for a message template, we recommend that you wait for at least 30 seconds before you apply for another one. If you use the Alibaba Cloud SMS console, you can apply for an unlimited number of message templates.
+     * *   Messages sent to the Chinese mainland and messages sent to countries or regions outside the Chinese mainland use separate message templates. Create message templates based on your needs.
+     * *   If you apply for a signature or message template, you must specify the signature scenario or template type. You must also provide the information of your services, such as a website URL, a domain name with an ICP filing, an application download URL, or the name of your WeChat official account or mini program. For sign-in scenarios, you must also provide an account and password for tests. A detailed description can improve the review efficiency of signatures and templates.
+     * *   A signature must undergo a thorough review process before it can be approved for use. For more information, see [Usage notes](https://help.aliyun.com/document_detail/55324.html).
+     * ### QPS limits
+     * You can call this operation up to 1,000 times per second per account. If the number of calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param AddSmsTemplateRequest $request AddSmsTemplateRequest
+     *
+     * @return AddSmsTemplateResponse AddSmsTemplateResponse
+     */
+    public function addSmsTemplate($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->addSmsTemplateWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary Checks whether a mobile phone number can receive card messages.
+     *  *
+     * @description ### QPS limit
+     * You can call this operation up to 2,000 times per second per account. If the number of the calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param CheckMobilesCardSupportRequest $request CheckMobilesCardSupportRequest
+     * @param RuntimeOptions                 $runtime runtime options for this request RuntimeOptions
+     *
+     * @return CheckMobilesCardSupportResponse CheckMobilesCardSupportResponse
+     */
+    public function checkMobilesCardSupportWithOptions($request, $runtime)
+    {
+        Utils::validateModel($request);
+        $query = [];
+        if (!Utils::isUnset($request->mobiles)) {
+            $query['Mobiles'] = $request->mobiles;
+        }
+        if (!Utils::isUnset($request->templateCode)) {
+            $query['TemplateCode'] = $request->templateCode;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+        ]);
+        $params = new Params([
+            'action'      => 'CheckMobilesCardSupport',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return CheckMobilesCardSupportResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary Checks whether a mobile phone number can receive card messages.
+     *  *
+     * @description ### QPS limit
+     * You can call this operation up to 2,000 times per second per account. If the number of the calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param CheckMobilesCardSupportRequest $request CheckMobilesCardSupportRequest
+     *
+     * @return CheckMobilesCardSupportResponse CheckMobilesCardSupportResponse
+     */
+    public function checkMobilesCardSupport($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->checkMobilesCardSupportWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary Sends conversion rate information to Alibaba Cloud SMS.
+     *  *
+     * @param ConversionDataIntlRequest $request ConversionDataIntlRequest
+     * @param RuntimeOptions            $runtime runtime options for this request RuntimeOptions
+     *
+     * @return ConversionDataIntlResponse ConversionDataIntlResponse
+     */
+    public function conversionDataIntlWithOptions($request, $runtime)
+    {
+        Utils::validateModel($request);
+        $query = [];
+        if (!Utils::isUnset($request->conversionRate)) {
+            $query['ConversionRate'] = $request->conversionRate;
+        }
+        if (!Utils::isUnset($request->ownerId)) {
+            $query['OwnerId'] = $request->ownerId;
+        }
+        if (!Utils::isUnset($request->reportTime)) {
+            $query['ReportTime'] = $request->reportTime;
+        }
+        if (!Utils::isUnset($request->resourceOwnerAccount)) {
+            $query['ResourceOwnerAccount'] = $request->resourceOwnerAccount;
+        }
+        if (!Utils::isUnset($request->resourceOwnerId)) {
+            $query['ResourceOwnerId'] = $request->resourceOwnerId;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+        ]);
+        $params = new Params([
+            'action'      => 'ConversionDataIntl',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return ConversionDataIntlResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary Sends conversion rate information to Alibaba Cloud SMS.
+     *  *
+     * @param ConversionDataIntlRequest $request ConversionDataIntlRequest
+     *
+     * @return ConversionDataIntlResponse ConversionDataIntlResponse
+     */
+    public function conversionDataIntl($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->conversionDataIntlWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary Creates a card message template.
+     *  *
+     * @description *   The CreateCardSmsTemplate operation saves the card message template information, submits it to the mobile phone manufacturer for approval, and returns the message template ID.
+     * *   If the type of the message template is not supported or events that are not supported by the mobile phone manufacturer are specified, the template is not submitted. For more information, see [Supported message templates](https://help.aliyun.com/document_detail/434611.html).
+     * *   For information about sample card message templates, see [Sample card message templates](https://help.aliyun.com/document_detail/435361.html).
+     * ### QPS limit
+     * You can call this operation up to 300 times per second per account. If the number of the calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param CreateCardSmsTemplateRequest $tmpReq  CreateCardSmsTemplateRequest
+     * @param RuntimeOptions               $runtime runtime options for this request RuntimeOptions
+     *
+     * @return CreateCardSmsTemplateResponse CreateCardSmsTemplateResponse
+     */
+    public function createCardSmsTemplateWithOptions($tmpReq, $runtime)
+    {
+        Utils::validateModel($tmpReq);
+        $request = new CreateCardSmsTemplateShrinkRequest([]);
+        OpenApiUtilClient::convert($tmpReq, $request);
+        if (!Utils::isUnset($tmpReq->template)) {
+            $request->templateShrink = OpenApiUtilClient::arrayToStringWithSpecifiedStyle($tmpReq->template, 'Template', 'json');
+        }
+        $query = [];
+        if (!Utils::isUnset($request->factorys)) {
+            $query['Factorys'] = $request->factorys;
+        }
+        if (!Utils::isUnset($request->memo)) {
+            $query['Memo'] = $request->memo;
+        }
+        if (!Utils::isUnset($request->templateShrink)) {
+            $query['Template'] = $request->templateShrink;
+        }
+        if (!Utils::isUnset($request->templateName)) {
+            $query['TemplateName'] = $request->templateName;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+        ]);
+        $params = new Params([
+            'action'      => 'CreateCardSmsTemplate',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return CreateCardSmsTemplateResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary Creates a card message template.
+     *  *
+     * @description *   The CreateCardSmsTemplate operation saves the card message template information, submits it to the mobile phone manufacturer for approval, and returns the message template ID.
+     * *   If the type of the message template is not supported or events that are not supported by the mobile phone manufacturer are specified, the template is not submitted. For more information, see [Supported message templates](https://help.aliyun.com/document_detail/434611.html).
+     * *   For information about sample card message templates, see [Sample card message templates](https://help.aliyun.com/document_detail/435361.html).
+     * ### QPS limit
+     * You can call this operation up to 300 times per second per account. If the number of the calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param CreateCardSmsTemplateRequest $request CreateCardSmsTemplateRequest
+     *
+     * @return CreateCardSmsTemplateResponse CreateCardSmsTemplateResponse
+     */
+    public function createCardSmsTemplate($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->createCardSmsTemplateWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary 创建短链
+     *  *
+     * @param CreateSmartShortUrlRequest $request CreateSmartShortUrlRequest
+     * @param RuntimeOptions             $runtime runtime options for this request RuntimeOptions
+     *
+     * @return CreateSmartShortUrlResponse CreateSmartShortUrlResponse
+     */
+    public function createSmartShortUrlWithOptions($request, $runtime)
+    {
+        Utils::validateModel($request);
+        $query = [];
+        if (!Utils::isUnset($request->outId)) {
+            $query['OutId'] = $request->outId;
+        }
+        if (!Utils::isUnset($request->ownerId)) {
+            $query['OwnerId'] = $request->ownerId;
+        }
+        if (!Utils::isUnset($request->phoneNumbers)) {
+            $query['PhoneNumbers'] = $request->phoneNumbers;
+        }
+        if (!Utils::isUnset($request->resourceOwnerAccount)) {
+            $query['ResourceOwnerAccount'] = $request->resourceOwnerAccount;
+        }
+        if (!Utils::isUnset($request->resourceOwnerId)) {
+            $query['ResourceOwnerId'] = $request->resourceOwnerId;
+        }
+        if (!Utils::isUnset($request->sourceUrl)) {
+            $query['SourceUrl'] = $request->sourceUrl;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+        ]);
+        $params = new Params([
+            'action'      => 'CreateSmartShortUrl',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return CreateSmartShortUrlResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary 创建短链
+     *  *
+     * @param CreateSmartShortUrlRequest $request CreateSmartShortUrlRequest
+     *
+     * @return CreateSmartShortUrlResponse CreateSmartShortUrlResponse
+     */
+    public function createSmartShortUrl($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->createSmartShortUrlWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary 创建短信签名
+     *  *
+     * @param CreateSmsSignRequest $tmpReq  CreateSmsSignRequest
+     * @param RuntimeOptions       $runtime runtime options for this request RuntimeOptions
+     *
+     * @return CreateSmsSignResponse CreateSmsSignResponse
+     */
+    public function createSmsSignWithOptions($tmpReq, $runtime)
+    {
+        Utils::validateModel($tmpReq);
+        $request = new CreateSmsSignShrinkRequest([]);
+        OpenApiUtilClient::convert($tmpReq, $request);
+        if (!Utils::isUnset($tmpReq->moreData)) {
+            $request->moreDataShrink = OpenApiUtilClient::arrayToStringWithSpecifiedStyle($tmpReq->moreData, 'MoreData', 'json');
+        }
+        $query = [];
+        if (!Utils::isUnset($request->applySceneContent)) {
+            $query['ApplySceneContent'] = $request->applySceneContent;
+        }
+        if (!Utils::isUnset($request->moreDataShrink)) {
+            $query['MoreData'] = $request->moreDataShrink;
+        }
+        if (!Utils::isUnset($request->ownerId)) {
+            $query['OwnerId'] = $request->ownerId;
+        }
+        if (!Utils::isUnset($request->qualificationId)) {
+            $query['QualificationId'] = $request->qualificationId;
+        }
+        if (!Utils::isUnset($request->remark)) {
+            $query['Remark'] = $request->remark;
+        }
+        if (!Utils::isUnset($request->resourceOwnerAccount)) {
+            $query['ResourceOwnerAccount'] = $request->resourceOwnerAccount;
+        }
+        if (!Utils::isUnset($request->resourceOwnerId)) {
+            $query['ResourceOwnerId'] = $request->resourceOwnerId;
+        }
+        if (!Utils::isUnset($request->signName)) {
+            $query['SignName'] = $request->signName;
+        }
+        if (!Utils::isUnset($request->signSource)) {
+            $query['SignSource'] = $request->signSource;
+        }
+        if (!Utils::isUnset($request->signType)) {
+            $query['SignType'] = $request->signType;
+        }
+        if (!Utils::isUnset($request->thirdParty)) {
+            $query['ThirdParty'] = $request->thirdParty;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+        ]);
+        $params = new Params([
+            'action'      => 'CreateSmsSign',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return CreateSmsSignResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary 创建短信签名
+     *  *
+     * @param CreateSmsSignRequest $request CreateSmsSignRequest
+     *
+     * @return CreateSmsSignResponse CreateSmsSignResponse
+     */
+    public function createSmsSign($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->createSmsSignWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary 创建短信模板
+     *  *
+     * @param CreateSmsTemplateRequest $tmpReq  CreateSmsTemplateRequest
+     * @param RuntimeOptions           $runtime runtime options for this request RuntimeOptions
+     *
+     * @return CreateSmsTemplateResponse CreateSmsTemplateResponse
+     */
+    public function createSmsTemplateWithOptions($tmpReq, $runtime)
+    {
+        Utils::validateModel($tmpReq);
+        $request = new CreateSmsTemplateShrinkRequest([]);
+        OpenApiUtilClient::convert($tmpReq, $request);
+        if (!Utils::isUnset($tmpReq->moreData)) {
+            $request->moreDataShrink = OpenApiUtilClient::arrayToStringWithSpecifiedStyle($tmpReq->moreData, 'MoreData', 'json');
+        }
+        $query = [];
+        if (!Utils::isUnset($request->applySceneContent)) {
+            $query['ApplySceneContent'] = $request->applySceneContent;
+        }
+        if (!Utils::isUnset($request->intlType)) {
+            $query['IntlType'] = $request->intlType;
+        }
+        if (!Utils::isUnset($request->moreDataShrink)) {
+            $query['MoreData'] = $request->moreDataShrink;
+        }
+        if (!Utils::isUnset($request->ownerId)) {
+            $query['OwnerId'] = $request->ownerId;
+        }
+        if (!Utils::isUnset($request->relatedSignName)) {
+            $query['RelatedSignName'] = $request->relatedSignName;
+        }
+        if (!Utils::isUnset($request->remark)) {
+            $query['Remark'] = $request->remark;
+        }
+        if (!Utils::isUnset($request->resourceOwnerAccount)) {
+            $query['ResourceOwnerAccount'] = $request->resourceOwnerAccount;
+        }
+        if (!Utils::isUnset($request->resourceOwnerId)) {
+            $query['ResourceOwnerId'] = $request->resourceOwnerId;
+        }
+        if (!Utils::isUnset($request->templateContent)) {
+            $query['TemplateContent'] = $request->templateContent;
+        }
+        if (!Utils::isUnset($request->templateName)) {
+            $query['TemplateName'] = $request->templateName;
+        }
+        if (!Utils::isUnset($request->templateRule)) {
+            $query['TemplateRule'] = $request->templateRule;
+        }
+        if (!Utils::isUnset($request->templateType)) {
+            $query['TemplateType'] = $request->templateType;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+        ]);
+        $params = new Params([
+            'action'      => 'CreateSmsTemplate',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return CreateSmsTemplateResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary 创建短信模板
+     *  *
+     * @param CreateSmsTemplateRequest $request CreateSmsTemplateRequest
+     *
+     * @return CreateSmsTemplateResponse CreateSmsTemplateResponse
+     */
+    public function createSmsTemplate($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->createSmsTemplateWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary Deletes a short URL. After you delete a short URL, it cannot be changed to its original state.
+     *  *
+     * @description ### QPS limits
+     * You can call this operation up to 100 times per second per account. If the number of the calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param DeleteShortUrlRequest $request DeleteShortUrlRequest
+     * @param RuntimeOptions        $runtime runtime options for this request RuntimeOptions
+     *
+     * @return DeleteShortUrlResponse DeleteShortUrlResponse
+     */
+    public function deleteShortUrlWithOptions($request, $runtime)
+    {
+        Utils::validateModel($request);
+        $query = [];
+        if (!Utils::isUnset($request->ownerId)) {
+            $query['OwnerId'] = $request->ownerId;
+        }
+        if (!Utils::isUnset($request->resourceOwnerAccount)) {
+            $query['ResourceOwnerAccount'] = $request->resourceOwnerAccount;
+        }
+        if (!Utils::isUnset($request->resourceOwnerId)) {
+            $query['ResourceOwnerId'] = $request->resourceOwnerId;
+        }
+        $body = [];
+        if (!Utils::isUnset($request->sourceUrl)) {
+            $body['SourceUrl'] = $request->sourceUrl;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+            'body'  => OpenApiUtilClient::parseToMap($body),
+        ]);
+        $params = new Params([
+            'action'      => 'DeleteShortUrl',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return DeleteShortUrlResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary Deletes a short URL. After you delete a short URL, it cannot be changed to its original state.
+     *  *
+     * @description ### QPS limits
+     * You can call this operation up to 100 times per second per account. If the number of the calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param DeleteShortUrlRequest $request DeleteShortUrlRequest
+     *
+     * @return DeleteShortUrlResponse DeleteShortUrlResponse
+     */
+    public function deleteShortUrl($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->deleteShortUrlWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary Deletes a signature.
+     *  *
+     * @description *   You cannot delete a signature that has not been approved.
+     * *   After you delete a signature, you cannot recover it. Proceed with caution.
+     * ### QPS limits
+     * You can call this operation up to 1,000 times per second per account. If the number of the calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param DeleteSmsSignRequest $request DeleteSmsSignRequest
+     * @param RuntimeOptions       $runtime runtime options for this request RuntimeOptions
+     *
+     * @return DeleteSmsSignResponse DeleteSmsSignResponse
+     */
+    public function deleteSmsSignWithOptions($request, $runtime)
+    {
+        Utils::validateModel($request);
+        $query = [];
+        if (!Utils::isUnset($request->ownerId)) {
+            $query['OwnerId'] = $request->ownerId;
+        }
+        if (!Utils::isUnset($request->resourceOwnerAccount)) {
+            $query['ResourceOwnerAccount'] = $request->resourceOwnerAccount;
+        }
+        if (!Utils::isUnset($request->resourceOwnerId)) {
+            $query['ResourceOwnerId'] = $request->resourceOwnerId;
+        }
+        if (!Utils::isUnset($request->signName)) {
+            $query['SignName'] = $request->signName;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+        ]);
+        $params = new Params([
+            'action'      => 'DeleteSmsSign',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return DeleteSmsSignResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary Deletes a signature.
+     *  *
+     * @description *   You cannot delete a signature that has not been approved.
+     * *   After you delete a signature, you cannot recover it. Proceed with caution.
+     * ### QPS limits
+     * You can call this operation up to 1,000 times per second per account. If the number of the calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param DeleteSmsSignRequest $request DeleteSmsSignRequest
+     *
+     * @return DeleteSmsSignResponse DeleteSmsSignResponse
+     */
+    public function deleteSmsSign($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->deleteSmsSignWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary Deletes a message template.
+     *  *
+     * @description *   Message templates pending approval can be withdrawn. You can delete a message template pending approval on the Message Templates tab in the [Alibaba Cloud SMS console](https://dysms.console.aliyun.com/dysms.htm#/overview).
+     * *   Message templates that have been approved can be deleted, and cannot be modified. You can delete a message template pending approval on the Message Templates tab in the [Alibaba Cloud SMS console](https://dysms.console.aliyun.com/dysms.htm#/overview).
+     * *   You cannot recover deleted message templates. Proceed with caution.
+     * ### QPS limits
+     * You can call this operation up to 1,000 times per second per account. If the number of calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param DeleteSmsTemplateRequest $request DeleteSmsTemplateRequest
+     * @param RuntimeOptions           $runtime runtime options for this request RuntimeOptions
+     *
+     * @return DeleteSmsTemplateResponse DeleteSmsTemplateResponse
+     */
+    public function deleteSmsTemplateWithOptions($request, $runtime)
+    {
+        Utils::validateModel($request);
+        $query = [];
+        if (!Utils::isUnset($request->ownerId)) {
+            $query['OwnerId'] = $request->ownerId;
+        }
+        if (!Utils::isUnset($request->resourceOwnerAccount)) {
+            $query['ResourceOwnerAccount'] = $request->resourceOwnerAccount;
+        }
+        if (!Utils::isUnset($request->resourceOwnerId)) {
+            $query['ResourceOwnerId'] = $request->resourceOwnerId;
+        }
+        if (!Utils::isUnset($request->templateCode)) {
+            $query['TemplateCode'] = $request->templateCode;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+        ]);
+        $params = new Params([
+            'action'      => 'DeleteSmsTemplate',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return DeleteSmsTemplateResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary Deletes a message template.
+     *  *
+     * @description *   Message templates pending approval can be withdrawn. You can delete a message template pending approval on the Message Templates tab in the [Alibaba Cloud SMS console](https://dysms.console.aliyun.com/dysms.htm#/overview).
+     * *   Message templates that have been approved can be deleted, and cannot be modified. You can delete a message template pending approval on the Message Templates tab in the [Alibaba Cloud SMS console](https://dysms.console.aliyun.com/dysms.htm#/overview).
+     * *   You cannot recover deleted message templates. Proceed with caution.
+     * ### QPS limits
+     * You can call this operation up to 1,000 times per second per account. If the number of calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param DeleteSmsTemplateRequest $request DeleteSmsTemplateRequest
+     *
+     * @return DeleteSmsTemplateResponse DeleteSmsTemplateResponse
+     */
+    public function deleteSmsTemplate($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->deleteSmsTemplateWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary Queries the short URLs of a card messages template.
+     *  *
+     * @description ### QPS limit
+     * You can call this operation up to 1,000 times per second per account. If the number of the calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param GetCardSmsLinkRequest $request GetCardSmsLinkRequest
+     * @param RuntimeOptions        $runtime runtime options for this request RuntimeOptions
+     *
+     * @return GetCardSmsLinkResponse GetCardSmsLinkResponse
+     */
+    public function getCardSmsLinkWithOptions($request, $runtime)
+    {
+        Utils::validateModel($request);
+        $query = [];
+        if (!Utils::isUnset($request->cardCodeType)) {
+            $query['CardCodeType'] = $request->cardCodeType;
+        }
+        if (!Utils::isUnset($request->cardLinkType)) {
+            $query['CardLinkType'] = $request->cardLinkType;
+        }
+        if (!Utils::isUnset($request->cardTemplateCode)) {
+            $query['CardTemplateCode'] = $request->cardTemplateCode;
+        }
+        if (!Utils::isUnset($request->cardTemplateParamJson)) {
+            $query['CardTemplateParamJson'] = $request->cardTemplateParamJson;
+        }
+        if (!Utils::isUnset($request->customShortCodeJson)) {
+            $query['CustomShortCodeJson'] = $request->customShortCodeJson;
+        }
+        if (!Utils::isUnset($request->domain)) {
+            $query['Domain'] = $request->domain;
+        }
+        if (!Utils::isUnset($request->outId)) {
+            $query['OutId'] = $request->outId;
+        }
+        if (!Utils::isUnset($request->phoneNumberJson)) {
+            $query['PhoneNumberJson'] = $request->phoneNumberJson;
+        }
+        if (!Utils::isUnset($request->signNameJson)) {
+            $query['SignNameJson'] = $request->signNameJson;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+        ]);
+        $params = new Params([
+            'action'      => 'GetCardSmsLink',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return GetCardSmsLinkResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary Queries the short URLs of a card messages template.
+     *  *
+     * @description ### QPS limit
+     * You can call this operation up to 1,000 times per second per account. If the number of the calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param GetCardSmsLinkRequest $request GetCardSmsLinkRequest
+     *
+     * @return GetCardSmsLinkResponse GetCardSmsLinkResponse
+     */
+    public function getCardSmsLink($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->getCardSmsLinkWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary Converts a resource uploaded to the specified Object Storage Service (OSS) bucket for unified management. Then, a resource ID is returned. You can manage the resource based on the ID.
+     *  *
+     * @description ### QPS limit
+     * You can call this operation up to 300 times per second per account. If the number of the calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param GetMediaResourceIdRequest $request GetMediaResourceIdRequest
+     * @param RuntimeOptions            $runtime runtime options for this request RuntimeOptions
+     *
+     * @return GetMediaResourceIdResponse GetMediaResourceIdResponse
+     */
+    public function getMediaResourceIdWithOptions($request, $runtime)
+    {
+        Utils::validateModel($request);
+        $query = [];
+        if (!Utils::isUnset($request->extendInfo)) {
+            $query['ExtendInfo'] = $request->extendInfo;
+        }
+        if (!Utils::isUnset($request->fileSize)) {
+            $query['FileSize'] = $request->fileSize;
+        }
+        if (!Utils::isUnset($request->memo)) {
+            $query['Memo'] = $request->memo;
+        }
+        if (!Utils::isUnset($request->ossKey)) {
+            $query['OssKey'] = $request->ossKey;
+        }
+        if (!Utils::isUnset($request->resourceType)) {
+            $query['ResourceType'] = $request->resourceType;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+        ]);
+        $params = new Params([
+            'action'      => 'GetMediaResourceId',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return GetMediaResourceIdResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary Converts a resource uploaded to the specified Object Storage Service (OSS) bucket for unified management. Then, a resource ID is returned. You can manage the resource based on the ID.
+     *  *
+     * @description ### QPS limit
+     * You can call this operation up to 300 times per second per account. If the number of the calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param GetMediaResourceIdRequest $request GetMediaResourceIdRequest
+     *
+     * @return GetMediaResourceIdResponse GetMediaResourceIdResponse
+     */
+    public function getMediaResourceId($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->getMediaResourceIdWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary Queries the OSS configuration information about card messages.
+     *  *
+     * @description Resources such as images and videos used for card message templates can be uploaded to Object Storage Service (OSS) buckets for storage. For more information, see [Upload files to OSS](https://help.aliyun.com/document_detail/437303.html).
+     * ### QPS limit
+     * You can call this operation up to 300 times per second per account. If the number of the calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param RuntimeOptions $runtime runtime options for this request RuntimeOptions
+     *
+     * @return GetOSSInfoForCardTemplateResponse GetOSSInfoForCardTemplateResponse
+     */
+    public function getOSSInfoForCardTemplateWithOptions($runtime)
+    {
+        $req    = new OpenApiRequest([]);
+        $params = new Params([
+            'action'      => 'GetOSSInfoForCardTemplate',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return GetOSSInfoForCardTemplateResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary Queries the OSS configuration information about card messages.
+     *  *
+     * @description Resources such as images and videos used for card message templates can be uploaded to Object Storage Service (OSS) buckets for storage. For more information, see [Upload files to OSS](https://help.aliyun.com/document_detail/437303.html).
+     * ### QPS limit
+     * You can call this operation up to 300 times per second per account. If the number of the calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @return GetOSSInfoForCardTemplateResponse GetOSSInfoForCardTemplateResponse
+     */
+    public function getOSSInfoForCardTemplate()
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->getOSSInfoForCardTemplateWithOptions($runtime);
+    }
+
+    /**
+     * @summary 短信上传文件,获取授权信息
+     *  *
+     * @param GetOSSInfoForUploadFileRequest $request GetOSSInfoForUploadFileRequest
+     * @param RuntimeOptions                 $runtime runtime options for this request RuntimeOptions
+     *
+     * @return GetOSSInfoForUploadFileResponse GetOSSInfoForUploadFileResponse
+     */
+    public function getOSSInfoForUploadFileWithOptions($request, $runtime)
+    {
+        Utils::validateModel($request);
+        $query = [];
+        if (!Utils::isUnset($request->bizType)) {
+            $query['BizType'] = $request->bizType;
+        }
+        if (!Utils::isUnset($request->ownerId)) {
+            $query['OwnerId'] = $request->ownerId;
+        }
+        if (!Utils::isUnset($request->resourceOwnerAccount)) {
+            $query['ResourceOwnerAccount'] = $request->resourceOwnerAccount;
+        }
+        if (!Utils::isUnset($request->resourceOwnerId)) {
+            $query['ResourceOwnerId'] = $request->resourceOwnerId;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+        ]);
+        $params = new Params([
+            'action'      => 'GetOSSInfoForUploadFile',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return GetOSSInfoForUploadFileResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary 短信上传文件,获取授权信息
+     *  *
+     * @param GetOSSInfoForUploadFileRequest $request GetOSSInfoForUploadFileRequest
+     *
+     * @return GetOSSInfoForUploadFileResponse GetOSSInfoForUploadFileResponse
+     */
+    public function getOSSInfoForUploadFile($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->getOSSInfoForUploadFileWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary 查询短信签名详情
+     *  *
+     * @param GetSmsSignRequest $request GetSmsSignRequest
+     * @param RuntimeOptions    $runtime runtime options for this request RuntimeOptions
+     *
+     * @return GetSmsSignResponse GetSmsSignResponse
+     */
+    public function getSmsSignWithOptions($request, $runtime)
+    {
+        Utils::validateModel($request);
+        $query = [];
+        if (!Utils::isUnset($request->ownerId)) {
+            $query['OwnerId'] = $request->ownerId;
+        }
+        if (!Utils::isUnset($request->resourceOwnerAccount)) {
+            $query['ResourceOwnerAccount'] = $request->resourceOwnerAccount;
+        }
+        if (!Utils::isUnset($request->resourceOwnerId)) {
+            $query['ResourceOwnerId'] = $request->resourceOwnerId;
+        }
+        if (!Utils::isUnset($request->signName)) {
+            $query['SignName'] = $request->signName;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+        ]);
+        $params = new Params([
+            'action'      => 'GetSmsSign',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return GetSmsSignResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary 查询短信签名详情
+     *  *
+     * @param GetSmsSignRequest $request GetSmsSignRequest
+     *
+     * @return GetSmsSignResponse GetSmsSignResponse
+     */
+    public function getSmsSign($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->getSmsSignWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary 查询文本短信模板详情
+     *  *
+     * @param GetSmsTemplateRequest $request GetSmsTemplateRequest
+     * @param RuntimeOptions        $runtime runtime options for this request RuntimeOptions
+     *
+     * @return GetSmsTemplateResponse GetSmsTemplateResponse
+     */
+    public function getSmsTemplateWithOptions($request, $runtime)
+    {
+        Utils::validateModel($request);
+        $query = [];
+        if (!Utils::isUnset($request->ownerId)) {
+            $query['OwnerId'] = $request->ownerId;
+        }
+        if (!Utils::isUnset($request->resourceOwnerAccount)) {
+            $query['ResourceOwnerAccount'] = $request->resourceOwnerAccount;
+        }
+        if (!Utils::isUnset($request->resourceOwnerId)) {
+            $query['ResourceOwnerId'] = $request->resourceOwnerId;
+        }
+        if (!Utils::isUnset($request->templateCode)) {
+            $query['TemplateCode'] = $request->templateCode;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+        ]);
+        $params = new Params([
+            'action'      => 'GetSmsTemplate',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return GetSmsTemplateResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary 查询文本短信模板详情
+     *  *
+     * @param GetSmsTemplateRequest $request GetSmsTemplateRequest
+     *
+     * @return GetSmsTemplateResponse GetSmsTemplateResponse
+     */
+    public function getSmsTemplate($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->getSmsTemplateWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary Queries the tags of a message template.
+     *  *
+     * @description ### QPS limit
+     * You can call this operation up to 50 times per second per account. If the number of the calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param ListTagResourcesRequest $request ListTagResourcesRequest
+     * @param RuntimeOptions          $runtime runtime options for this request RuntimeOptions
+     *
+     * @return ListTagResourcesResponse ListTagResourcesResponse
+     */
+    public function listTagResourcesWithOptions($request, $runtime)
+    {
+        Utils::validateModel($request);
+        $query = [];
+        if (!Utils::isUnset($request->nextToken)) {
+            $query['NextToken'] = $request->nextToken;
+        }
+        if (!Utils::isUnset($request->ownerId)) {
+            $query['OwnerId'] = $request->ownerId;
+        }
+        if (!Utils::isUnset($request->pageSize)) {
+            $query['PageSize'] = $request->pageSize;
+        }
+        if (!Utils::isUnset($request->prodCode)) {
+            $query['ProdCode'] = $request->prodCode;
+        }
+        if (!Utils::isUnset($request->regionId)) {
+            $query['RegionId'] = $request->regionId;
+        }
+        if (!Utils::isUnset($request->resourceId)) {
+            $query['ResourceId'] = $request->resourceId;
+        }
+        if (!Utils::isUnset($request->resourceOwnerAccount)) {
+            $query['ResourceOwnerAccount'] = $request->resourceOwnerAccount;
+        }
+        if (!Utils::isUnset($request->resourceOwnerId)) {
+            $query['ResourceOwnerId'] = $request->resourceOwnerId;
+        }
+        if (!Utils::isUnset($request->resourceType)) {
+            $query['ResourceType'] = $request->resourceType;
+        }
+        if (!Utils::isUnset($request->tag)) {
+            $query['Tag'] = $request->tag;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+        ]);
+        $params = new Params([
+            'action'      => 'ListTagResources',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return ListTagResourcesResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary Queries the tags of a message template.
+     *  *
+     * @description ### QPS limit
+     * You can call this operation up to 50 times per second per account. If the number of the calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param ListTagResourcesRequest $request ListTagResourcesRequest
+     *
+     * @return ListTagResourcesResponse ListTagResourcesResponse
+     */
+    public function listTagResources($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->listTagResourcesWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary Modifies a rejected signature and submit it for approval. Signatures that are pending approval or have been approved cannot be modified.
+     *  *
+     * @description You can call the operation or use the [Alibaba Cloud SMS console](https://dysms.console.aliyun.com/dysms.htm#/overview) to modify an existing signature and submit the signature for approval. The signature must comply with the [signature specifications](https://help.aliyun.com/document_detail/108076.html).
+     * For more information, see [Usage notes](https://help.aliyun.com/document_detail/55324.html).
+     * ### QPS limits
+     * You can call this operation up to 1,000 times per second per account. If the number of calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     * >
+     * *   Signatures pending approval cannot be modified.
+     * *   You cannot modify a signature after it is approved. If you no longer need the signature, you can delete it.
+     * *   If you are an individual user, you cannot apply for a new signature on the same day that your signature is rejected or deleted. We recommend that you modify the rejected signature and submit it again.
+     *  *
+     * @param ModifySmsSignRequest $request ModifySmsSignRequest
+     * @param RuntimeOptions       $runtime runtime options for this request RuntimeOptions
+     *
+     * @return ModifySmsSignResponse ModifySmsSignResponse
+     */
+    public function modifySmsSignWithOptions($request, $runtime)
+    {
+        Utils::validateModel($request);
+        $query = [];
+        if (!Utils::isUnset($request->ownerId)) {
+            $query['OwnerId'] = $request->ownerId;
+        }
+        if (!Utils::isUnset($request->remark)) {
+            $query['Remark'] = $request->remark;
+        }
+        if (!Utils::isUnset($request->resourceOwnerAccount)) {
+            $query['ResourceOwnerAccount'] = $request->resourceOwnerAccount;
+        }
+        if (!Utils::isUnset($request->resourceOwnerId)) {
+            $query['ResourceOwnerId'] = $request->resourceOwnerId;
+        }
+        if (!Utils::isUnset($request->signName)) {
+            $query['SignName'] = $request->signName;
+        }
+        if (!Utils::isUnset($request->signSource)) {
+            $query['SignSource'] = $request->signSource;
+        }
+        if (!Utils::isUnset($request->signType)) {
+            $query['SignType'] = $request->signType;
+        }
+        $body = [];
+        if (!Utils::isUnset($request->signFileList)) {
+            $body['SignFileList'] = $request->signFileList;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+            'body'  => OpenApiUtilClient::parseToMap($body),
+        ]);
+        $params = new Params([
+            'action'      => 'ModifySmsSign',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return ModifySmsSignResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary Modifies a rejected signature and submit it for approval. Signatures that are pending approval or have been approved cannot be modified.
+     *  *
+     * @description You can call the operation or use the [Alibaba Cloud SMS console](https://dysms.console.aliyun.com/dysms.htm#/overview) to modify an existing signature and submit the signature for approval. The signature must comply with the [signature specifications](https://help.aliyun.com/document_detail/108076.html).
+     * For more information, see [Usage notes](https://help.aliyun.com/document_detail/55324.html).
+     * ### QPS limits
+     * You can call this operation up to 1,000 times per second per account. If the number of calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     * >
+     * *   Signatures pending approval cannot be modified.
+     * *   You cannot modify a signature after it is approved. If you no longer need the signature, you can delete it.
+     * *   If you are an individual user, you cannot apply for a new signature on the same day that your signature is rejected or deleted. We recommend that you modify the rejected signature and submit it again.
+     *  *
+     * @param ModifySmsSignRequest $request ModifySmsSignRequest
+     *
+     * @return ModifySmsSignResponse ModifySmsSignResponse
+     */
+    public function modifySmsSign($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->modifySmsSignWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary Modifies the information of an unapproved message template and submits it for review again.
+     *  *
+     * @description After you apply for a message template, if the template fails to pass the review, you can call this operation to modify the template and submit the template again. You can call this operation to modify only a template for a specific message type.
+     * The template content must comply with the [SMS template specifications](https://help.aliyun.com/document_detail/108253.html).
+     * For more information, see [Usage notes](https://help.aliyun.com/document_detail/55324.html).
+     * ### QPS limit
+     * You can call this operation up to 1,000 times per second per account. If the number of calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param ModifySmsTemplateRequest $request ModifySmsTemplateRequest
+     * @param RuntimeOptions           $runtime runtime options for this request RuntimeOptions
+     *
+     * @return ModifySmsTemplateResponse ModifySmsTemplateResponse
+     */
+    public function modifySmsTemplateWithOptions($request, $runtime)
+    {
+        Utils::validateModel($request);
+        $query = [];
+        if (!Utils::isUnset($request->ownerId)) {
+            $query['OwnerId'] = $request->ownerId;
+        }
+        if (!Utils::isUnset($request->remark)) {
+            $query['Remark'] = $request->remark;
+        }
+        if (!Utils::isUnset($request->resourceOwnerAccount)) {
+            $query['ResourceOwnerAccount'] = $request->resourceOwnerAccount;
+        }
+        if (!Utils::isUnset($request->resourceOwnerId)) {
+            $query['ResourceOwnerId'] = $request->resourceOwnerId;
+        }
+        if (!Utils::isUnset($request->templateCode)) {
+            $query['TemplateCode'] = $request->templateCode;
+        }
+        if (!Utils::isUnset($request->templateContent)) {
+            $query['TemplateContent'] = $request->templateContent;
+        }
+        if (!Utils::isUnset($request->templateName)) {
+            $query['TemplateName'] = $request->templateName;
+        }
+        if (!Utils::isUnset($request->templateType)) {
+            $query['TemplateType'] = $request->templateType;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+        ]);
+        $params = new Params([
+            'action'      => 'ModifySmsTemplate',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return ModifySmsTemplateResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary Modifies the information of an unapproved message template and submits it for review again.
+     *  *
+     * @description After you apply for a message template, if the template fails to pass the review, you can call this operation to modify the template and submit the template again. You can call this operation to modify only a template for a specific message type.
+     * The template content must comply with the [SMS template specifications](https://help.aliyun.com/document_detail/108253.html).
+     * For more information, see [Usage notes](https://help.aliyun.com/document_detail/55324.html).
+     * ### QPS limit
+     * You can call this operation up to 1,000 times per second per account. If the number of calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param ModifySmsTemplateRequest $request ModifySmsTemplateRequest
+     *
+     * @return ModifySmsTemplateResponse ModifySmsTemplateResponse
+     */
+    public function modifySmsTemplate($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->modifySmsTemplateWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary Queries the review status of a message template.
+     *  *
+     * @description ### QPS limit
+     * You can call this operation up to 300 times per second per account. If the number of the calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param QueryCardSmsTemplateRequest $request QueryCardSmsTemplateRequest
+     * @param RuntimeOptions              $runtime runtime options for this request RuntimeOptions
+     *
+     * @return QueryCardSmsTemplateResponse QueryCardSmsTemplateResponse
+     */
+    public function queryCardSmsTemplateWithOptions($request, $runtime)
+    {
+        Utils::validateModel($request);
+        $query = [];
+        if (!Utils::isUnset($request->templateCode)) {
+            $query['TemplateCode'] = $request->templateCode;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+        ]);
+        $params = new Params([
+            'action'      => 'QueryCardSmsTemplate',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return QueryCardSmsTemplateResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary Queries the review status of a message template.
+     *  *
+     * @description ### QPS limit
+     * You can call this operation up to 300 times per second per account. If the number of the calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param QueryCardSmsTemplateRequest $request QueryCardSmsTemplateRequest
+     *
+     * @return QueryCardSmsTemplateResponse QueryCardSmsTemplateResponse
+     */
+    public function queryCardSmsTemplate($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->queryCardSmsTemplateWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary Queries sent card messages.
+     *  *
+     * @description ### QPS limit
+     * You can call this operation up to 300 times per second per account. If the number of the calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param QueryCardSmsTemplateReportRequest $request QueryCardSmsTemplateReportRequest
+     * @param RuntimeOptions                    $runtime runtime options for this request RuntimeOptions
+     *
+     * @return QueryCardSmsTemplateReportResponse QueryCardSmsTemplateReportResponse
+     */
+    public function queryCardSmsTemplateReportWithOptions($request, $runtime)
+    {
+        Utils::validateModel($request);
+        $query = [];
+        if (!Utils::isUnset($request->endDate)) {
+            $query['EndDate'] = $request->endDate;
+        }
+        if (!Utils::isUnset($request->startDate)) {
+            $query['StartDate'] = $request->startDate;
+        }
+        if (!Utils::isUnset($request->templateCodes)) {
+            $query['TemplateCodes'] = $request->templateCodes;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+        ]);
+        $params = new Params([
+            'action'      => 'QueryCardSmsTemplateReport',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return QueryCardSmsTemplateReportResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary Queries sent card messages.
+     *  *
+     * @description ### QPS limit
+     * You can call this operation up to 300 times per second per account. If the number of the calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param QueryCardSmsTemplateReportRequest $request QueryCardSmsTemplateReportRequest
+     *
+     * @return QueryCardSmsTemplateReportResponse QueryCardSmsTemplateReportResponse
+     */
+    public function queryCardSmsTemplateReport($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->queryCardSmsTemplateReportWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary Checks whether a mobile phone number can receive card messages.
+     *  *
+     * @param QueryMobilesCardSupportRequest $tmpReq  QueryMobilesCardSupportRequest
+     * @param RuntimeOptions                 $runtime runtime options for this request RuntimeOptions
+     *
+     * @return QueryMobilesCardSupportResponse QueryMobilesCardSupportResponse
+     */
+    public function queryMobilesCardSupportWithOptions($tmpReq, $runtime)
+    {
+        Utils::validateModel($tmpReq);
+        $request = new QueryMobilesCardSupportShrinkRequest([]);
+        OpenApiUtilClient::convert($tmpReq, $request);
+        if (!Utils::isUnset($tmpReq->mobiles)) {
+            $request->mobilesShrink = OpenApiUtilClient::arrayToStringWithSpecifiedStyle($tmpReq->mobiles, 'Mobiles', 'json');
+        }
+        $query = [];
+        if (!Utils::isUnset($request->mobilesShrink)) {
+            $query['Mobiles'] = $request->mobilesShrink;
+        }
+        if (!Utils::isUnset($request->templateCode)) {
+            $query['TemplateCode'] = $request->templateCode;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+        ]);
+        $params = new Params([
+            'action'      => 'QueryMobilesCardSupport',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return QueryMobilesCardSupportResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary Checks whether a mobile phone number can receive card messages.
+     *  *
+     * @param QueryMobilesCardSupportRequest $request QueryMobilesCardSupportRequest
+     *
+     * @return QueryMobilesCardSupportResponse QueryMobilesCardSupportResponse
+     */
+    public function queryMobilesCardSupport($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->queryMobilesCardSupportWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary 点击明细查询
+     *  *
+     * @param QueryPageSmartShortUrlLogRequest $request QueryPageSmartShortUrlLogRequest
+     * @param RuntimeOptions                   $runtime runtime options for this request RuntimeOptions
+     *
+     * @return QueryPageSmartShortUrlLogResponse QueryPageSmartShortUrlLogResponse
+     */
+    public function queryPageSmartShortUrlLogWithOptions($request, $runtime)
+    {
+        Utils::validateModel($request);
+        $query = [];
+        if (!Utils::isUnset($request->createDateEnd)) {
+            $query['CreateDateEnd'] = $request->createDateEnd;
+        }
+        if (!Utils::isUnset($request->createDateStart)) {
+            $query['CreateDateStart'] = $request->createDateStart;
+        }
+        if (!Utils::isUnset($request->ownerId)) {
+            $query['OwnerId'] = $request->ownerId;
+        }
+        if (!Utils::isUnset($request->pageNo)) {
+            $query['PageNo'] = $request->pageNo;
+        }
+        if (!Utils::isUnset($request->pageSize)) {
+            $query['PageSize'] = $request->pageSize;
+        }
+        if (!Utils::isUnset($request->phoneNumber)) {
+            $query['PhoneNumber'] = $request->phoneNumber;
+        }
+        if (!Utils::isUnset($request->resourceOwnerAccount)) {
+            $query['ResourceOwnerAccount'] = $request->resourceOwnerAccount;
+        }
+        if (!Utils::isUnset($request->resourceOwnerId)) {
+            $query['ResourceOwnerId'] = $request->resourceOwnerId;
+        }
+        if (!Utils::isUnset($request->shortUrl)) {
+            $query['ShortUrl'] = $request->shortUrl;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+        ]);
+        $params = new Params([
+            'action'      => 'QueryPageSmartShortUrlLog',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return QueryPageSmartShortUrlLogResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary 点击明细查询
+     *  *
+     * @param QueryPageSmartShortUrlLogRequest $request QueryPageSmartShortUrlLogRequest
+     *
+     * @return QueryPageSmartShortUrlLogResponse QueryPageSmartShortUrlLogResponse
+     */
+    public function queryPageSmartShortUrlLog($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->queryPageSmartShortUrlLogWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary Queries the information about a message.
+     *  *
+     * @param QuerySendDetailsRequest $request QuerySendDetailsRequest
+     * @param RuntimeOptions          $runtime runtime options for this request RuntimeOptions
+     *
+     * @return QuerySendDetailsResponse QuerySendDetailsResponse
+     */
+    public function querySendDetailsWithOptions($request, $runtime)
+    {
+        Utils::validateModel($request);
+        $query = [];
+        if (!Utils::isUnset($request->bizId)) {
+            $query['BizId'] = $request->bizId;
+        }
+        if (!Utils::isUnset($request->currentPage)) {
+            $query['CurrentPage'] = $request->currentPage;
+        }
+        if (!Utils::isUnset($request->ownerId)) {
+            $query['OwnerId'] = $request->ownerId;
+        }
+        if (!Utils::isUnset($request->pageSize)) {
+            $query['PageSize'] = $request->pageSize;
+        }
+        if (!Utils::isUnset($request->phoneNumber)) {
+            $query['PhoneNumber'] = $request->phoneNumber;
+        }
+        if (!Utils::isUnset($request->resourceOwnerAccount)) {
+            $query['ResourceOwnerAccount'] = $request->resourceOwnerAccount;
+        }
+        if (!Utils::isUnset($request->resourceOwnerId)) {
+            $query['ResourceOwnerId'] = $request->resourceOwnerId;
+        }
+        if (!Utils::isUnset($request->sendDate)) {
+            $query['SendDate'] = $request->sendDate;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+        ]);
+        $params = new Params([
+            'action'      => 'QuerySendDetails',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return QuerySendDetailsResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary Queries the information about a message.
+     *  *
+     * @param QuerySendDetailsRequest $request QuerySendDetailsRequest
+     *
+     * @return QuerySendDetailsResponse QuerySendDetailsResponse
+     */
+    public function querySendDetails($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->querySendDetailsWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary Queries message delivery details.
+     *  *
+     * @description You can call the operation to query message delivery details, including the number of delivered messages, the number of messages with delivery receipts, and the time that a message is sent. If a large number of messages are sent on the specified date, you can specify the number of items displayed on each page and the number of pages to view the details by page.
+     * ### QPS limits
+     * You can call this operation up to 20 times per second per account. If the number of the calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param QuerySendStatisticsRequest $request QuerySendStatisticsRequest
+     * @param RuntimeOptions             $runtime runtime options for this request RuntimeOptions
+     *
+     * @return QuerySendStatisticsResponse QuerySendStatisticsResponse
+     */
+    public function querySendStatisticsWithOptions($request, $runtime)
+    {
+        Utils::validateModel($request);
+        $query = [];
+        if (!Utils::isUnset($request->endDate)) {
+            $query['EndDate'] = $request->endDate;
+        }
+        if (!Utils::isUnset($request->isGlobe)) {
+            $query['IsGlobe'] = $request->isGlobe;
+        }
+        if (!Utils::isUnset($request->ownerId)) {
+            $query['OwnerId'] = $request->ownerId;
+        }
+        if (!Utils::isUnset($request->pageIndex)) {
+            $query['PageIndex'] = $request->pageIndex;
+        }
+        if (!Utils::isUnset($request->pageSize)) {
+            $query['PageSize'] = $request->pageSize;
+        }
+        if (!Utils::isUnset($request->resourceOwnerAccount)) {
+            $query['ResourceOwnerAccount'] = $request->resourceOwnerAccount;
+        }
+        if (!Utils::isUnset($request->resourceOwnerId)) {
+            $query['ResourceOwnerId'] = $request->resourceOwnerId;
+        }
+        if (!Utils::isUnset($request->signName)) {
+            $query['SignName'] = $request->signName;
+        }
+        if (!Utils::isUnset($request->startDate)) {
+            $query['StartDate'] = $request->startDate;
+        }
+        if (!Utils::isUnset($request->templateType)) {
+            $query['TemplateType'] = $request->templateType;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+        ]);
+        $params = new Params([
+            'action'      => 'QuerySendStatistics',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return QuerySendStatisticsResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary Queries message delivery details.
+     *  *
+     * @description You can call the operation to query message delivery details, including the number of delivered messages, the number of messages with delivery receipts, and the time that a message is sent. If a large number of messages are sent on the specified date, you can specify the number of items displayed on each page and the number of pages to view the details by page.
+     * ### QPS limits
+     * You can call this operation up to 20 times per second per account. If the number of the calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param QuerySendStatisticsRequest $request QuerySendStatisticsRequest
+     *
+     * @return QuerySendStatisticsResponse QuerySendStatisticsResponse
+     */
+    public function querySendStatistics($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->querySendStatisticsWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary Queries the status of a short URL.
+     *  *
+     * @description ### QPS limits
+     * You can call this operation up to 20 times per second per account. If the number of the calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param QueryShortUrlRequest $request QueryShortUrlRequest
+     * @param RuntimeOptions       $runtime runtime options for this request RuntimeOptions
+     *
+     * @return QueryShortUrlResponse QueryShortUrlResponse
+     */
+    public function queryShortUrlWithOptions($request, $runtime)
+    {
+        Utils::validateModel($request);
+        $query = [];
+        if (!Utils::isUnset($request->ownerId)) {
+            $query['OwnerId'] = $request->ownerId;
+        }
+        if (!Utils::isUnset($request->resourceOwnerAccount)) {
+            $query['ResourceOwnerAccount'] = $request->resourceOwnerAccount;
+        }
+        if (!Utils::isUnset($request->resourceOwnerId)) {
+            $query['ResourceOwnerId'] = $request->resourceOwnerId;
+        }
+        $body = [];
+        if (!Utils::isUnset($request->shortUrl)) {
+            $body['ShortUrl'] = $request->shortUrl;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+            'body'  => OpenApiUtilClient::parseToMap($body),
+        ]);
+        $params = new Params([
+            'action'      => 'QueryShortUrl',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return QueryShortUrlResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary Queries the status of a short URL.
+     *  *
+     * @description ### QPS limits
+     * You can call this operation up to 20 times per second per account. If the number of the calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param QueryShortUrlRequest $request QueryShortUrlRequest
+     *
+     * @return QueryShortUrlResponse QueryShortUrlResponse
+     */
+    public function queryShortUrl($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->queryShortUrlWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary Queries the status of a signature.
+     *  *
+     * @description After you apply for an SMS signature, you can query its status by using the [Alibaba Cloud SMS console](https://dysms.console.aliyun.com/dysms.htm) or calling the operation. If the signature is rejected, you can modify the signature based on the reason why it is rejected.
+     * ### QPS limits
+     * You can call this API operation up to 500 times per second per account. If the number of the calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param QuerySmsSignRequest $request QuerySmsSignRequest
+     * @param RuntimeOptions      $runtime runtime options for this request RuntimeOptions
+     *
+     * @return QuerySmsSignResponse QuerySmsSignResponse
+     */
+    public function querySmsSignWithOptions($request, $runtime)
+    {
+        Utils::validateModel($request);
+        $query = [];
+        if (!Utils::isUnset($request->ownerId)) {
+            $query['OwnerId'] = $request->ownerId;
+        }
+        if (!Utils::isUnset($request->resourceOwnerAccount)) {
+            $query['ResourceOwnerAccount'] = $request->resourceOwnerAccount;
+        }
+        if (!Utils::isUnset($request->resourceOwnerId)) {
+            $query['ResourceOwnerId'] = $request->resourceOwnerId;
+        }
+        if (!Utils::isUnset($request->signName)) {
+            $query['SignName'] = $request->signName;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+        ]);
+        $params = new Params([
+            'action'      => 'QuerySmsSign',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return QuerySmsSignResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary Queries the status of a signature.
+     *  *
+     * @description After you apply for an SMS signature, you can query its status by using the [Alibaba Cloud SMS console](https://dysms.console.aliyun.com/dysms.htm) or calling the operation. If the signature is rejected, you can modify the signature based on the reason why it is rejected.
+     * ### QPS limits
+     * You can call this API operation up to 500 times per second per account. If the number of the calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param QuerySmsSignRequest $request QuerySmsSignRequest
+     *
+     * @return QuerySmsSignResponse QuerySmsSignResponse
+     */
+    public function querySmsSign($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->querySmsSignWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary Queries message signatures by page.
+     *  *
+     * @description You can call this operation to query the details of message signatures, including the name, creation time, and approval status of each signature. If a message template is rejected, the reason is returned. Modify the message signature based on the reason.
+     * ### QPS limit
+     * You can call this operation up to 10 times per second per account. If the number of calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param QuerySmsSignListRequest $request QuerySmsSignListRequest
+     * @param RuntimeOptions          $runtime runtime options for this request RuntimeOptions
+     *
+     * @return QuerySmsSignListResponse QuerySmsSignListResponse
+     */
+    public function querySmsSignListWithOptions($request, $runtime)
+    {
+        Utils::validateModel($request);
+        $query = [];
+        if (!Utils::isUnset($request->ownerId)) {
+            $query['OwnerId'] = $request->ownerId;
+        }
+        if (!Utils::isUnset($request->pageIndex)) {
+            $query['PageIndex'] = $request->pageIndex;
+        }
+        if (!Utils::isUnset($request->pageSize)) {
+            $query['PageSize'] = $request->pageSize;
+        }
+        if (!Utils::isUnset($request->resourceOwnerAccount)) {
+            $query['ResourceOwnerAccount'] = $request->resourceOwnerAccount;
+        }
+        if (!Utils::isUnset($request->resourceOwnerId)) {
+            $query['ResourceOwnerId'] = $request->resourceOwnerId;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+        ]);
+        $params = new Params([
+            'action'      => 'QuerySmsSignList',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return QuerySmsSignListResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary Queries message signatures by page.
+     *  *
+     * @description You can call this operation to query the details of message signatures, including the name, creation time, and approval status of each signature. If a message template is rejected, the reason is returned. Modify the message signature based on the reason.
+     * ### QPS limit
+     * You can call this operation up to 10 times per second per account. If the number of calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param QuerySmsSignListRequest $request QuerySmsSignListRequest
+     *
+     * @return QuerySmsSignListResponse QuerySmsSignListResponse
+     */
+    public function querySmsSignList($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->querySmsSignListWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary Queries the approval status of a message template.
+     *  *
+     * @description After you create a message template, you can call this operation to query the approval status of the template. If a message template is rejected, the reason is returned. Modify the message template based on the reason.
+     * ### QPS limit
+     * You can call this operation up to 5,000 times per second per account. If the number of calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param QuerySmsTemplateRequest $request QuerySmsTemplateRequest
+     * @param RuntimeOptions          $runtime runtime options for this request RuntimeOptions
+     *
+     * @return QuerySmsTemplateResponse QuerySmsTemplateResponse
+     */
+    public function querySmsTemplateWithOptions($request, $runtime)
+    {
+        Utils::validateModel($request);
+        $query = [];
+        if (!Utils::isUnset($request->ownerId)) {
+            $query['OwnerId'] = $request->ownerId;
+        }
+        if (!Utils::isUnset($request->resourceOwnerAccount)) {
+            $query['ResourceOwnerAccount'] = $request->resourceOwnerAccount;
+        }
+        if (!Utils::isUnset($request->resourceOwnerId)) {
+            $query['ResourceOwnerId'] = $request->resourceOwnerId;
+        }
+        if (!Utils::isUnset($request->templateCode)) {
+            $query['TemplateCode'] = $request->templateCode;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+        ]);
+        $params = new Params([
+            'action'      => 'QuerySmsTemplate',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return QuerySmsTemplateResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary Queries the approval status of a message template.
+     *  *
+     * @description After you create a message template, you can call this operation to query the approval status of the template. If a message template is rejected, the reason is returned. Modify the message template based on the reason.
+     * ### QPS limit
+     * You can call this operation up to 5,000 times per second per account. If the number of calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param QuerySmsTemplateRequest $request QuerySmsTemplateRequest
+     *
+     * @return QuerySmsTemplateResponse QuerySmsTemplateResponse
+     */
+    public function querySmsTemplate($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->querySmsTemplateWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary Queries message templates.
+     *  *
+     * @description You can call this operation to query the details of message templates, including the name, creation time, and approval status of each template. If a message template is rejected, the reason is returned. Modify the message template based on the reason.
+     * ### QPS limit
+     * You can call this operation up to 10 times per second per account. If the number of calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param QuerySmsTemplateListRequest $request QuerySmsTemplateListRequest
+     * @param RuntimeOptions              $runtime runtime options for this request RuntimeOptions
+     *
+     * @return QuerySmsTemplateListResponse QuerySmsTemplateListResponse
+     */
+    public function querySmsTemplateListWithOptions($request, $runtime)
+    {
+        Utils::validateModel($request);
+        $query = [];
+        if (!Utils::isUnset($request->ownerId)) {
+            $query['OwnerId'] = $request->ownerId;
+        }
+        if (!Utils::isUnset($request->pageIndex)) {
+            $query['PageIndex'] = $request->pageIndex;
+        }
+        if (!Utils::isUnset($request->pageSize)) {
+            $query['PageSize'] = $request->pageSize;
+        }
+        if (!Utils::isUnset($request->resourceOwnerAccount)) {
+            $query['ResourceOwnerAccount'] = $request->resourceOwnerAccount;
+        }
+        if (!Utils::isUnset($request->resourceOwnerId)) {
+            $query['ResourceOwnerId'] = $request->resourceOwnerId;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+        ]);
+        $params = new Params([
+            'action'      => 'QuerySmsTemplateList',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return QuerySmsTemplateListResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary Queries message templates.
+     *  *
+     * @description You can call this operation to query the details of message templates, including the name, creation time, and approval status of each template. If a message template is rejected, the reason is returned. Modify the message template based on the reason.
+     * ### QPS limit
+     * You can call this operation up to 10 times per second per account. If the number of calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param QuerySmsTemplateListRequest $request QuerySmsTemplateListRequest
+     *
+     * @return QuerySmsTemplateListResponse QuerySmsTemplateListResponse
+     */
+    public function querySmsTemplateList($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->querySmsTemplateListWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary Sends multiple card messages at a time.
+     *  *
+     * @description You can call the operation to send multiple card messages to a maximum of mobile phone numbers at a time. Different signatures and rollback settings can be specified for the mobile phone numbers.
+     * ### QPS limit
+     * You can call this operation up to 1,000 times per second per account. If the number of the calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param SendBatchCardSmsRequest $request SendBatchCardSmsRequest
+     * @param RuntimeOptions          $runtime runtime options for this request RuntimeOptions
+     *
+     * @return SendBatchCardSmsResponse SendBatchCardSmsResponse
+     */
+    public function sendBatchCardSmsWithOptions($request, $runtime)
+    {
+        Utils::validateModel($request);
+        $query = [];
+        if (!Utils::isUnset($request->cardTemplateCode)) {
+            $query['CardTemplateCode'] = $request->cardTemplateCode;
+        }
+        if (!Utils::isUnset($request->cardTemplateParamJson)) {
+            $query['CardTemplateParamJson'] = $request->cardTemplateParamJson;
+        }
+        if (!Utils::isUnset($request->digitalTemplateCode)) {
+            $query['DigitalTemplateCode'] = $request->digitalTemplateCode;
+        }
+        if (!Utils::isUnset($request->digitalTemplateParamJson)) {
+            $query['DigitalTemplateParamJson'] = $request->digitalTemplateParamJson;
+        }
+        if (!Utils::isUnset($request->fallbackType)) {
+            $query['FallbackType'] = $request->fallbackType;
+        }
+        if (!Utils::isUnset($request->outId)) {
+            $query['OutId'] = $request->outId;
+        }
+        if (!Utils::isUnset($request->phoneNumberJson)) {
+            $query['PhoneNumberJson'] = $request->phoneNumberJson;
+        }
+        if (!Utils::isUnset($request->signNameJson)) {
+            $query['SignNameJson'] = $request->signNameJson;
+        }
+        if (!Utils::isUnset($request->smsTemplateCode)) {
+            $query['SmsTemplateCode'] = $request->smsTemplateCode;
+        }
+        if (!Utils::isUnset($request->smsTemplateParamJson)) {
+            $query['SmsTemplateParamJson'] = $request->smsTemplateParamJson;
+        }
+        if (!Utils::isUnset($request->smsUpExtendCodeJson)) {
+            $query['SmsUpExtendCodeJson'] = $request->smsUpExtendCodeJson;
+        }
+        if (!Utils::isUnset($request->templateCode)) {
+            $query['TemplateCode'] = $request->templateCode;
+        }
+        if (!Utils::isUnset($request->templateParamJson)) {
+            $query['TemplateParamJson'] = $request->templateParamJson;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+        ]);
+        $params = new Params([
+            'action'      => 'SendBatchCardSms',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return SendBatchCardSmsResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary Sends multiple card messages at a time.
+     *  *
+     * @description You can call the operation to send multiple card messages to a maximum of mobile phone numbers at a time. Different signatures and rollback settings can be specified for the mobile phone numbers.
+     * ### QPS limit
+     * You can call this operation up to 1,000 times per second per account. If the number of the calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param SendBatchCardSmsRequest $request SendBatchCardSmsRequest
+     *
+     * @return SendBatchCardSmsResponse SendBatchCardSmsResponse
+     */
+    public function sendBatchCardSms($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->sendBatchCardSmsWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary Uses a single message template and multiple signatures to send messages to multiple recipients.
+     *  *
+     * @description You can call the operation to send messages to a maximum of 100 recipients at a time.
+     *  *
+     * @param SendBatchSmsRequest $request SendBatchSmsRequest
+     * @param RuntimeOptions      $runtime runtime options for this request RuntimeOptions
+     *
+     * @return SendBatchSmsResponse SendBatchSmsResponse
+     */
+    public function sendBatchSmsWithOptions($request, $runtime)
+    {
+        Utils::validateModel($request);
+        $query = [];
+        if (!Utils::isUnset($request->outId)) {
+            $query['OutId'] = $request->outId;
+        }
+        if (!Utils::isUnset($request->ownerId)) {
+            $query['OwnerId'] = $request->ownerId;
+        }
+        if (!Utils::isUnset($request->resourceOwnerAccount)) {
+            $query['ResourceOwnerAccount'] = $request->resourceOwnerAccount;
+        }
+        if (!Utils::isUnset($request->resourceOwnerId)) {
+            $query['ResourceOwnerId'] = $request->resourceOwnerId;
+        }
+        if (!Utils::isUnset($request->templateCode)) {
+            $query['TemplateCode'] = $request->templateCode;
+        }
+        $body = [];
+        if (!Utils::isUnset($request->phoneNumberJson)) {
+            $body['PhoneNumberJson'] = $request->phoneNumberJson;
+        }
+        if (!Utils::isUnset($request->signNameJson)) {
+            $body['SignNameJson'] = $request->signNameJson;
+        }
+        if (!Utils::isUnset($request->smsUpExtendCodeJson)) {
+            $body['SmsUpExtendCodeJson'] = $request->smsUpExtendCodeJson;
+        }
+        if (!Utils::isUnset($request->templateParamJson)) {
+            $body['TemplateParamJson'] = $request->templateParamJson;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+            'body'  => OpenApiUtilClient::parseToMap($body),
+        ]);
+        $params = new Params([
+            'action'      => 'SendBatchSms',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return SendBatchSmsResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary Uses a single message template and multiple signatures to send messages to multiple recipients.
+     *  *
+     * @description You can call the operation to send messages to a maximum of 100 recipients at a time.
+     *  *
+     * @param SendBatchSmsRequest $request SendBatchSmsRequest
+     *
+     * @return SendBatchSmsResponse SendBatchSmsResponse
+     */
+    public function sendBatchSms($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->sendBatchSmsWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary Sends a card message.
+     *  *
+     * @description *   Make sure that the message template that you want to use has been approved. If the mobile phone number of a recipient does not support card messages, the SendCardSms operation allows the rollback feature to ensure successful delivery.
+     * *   When you call the SendCardSms operation to send card messages, the operation checks whether the mobile phone numbers of the recipients support card messages. If the mobile phone numbers do not support card messages, you can specify whether to enable rollback. Otherwise, the card message cannot be delivered.
+     * ### QPS limit
+     * You can call this operation up to 1,000 times per second per account. If the number of the calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param SendCardSmsRequest $request SendCardSmsRequest
+     * @param RuntimeOptions     $runtime runtime options for this request RuntimeOptions
+     *
+     * @return SendCardSmsResponse SendCardSmsResponse
+     */
+    public function sendCardSmsWithOptions($request, $runtime)
+    {
+        Utils::validateModel($request);
+        $query = [];
+        if (!Utils::isUnset($request->cardObjects)) {
+            $query['CardObjects'] = $request->cardObjects;
+        }
+        if (!Utils::isUnset($request->cardTemplateCode)) {
+            $query['CardTemplateCode'] = $request->cardTemplateCode;
+        }
+        if (!Utils::isUnset($request->digitalTemplateCode)) {
+            $query['DigitalTemplateCode'] = $request->digitalTemplateCode;
+        }
+        if (!Utils::isUnset($request->digitalTemplateParam)) {
+            $query['DigitalTemplateParam'] = $request->digitalTemplateParam;
+        }
+        if (!Utils::isUnset($request->fallbackType)) {
+            $query['FallbackType'] = $request->fallbackType;
+        }
+        if (!Utils::isUnset($request->outId)) {
+            $query['OutId'] = $request->outId;
+        }
+        if (!Utils::isUnset($request->signName)) {
+            $query['SignName'] = $request->signName;
+        }
+        if (!Utils::isUnset($request->smsTemplateCode)) {
+            $query['SmsTemplateCode'] = $request->smsTemplateCode;
+        }
+        if (!Utils::isUnset($request->smsTemplateParam)) {
+            $query['SmsTemplateParam'] = $request->smsTemplateParam;
+        }
+        if (!Utils::isUnset($request->smsUpExtendCode)) {
+            $query['SmsUpExtendCode'] = $request->smsUpExtendCode;
+        }
+        if (!Utils::isUnset($request->templateCode)) {
+            $query['TemplateCode'] = $request->templateCode;
+        }
+        if (!Utils::isUnset($request->templateParam)) {
+            $query['TemplateParam'] = $request->templateParam;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+        ]);
+        $params = new Params([
+            'action'      => 'SendCardSms',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return SendCardSmsResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary Sends a card message.
+     *  *
+     * @description *   Make sure that the message template that you want to use has been approved. If the mobile phone number of a recipient does not support card messages, the SendCardSms operation allows the rollback feature to ensure successful delivery.
+     * *   When you call the SendCardSms operation to send card messages, the operation checks whether the mobile phone numbers of the recipients support card messages. If the mobile phone numbers do not support card messages, you can specify whether to enable rollback. Otherwise, the card message cannot be delivered.
+     * ### QPS limit
+     * You can call this operation up to 1,000 times per second per account. If the number of the calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param SendCardSmsRequest $request SendCardSmsRequest
+     *
+     * @return SendCardSmsResponse SendCardSmsResponse
+     */
+    public function sendCardSms($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->sendCardSmsWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary Sends a message. Before you call this operation, submit a message signature and message template, and make sure that the signature and template are approved.
+     *  *
+     * @description *   This operation is mainly used to send a single message. In special scenarios, you can send multiple messages with the same content to a maximum of 1,000 mobile numbers. Note that group sending may be delayed.
+     * *   To send messages with different signatures and template content to multiple mobile numbers in a single request, call the [SendBatchSms](https://help.aliyun.com/document_detail/102364.html) operation.
+     * *   You are charged for using Alibaba Cloud Short Message Service (SMS) based on the amount of messages sent. For more information, see [Pricing](https://www.aliyun.com/price/product#/sms/detail).
+     * *   If your verification code signature and general-purpose signature have the same name, the system uses the general-purpose signature to send messages by default.
+     *  *
+     * @param SendSmsRequest $request SendSmsRequest
+     * @param RuntimeOptions $runtime runtime options for this request RuntimeOptions
+     *
+     * @return SendSmsResponse SendSmsResponse
+     */
+    public function sendSmsWithOptions($request, $runtime)
+    {
+        Utils::validateModel($request);
+        $query = [];
+        if (!Utils::isUnset($request->outId)) {
+            $query['OutId'] = $request->outId;
+        }
+        if (!Utils::isUnset($request->ownerId)) {
+            $query['OwnerId'] = $request->ownerId;
+        }
+        if (!Utils::isUnset($request->phoneNumbers)) {
+            $query['PhoneNumbers'] = $request->phoneNumbers;
+        }
+        if (!Utils::isUnset($request->resourceOwnerAccount)) {
+            $query['ResourceOwnerAccount'] = $request->resourceOwnerAccount;
+        }
+        if (!Utils::isUnset($request->resourceOwnerId)) {
+            $query['ResourceOwnerId'] = $request->resourceOwnerId;
+        }
+        if (!Utils::isUnset($request->signName)) {
+            $query['SignName'] = $request->signName;
+        }
+        if (!Utils::isUnset($request->smsUpExtendCode)) {
+            $query['SmsUpExtendCode'] = $request->smsUpExtendCode;
+        }
+        if (!Utils::isUnset($request->templateCode)) {
+            $query['TemplateCode'] = $request->templateCode;
+        }
+        if (!Utils::isUnset($request->templateParam)) {
+            $query['TemplateParam'] = $request->templateParam;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+        ]);
+        $params = new Params([
+            'action'      => 'SendSms',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return SendSmsResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary Sends a message. Before you call this operation, submit a message signature and message template, and make sure that the signature and template are approved.
+     *  *
+     * @description *   This operation is mainly used to send a single message. In special scenarios, you can send multiple messages with the same content to a maximum of 1,000 mobile numbers. Note that group sending may be delayed.
+     * *   To send messages with different signatures and template content to multiple mobile numbers in a single request, call the [SendBatchSms](https://help.aliyun.com/document_detail/102364.html) operation.
+     * *   You are charged for using Alibaba Cloud Short Message Service (SMS) based on the amount of messages sent. For more information, see [Pricing](https://www.aliyun.com/price/product#/sms/detail).
+     * *   If your verification code signature and general-purpose signature have the same name, the system uses the general-purpose signature to send messages by default.
+     *  *
+     * @param SendSmsRequest $request SendSmsRequest
+     *
+     * @return SendSmsResponse SendSmsResponse
+     */
+    public function sendSms($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->sendSmsWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary Reports the status of an OTP message to Alibaba Cloud SMS.
+     *  *
+     * @description Metrics:
+     * *   Requested OTP messages
+     * *   Verified OTP messages
+     * An OTP conversion rate is calculated based on the following formula: OTP conversion rate = Number of verified OTP messages/Number of requested OTP messages.
+     * > If you call the SmsConversion operation to query OTP conversion rates, your business may be affected. We recommend that you perform the following operations: 1. Call the SmsConversion operation in an asynchronous manner by configuring queues or events. 2. Manually degrade your services or use a circuit breaker to automatically degrade services.
+     *  *
+     * @param SmsConversionIntlRequest $request SmsConversionIntlRequest
+     * @param RuntimeOptions           $runtime runtime options for this request RuntimeOptions
+     *
+     * @return SmsConversionIntlResponse SmsConversionIntlResponse
+     */
+    public function smsConversionIntlWithOptions($request, $runtime)
+    {
+        Utils::validateModel($request);
+        $query = [];
+        if (!Utils::isUnset($request->conversionTime)) {
+            $query['ConversionTime'] = $request->conversionTime;
+        }
+        if (!Utils::isUnset($request->delivered)) {
+            $query['Delivered'] = $request->delivered;
+        }
+        if (!Utils::isUnset($request->messageId)) {
+            $query['MessageId'] = $request->messageId;
+        }
+        if (!Utils::isUnset($request->ownerId)) {
+            $query['OwnerId'] = $request->ownerId;
+        }
+        if (!Utils::isUnset($request->resourceOwnerAccount)) {
+            $query['ResourceOwnerAccount'] = $request->resourceOwnerAccount;
+        }
+        if (!Utils::isUnset($request->resourceOwnerId)) {
+            $query['ResourceOwnerId'] = $request->resourceOwnerId;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+        ]);
+        $params = new Params([
+            'action'      => 'SmsConversionIntl',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return SmsConversionIntlResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary Reports the status of an OTP message to Alibaba Cloud SMS.
+     *  *
+     * @description Metrics:
+     * *   Requested OTP messages
+     * *   Verified OTP messages
+     * An OTP conversion rate is calculated based on the following formula: OTP conversion rate = Number of verified OTP messages/Number of requested OTP messages.
+     * > If you call the SmsConversion operation to query OTP conversion rates, your business may be affected. We recommend that you perform the following operations: 1. Call the SmsConversion operation in an asynchronous manner by configuring queues or events. 2. Manually degrade your services or use a circuit breaker to automatically degrade services.
+     *  *
+     * @param SmsConversionIntlRequest $request SmsConversionIntlRequest
+     *
+     * @return SmsConversionIntlResponse SmsConversionIntlResponse
+     */
+    public function smsConversionIntl($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->smsConversionIntlWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary Attaches tags to a message template.
+     *  *
+     * @description ### QPS limit
+     * You can call this operation up to 50 times per second per account. If the number of the calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param TagResourcesRequest $request TagResourcesRequest
+     * @param RuntimeOptions      $runtime runtime options for this request RuntimeOptions
+     *
+     * @return TagResourcesResponse TagResourcesResponse
+     */
+    public function tagResourcesWithOptions($request, $runtime)
+    {
+        Utils::validateModel($request);
+        $query = [];
+        if (!Utils::isUnset($request->ownerId)) {
+            $query['OwnerId'] = $request->ownerId;
+        }
+        if (!Utils::isUnset($request->prodCode)) {
+            $query['ProdCode'] = $request->prodCode;
+        }
+        if (!Utils::isUnset($request->regionId)) {
+            $query['RegionId'] = $request->regionId;
+        }
+        if (!Utils::isUnset($request->resourceId)) {
+            $query['ResourceId'] = $request->resourceId;
+        }
+        if (!Utils::isUnset($request->resourceOwnerAccount)) {
+            $query['ResourceOwnerAccount'] = $request->resourceOwnerAccount;
+        }
+        if (!Utils::isUnset($request->resourceOwnerId)) {
+            $query['ResourceOwnerId'] = $request->resourceOwnerId;
+        }
+        if (!Utils::isUnset($request->resourceType)) {
+            $query['ResourceType'] = $request->resourceType;
+        }
+        if (!Utils::isUnset($request->tag)) {
+            $query['Tag'] = $request->tag;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+        ]);
+        $params = new Params([
+            'action'      => 'TagResources',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return TagResourcesResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary Attaches tags to a message template.
+     *  *
+     * @description ### QPS limit
+     * You can call this operation up to 50 times per second per account. If the number of the calls per second exceeds the limit, throttling is triggered. As a result, your business may be affected. We recommend that you take note of the limit when you call this operation.
+     *  *
+     * @param TagResourcesRequest $request TagResourcesRequest
+     *
+     * @return TagResourcesResponse TagResourcesResponse
+     */
+    public function tagResources($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->tagResourcesWithOptions($request, $runtime);
+    }
+
+    /**
+     * @param UntagResourcesRequest $request UntagResourcesRequest
+     * @param RuntimeOptions        $runtime runtime options for this request RuntimeOptions
+     *
+     * @return UntagResourcesResponse UntagResourcesResponse
+     */
+    public function untagResourcesWithOptions($request, $runtime)
+    {
+        Utils::validateModel($request);
+        $query = [];
+        if (!Utils::isUnset($request->all)) {
+            $query['All'] = $request->all;
+        }
+        if (!Utils::isUnset($request->ownerId)) {
+            $query['OwnerId'] = $request->ownerId;
+        }
+        if (!Utils::isUnset($request->prodCode)) {
+            $query['ProdCode'] = $request->prodCode;
+        }
+        if (!Utils::isUnset($request->regionId)) {
+            $query['RegionId'] = $request->regionId;
+        }
+        if (!Utils::isUnset($request->resourceId)) {
+            $query['ResourceId'] = $request->resourceId;
+        }
+        if (!Utils::isUnset($request->resourceOwnerAccount)) {
+            $query['ResourceOwnerAccount'] = $request->resourceOwnerAccount;
+        }
+        if (!Utils::isUnset($request->resourceOwnerId)) {
+            $query['ResourceOwnerId'] = $request->resourceOwnerId;
+        }
+        if (!Utils::isUnset($request->resourceType)) {
+            $query['ResourceType'] = $request->resourceType;
+        }
+        if (!Utils::isUnset($request->tagKey)) {
+            $query['TagKey'] = $request->tagKey;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+        ]);
+        $params = new Params([
+            'action'      => 'UntagResources',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return UntagResourcesResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @param UntagResourcesRequest $request UntagResourcesRequest
+     *
+     * @return UntagResourcesResponse UntagResourcesResponse
+     */
+    public function untagResources($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->untagResourcesWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary 修改文本短信签名
+     *  *
+     * @param UpdateSmsSignRequest $tmpReq  UpdateSmsSignRequest
+     * @param RuntimeOptions       $runtime runtime options for this request RuntimeOptions
+     *
+     * @return UpdateSmsSignResponse UpdateSmsSignResponse
+     */
+    public function updateSmsSignWithOptions($tmpReq, $runtime)
+    {
+        Utils::validateModel($tmpReq);
+        $request = new UpdateSmsSignShrinkRequest([]);
+        OpenApiUtilClient::convert($tmpReq, $request);
+        if (!Utils::isUnset($tmpReq->moreData)) {
+            $request->moreDataShrink = OpenApiUtilClient::arrayToStringWithSpecifiedStyle($tmpReq->moreData, 'MoreData', 'json');
+        }
+        $query = [];
+        if (!Utils::isUnset($request->applySceneContent)) {
+            $query['ApplySceneContent'] = $request->applySceneContent;
+        }
+        if (!Utils::isUnset($request->moreDataShrink)) {
+            $query['MoreData'] = $request->moreDataShrink;
+        }
+        if (!Utils::isUnset($request->ownerId)) {
+            $query['OwnerId'] = $request->ownerId;
+        }
+        if (!Utils::isUnset($request->qualificationId)) {
+            $query['QualificationId'] = $request->qualificationId;
+        }
+        if (!Utils::isUnset($request->remark)) {
+            $query['Remark'] = $request->remark;
+        }
+        if (!Utils::isUnset($request->resourceOwnerAccount)) {
+            $query['ResourceOwnerAccount'] = $request->resourceOwnerAccount;
+        }
+        if (!Utils::isUnset($request->resourceOwnerId)) {
+            $query['ResourceOwnerId'] = $request->resourceOwnerId;
+        }
+        if (!Utils::isUnset($request->signName)) {
+            $query['SignName'] = $request->signName;
+        }
+        if (!Utils::isUnset($request->signSource)) {
+            $query['SignSource'] = $request->signSource;
+        }
+        if (!Utils::isUnset($request->signType)) {
+            $query['SignType'] = $request->signType;
+        }
+        if (!Utils::isUnset($request->thirdParty)) {
+            $query['ThirdParty'] = $request->thirdParty;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+        ]);
+        $params = new Params([
+            'action'      => 'UpdateSmsSign',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return UpdateSmsSignResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary 修改文本短信签名
+     *  *
+     * @param UpdateSmsSignRequest $request UpdateSmsSignRequest
+     *
+     * @return UpdateSmsSignResponse UpdateSmsSignResponse
+     */
+    public function updateSmsSign($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->updateSmsSignWithOptions($request, $runtime);
+    }
+
+    /**
+     * @summary 修改文本短信模板
+     *  *
+     * @param UpdateSmsTemplateRequest $tmpReq  UpdateSmsTemplateRequest
+     * @param RuntimeOptions           $runtime runtime options for this request RuntimeOptions
+     *
+     * @return UpdateSmsTemplateResponse UpdateSmsTemplateResponse
+     */
+    public function updateSmsTemplateWithOptions($tmpReq, $runtime)
+    {
+        Utils::validateModel($tmpReq);
+        $request = new UpdateSmsTemplateShrinkRequest([]);
+        OpenApiUtilClient::convert($tmpReq, $request);
+        if (!Utils::isUnset($tmpReq->moreData)) {
+            $request->moreDataShrink = OpenApiUtilClient::arrayToStringWithSpecifiedStyle($tmpReq->moreData, 'MoreData', 'json');
+        }
+        $query = [];
+        if (!Utils::isUnset($request->applySceneContent)) {
+            $query['ApplySceneContent'] = $request->applySceneContent;
+        }
+        if (!Utils::isUnset($request->intlType)) {
+            $query['IntlType'] = $request->intlType;
+        }
+        if (!Utils::isUnset($request->moreDataShrink)) {
+            $query['MoreData'] = $request->moreDataShrink;
+        }
+        if (!Utils::isUnset($request->ownerId)) {
+            $query['OwnerId'] = $request->ownerId;
+        }
+        if (!Utils::isUnset($request->relatedSignName)) {
+            $query['RelatedSignName'] = $request->relatedSignName;
+        }
+        if (!Utils::isUnset($request->remark)) {
+            $query['Remark'] = $request->remark;
+        }
+        if (!Utils::isUnset($request->resourceOwnerAccount)) {
+            $query['ResourceOwnerAccount'] = $request->resourceOwnerAccount;
+        }
+        if (!Utils::isUnset($request->resourceOwnerId)) {
+            $query['ResourceOwnerId'] = $request->resourceOwnerId;
+        }
+        if (!Utils::isUnset($request->templateCode)) {
+            $query['TemplateCode'] = $request->templateCode;
+        }
+        if (!Utils::isUnset($request->templateContent)) {
+            $query['TemplateContent'] = $request->templateContent;
+        }
+        if (!Utils::isUnset($request->templateName)) {
+            $query['TemplateName'] = $request->templateName;
+        }
+        if (!Utils::isUnset($request->templateRule)) {
+            $query['TemplateRule'] = $request->templateRule;
+        }
+        if (!Utils::isUnset($request->templateType)) {
+            $query['TemplateType'] = $request->templateType;
+        }
+        $req = new OpenApiRequest([
+            'query' => OpenApiUtilClient::query($query),
+        ]);
+        $params = new Params([
+            'action'      => 'UpdateSmsTemplate',
+            'version'     => '2017-05-25',
+            'protocol'    => 'HTTPS',
+            'pathname'    => '/',
+            'method'      => 'POST',
+            'authType'    => 'AK',
+            'style'       => 'RPC',
+            'reqBodyType' => 'formData',
+            'bodyType'    => 'json',
+        ]);
+
+        return UpdateSmsTemplateResponse::fromMap($this->callApi($params, $req, $runtime));
+    }
+
+    /**
+     * @summary 修改文本短信模板
+     *  *
+     * @param UpdateSmsTemplateRequest $request UpdateSmsTemplateRequest
+     *
+     * @return UpdateSmsTemplateResponse UpdateSmsTemplateResponse
+     */
+    public function updateSmsTemplate($request)
+    {
+        $runtime = new RuntimeOptions([]);
+
+        return $this->updateSmsTemplateWithOptions($request, $runtime);
+    }
+}

+ 122 - 0
vendor/alibabacloud/dysmsapi-20170525/src/Models/AddShortUrlRequest.php

@@ -0,0 +1,122 @@
+<?php
+
+// This file is auto-generated, don't edit it. Thanks.
+
+namespace AlibabaCloud\SDK\Dysmsapi\V20170525\Models;
+
+use AlibabaCloud\Tea\Model;
+
+class AddShortUrlRequest extends Model
+{
+    /**
+     * @description The validity period of the short URL. Unit: days. The maximum validity period is 90 days.
+     *
+     * This parameter is required.
+     * @example 7
+     *
+     * @var string
+     */
+    public $effectiveDays;
+
+    /**
+     * @var int
+     */
+    public $ownerId;
+
+    /**
+     * @var string
+     */
+    public $resourceOwnerAccount;
+
+    /**
+     * @var int
+     */
+    public $resourceOwnerId;
+
+    /**
+     * @description The service name of the short URL. The name cannot exceed 13 characters in length.
+     *
+     * This parameter is required.
+     * @example The Alibaba Cloud Short Link service.
+     *
+     * @var string
+     */
+    public $shortUrlName;
+
+    /**
+     * @description The source URL. The URL cannot exceed 1,000 characters in length.
+     *
+     * This parameter is required.
+     * @example https://www.****.com/product/sms
+     *
+     * @var string
+     */
+    public $sourceUrl;
+    protected $_name = [
+        'effectiveDays'        => 'EffectiveDays',
+        'ownerId'              => 'OwnerId',
+        'resourceOwnerAccount' => 'ResourceOwnerAccount',
+        'resourceOwnerId'      => 'ResourceOwnerId',
+        'shortUrlName'         => 'ShortUrlName',
+        'sourceUrl'            => 'SourceUrl',
+    ];
+
+    public function validate()
+    {
+    }
+
+    public function toMap()
+    {
+        $res = [];
+        if (null !== $this->effectiveDays) {
+            $res['EffectiveDays'] = $this->effectiveDays;
+        }
+        if (null !== $this->ownerId) {
+            $res['OwnerId'] = $this->ownerId;
+        }
+        if (null !== $this->resourceOwnerAccount) {
+            $res['ResourceOwnerAccount'] = $this->resourceOwnerAccount;
+        }
+        if (null !== $this->resourceOwnerId) {
+            $res['ResourceOwnerId'] = $this->resourceOwnerId;
+        }
+        if (null !== $this->shortUrlName) {
+            $res['ShortUrlName'] = $this->shortUrlName;
+        }
+        if (null !== $this->sourceUrl) {
+            $res['SourceUrl'] = $this->sourceUrl;
+        }
+
+        return $res;
+    }
+
+    /**
+     * @param array $map
+     *
+     * @return AddShortUrlRequest
+     */
+    public static function fromMap($map = [])
+    {
+        $model = new self();
+        if (isset($map['EffectiveDays'])) {
+            $model->effectiveDays = $map['EffectiveDays'];
+        }
+        if (isset($map['OwnerId'])) {
+            $model->ownerId = $map['OwnerId'];
+        }
+        if (isset($map['ResourceOwnerAccount'])) {
+            $model->resourceOwnerAccount = $map['ResourceOwnerAccount'];
+        }
+        if (isset($map['ResourceOwnerId'])) {
+            $model->resourceOwnerId = $map['ResourceOwnerId'];
+        }
+        if (isset($map['ShortUrlName'])) {
+            $model->shortUrlName = $map['ShortUrlName'];
+        }
+        if (isset($map['SourceUrl'])) {
+            $model->sourceUrl = $map['SourceUrl'];
+        }
+
+        return $model;
+    }
+}

+ 71 - 0
vendor/alibabacloud/dysmsapi-20170525/src/Models/AddShortUrlResponse.php

@@ -0,0 +1,71 @@
+<?php
+
+// This file is auto-generated, don't edit it. Thanks.
+
+namespace AlibabaCloud\SDK\Dysmsapi\V20170525\Models;
+
+use AlibabaCloud\Tea\Model;
+
+class AddShortUrlResponse extends Model
+{
+    /**
+     * @var string[]
+     */
+    public $headers;
+
+    /**
+     * @var int
+     */
+    public $statusCode;
+
+    /**
+     * @var AddShortUrlResponseBody
+     */
+    public $body;
+    protected $_name = [
+        'headers'    => 'headers',
+        'statusCode' => 'statusCode',
+        'body'       => 'body',
+    ];
+
+    public function validate()
+    {
+    }
+
+    public function toMap()
+    {
+        $res = [];
+        if (null !== $this->headers) {
+            $res['headers'] = $this->headers;
+        }
+        if (null !== $this->statusCode) {
+            $res['statusCode'] = $this->statusCode;
+        }
+        if (null !== $this->body) {
+            $res['body'] = null !== $this->body ? $this->body->toMap() : null;
+        }
+
+        return $res;
+    }
+
+    /**
+     * @param array $map
+     *
+     * @return AddShortUrlResponse
+     */
+    public static function fromMap($map = [])
+    {
+        $model = new self();
+        if (isset($map['headers'])) {
+            $model->headers = $map['headers'];
+        }
+        if (isset($map['statusCode'])) {
+            $model->statusCode = $map['statusCode'];
+        }
+        if (isset($map['body'])) {
+            $model->body = AddShortUrlResponseBody::fromMap($map['body']);
+        }
+
+        return $model;
+    }
+}

+ 101 - 0
vendor/alibabacloud/dysmsapi-20170525/src/Models/AddShortUrlResponseBody.php

@@ -0,0 +1,101 @@
+<?php
+
+// This file is auto-generated, don't edit it. Thanks.
+
+namespace AlibabaCloud\SDK\Dysmsapi\V20170525\Models;
+
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\AddShortUrlResponseBody\data;
+use AlibabaCloud\Tea\Model;
+
+class AddShortUrlResponseBody extends Model
+{
+    /**
+     * @description The response code.
+     *
+     *   The value OK indicates that the request was successful.
+     *   Other values indicate that the request failed. For more information, see [Error codes](https://help.aliyun.com/document_detail/101346.html).
+     *
+     * @example OK
+     *
+     * @var string
+     */
+    public $code;
+
+    /**
+     * @description The details of the short URL.
+     *
+     * @var data
+     */
+    public $data;
+
+    /**
+     * @description The returned message.
+     *
+     * @example OK
+     *
+     * @var string
+     */
+    public $message;
+
+    /**
+     * @description The request ID.
+     *
+     * @example 819BE656-D2E0-4858-8B21-B2E477085AAF
+     *
+     * @var string
+     */
+    public $requestId;
+    protected $_name = [
+        'code'      => 'Code',
+        'data'      => 'Data',
+        'message'   => 'Message',
+        'requestId' => 'RequestId',
+    ];
+
+    public function validate()
+    {
+    }
+
+    public function toMap()
+    {
+        $res = [];
+        if (null !== $this->code) {
+            $res['Code'] = $this->code;
+        }
+        if (null !== $this->data) {
+            $res['Data'] = null !== $this->data ? $this->data->toMap() : null;
+        }
+        if (null !== $this->message) {
+            $res['Message'] = $this->message;
+        }
+        if (null !== $this->requestId) {
+            $res['RequestId'] = $this->requestId;
+        }
+
+        return $res;
+    }
+
+    /**
+     * @param array $map
+     *
+     * @return AddShortUrlResponseBody
+     */
+    public static function fromMap($map = [])
+    {
+        $model = new self();
+        if (isset($map['Code'])) {
+            $model->code = $map['Code'];
+        }
+        if (isset($map['Data'])) {
+            $model->data = data::fromMap($map['Data']);
+        }
+        if (isset($map['Message'])) {
+            $model->message = $map['Message'];
+        }
+        if (isset($map['RequestId'])) {
+            $model->requestId = $map['RequestId'];
+        }
+
+        return $model;
+    }
+}

+ 84 - 0
vendor/alibabacloud/dysmsapi-20170525/src/Models/AddShortUrlResponseBody/data.php

@@ -0,0 +1,84 @@
+<?php
+
+// This file is auto-generated, don't edit it. Thanks.
+
+namespace AlibabaCloud\SDK\Dysmsapi\V20170525\Models\AddShortUrlResponseBody;
+
+use AlibabaCloud\Tea\Model;
+
+class data extends Model
+{
+    /**
+     * @description The time when the short URL expires.
+     *
+     * > The value of **ExpireDate** is on the hour.
+     * @example 2021-09-19 00:00:00
+     *
+     * @var string
+     */
+    public $expireDate;
+
+    /**
+     * @description The short URL.
+     *
+     * @example http://****.cn/6y8uy7
+     *
+     * @var string
+     */
+    public $shortUrl;
+
+    /**
+     * @description The source URL.
+     *
+     * @example https://www.****.com/product/sms
+     *
+     * @var string
+     */
+    public $sourceUrl;
+    protected $_name = [
+        'expireDate' => 'ExpireDate',
+        'shortUrl'   => 'ShortUrl',
+        'sourceUrl'  => 'SourceUrl',
+    ];
+
+    public function validate()
+    {
+    }
+
+    public function toMap()
+    {
+        $res = [];
+        if (null !== $this->expireDate) {
+            $res['ExpireDate'] = $this->expireDate;
+        }
+        if (null !== $this->shortUrl) {
+            $res['ShortUrl'] = $this->shortUrl;
+        }
+        if (null !== $this->sourceUrl) {
+            $res['SourceUrl'] = $this->sourceUrl;
+        }
+
+        return $res;
+    }
+
+    /**
+     * @param array $map
+     *
+     * @return data
+     */
+    public static function fromMap($map = [])
+    {
+        $model = new self();
+        if (isset($map['ExpireDate'])) {
+            $model->expireDate = $map['ExpireDate'];
+        }
+        if (isset($map['ShortUrl'])) {
+            $model->shortUrl = $map['ShortUrl'];
+        }
+        if (isset($map['SourceUrl'])) {
+            $model->sourceUrl = $map['SourceUrl'];
+        }
+
+        return $model;
+    }
+}

+ 182 - 0
vendor/alibabacloud/dysmsapi-20170525/src/Models/AddSmsSignRequest.php

@@ -0,0 +1,182 @@
+<?php
+
+// This file is auto-generated, don't edit it. Thanks.
+
+namespace AlibabaCloud\SDK\Dysmsapi\V20170525\Models;
+
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\AddSmsSignRequest\signFileList;
+use AlibabaCloud\Tea\Model;
+
+class AddSmsSignRequest extends Model
+{
+    /**
+     * @var int
+     */
+    public $ownerId;
+
+    /**
+     * @description The description of the signature application. The description cannot exceed 200 characters in length. The description is one of the reference information for signature review. We recommend that you describe the use scenarios of your services in detail, and provide information that can verify the services, such as a website URL, a domain name with an ICP filing, an app download URL, an official account name, or a mini program name. For sign-in scenarios, you must also provide an account and password for tests. A detailed description can improve the review efficiency of signatures and templates.
+     *
+     * This parameter is required.
+     * @example This is the abbreviation of our company.
+     *
+     * @var string
+     */
+    public $remark;
+
+    /**
+     * @var string
+     */
+    public $resourceOwnerAccount;
+
+    /**
+     * @var int
+     */
+    public $resourceOwnerId;
+
+    /**
+     * @description The signature files.
+     *
+     * This parameter is required.
+     * @var signFileList[]
+     */
+    public $signFileList;
+
+    /**
+     * @description The name of the signature.
+     *
+     * >
+     *
+     *   The signature name is not case-sensitive. For example, [Alibaba Cloud Communication] and [alibaba cloud communication] are considered as the same name.
+     *
+     *   If your verification code signature and general-purpose signature have the same name, the system uses the general-purpose signature to send messages by default.
+     *
+     * This parameter is required.
+     * @example Aliyun
+     *
+     * @var string
+     */
+    public $signName;
+
+    /**
+     * @description The source of the signature. Valid values:
+     *
+     *   **0**: the full name or abbreviation of an enterprise or institution
+     *   **1**: the full name or abbreviation of a website that has obtained an ICP filing from the Ministry of Industry and Information Technology (MIIT) of China
+     *   **2**: the full name or abbreviation of an app
+     *   **3**: the full name or abbreviation of an official account or mini-program
+     *   **4**: the full name or abbreviation of an e-commerce store
+     *   **5**: the full name or abbreviation of a trademark
+     *
+     * This parameter is required.
+     * @example 1
+     *
+     * @var int
+     */
+    public $signSource;
+
+    /**
+     * @description The type of the signature. Valid values:
+     *
+     *   **0**: verification code
+     *   **1**: general-purpose
+     *
+     * @example 1
+     *
+     * @var int
+     */
+    public $signType;
+    protected $_name = [
+        'ownerId'              => 'OwnerId',
+        'remark'               => 'Remark',
+        'resourceOwnerAccount' => 'ResourceOwnerAccount',
+        'resourceOwnerId'      => 'ResourceOwnerId',
+        'signFileList'         => 'SignFileList',
+        'signName'             => 'SignName',
+        'signSource'           => 'SignSource',
+        'signType'             => 'SignType',
+    ];
+
+    public function validate()
+    {
+    }
+
+    public function toMap()
+    {
+        $res = [];
+        if (null !== $this->ownerId) {
+            $res['OwnerId'] = $this->ownerId;
+        }
+        if (null !== $this->remark) {
+            $res['Remark'] = $this->remark;
+        }
+        if (null !== $this->resourceOwnerAccount) {
+            $res['ResourceOwnerAccount'] = $this->resourceOwnerAccount;
+        }
+        if (null !== $this->resourceOwnerId) {
+            $res['ResourceOwnerId'] = $this->resourceOwnerId;
+        }
+        if (null !== $this->signFileList) {
+            $res['SignFileList'] = [];
+            if (null !== $this->signFileList && \is_array($this->signFileList)) {
+                $n = 0;
+                foreach ($this->signFileList as $item) {
+                    $res['SignFileList'][$n++] = null !== $item ? $item->toMap() : $item;
+                }
+            }
+        }
+        if (null !== $this->signName) {
+            $res['SignName'] = $this->signName;
+        }
+        if (null !== $this->signSource) {
+            $res['SignSource'] = $this->signSource;
+        }
+        if (null !== $this->signType) {
+            $res['SignType'] = $this->signType;
+        }
+
+        return $res;
+    }
+
+    /**
+     * @param array $map
+     *
+     * @return AddSmsSignRequest
+     */
+    public static function fromMap($map = [])
+    {
+        $model = new self();
+        if (isset($map['OwnerId'])) {
+            $model->ownerId = $map['OwnerId'];
+        }
+        if (isset($map['Remark'])) {
+            $model->remark = $map['Remark'];
+        }
+        if (isset($map['ResourceOwnerAccount'])) {
+            $model->resourceOwnerAccount = $map['ResourceOwnerAccount'];
+        }
+        if (isset($map['ResourceOwnerId'])) {
+            $model->resourceOwnerId = $map['ResourceOwnerId'];
+        }
+        if (isset($map['SignFileList'])) {
+            if (!empty($map['SignFileList'])) {
+                $model->signFileList = [];
+                $n                   = 0;
+                foreach ($map['SignFileList'] as $item) {
+                    $model->signFileList[$n++] = null !== $item ? signFileList::fromMap($item) : $item;
+                }
+            }
+        }
+        if (isset($map['SignName'])) {
+            $model->signName = $map['SignName'];
+        }
+        if (isset($map['SignSource'])) {
+            $model->signSource = $map['SignSource'];
+        }
+        if (isset($map['SignType'])) {
+            $model->signType = $map['SignType'];
+        }
+
+        return $model;
+    }
+}

+ 69 - 0
vendor/alibabacloud/dysmsapi-20170525/src/Models/AddSmsSignRequest/signFileList.php

@@ -0,0 +1,69 @@
+<?php
+
+// This file is auto-generated, don't edit it. Thanks.
+
+namespace AlibabaCloud\SDK\Dysmsapi\V20170525\Models\AddSmsSignRequest;
+
+use AlibabaCloud\Tea\Model;
+
+class signFileList extends Model
+{
+    /**
+     * @description The Base64-encoded string of the qualification document. An image cannot exceed 2 MB in size. In some scenarios, you must upload supporting documents to apply for signatures. For more information, see [SMS signature specifications](https://help.aliyun.com/document_detail/108076.html).
+     *
+     * This parameter is required.
+     * @example R0lGODlhHAAmAKIHAKqqqsvLy0hISObm5vf394uL****
+     *
+     * @var string
+     */
+    public $fileContents;
+
+    /**
+     * @description The format of the qualification document. You can upload multiple images. Images in JPG, PNG, GIF, or JPEG format are supported.
+     *
+     * This parameter is required.
+     * @example jpg
+     *
+     * @var string
+     */
+    public $fileSuffix;
+    protected $_name = [
+        'fileContents' => 'FileContents',
+        'fileSuffix'   => 'FileSuffix',
+    ];
+
+    public function validate()
+    {
+    }
+
+    public function toMap()
+    {
+        $res = [];
+        if (null !== $this->fileContents) {
+            $res['FileContents'] = $this->fileContents;
+        }
+        if (null !== $this->fileSuffix) {
+            $res['FileSuffix'] = $this->fileSuffix;
+        }
+
+        return $res;
+    }
+
+    /**
+     * @param array $map
+     *
+     * @return signFileList
+     */
+    public static function fromMap($map = [])
+    {
+        $model = new self();
+        if (isset($map['FileContents'])) {
+            $model->fileContents = $map['FileContents'];
+        }
+        if (isset($map['FileSuffix'])) {
+            $model->fileSuffix = $map['FileSuffix'];
+        }
+
+        return $model;
+    }
+}

+ 71 - 0
vendor/alibabacloud/dysmsapi-20170525/src/Models/AddSmsSignResponse.php

@@ -0,0 +1,71 @@
+<?php
+
+// This file is auto-generated, don't edit it. Thanks.
+
+namespace AlibabaCloud\SDK\Dysmsapi\V20170525\Models;
+
+use AlibabaCloud\Tea\Model;
+
+class AddSmsSignResponse extends Model
+{
+    /**
+     * @var string[]
+     */
+    public $headers;
+
+    /**
+     * @var int
+     */
+    public $statusCode;
+
+    /**
+     * @var AddSmsSignResponseBody
+     */
+    public $body;
+    protected $_name = [
+        'headers'    => 'headers',
+        'statusCode' => 'statusCode',
+        'body'       => 'body',
+    ];
+
+    public function validate()
+    {
+    }
+
+    public function toMap()
+    {
+        $res = [];
+        if (null !== $this->headers) {
+            $res['headers'] = $this->headers;
+        }
+        if (null !== $this->statusCode) {
+            $res['statusCode'] = $this->statusCode;
+        }
+        if (null !== $this->body) {
+            $res['body'] = null !== $this->body ? $this->body->toMap() : null;
+        }
+
+        return $res;
+    }
+
+    /**
+     * @param array $map
+     *
+     * @return AddSmsSignResponse
+     */
+    public static function fromMap($map = [])
+    {
+        $model = new self();
+        if (isset($map['headers'])) {
+            $model->headers = $map['headers'];
+        }
+        if (isset($map['statusCode'])) {
+            $model->statusCode = $map['statusCode'];
+        }
+        if (isset($map['body'])) {
+            $model->body = AddSmsSignResponseBody::fromMap($map['body']);
+        }
+
+        return $model;
+    }
+}

+ 102 - 0
vendor/alibabacloud/dysmsapi-20170525/src/Models/AddSmsSignResponseBody.php

@@ -0,0 +1,102 @@
+<?php
+
+// This file is auto-generated, don't edit it. Thanks.
+
+namespace AlibabaCloud\SDK\Dysmsapi\V20170525\Models;
+
+use AlibabaCloud\Tea\Model;
+
+class AddSmsSignResponseBody extends Model
+{
+    /**
+     * @description The response code.
+     *
+     *   The value OK indicates that the request was successful.
+     *   Other values indicate that the request failed. For more information, see [Error codes](https://help.aliyun.com/document_detail/101346.html).
+     *
+     * @example OK
+     *
+     * @var string
+     */
+    public $code;
+
+    /**
+     * @description The returned message.
+     *
+     * @example OK
+     *
+     * @var string
+     */
+    public $message;
+
+    /**
+     * @description The request ID.
+     *
+     * @example F655A8D5-B967-440B-8683-DAD6FF8DE990
+     *
+     * @var string
+     */
+    public $requestId;
+
+    /**
+     * @description The name of the signature.
+     *
+     * @example Aliyun
+     *
+     * @var string
+     */
+    public $signName;
+    protected $_name = [
+        'code'      => 'Code',
+        'message'   => 'Message',
+        'requestId' => 'RequestId',
+        'signName'  => 'SignName',
+    ];
+
+    public function validate()
+    {
+    }
+
+    public function toMap()
+    {
+        $res = [];
+        if (null !== $this->code) {
+            $res['Code'] = $this->code;
+        }
+        if (null !== $this->message) {
+            $res['Message'] = $this->message;
+        }
+        if (null !== $this->requestId) {
+            $res['RequestId'] = $this->requestId;
+        }
+        if (null !== $this->signName) {
+            $res['SignName'] = $this->signName;
+        }
+
+        return $res;
+    }
+
+    /**
+     * @param array $map
+     *
+     * @return AddSmsSignResponseBody
+     */
+    public static function fromMap($map = [])
+    {
+        $model = new self();
+        if (isset($map['Code'])) {
+            $model->code = $map['Code'];
+        }
+        if (isset($map['Message'])) {
+            $model->message = $map['Message'];
+        }
+        if (isset($map['RequestId'])) {
+            $model->requestId = $map['RequestId'];
+        }
+        if (isset($map['SignName'])) {
+            $model->signName = $map['SignName'];
+        }
+
+        return $model;
+    }
+}

+ 144 - 0
vendor/alibabacloud/dysmsapi-20170525/src/Models/AddSmsTemplateRequest.php

@@ -0,0 +1,144 @@
+<?php
+
+// This file is auto-generated, don't edit it. Thanks.
+
+namespace AlibabaCloud\SDK\Dysmsapi\V20170525\Models;
+
+use AlibabaCloud\Tea\Model;
+
+class AddSmsTemplateRequest extends Model
+{
+    /**
+     * @var int
+     */
+    public $ownerId;
+
+    /**
+     * @description The description of the message template. It is one of the reference information for template review. The description cannot exceed 100 characters in length.
+     *
+     * This parameter is required.
+     * @example Apply for a template to send verification codes.
+     *
+     * @var string
+     */
+    public $remark;
+
+    /**
+     * @var string
+     */
+    public $resourceOwnerAccount;
+
+    /**
+     * @var int
+     */
+    public $resourceOwnerId;
+
+    /**
+     * @description The content of the template. The content can be up to 500 characters in length. For more information, see [Message template specifications](https://help.aliyun.com/document_detail/108253.html).
+     *
+     * This parameter is required.
+     * @example You are applying for mobile registration. The verification code is: ${code}, valid for 5 minutes!
+     *
+     * @var string
+     */
+    public $templateContent;
+
+    /**
+     * @description The name of the template. The name can be up to 30 characters in length.
+     *
+     * This parameter is required.
+     * @example Aliyun Test
+     *
+     * @var string
+     */
+    public $templateName;
+
+    /**
+     * @description The type of the message. Valid values:
+     *
+     *   **0**: verification code
+     *   **1**: notification
+     *   **2**: promotional message
+     *   **3**: message sent to countries or regions outside the Chinese mainland
+     *
+     * This parameter is required.
+     * @example 1
+     *
+     * @var int
+     */
+    public $templateType;
+    protected $_name = [
+        'ownerId'              => 'OwnerId',
+        'remark'               => 'Remark',
+        'resourceOwnerAccount' => 'ResourceOwnerAccount',
+        'resourceOwnerId'      => 'ResourceOwnerId',
+        'templateContent'      => 'TemplateContent',
+        'templateName'         => 'TemplateName',
+        'templateType'         => 'TemplateType',
+    ];
+
+    public function validate()
+    {
+    }
+
+    public function toMap()
+    {
+        $res = [];
+        if (null !== $this->ownerId) {
+            $res['OwnerId'] = $this->ownerId;
+        }
+        if (null !== $this->remark) {
+            $res['Remark'] = $this->remark;
+        }
+        if (null !== $this->resourceOwnerAccount) {
+            $res['ResourceOwnerAccount'] = $this->resourceOwnerAccount;
+        }
+        if (null !== $this->resourceOwnerId) {
+            $res['ResourceOwnerId'] = $this->resourceOwnerId;
+        }
+        if (null !== $this->templateContent) {
+            $res['TemplateContent'] = $this->templateContent;
+        }
+        if (null !== $this->templateName) {
+            $res['TemplateName'] = $this->templateName;
+        }
+        if (null !== $this->templateType) {
+            $res['TemplateType'] = $this->templateType;
+        }
+
+        return $res;
+    }
+
+    /**
+     * @param array $map
+     *
+     * @return AddSmsTemplateRequest
+     */
+    public static function fromMap($map = [])
+    {
+        $model = new self();
+        if (isset($map['OwnerId'])) {
+            $model->ownerId = $map['OwnerId'];
+        }
+        if (isset($map['Remark'])) {
+            $model->remark = $map['Remark'];
+        }
+        if (isset($map['ResourceOwnerAccount'])) {
+            $model->resourceOwnerAccount = $map['ResourceOwnerAccount'];
+        }
+        if (isset($map['ResourceOwnerId'])) {
+            $model->resourceOwnerId = $map['ResourceOwnerId'];
+        }
+        if (isset($map['TemplateContent'])) {
+            $model->templateContent = $map['TemplateContent'];
+        }
+        if (isset($map['TemplateName'])) {
+            $model->templateName = $map['TemplateName'];
+        }
+        if (isset($map['TemplateType'])) {
+            $model->templateType = $map['TemplateType'];
+        }
+
+        return $model;
+    }
+}

+ 71 - 0
vendor/alibabacloud/dysmsapi-20170525/src/Models/AddSmsTemplateResponse.php

@@ -0,0 +1,71 @@
+<?php
+
+// This file is auto-generated, don't edit it. Thanks.
+
+namespace AlibabaCloud\SDK\Dysmsapi\V20170525\Models;
+
+use AlibabaCloud\Tea\Model;
+
+class AddSmsTemplateResponse extends Model
+{
+    /**
+     * @var string[]
+     */
+    public $headers;
+
+    /**
+     * @var int
+     */
+    public $statusCode;
+
+    /**
+     * @var AddSmsTemplateResponseBody
+     */
+    public $body;
+    protected $_name = [
+        'headers'    => 'headers',
+        'statusCode' => 'statusCode',
+        'body'       => 'body',
+    ];
+
+    public function validate()
+    {
+    }
+
+    public function toMap()
+    {
+        $res = [];
+        if (null !== $this->headers) {
+            $res['headers'] = $this->headers;
+        }
+        if (null !== $this->statusCode) {
+            $res['statusCode'] = $this->statusCode;
+        }
+        if (null !== $this->body) {
+            $res['body'] = null !== $this->body ? $this->body->toMap() : null;
+        }
+
+        return $res;
+    }
+
+    /**
+     * @param array $map
+     *
+     * @return AddSmsTemplateResponse
+     */
+    public static function fromMap($map = [])
+    {
+        $model = new self();
+        if (isset($map['headers'])) {
+            $model->headers = $map['headers'];
+        }
+        if (isset($map['statusCode'])) {
+            $model->statusCode = $map['statusCode'];
+        }
+        if (isset($map['body'])) {
+            $model->body = AddSmsTemplateResponseBody::fromMap($map['body']);
+        }
+
+        return $model;
+    }
+}

+ 102 - 0
vendor/alibabacloud/dysmsapi-20170525/src/Models/AddSmsTemplateResponseBody.php

@@ -0,0 +1,102 @@
+<?php
+
+// This file is auto-generated, don't edit it. Thanks.
+
+namespace AlibabaCloud\SDK\Dysmsapi\V20170525\Models;
+
+use AlibabaCloud\Tea\Model;
+
+class AddSmsTemplateResponseBody extends Model
+{
+    /**
+     * @description The response code.
+     *
+     *   The value OK indicates that the request was successful.
+     *   For more information about other response codes, see [API error codes](https://help.aliyun.com/document_detail/101346.html).
+     *
+     * @example OK
+     *
+     * @var string
+     */
+    public $code;
+
+    /**
+     * @description The returned message.
+     *
+     * @example OK
+     *
+     * @var string
+     */
+    public $message;
+
+    /**
+     * @description The request ID.
+     *
+     * @example F655A8D5-B967-440B-8683-DAD6FF8DE990
+     *
+     * @var string
+     */
+    public $requestId;
+
+    /**
+     * @description The code of the message template.
+     *
+     * @example SMS_15255****
+     *
+     * @var string
+     */
+    public $templateCode;
+    protected $_name = [
+        'code'         => 'Code',
+        'message'      => 'Message',
+        'requestId'    => 'RequestId',
+        'templateCode' => 'TemplateCode',
+    ];
+
+    public function validate()
+    {
+    }
+
+    public function toMap()
+    {
+        $res = [];
+        if (null !== $this->code) {
+            $res['Code'] = $this->code;
+        }
+        if (null !== $this->message) {
+            $res['Message'] = $this->message;
+        }
+        if (null !== $this->requestId) {
+            $res['RequestId'] = $this->requestId;
+        }
+        if (null !== $this->templateCode) {
+            $res['TemplateCode'] = $this->templateCode;
+        }
+
+        return $res;
+    }
+
+    /**
+     * @param array $map
+     *
+     * @return AddSmsTemplateResponseBody
+     */
+    public static function fromMap($map = [])
+    {
+        $model = new self();
+        if (isset($map['Code'])) {
+            $model->code = $map['Code'];
+        }
+        if (isset($map['Message'])) {
+            $model->message = $map['Message'];
+        }
+        if (isset($map['RequestId'])) {
+            $model->requestId = $map['RequestId'];
+        }
+        if (isset($map['TemplateCode'])) {
+            $model->templateCode = $map['TemplateCode'];
+        }
+
+        return $model;
+    }
+}

+ 69 - 0
vendor/alibabacloud/dysmsapi-20170525/src/Models/CheckMobilesCardSupportRequest.php

@@ -0,0 +1,69 @@
+<?php
+
+// This file is auto-generated, don't edit it. Thanks.
+
+namespace AlibabaCloud\SDK\Dysmsapi\V20170525\Models;
+
+use AlibabaCloud\Tea\Model;
+
+class CheckMobilesCardSupportRequest extends Model
+{
+    /**
+     * @description The list of mobile phone numbers that receive messages.
+     *
+     * This parameter is required.
+     * @var mixed[][]
+     */
+    public $mobiles;
+
+    /**
+     * @description The code of the message template. You can view the template code in the **Template Code** column on the **Templates** tab of the **Go China** page in the Alibaba Cloud SMS console.
+     *
+     * This parameter is required.
+     * @example CARD_SMS_****
+     *
+     * @var string
+     */
+    public $templateCode;
+    protected $_name = [
+        'mobiles'      => 'Mobiles',
+        'templateCode' => 'TemplateCode',
+    ];
+
+    public function validate()
+    {
+    }
+
+    public function toMap()
+    {
+        $res = [];
+        if (null !== $this->mobiles) {
+            $res['Mobiles'] = $this->mobiles;
+        }
+        if (null !== $this->templateCode) {
+            $res['TemplateCode'] = $this->templateCode;
+        }
+
+        return $res;
+    }
+
+    /**
+     * @param array $map
+     *
+     * @return CheckMobilesCardSupportRequest
+     */
+    public static function fromMap($map = [])
+    {
+        $model = new self();
+        if (isset($map['Mobiles'])) {
+            if (!empty($map['Mobiles'])) {
+                $model->mobiles = $map['Mobiles'];
+            }
+        }
+        if (isset($map['TemplateCode'])) {
+            $model->templateCode = $map['TemplateCode'];
+        }
+
+        return $model;
+    }
+}

+ 71 - 0
vendor/alibabacloud/dysmsapi-20170525/src/Models/CheckMobilesCardSupportResponse.php

@@ -0,0 +1,71 @@
+<?php
+
+// This file is auto-generated, don't edit it. Thanks.
+
+namespace AlibabaCloud\SDK\Dysmsapi\V20170525\Models;
+
+use AlibabaCloud\Tea\Model;
+
+class CheckMobilesCardSupportResponse extends Model
+{
+    /**
+     * @var string[]
+     */
+    public $headers;
+
+    /**
+     * @var int
+     */
+    public $statusCode;
+
+    /**
+     * @var CheckMobilesCardSupportResponseBody
+     */
+    public $body;
+    protected $_name = [
+        'headers'    => 'headers',
+        'statusCode' => 'statusCode',
+        'body'       => 'body',
+    ];
+
+    public function validate()
+    {
+    }
+
+    public function toMap()
+    {
+        $res = [];
+        if (null !== $this->headers) {
+            $res['headers'] = $this->headers;
+        }
+        if (null !== $this->statusCode) {
+            $res['statusCode'] = $this->statusCode;
+        }
+        if (null !== $this->body) {
+            $res['body'] = null !== $this->body ? $this->body->toMap() : null;
+        }
+
+        return $res;
+    }
+
+    /**
+     * @param array $map
+     *
+     * @return CheckMobilesCardSupportResponse
+     */
+    public static function fromMap($map = [])
+    {
+        $model = new self();
+        if (isset($map['headers'])) {
+            $model->headers = $map['headers'];
+        }
+        if (isset($map['statusCode'])) {
+            $model->statusCode = $map['statusCode'];
+        }
+        if (isset($map['body'])) {
+            $model->body = CheckMobilesCardSupportResponseBody::fromMap($map['body']);
+        }
+
+        return $model;
+    }
+}

+ 104 - 0
vendor/alibabacloud/dysmsapi-20170525/src/Models/CheckMobilesCardSupportResponseBody.php

@@ -0,0 +1,104 @@
+<?php
+
+// This file is auto-generated, don't edit it. Thanks.
+
+namespace AlibabaCloud\SDK\Dysmsapi\V20170525\Models;
+
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\CheckMobilesCardSupportResponseBody\data;
+use AlibabaCloud\Tea\Model;
+
+class CheckMobilesCardSupportResponseBody extends Model
+{
+    /**
+     * @description The HTTP status code.
+     *
+     *   The value OK indicates that the request was successful.
+     *   Other values indicate that the request failed. For more information, see [Error codes](https://help.aliyun.com/document_detail/101346.html).
+     *
+     * @example OK
+     *
+     * @var string
+     */
+    public $code;
+
+    /**
+     * @description The data returned.
+     *
+     * @var data
+     */
+    public $data;
+
+    /**
+     * @description The request ID.
+     *
+     * @example 819BE656-D2E0-4858-8B21-B2E477085AAF
+     *
+     * @var string
+     */
+    public $requestId;
+
+    /**
+     * @description Indicates whether the request is successful. Valid values:
+     *
+     *   **true**
+     *   **false**
+     *
+     * @example true
+     *
+     * @var bool
+     */
+    public $success;
+    protected $_name = [
+        'code'      => 'Code',
+        'data'      => 'Data',
+        'requestId' => 'RequestId',
+        'success'   => 'Success',
+    ];
+
+    public function validate()
+    {
+    }
+
+    public function toMap()
+    {
+        $res = [];
+        if (null !== $this->code) {
+            $res['Code'] = $this->code;
+        }
+        if (null !== $this->data) {
+            $res['Data'] = null !== $this->data ? $this->data->toMap() : null;
+        }
+        if (null !== $this->requestId) {
+            $res['RequestId'] = $this->requestId;
+        }
+        if (null !== $this->success) {
+            $res['Success'] = $this->success;
+        }
+
+        return $res;
+    }
+
+    /**
+     * @param array $map
+     *
+     * @return CheckMobilesCardSupportResponseBody
+     */
+    public static function fromMap($map = [])
+    {
+        $model = new self();
+        if (isset($map['Code'])) {
+            $model->code = $map['Code'];
+        }
+        if (isset($map['Data'])) {
+            $model->data = data::fromMap($map['Data']);
+        }
+        if (isset($map['RequestId'])) {
+            $model->requestId = $map['RequestId'];
+        }
+        if (isset($map['Success'])) {
+            $model->success = $map['Success'];
+        }
+
+        return $model;
+    }
+}

+ 62 - 0
vendor/alibabacloud/dysmsapi-20170525/src/Models/CheckMobilesCardSupportResponseBody/data.php

@@ -0,0 +1,62 @@
+<?php
+
+// This file is auto-generated, don't edit it. Thanks.
+
+namespace AlibabaCloud\SDK\Dysmsapi\V20170525\Models\CheckMobilesCardSupportResponseBody;
+
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\CheckMobilesCardSupportResponseBody\data\queryResult;
+use AlibabaCloud\Tea\Model;
+
+class data extends Model
+{
+    /**
+     * @description The list of returned results.
+     *
+     * @var queryResult[]
+     */
+    public $queryResult;
+    protected $_name = [
+        'queryResult' => 'queryResult',
+    ];
+
+    public function validate()
+    {
+    }
+
+    public function toMap()
+    {
+        $res = [];
+        if (null !== $this->queryResult) {
+            $res['queryResult'] = [];
+            if (null !== $this->queryResult && \is_array($this->queryResult)) {
+                $n = 0;
+                foreach ($this->queryResult as $item) {
+                    $res['queryResult'][$n++] = null !== $item ? $item->toMap() : $item;
+                }
+            }
+        }
+
+        return $res;
+    }
+
+    /**
+     * @param array $map
+     *
+     * @return data
+     */
+    public static function fromMap($map = [])
+    {
+        $model = new self();
+        if (isset($map['queryResult'])) {
+            if (!empty($map['queryResult'])) {
+                $model->queryResult = [];
+                $n                  = 0;
+                foreach ($map['queryResult'] as $item) {
+                    $model->queryResult[$n++] = null !== $item ? queryResult::fromMap($item) : $item;
+                }
+            }
+        }
+
+        return $model;
+    }
+}

+ 70 - 0
vendor/alibabacloud/dysmsapi-20170525/src/Models/CheckMobilesCardSupportResponseBody/data/queryResult.php

@@ -0,0 +1,70 @@
+<?php
+
+// This file is auto-generated, don't edit it. Thanks.
+
+namespace AlibabaCloud\SDK\Dysmsapi\V20170525\Models\CheckMobilesCardSupportResponseBody\data;
+
+use AlibabaCloud\Tea\Model;
+
+class queryResult extends Model
+{
+    /**
+     * @description The mobile phone number.
+     *
+     * @example 1390000****
+     *
+     * @var string
+     */
+    public $mobile;
+
+    /**
+     * @description Indicates whether the mobile phone number supports card messages.
+     *
+     *   **true**
+     *   **false**
+     *
+     * @example true
+     *
+     * @var bool
+     */
+    public $support;
+    protected $_name = [
+        'mobile'  => 'mobile',
+        'support' => 'support',
+    ];
+
+    public function validate()
+    {
+    }
+
+    public function toMap()
+    {
+        $res = [];
+        if (null !== $this->mobile) {
+            $res['mobile'] = $this->mobile;
+        }
+        if (null !== $this->support) {
+            $res['support'] = $this->support;
+        }
+
+        return $res;
+    }
+
+    /**
+     * @param array $map
+     *
+     * @return queryResult
+     */
+    public static function fromMap($map = [])
+    {
+        $model = new self();
+        if (isset($map['mobile'])) {
+            $model->mobile = $map['mobile'];
+        }
+        if (isset($map['support'])) {
+            $model->support = $map['support'];
+        }
+
+        return $model;
+    }
+}

+ 105 - 0
vendor/alibabacloud/dysmsapi-20170525/src/Models/ConversionDataIntlRequest.php

@@ -0,0 +1,105 @@
+<?php
+
+// This file is auto-generated, don't edit it. Thanks.
+
+namespace AlibabaCloud\SDK\Dysmsapi\V20170525\Models;
+
+use AlibabaCloud\Tea\Model;
+
+class ConversionDataIntlRequest extends Model
+{
+    /**
+     * @description The conversion rate.
+     *
+     * This parameter is required.
+     * @example 0.53
+     *
+     * @var string
+     */
+    public $conversionRate;
+
+    /**
+     * @var int
+     */
+    public $ownerId;
+
+    /**
+     * @description The time point at which the conversion rate is monitored. The value is a UNIX timestamp. Unit: milliseconds.
+     *
+     * > If you do not specify this parameter, the current timestamp is used by default.
+     * @example 1349055900000
+     *
+     * @var int
+     */
+    public $reportTime;
+
+    /**
+     * @var string
+     */
+    public $resourceOwnerAccount;
+
+    /**
+     * @var int
+     */
+    public $resourceOwnerId;
+    protected $_name = [
+        'conversionRate'       => 'ConversionRate',
+        'ownerId'              => 'OwnerId',
+        'reportTime'           => 'ReportTime',
+        'resourceOwnerAccount' => 'ResourceOwnerAccount',
+        'resourceOwnerId'      => 'ResourceOwnerId',
+    ];
+
+    public function validate()
+    {
+    }
+
+    public function toMap()
+    {
+        $res = [];
+        if (null !== $this->conversionRate) {
+            $res['ConversionRate'] = $this->conversionRate;
+        }
+        if (null !== $this->ownerId) {
+            $res['OwnerId'] = $this->ownerId;
+        }
+        if (null !== $this->reportTime) {
+            $res['ReportTime'] = $this->reportTime;
+        }
+        if (null !== $this->resourceOwnerAccount) {
+            $res['ResourceOwnerAccount'] = $this->resourceOwnerAccount;
+        }
+        if (null !== $this->resourceOwnerId) {
+            $res['ResourceOwnerId'] = $this->resourceOwnerId;
+        }
+
+        return $res;
+    }
+
+    /**
+     * @param array $map
+     *
+     * @return ConversionDataIntlRequest
+     */
+    public static function fromMap($map = [])
+    {
+        $model = new self();
+        if (isset($map['ConversionRate'])) {
+            $model->conversionRate = $map['ConversionRate'];
+        }
+        if (isset($map['OwnerId'])) {
+            $model->ownerId = $map['OwnerId'];
+        }
+        if (isset($map['ReportTime'])) {
+            $model->reportTime = $map['ReportTime'];
+        }
+        if (isset($map['ResourceOwnerAccount'])) {
+            $model->resourceOwnerAccount = $map['ResourceOwnerAccount'];
+        }
+        if (isset($map['ResourceOwnerId'])) {
+            $model->resourceOwnerId = $map['ResourceOwnerId'];
+        }
+
+        return $model;
+    }
+}

+ 71 - 0
vendor/alibabacloud/dysmsapi-20170525/src/Models/ConversionDataIntlResponse.php

@@ -0,0 +1,71 @@
+<?php
+
+// This file is auto-generated, don't edit it. Thanks.
+
+namespace AlibabaCloud\SDK\Dysmsapi\V20170525\Models;
+
+use AlibabaCloud\Tea\Model;
+
+class ConversionDataIntlResponse extends Model
+{
+    /**
+     * @var string[]
+     */
+    public $headers;
+
+    /**
+     * @var int
+     */
+    public $statusCode;
+
+    /**
+     * @var ConversionDataIntlResponseBody
+     */
+    public $body;
+    protected $_name = [
+        'headers'    => 'headers',
+        'statusCode' => 'statusCode',
+        'body'       => 'body',
+    ];
+
+    public function validate()
+    {
+    }
+
+    public function toMap()
+    {
+        $res = [];
+        if (null !== $this->headers) {
+            $res['headers'] = $this->headers;
+        }
+        if (null !== $this->statusCode) {
+            $res['statusCode'] = $this->statusCode;
+        }
+        if (null !== $this->body) {
+            $res['body'] = null !== $this->body ? $this->body->toMap() : null;
+        }
+
+        return $res;
+    }
+
+    /**
+     * @param array $map
+     *
+     * @return ConversionDataIntlResponse
+     */
+    public static function fromMap($map = [])
+    {
+        $model = new self();
+        if (isset($map['headers'])) {
+            $model->headers = $map['headers'];
+        }
+        if (isset($map['statusCode'])) {
+            $model->statusCode = $map['statusCode'];
+        }
+        if (isset($map['body'])) {
+            $model->body = ConversionDataIntlResponseBody::fromMap($map['body']);
+        }
+
+        return $model;
+    }
+}

+ 83 - 0
vendor/alibabacloud/dysmsapi-20170525/src/Models/ConversionDataIntlResponseBody.php

@@ -0,0 +1,83 @@
+<?php
+
+// This file is auto-generated, don't edit it. Thanks.
+
+namespace AlibabaCloud\SDK\Dysmsapi\V20170525\Models;
+
+use AlibabaCloud\Tea\Model;
+
+class ConversionDataIntlResponseBody extends Model
+{
+    /**
+     * @description The status code. If OK is returned, the request is successful. For more information, see [Error codes](https://help.aliyun.com/document_detail/101346.html?spm=a2c4g.101345.0.0.74326ff2J5EZyt).
+     *
+     * @example OK
+     *
+     * @var string
+     */
+    public $code;
+
+    /**
+     * @description The returned message.
+     *
+     * @example OK
+     *
+     * @var string
+     */
+    public $message;
+
+    /**
+     * @description The request ID.
+     *
+     * @example F655A8D5-B967-440B-8683-DAD6FF8D****
+     *
+     * @var string
+     */
+    public $requestId;
+    protected $_name = [
+        'code'      => 'Code',
+        'message'   => 'Message',
+        'requestId' => 'RequestId',
+    ];
+
+    public function validate()
+    {
+    }
+
+    public function toMap()
+    {
+        $res = [];
+        if (null !== $this->code) {
+            $res['Code'] = $this->code;
+        }
+        if (null !== $this->message) {
+            $res['Message'] = $this->message;
+        }
+        if (null !== $this->requestId) {
+            $res['RequestId'] = $this->requestId;
+        }
+
+        return $res;
+    }
+
+    /**
+     * @param array $map
+     *
+     * @return ConversionDataIntlResponseBody
+     */
+    public static function fromMap($map = [])
+    {
+        $model = new self();
+        if (isset($map['Code'])) {
+            $model->code = $map['Code'];
+        }
+        if (isset($map['Message'])) {
+            $model->message = $map['Message'];
+        }
+        if (isset($map['RequestId'])) {
+            $model->requestId = $map['RequestId'];
+        }
+
+        return $model;
+    }
+}

+ 108 - 0
vendor/alibabacloud/dysmsapi-20170525/src/Models/CreateCardSmsTemplateRequest.php

@@ -0,0 +1,108 @@
+<?php
+
+// This file is auto-generated, don't edit it. Thanks.
+
+namespace AlibabaCloud\SDK\Dysmsapi\V20170525\Models;
+
+use AlibabaCloud\Tea\Model;
+
+class CreateCardSmsTemplateRequest extends Model
+{
+    /**
+     * @description The mobile phone manufacturer. Valid values:
+     *
+     *   **HuaWei**: HUAWEI
+     *   **XiaoMi**: Xiaomi
+     *   **OPPO**: OPPO
+     *   **VIVO**: vivo
+     *   **MEIZU**: MEIZU
+     *
+     * > If this parameter is not specified, the system automatically specifies a supported mobile phone manufacturer.
+     * @example XiaoMi
+     *
+     * @var string
+     */
+    public $factorys;
+
+    /**
+     * @description The description of the message template.
+     *
+     * @var string
+     */
+    public $memo;
+
+    /**
+     * @description The content of the card message template.
+     *
+     * >
+     *
+     *   For information about fields such as Template, ExtendInfo, TemplateContent, TmpCard, and Action, see [Parameters of card message templates](https://help.aliyun.com/document_detail/434929.html).
+     *
+     *   Message template content varies based on the template type. For more information, see [Sample message templates](https://help.aliyun.com/document_detail/435361.html).
+     *
+     * This parameter is required.
+     * @var mixed[]
+     */
+    public $template;
+
+    /**
+     * @description The name of the card message template.
+     *
+     * This parameter is required.
+     * @var string
+     */
+    public $templateName;
+    protected $_name = [
+        'factorys'     => 'Factorys',
+        'memo'         => 'Memo',
+        'template'     => 'Template',
+        'templateName' => 'TemplateName',
+    ];
+
+    public function validate()
+    {
+    }
+
+    public function toMap()
+    {
+        $res = [];
+        if (null !== $this->factorys) {
+            $res['Factorys'] = $this->factorys;
+        }
+        if (null !== $this->memo) {
+            $res['Memo'] = $this->memo;
+        }
+        if (null !== $this->template) {
+            $res['Template'] = $this->template;
+        }
+        if (null !== $this->templateName) {
+            $res['TemplateName'] = $this->templateName;
+        }
+
+        return $res;
+    }
+
+    /**
+     * @param array $map
+     *
+     * @return CreateCardSmsTemplateRequest
+     */
+    public static function fromMap($map = [])
+    {
+        $model = new self();
+        if (isset($map['Factorys'])) {
+            $model->factorys = $map['Factorys'];
+        }
+        if (isset($map['Memo'])) {
+            $model->memo = $map['Memo'];
+        }
+        if (isset($map['Template'])) {
+            $model->template = $map['Template'];
+        }
+        if (isset($map['TemplateName'])) {
+            $model->templateName = $map['TemplateName'];
+        }
+
+        return $model;
+    }
+}

+ 71 - 0
vendor/alibabacloud/dysmsapi-20170525/src/Models/CreateCardSmsTemplateResponse.php

@@ -0,0 +1,71 @@
+<?php
+
+// This file is auto-generated, don't edit it. Thanks.
+
+namespace AlibabaCloud\SDK\Dysmsapi\V20170525\Models;
+
+use AlibabaCloud\Tea\Model;
+
+class CreateCardSmsTemplateResponse extends Model
+{
+    /**
+     * @var string[]
+     */
+    public $headers;
+
+    /**
+     * @var int
+     */
+    public $statusCode;
+
+    /**
+     * @var CreateCardSmsTemplateResponseBody
+     */
+    public $body;
+    protected $_name = [
+        'headers'    => 'headers',
+        'statusCode' => 'statusCode',
+        'body'       => 'body',
+    ];
+
+    public function validate()
+    {
+    }
+
+    public function toMap()
+    {
+        $res = [];
+        if (null !== $this->headers) {
+            $res['headers'] = $this->headers;
+        }
+        if (null !== $this->statusCode) {
+            $res['statusCode'] = $this->statusCode;
+        }
+        if (null !== $this->body) {
+            $res['body'] = null !== $this->body ? $this->body->toMap() : null;
+        }
+
+        return $res;
+    }
+
+    /**
+     * @param array $map
+     *
+     * @return CreateCardSmsTemplateResponse
+     */
+    public static function fromMap($map = [])
+    {
+        $model = new self();
+        if (isset($map['headers'])) {
+            $model->headers = $map['headers'];
+        }
+        if (isset($map['statusCode'])) {
+            $model->statusCode = $map['statusCode'];
+        }
+        if (isset($map['body'])) {
+            $model->body = CreateCardSmsTemplateResponseBody::fromMap($map['body']);
+        }
+
+        return $model;
+    }
+}

+ 104 - 0
vendor/alibabacloud/dysmsapi-20170525/src/Models/CreateCardSmsTemplateResponseBody.php

@@ -0,0 +1,104 @@
+<?php
+
+// This file is auto-generated, don't edit it. Thanks.
+
+namespace AlibabaCloud\SDK\Dysmsapi\V20170525\Models;
+
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\CreateCardSmsTemplateResponseBody\data;
+use AlibabaCloud\Tea\Model;
+
+class CreateCardSmsTemplateResponseBody extends Model
+{
+    /**
+     * @description The response code.
+     *
+     *   If OK is returned, the request is successful.
+     *   Other values indicate that the request fails. For more information, see [Error codes](https://help.aliyun.com/document_detail/101346.html).
+     *
+     * @example OK
+     *
+     * @var string
+     */
+    public $code;
+
+    /**
+     * @description The data returned.
+     *
+     * @var data
+     */
+    public $data;
+
+    /**
+     * @description The request ID.
+     *
+     * @example F655A8D5-B967-440B-8683-DAD6FF8DE990
+     *
+     * @var string
+     */
+    public $requestId;
+
+    /**
+     * @description Indicates whether the request was successful. Valid values:
+     *
+     *   **true**
+     *   **false**
+     *
+     * @example true
+     *
+     * @var bool
+     */
+    public $success;
+    protected $_name = [
+        'code'      => 'Code',
+        'data'      => 'Data',
+        'requestId' => 'RequestId',
+        'success'   => 'Success',
+    ];
+
+    public function validate()
+    {
+    }
+
+    public function toMap()
+    {
+        $res = [];
+        if (null !== $this->code) {
+            $res['Code'] = $this->code;
+        }
+        if (null !== $this->data) {
+            $res['Data'] = null !== $this->data ? $this->data->toMap() : null;
+        }
+        if (null !== $this->requestId) {
+            $res['RequestId'] = $this->requestId;
+        }
+        if (null !== $this->success) {
+            $res['Success'] = $this->success;
+        }
+
+        return $res;
+    }
+
+    /**
+     * @param array $map
+     *
+     * @return CreateCardSmsTemplateResponseBody
+     */
+    public static function fromMap($map = [])
+    {
+        $model = new self();
+        if (isset($map['Code'])) {
+            $model->code = $map['Code'];
+        }
+        if (isset($map['Data'])) {
+            $model->data = data::fromMap($map['Data']);
+        }
+        if (isset($map['RequestId'])) {
+            $model->requestId = $map['RequestId'];
+        }
+        if (isset($map['Success'])) {
+            $model->success = $map['Success'];
+        }
+
+        return $model;
+    }
+}

+ 54 - 0
vendor/alibabacloud/dysmsapi-20170525/src/Models/CreateCardSmsTemplateResponseBody/data.php

@@ -0,0 +1,54 @@
+<?php
+
+// This file is auto-generated, don't edit it. Thanks.
+
+namespace AlibabaCloud\SDK\Dysmsapi\V20170525\Models\CreateCardSmsTemplateResponseBody;
+
+use AlibabaCloud\Tea\Model;
+
+class data extends Model
+{
+    /**
+     * @description The code of the message template.
+     *
+     * You can view the template code in the **Template Code** column on the **Templates** tab of the **Go China** page in the [Alibaba Cloud SMS console](https://dysms.console.aliyun.com/dysms.htm?spm=5176.12818093.categories-n-products.ddysms.3b2816d0xml2NA#/overview).
+     *
+     * > Make sure that the message template has been approved.
+     * @example CARD_SMS_60000****
+     *
+     * @var string
+     */
+    public $templateCode;
+    protected $_name = [
+        'templateCode' => 'TemplateCode',
+    ];
+
+    public function validate()
+    {
+    }
+
+    public function toMap()
+    {
+        $res = [];
+        if (null !== $this->templateCode) {
+            $res['TemplateCode'] = $this->templateCode;
+        }
+
+        return $res;
+    }
+
+    /**
+     * @param array $map
+     *
+     * @return data
+     */
+    public static function fromMap($map = [])
+    {
+        $model = new self();
+        if (isset($map['TemplateCode'])) {
+            $model->templateCode = $map['TemplateCode'];
+        }
+
+        return $model;
+    }
+}

+ 108 - 0
vendor/alibabacloud/dysmsapi-20170525/src/Models/CreateCardSmsTemplateShrinkRequest.php

@@ -0,0 +1,108 @@
+<?php
+
+// This file is auto-generated, don't edit it. Thanks.
+
+namespace AlibabaCloud\SDK\Dysmsapi\V20170525\Models;
+
+use AlibabaCloud\Tea\Model;
+
+class CreateCardSmsTemplateShrinkRequest extends Model
+{
+    /**
+     * @description The mobile phone manufacturer. Valid values:
+     *
+     *   **HuaWei**: HUAWEI
+     *   **XiaoMi**: Xiaomi
+     *   **OPPO**: OPPO
+     *   **VIVO**: vivo
+     *   **MEIZU**: MEIZU
+     *
+     * > If this parameter is not specified, the system automatically specifies a supported mobile phone manufacturer.
+     * @example XiaoMi
+     *
+     * @var string
+     */
+    public $factorys;
+
+    /**
+     * @description The description of the message template.
+     *
+     * @var string
+     */
+    public $memo;
+
+    /**
+     * @description The content of the card message template.
+     *
+     * >
+     *
+     *   For information about fields such as Template, ExtendInfo, TemplateContent, TmpCard, and Action, see [Parameters of card message templates](https://help.aliyun.com/document_detail/434929.html).
+     *
+     *   Message template content varies based on the template type. For more information, see [Sample message templates](https://help.aliyun.com/document_detail/435361.html).
+     *
+     * This parameter is required.
+     * @var string
+     */
+    public $templateShrink;
+
+    /**
+     * @description The name of the card message template.
+     *
+     * This parameter is required.
+     * @var string
+     */
+    public $templateName;
+    protected $_name = [
+        'factorys'       => 'Factorys',
+        'memo'           => 'Memo',
+        'templateShrink' => 'Template',
+        'templateName'   => 'TemplateName',
+    ];
+
+    public function validate()
+    {
+    }
+
+    public function toMap()
+    {
+        $res = [];
+        if (null !== $this->factorys) {
+            $res['Factorys'] = $this->factorys;
+        }
+        if (null !== $this->memo) {
+            $res['Memo'] = $this->memo;
+        }
+        if (null !== $this->templateShrink) {
+            $res['Template'] = $this->templateShrink;
+        }
+        if (null !== $this->templateName) {
+            $res['TemplateName'] = $this->templateName;
+        }
+
+        return $res;
+    }
+
+    /**
+     * @param array $map
+     *
+     * @return CreateCardSmsTemplateShrinkRequest
+     */
+    public static function fromMap($map = [])
+    {
+        $model = new self();
+        if (isset($map['Factorys'])) {
+            $model->factorys = $map['Factorys'];
+        }
+        if (isset($map['Memo'])) {
+            $model->memo = $map['Memo'];
+        }
+        if (isset($map['Template'])) {
+            $model->templateShrink = $map['Template'];
+        }
+        if (isset($map['TemplateName'])) {
+            $model->templateName = $map['TemplateName'];
+        }
+
+        return $model;
+    }
+}

+ 117 - 0
vendor/alibabacloud/dysmsapi-20170525/src/Models/CreateSmartShortUrlRequest.php

@@ -0,0 +1,117 @@
+<?php
+
+// This file is auto-generated, don't edit it. Thanks.
+
+namespace AlibabaCloud\SDK\Dysmsapi\V20170525\Models;
+
+use AlibabaCloud\Tea\Model;
+
+class CreateSmartShortUrlRequest extends Model
+{
+    /**
+     * @example 示例值示例值
+     *
+     * @var string
+     */
+    public $outId;
+
+    /**
+     * @var int
+     */
+    public $ownerId;
+
+    /**
+     * @description This parameter is required.
+     *
+     * @example 15900195***
+     *
+     * @var string
+     */
+    public $phoneNumbers;
+
+    /**
+     * @var string
+     */
+    public $resourceOwnerAccount;
+
+    /**
+     * @var int
+     */
+    public $resourceOwnerId;
+
+    /**
+     * @description This parameter is required.
+     *
+     * @example 示例值
+     *
+     * @var string
+     */
+    public $sourceUrl;
+    protected $_name = [
+        'outId'                => 'OutId',
+        'ownerId'              => 'OwnerId',
+        'phoneNumbers'         => 'PhoneNumbers',
+        'resourceOwnerAccount' => 'ResourceOwnerAccount',
+        'resourceOwnerId'      => 'ResourceOwnerId',
+        'sourceUrl'            => 'SourceUrl',
+    ];
+
+    public function validate()
+    {
+    }
+
+    public function toMap()
+    {
+        $res = [];
+        if (null !== $this->outId) {
+            $res['OutId'] = $this->outId;
+        }
+        if (null !== $this->ownerId) {
+            $res['OwnerId'] = $this->ownerId;
+        }
+        if (null !== $this->phoneNumbers) {
+            $res['PhoneNumbers'] = $this->phoneNumbers;
+        }
+        if (null !== $this->resourceOwnerAccount) {
+            $res['ResourceOwnerAccount'] = $this->resourceOwnerAccount;
+        }
+        if (null !== $this->resourceOwnerId) {
+            $res['ResourceOwnerId'] = $this->resourceOwnerId;
+        }
+        if (null !== $this->sourceUrl) {
+            $res['SourceUrl'] = $this->sourceUrl;
+        }
+
+        return $res;
+    }
+
+    /**
+     * @param array $map
+     *
+     * @return CreateSmartShortUrlRequest
+     */
+    public static function fromMap($map = [])
+    {
+        $model = new self();
+        if (isset($map['OutId'])) {
+            $model->outId = $map['OutId'];
+        }
+        if (isset($map['OwnerId'])) {
+            $model->ownerId = $map['OwnerId'];
+        }
+        if (isset($map['PhoneNumbers'])) {
+            $model->phoneNumbers = $map['PhoneNumbers'];
+        }
+        if (isset($map['ResourceOwnerAccount'])) {
+            $model->resourceOwnerAccount = $map['ResourceOwnerAccount'];
+        }
+        if (isset($map['ResourceOwnerId'])) {
+            $model->resourceOwnerId = $map['ResourceOwnerId'];
+        }
+        if (isset($map['SourceUrl'])) {
+            $model->sourceUrl = $map['SourceUrl'];
+        }
+
+        return $model;
+    }
+}

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