wesmiler 2 năm trước cách đây
mục cha
commit
357db3b157
100 tập tin đã thay đổi với 11935 bổ sung85 xóa
  1. 6 81
      app/Http/Controllers/Api/v1/NotifyController.php
  2. 3 1
      app/Http/Controllers/Api/v1/TestController.php
  3. 5 0
      app/Services/Api/MemberService.php
  4. 143 0
      app/Services/UdunpayService.php
  5. 1 0
      composer.json
  6. 268 1
      composer.lock
  7. 67 0
      vendor/composer/autoload_classmap.php
  8. 1 0
      vendor/composer/autoload_namespaces.php
  9. 3 0
      vendor/composer/autoload_psr4.php
  10. 95 0
      vendor/composer/autoload_static.php
  11. 279 0
      vendor/composer/installed.json
  12. 38 2
      vendor/composer/installed.php
  13. 19 0
      vendor/doctrine/cache/LICENSE
  14. 13 0
      vendor/doctrine/cache/README.md
  15. 15 0
      vendor/doctrine/cache/UPGRADE-1.11.md
  16. 16 0
      vendor/doctrine/cache/UPGRADE-1.4.md
  17. 56 0
      vendor/doctrine/cache/composer.json
  18. 106 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/ApcCache.php
  19. 108 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/ApcuCache.php
  20. 115 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/ArrayCache.php
  21. 90 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/Cache.php
  22. 325 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/CacheProvider.php
  23. 198 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/ChainCache.php
  24. 21 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/ClearableCache.php
  25. 200 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseBucketCache.php
  26. 106 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseCache.php
  27. 199 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/ExtMongoDBCache.php
  28. 292 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php
  29. 105 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/FilesystemCache.php
  30. 18 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/FlushableCache.php
  31. 38 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/InvalidCacheId.php
  32. 177 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/LegacyMongoDBCache.php
  33. 105 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/MemcacheCache.php
  34. 173 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/MemcachedCache.php
  35. 116 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/MongoDBCache.php
  36. 22 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/MultiDeleteCache.php
  37. 23 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/MultiGetCache.php
  38. 12 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/MultiOperationCache.php
  39. 24 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/MultiPutCache.php
  40. 120 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/PhpFileCache.php
  41. 147 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/PredisCache.php
  42. 340 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/CacheAdapter.php
  43. 118 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/CacheItem.php
  44. 135 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/DoctrineProvider.php
  45. 13 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/InvalidArgument.php
  46. 99 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/TypedCacheItem.php
  47. 186 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/RedisCache.php
  48. 210 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/SQLite3Cache.php
  49. 11 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/Version.php
  50. 61 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/VoidCache.php
  51. 108 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/WinCacheCache.php
  52. 106 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/XcacheCache.php
  53. 71 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/ZendDataCache.php
  54. 8 0
      vendor/hanson/foundation-sdk/.gitignore
  55. 21 0
      vendor/hanson/foundation-sdk/LICENSE
  56. 25 0
      vendor/hanson/foundation-sdk/README.md
  57. 27 0
      vendor/hanson/foundation-sdk/composer.json
  58. 61 0
      vendor/hanson/foundation-sdk/src/AbstractAPI.php
  59. 237 0
      vendor/hanson/foundation-sdk/src/AbstractAccessToken.php
  60. 11 0
      vendor/hanson/foundation-sdk/src/Exception/HttpException.php
  61. 147 0
      vendor/hanson/foundation-sdk/src/Foundation.php
  62. 300 0
      vendor/hanson/foundation-sdk/src/Http.php
  63. 104 0
      vendor/hanson/foundation-sdk/src/Log.php
  64. 19 0
      vendor/hanson/foundation-sdk/tests/HttpTest.php
  65. 47 0
      vendor/pimple/pimple/.github/workflows/tests.yml
  66. 4 0
      vendor/pimple/pimple/.gitignore
  67. 20 0
      vendor/pimple/pimple/.php_cs.dist
  68. 72 0
      vendor/pimple/pimple/CHANGELOG
  69. 19 0
      vendor/pimple/pimple/LICENSE
  70. 332 0
      vendor/pimple/pimple/README.rst
  71. 29 0
      vendor/pimple/pimple/composer.json
  72. 18 0
      vendor/pimple/pimple/phpunit.xml.dist
  73. 305 0
      vendor/pimple/pimple/src/Pimple/Container.php
  74. 38 0
      vendor/pimple/pimple/src/Pimple/Exception/ExpectedInvokableException.php
  75. 45 0
      vendor/pimple/pimple/src/Pimple/Exception/FrozenServiceException.php
  76. 45 0
      vendor/pimple/pimple/src/Pimple/Exception/InvalidServiceIdentifierException.php
  77. 45 0
      vendor/pimple/pimple/src/Pimple/Exception/UnknownIdentifierException.php
  78. 55 0
      vendor/pimple/pimple/src/Pimple/Psr11/Container.php
  79. 75 0
      vendor/pimple/pimple/src/Pimple/Psr11/ServiceLocator.php
  80. 89 0
      vendor/pimple/pimple/src/Pimple/ServiceIterator.php
  81. 44 0
      vendor/pimple/pimple/src/Pimple/ServiceProviderInterface.php
  82. 38 0
      vendor/pimple/pimple/src/Pimple/Tests/Fixtures/Invokable.php
  83. 34 0
      vendor/pimple/pimple/src/Pimple/Tests/Fixtures/NonInvokable.php
  84. 52 0
      vendor/pimple/pimple/src/Pimple/Tests/Fixtures/PimpleServiceProvider.php
  85. 35 0
      vendor/pimple/pimple/src/Pimple/Tests/Fixtures/Service.php
  86. 77 0
      vendor/pimple/pimple/src/Pimple/Tests/PimpleServiceProviderInterfaceTest.php
  87. 610 0
      vendor/pimple/pimple/src/Pimple/Tests/PimpleTest.php
  88. 76 0
      vendor/pimple/pimple/src/Pimple/Tests/Psr11/ContainerTest.php
  89. 131 0
      vendor/pimple/pimple/src/Pimple/Tests/Psr11/ServiceLocatorTest.php
  90. 52 0
      vendor/pimple/pimple/src/Pimple/Tests/ServiceIteratorTest.php
  91. 1 0
      vendor/uduncloud/udun-wallet-sdk/.gitignore
  92. 111 0
      vendor/uduncloud/udun-wallet-sdk/README.md
  93. 24 0
      vendor/uduncloud/udun-wallet-sdk/composer.json
  94. 2799 0
      vendor/uduncloud/udun-wallet-sdk/composer.lock
  95. 41 0
      vendor/uduncloud/udun-wallet-sdk/demo/testApi.php
  96. 70 0
      vendor/uduncloud/udun-wallet-sdk/src/Api.php
  97. 162 0
      vendor/uduncloud/udun-wallet-sdk/src/Clients.php
  98. 26 0
      vendor/uduncloud/udun-wallet-sdk/src/ClientsServiceProvider.php
  99. 28 0
      vendor/uduncloud/udun-wallet-sdk/src/UdunDispatch.php
  100. 0 0
      vendor/uduncloud/udun-wallet-sdk/src/UdunDispatchException.php

+ 6 - 81
app/Http/Controllers/Api/v1/NotifyController.php

@@ -5,6 +5,7 @@ namespace App\Http\Controllers\Api\v1;
 use App\Http\Controllers\Api\webApp;
 use App\Services\Api\PaymentService;
 use App\Services\RedisService;
+use App\Services\UdunpayService;
 use Yansongda\Pay\Pay;
 
 /**
@@ -14,89 +15,13 @@ use Yansongda\Pay\Pay;
  */
 class NotifyController extends webApp
 {
-
     /**
-     * 支付回调
-     * @param string $scene 场景,buy-购买服务,cost-店内消费,shop-商城购买,recharge-充值,chat-聊天服务付款,deliver-投递简历,download-下载简历
-     * @param int $payType 支付方式:10-微信,20-支付宝
-     * @return array|false|\Psr\Http\Message\ResponseInterface
+     * U盾钱包回调
+     * @return string
      */
-    public function callback($scene, $payType = 10)
+    public function udunpay()
     {
-        $date = date('Y-m-d H:i:s');
-        $result = request()->post();
-        if (empty($result)) {
-            $result = file_get_contents('php://input');
-            $result = $result ? json_decode($result, true) : [];
-        }
-        try {
-            RedisService::set("caches:payments:notify_result".date('YmdHis').rand(10,99), ['all' => request()->all(), 'scene' => $scene, 'payType' => $payType, 'data' => $result], 7200);
-            $pay = PaymentService::make()->createPay($scene, $payType);
-            $key = date('YmdHis') . '_' . rand(1000, 9999);
-            if (empty($pay) || empty($scene) || empty($payType)) {
-                if (env('APP_DEBUG')) {
-                    logger()->error("【{$date} 支付回调】参数错误:" . json_encode(['scene' => $scene, 'payType' => $payType, 'data' => $result], 256));
-                }
-
-                RedisService::set("caches:payments:notify_error_" . $key, ['all' => request()->all(), 'scene' => $scene, 'payType' => $payType, 'data' => $result], 7200);
-                return false;
-            }
-
-            // 验签和重组参数
-            //$data = $result;  // 本地测试
-            $data = $pay->callback();
-            RedisService::set("caches:payments:notify_data_" . $key, ['all' => request()->all(), 'scene' => $scene, 'payType' => $payType, 'data' => $result], 7200);
-            if (env('APP_DEBUG')) {
-                logger()->info("【{$date} 支付回调】验证结果:" . json_encode(['data' => $data,'scene'=>$scene,'payType'=>$payType],256));
-            }
-
-            // 回调处理
-            if (PaymentService::make()->catchNotify($scene, $payType, $data)) {
-                logger()->info("【{$date} 支付回调】回调成功:" . json_encode(['data' => $data,'scene'=>$scene,'payType'=>$payType],256));
-                return response('success');
-            } else {
-                $msg = PaymentService::make()->getError();
-                logger()->info("【{$date} 支付回调】回调失败:" . json_encode(['data' => $data,'scene'=>$scene,'payType'=>$payType, 'error' => lang($msg)], 256));
-                return message($msg ? $msg : 2635, false);
-            }
-        } catch (\Exception $exception) {
-            logger()->error("【{$date} 支付回调】回调错误:" . json_encode(['data' => $result,'scene'=>$scene,'payType'=>$payType, 'error' => $exception->getMessage()], 256));
-            return message(2635, false, ['error' => $exception->getMessage()]);
-        }
-    }
-
-
-    /**
-     * 退款回调
-     * @param string $scene 场景,buy-购买服务,cost-店内消费,shop-商城购买,recharge-充值,chat-聊天服务付款,deliver-投递简历,download-下载简历
-     * @param int $payType 支付方式:10-微信,20-支付宝
-     * @return array|false
-     * @throws \Yansongda\Pay\Exception\ContainerException
-     * @throws \Yansongda\Pay\Exception\InvalidParamsException
-     */
-    public function refund($payType = 10)
-    {
-        $scene = 'refund';
-        $date = date('Y-m-d H:i:s');
-        $result = request()->post();
-        $pay = PaymentService::make()->createPay('refund', $payType);
-
-        if (empty($pay) || empty($scene) || empty($payType)) {
-            if (env('APP_DEBUG')) {
-                logger()->error("【{$date} 退款回调】验证错误:" . json_encode(['scene' => $scene, 'payType' => $payType, 'data' => $result], 256));
-            }
-
-            RedisService::set("caches:refunds:notify_error_" . date('YmdH'), ['all' => request()->all(), 'scene' => $scene, 'payType' => $payType, 'data' => $result], 7200);
-            return false;
-        }
-
-        // 验签和重组参数
-        $data = $pay->callback();
-        RedisService::set("caches:refunds:notify_data_" . date('YmdH'), ['all' => request()->all(), 'scene' => $scene, 'payType' => $payType, 'data' => $result], 7200);
-        if (env('APP_DEBUG')) {
-            logger()->info("【{$date} 退款回调】验证结果:" . json_encode($data, 256));
-        }
-
-
+        $result =  UdunpayService::make()->callback();
+        return '';
     }
 }

+ 3 - 1
app/Http/Controllers/Api/v1/TestController.php

@@ -3,6 +3,7 @@
 namespace App\Http\Controllers\Api\v1;
 
 use App\Http\Controllers\Api\webApp;
+use App\Services\UdunpayService;
 
 /**
  * 测试
@@ -14,6 +15,7 @@ class TestController extends webApp
 
     public function check()
     {
-        return message('获取结果');
+        $wallet = UdunpayService::make()->createAddress();
+        return message('获取结果', $wallet);
     }
 }

+ 5 - 0
app/Services/Api/MemberService.php

@@ -31,6 +31,7 @@ use App\Services\PushService;
 use App\Services\RedisService;
 use App\Services\SmsService;
 use App\Services\ToolService;
+use App\Services\UdunpayService;
 use App\Services\ZegoService;
 use Illuminate\Support\Facades\DB;
 use phpQrcode\QRcode;
@@ -514,6 +515,8 @@ class MemberService extends BaseService
         $ipData = ToolService::make()->getIpAddress($ip,'');
         $province = isset($ipData['regionName'])? $ipData['regionName'] : '';
         $city = isset($ipData['city'])? $ipData['city'] : '';
+
+        // 钱包
         $data = [
             'parent_id' => $parentId,
             'point_id' => $pointId,
@@ -524,7 +527,9 @@ class MemberService extends BaseService
             'username' => $email,
             'password' => get_password('xl123456'),
             'code' => strtoupper(get_random_code(8, 'XL', "{$id}")),
+            'email' => $email,
             'mobile' => $mobile,
+            'recharge_trc_addr' => UdunpayService::make()->createAddress(195),
             'parents' => $parents,
             'province_id' => CityService::make()->getFieldByName($province),
             'city_id' => CityService::make()->getFieldByName($city),

+ 143 - 0
app/Services/UdunpayService.php

@@ -0,0 +1,143 @@
+<?php
+// +----------------------------------------------------------------------
+// | LARAVEL8.0 框架 [ LARAVEL ][ RXThinkCMF ]
+// +----------------------------------------------------------------------
+// | 版权所有 2017~2021 LARAVEL研发中心
+// +----------------------------------------------------------------------
+// | 官方网站: http://www.laravel.cn
+// +----------------------------------------------------------------------
+// | Author: laravel开发员 <laravel.qq.com>
+// +----------------------------------------------------------------------
+
+namespace App\Services;
+
+use AlibabaCloud\Tea\Exception\TeaUnableRetryError;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Dysmsapi;
+use Darabonba\OpenApi\Models\Config;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\SendSmsRequest;
+use AlibabaCloud\Tea\Utils\Utils\RuntimeOptions;
+use Udun\Dispatch\UdunDispatch;
+
+/**
+ * udun钱包服务管理-服务类
+ * @author laravel开发员
+ * @since 2020/11/11
+ * Class UdunpayService
+ * @package App\Services
+ */
+class UdunpayService extends BaseService
+{
+    // 静态对象
+    protected static $instance = null;
+
+    protected $dispatch = null;
+
+    protected static $config = [];
+
+    public function __construct()
+    {
+        $config = ConfigService::make()->getConfigByGroup(10);
+        self::$config = [
+            'merchant_no' => isset($config['udun_merchant_no']['value'])? $config['udun_merchant_no']['value'] : '', //商户号
+            'api_key' => isset($config['udun_api_key']['value'])? $config['udun_api_key']['value'] : '', //apikey
+            'gateway_address' => isset($config['udun_gateway_address']['value'])? $config['udun_gateway_address']['value'] : '', //节点
+            'callUrl'=> url('/notify/wallet/udunpay','',true), //回调地址
+            'debug' => false  //调试模式
+        ];
+        $this->dispatch = new UdunDispatch(self::$config);
+    }
+
+    /**
+     * 静态入口
+     * @return UdunpayService|static|null
+     */
+    public static function make(){
+        if(!self::$instance){
+            self::$instance = new static();
+        }
+
+        return self::$instance;
+    }
+
+    /**
+     * 获取支持的币种
+     * @param bool $showBalance 是否返回余额
+     * @return mixed
+     */
+    public function supportCoins($showBalance=true)
+    {
+        return $this->dispatch->supportCoins($showBalance);
+    }
+
+
+    /**
+     * 创建钱包地址
+     * @param string $mainCoinType
+     * @return mixed
+     */
+    public function createAddress($mainCoinType='195')
+    {
+        $result = $this->dispatch->createAddress($mainCoinType);
+        $code = isset($result['code'])? intval($result['code']) : 0;
+        $address = isset($result['data']['address'])? trim($result['data']['address']) : '';
+        if($code == 200 && $address){
+            return $address;
+        }else{
+            RedisService::set("caches:udunpay:createAddress:error_".date('YmdHis'),['mainCoinType'=>$mainCoinType,'result'=> $result], 7200);
+            return '';
+        }
+
+    }
+
+    /**
+     * 验证钱包地址合法性
+     * @param $address 地址
+     * @param string $mainCoinType 主币
+     * @return mixed
+     */
+    public function checkAddress($address,$mainCoinType='195')
+    {
+        return $this->dispatch->checkAddress($mainCoinType,$address);
+    }
+
+    /**
+     * 查询地址是否存在
+     * @return mixed
+     */
+    public function existAddress($address,$mainCoinType='195')
+    {
+        return $this->dispatch->existAddress($mainCoinType,$address);
+    }
+
+    /**
+     * 提币
+     * @return mixed
+     */
+    public function withdraw($address, $amount, $orderNo, $mainCoinType='195', $coinType='', $remark='')
+    {
+        $coinType = $coinType? $coinType : 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t';
+        return $this->dispatch->withdraw($orderNo,$mainCoinType,$coinType,$address,$amount,$remark);
+    }
+
+    /**
+     * 回调
+     * @return mixed
+     */
+    public function callback()
+    {
+        $result = $this->dispatch->callback();
+        RedisService::set("caches:udunpay:notify",['params'=> request()->all(),'result'=> $result], 3600);
+        return $result;
+    }
+
+    /**
+     * 回调处理
+     * @param $params
+     */
+    public function catchNotify($params)
+    {
+        RedisService::set('caches:udunpay:notify',$params);
+    }
+
+
+}

+ 1 - 0
composer.json

@@ -27,6 +27,7 @@
         "maatwebsite/excel": "^3.1",
         "socialiteproviders/weixin": "^4.1",
         "socialiteproviders/weixin-web": "*",
+        "uduncloud/udun-wallet-sdk": "^1.0",
         "wechatpay/wechatpay-guzzle-middleware": "^0.2.2",
         "yansongda/pay": "~3.4.0"
     },

+ 268 - 1
composer.lock

@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "2747f7671be30f7e24d784373ee05292",
+    "content-hash": "fb6f6cfd048b059f09e6fabf89eaa3d4",
     "packages": [
         {
             "name": "adbario/php-dot-notation",
@@ -1379,6 +1379,111 @@
             "time": "2022-10-27T11:44:00+00:00"
         },
         {
+            "name": "doctrine/cache",
+            "version": "1.13.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/doctrine/cache.git",
+                "reference": "56cd022adb5514472cb144c087393c1821911d09"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/doctrine/cache/zipball/56cd022adb5514472cb144c087393c1821911d09",
+                "reference": "56cd022adb5514472cb144c087393c1821911d09",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": "~7.1 || ^8.0"
+            },
+            "conflict": {
+                "doctrine/common": ">2.2,<2.4"
+            },
+            "require-dev": {
+                "alcaeus/mongo-php-adapter": "^1.1",
+                "cache/integration-tests": "dev-master",
+                "doctrine/coding-standard": "^9",
+                "mongodb/mongodb": "^1.1",
+                "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
+                "predis/predis": "~1.0",
+                "psr/cache": "^1.0 || ^2.0 || ^3.0",
+                "symfony/cache": "^4.4 || ^5.4 || ^6",
+                "symfony/var-exporter": "^4.4 || ^5.4 || ^6"
+            },
+            "suggest": {
+                "alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Guilherme Blanco",
+                    "email": "guilhermeblanco@gmail.com"
+                },
+                {
+                    "name": "Roman Borschel",
+                    "email": "roman@code-factory.org"
+                },
+                {
+                    "name": "Benjamin Eberlei",
+                    "email": "kontakt@beberlei.de"
+                },
+                {
+                    "name": "Jonathan Wage",
+                    "email": "jonwage@gmail.com"
+                },
+                {
+                    "name": "Johannes Schmitt",
+                    "email": "schmittjoh@gmail.com"
+                }
+            ],
+            "description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.",
+            "homepage": "https://www.doctrine-project.org/projects/cache.html",
+            "keywords": [
+                "abstraction",
+                "apcu",
+                "cache",
+                "caching",
+                "couchdb",
+                "memcached",
+                "php",
+                "redis",
+                "xcache"
+            ],
+            "support": {
+                "issues": "https://github.com/doctrine/cache/issues",
+                "source": "https://github.com/doctrine/cache/tree/1.13.0"
+            },
+            "funding": [
+                {
+                    "url": "https://www.doctrine-project.org/sponsorship.html",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://www.patreon.com/phpdoctrine",
+                    "type": "patreon"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcache",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2022-05-20T20:06:54+00:00"
+        },
+        {
             "name": "doctrine/inflector",
             "version": "2.0.8",
             "source": {
@@ -2411,6 +2516,60 @@
             "time": "2023-12-03T20:05:35+00:00"
         },
         {
+            "name": "hanson/foundation-sdk",
+            "version": "5.0.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/Hanson/foundation-sdk.git",
+                "reference": "cffcef228937105b8c87c1376548b56f3e0564a4"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/Hanson/foundation-sdk/zipball/cffcef228937105b8c87c1376548b56f3e0564a4",
+                "reference": "cffcef228937105b8c87c1376548b56f3e0564a4",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "doctrine/cache": "^1.6",
+                "ext-curl": "*",
+                "guzzlehttp/guzzle": "^6.2|^7.0",
+                "monolog/monolog": "^1.22|^2.0|^3.0",
+                "php": "^7.0|^8.0",
+                "pimple/pimple": "^3.0",
+                "symfony/http-foundation": "^3.3|^4.0|^5.0|^6.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^9.3"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Hanson\\Foundation\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "HanSon",
+                    "email": "h@hanc.cc"
+                }
+            ],
+            "support": {
+                "issues": "https://github.com/Hanson/foundation-sdk/issues",
+                "source": "https://github.com/Hanson/foundation-sdk/tree/5.0.2"
+            },
+            "time": "2023-05-31T05:51:32+00:00"
+        },
+        {
             "name": "jaeger/g-http",
             "version": "V1.7.2",
             "source": {
@@ -4451,6 +4610,65 @@
             "time": "2023-11-12T21:59:55+00:00"
         },
         {
+            "name": "pimple/pimple",
+            "version": "v3.5.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/silexphp/Pimple.git",
+                "reference": "a94b3a4db7fb774b3d78dad2315ddc07629e1bed"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/silexphp/Pimple/zipball/a94b3a4db7fb774b3d78dad2315ddc07629e1bed",
+                "reference": "a94b3a4db7fb774b3d78dad2315ddc07629e1bed",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.2.5",
+                "psr/container": "^1.1 || ^2.0"
+            },
+            "require-dev": {
+                "symfony/phpunit-bridge": "^5.4@dev"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.4.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Pimple": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                }
+            ],
+            "description": "Pimple, a simple Dependency Injection Container",
+            "homepage": "https://pimple.symfony.com",
+            "keywords": [
+                "container",
+                "dependency injection"
+            ],
+            "support": {
+                "source": "https://github.com/silexphp/Pimple/tree/v3.5.0"
+            },
+            "time": "2021-10-28T11:13:42+00:00"
+        },
+        {
             "name": "psr/cache",
             "version": "2.0.0",
             "source": {
@@ -8262,6 +8480,55 @@
             "time": "2023-12-08T13:03:43+00:00"
         },
         {
+            "name": "uduncloud/udun-wallet-sdk",
+            "version": "1.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/uduncloud/udun-sdk-php.git",
+                "reference": "026af997276590542e29f281cfadf4e97c157087"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/uduncloud/udun-sdk-php/zipball/026af997276590542e29f281cfadf4e97c157087",
+                "reference": "026af997276590542e29f281cfadf4e97c157087",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "hanson/foundation-sdk": "^5.0",
+                "php": ">=7.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^9.5"
+            },
+            "type": "1",
+            "autoload": {
+                "psr-4": {
+                    "Udun\\Dispatch\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "udun wallet"
+                }
+            ],
+            "description": "udun-wallet-sdk",
+            "support": {
+                "issues": "https://github.com/uduncloud/udun-sdk-php/issues",
+                "source": "https://github.com/uduncloud/udun-sdk-php/tree/v1.0.0"
+            },
+            "time": "2022-07-29T09:37:18+00:00"
+        },
+        {
             "name": "vlucas/phpdotenv",
             "version": "v5.6.0",
             "source": {

+ 67 - 0
vendor/composer/autoload_classmap.php

@@ -664,6 +664,7 @@ return array(
     'App\\Services\\Api\\MessageService' => $baseDir . '/app/Services/Api/MessageService.php',
     'App\\Services\\BaseService' => $baseDir . '/app/Services/BaseService.php',
     'App\\Services\\CallService' => $baseDir . '/app/Services/CallService.php',
+    'App\\Services\\CityService' => $baseDir . '/app/Services/CityService.php',
     'App\\Services\\Common\\ActionLogService' => $baseDir . '/app/Services/Common/ActionLogService.php',
     'App\\Services\\Common\\AdService' => $baseDir . '/app/Services/Common/AdService.php',
     'App\\Services\\Common\\AdSortService' => $baseDir . '/app/Services/Common/AdSortService.php',
@@ -687,6 +688,7 @@ return array(
     'App\\Services\\RedisService' => $baseDir . '/app/Services/RedisService.php',
     'App\\Services\\SmsService' => $baseDir . '/app/Services/SmsService.php',
     'App\\Services\\ToolService' => $baseDir . '/app/Services/ToolService.php',
+    'App\\Services\\UdunpayService' => $baseDir . '/app/Services/UdunpayService.php',
     'Asm89\\Stack\\Cors' => $vendorDir . '/asm89/stack-cors/src/Cors.php',
     'Asm89\\Stack\\CorsService' => $vendorDir . '/asm89/stack-cors/src/CorsService.php',
     'Attribute' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
@@ -881,6 +883,42 @@ return array(
     'Dflydev\\DotAccessData\\Exception\\InvalidPathException' => $vendorDir . '/dflydev/dot-access-data/src/Exception/InvalidPathException.php',
     'Dflydev\\DotAccessData\\Exception\\MissingPathException' => $vendorDir . '/dflydev/dot-access-data/src/Exception/MissingPathException.php',
     'Dflydev\\DotAccessData\\Util' => $vendorDir . '/dflydev/dot-access-data/src/Util.php',
+    'Doctrine\\Common\\Cache\\ApcCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/ApcCache.php',
+    'Doctrine\\Common\\Cache\\ApcuCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/ApcuCache.php',
+    'Doctrine\\Common\\Cache\\ArrayCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/ArrayCache.php',
+    'Doctrine\\Common\\Cache\\Cache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/Cache.php',
+    'Doctrine\\Common\\Cache\\CacheProvider' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/CacheProvider.php',
+    'Doctrine\\Common\\Cache\\ChainCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/ChainCache.php',
+    'Doctrine\\Common\\Cache\\ClearableCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/ClearableCache.php',
+    'Doctrine\\Common\\Cache\\CouchbaseBucketCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseBucketCache.php',
+    'Doctrine\\Common\\Cache\\CouchbaseCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseCache.php',
+    'Doctrine\\Common\\Cache\\ExtMongoDBCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/ExtMongoDBCache.php',
+    'Doctrine\\Common\\Cache\\FileCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php',
+    'Doctrine\\Common\\Cache\\FilesystemCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/FilesystemCache.php',
+    'Doctrine\\Common\\Cache\\FlushableCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/FlushableCache.php',
+    'Doctrine\\Common\\Cache\\InvalidCacheId' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/InvalidCacheId.php',
+    'Doctrine\\Common\\Cache\\LegacyMongoDBCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/LegacyMongoDBCache.php',
+    'Doctrine\\Common\\Cache\\MemcacheCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/MemcacheCache.php',
+    'Doctrine\\Common\\Cache\\MemcachedCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/MemcachedCache.php',
+    'Doctrine\\Common\\Cache\\MongoDBCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/MongoDBCache.php',
+    'Doctrine\\Common\\Cache\\MultiDeleteCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/MultiDeleteCache.php',
+    'Doctrine\\Common\\Cache\\MultiGetCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/MultiGetCache.php',
+    'Doctrine\\Common\\Cache\\MultiOperationCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/MultiOperationCache.php',
+    'Doctrine\\Common\\Cache\\MultiPutCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/MultiPutCache.php',
+    'Doctrine\\Common\\Cache\\PhpFileCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/PhpFileCache.php',
+    'Doctrine\\Common\\Cache\\PredisCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/PredisCache.php',
+    'Doctrine\\Common\\Cache\\Psr6\\CacheAdapter' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/CacheAdapter.php',
+    'Doctrine\\Common\\Cache\\Psr6\\CacheItem' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/CacheItem.php',
+    'Doctrine\\Common\\Cache\\Psr6\\DoctrineProvider' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/DoctrineProvider.php',
+    'Doctrine\\Common\\Cache\\Psr6\\InvalidArgument' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/InvalidArgument.php',
+    'Doctrine\\Common\\Cache\\Psr6\\TypedCacheItem' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/TypedCacheItem.php',
+    'Doctrine\\Common\\Cache\\RedisCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/RedisCache.php',
+    'Doctrine\\Common\\Cache\\SQLite3Cache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/SQLite3Cache.php',
+    'Doctrine\\Common\\Cache\\Version' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/Version.php',
+    'Doctrine\\Common\\Cache\\VoidCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/VoidCache.php',
+    'Doctrine\\Common\\Cache\\WinCacheCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/WinCacheCache.php',
+    'Doctrine\\Common\\Cache\\XcacheCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/XcacheCache.php',
+    'Doctrine\\Common\\Cache\\ZendDataCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/ZendDataCache.php',
     'Doctrine\\Common\\Lexer\\AbstractLexer' => $vendorDir . '/doctrine/lexer/lib/Doctrine/Common/Lexer/AbstractLexer.php',
     'Doctrine\\Inflector\\CachedWordInflector' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/CachedWordInflector.php',
     'Doctrine\\Inflector\\GenericLanguageInflectorFactory' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/GenericLanguageInflectorFactory.php',
@@ -2115,6 +2153,12 @@ return array(
     'Hamcrest\\Type\\IsString' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Type/IsString.php',
     'Hamcrest\\Util' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Util.php',
     'Hamcrest\\Xml\\HasXPath' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Xml/HasXPath.php',
+    'Hanson\\Foundation\\AbstractAPI' => $vendorDir . '/hanson/foundation-sdk/src/AbstractAPI.php',
+    'Hanson\\Foundation\\AbstractAccessToken' => $vendorDir . '/hanson/foundation-sdk/src/AbstractAccessToken.php',
+    'Hanson\\Foundation\\Exception\\HttpException' => $vendorDir . '/hanson/foundation-sdk/src/Exception/HttpException.php',
+    'Hanson\\Foundation\\Foundation' => $vendorDir . '/hanson/foundation-sdk/src/Foundation.php',
+    'Hanson\\Foundation\\Http' => $vendorDir . '/hanson/foundation-sdk/src/Http.php',
+    'Hanson\\Foundation\\Log' => $vendorDir . '/hanson/foundation-sdk/src/Log.php',
     'ICallbackNamed' => $vendorDir . '/jaeger/phpquery-single/phpQuery.php',
     'Illuminate\\Auth\\Access\\AuthorizationException' => $vendorDir . '/laravel/framework/src/Illuminate/Auth/Access/AuthorizationException.php',
     'Illuminate\\Auth\\Access\\Events\\GateEvaluated' => $vendorDir . '/laravel/framework/src/Illuminate/Auth/Access/Events/GateEvaluated.php',
@@ -5272,6 +5316,24 @@ return array(
     'PhpParser\\PrettyPrinterAbstract' => $vendorDir . '/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php',
     'PhpParser\\PrettyPrinter\\Standard' => $vendorDir . '/nikic/php-parser/lib/PhpParser/PrettyPrinter/Standard.php',
     'PhpToken' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
+    'Pimple\\Container' => $vendorDir . '/pimple/pimple/src/Pimple/Container.php',
+    'Pimple\\Exception\\ExpectedInvokableException' => $vendorDir . '/pimple/pimple/src/Pimple/Exception/ExpectedInvokableException.php',
+    'Pimple\\Exception\\FrozenServiceException' => $vendorDir . '/pimple/pimple/src/Pimple/Exception/FrozenServiceException.php',
+    'Pimple\\Exception\\InvalidServiceIdentifierException' => $vendorDir . '/pimple/pimple/src/Pimple/Exception/InvalidServiceIdentifierException.php',
+    'Pimple\\Exception\\UnknownIdentifierException' => $vendorDir . '/pimple/pimple/src/Pimple/Exception/UnknownIdentifierException.php',
+    'Pimple\\Psr11\\Container' => $vendorDir . '/pimple/pimple/src/Pimple/Psr11/Container.php',
+    'Pimple\\Psr11\\ServiceLocator' => $vendorDir . '/pimple/pimple/src/Pimple/Psr11/ServiceLocator.php',
+    'Pimple\\ServiceIterator' => $vendorDir . '/pimple/pimple/src/Pimple/ServiceIterator.php',
+    'Pimple\\ServiceProviderInterface' => $vendorDir . '/pimple/pimple/src/Pimple/ServiceProviderInterface.php',
+    'Pimple\\Tests\\Fixtures\\Invokable' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/Fixtures/Invokable.php',
+    'Pimple\\Tests\\Fixtures\\NonInvokable' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/Fixtures/NonInvokable.php',
+    'Pimple\\Tests\\Fixtures\\PimpleServiceProvider' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/Fixtures/PimpleServiceProvider.php',
+    'Pimple\\Tests\\Fixtures\\Service' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/Fixtures/Service.php',
+    'Pimple\\Tests\\PimpleServiceProviderInterfaceTest' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/PimpleServiceProviderInterfaceTest.php',
+    'Pimple\\Tests\\PimpleTest' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/PimpleTest.php',
+    'Pimple\\Tests\\Psr11\\ContainerTest' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/Psr11/ContainerTest.php',
+    'Pimple\\Tests\\Psr11\\ServiceLocatorTest' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/Psr11/ServiceLocatorTest.php',
+    'Pimple\\Tests\\ServiceIteratorTest' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/ServiceIteratorTest.php',
     'Psr\\Cache\\CacheException' => $vendorDir . '/psr/cache/src/CacheException.php',
     'Psr\\Cache\\CacheItemInterface' => $vendorDir . '/psr/cache/src/CacheItemInterface.php',
     'Psr\\Cache\\CacheItemPoolInterface' => $vendorDir . '/psr/cache/src/CacheItemPoolInterface.php',
@@ -6843,6 +6905,11 @@ return array(
     'TijsVerkoyen\\CssToInlineStyles\\Css\\Property\\Property' => $vendorDir . '/tijsverkoyen/css-to-inline-styles/src/Css/Property/Property.php',
     'TijsVerkoyen\\CssToInlineStyles\\Css\\Rule\\Processor' => $vendorDir . '/tijsverkoyen/css-to-inline-styles/src/Css/Rule/Processor.php',
     'TijsVerkoyen\\CssToInlineStyles\\Css\\Rule\\Rule' => $vendorDir . '/tijsverkoyen/css-to-inline-styles/src/Css/Rule/Rule.php',
+    'Udun\\Dispatch\\Api' => $vendorDir . '/uduncloud/udun-wallet-sdk/src/Api.php',
+    'Udun\\Dispatch\\Clients' => $vendorDir . '/uduncloud/udun-wallet-sdk/src/Clients.php',
+    'Udun\\Dispatch\\ClientsServiceProvider' => $vendorDir . '/uduncloud/udun-wallet-sdk/src/ClientsServiceProvider.php',
+    'Udun\\Dispatch\\UdunDispatch' => $vendorDir . '/uduncloud/udun-wallet-sdk/src/UdunDispatch.php',
+    'Udun\\Dispatch\\UdunDispatchException' => $vendorDir . '/uduncloud/udun-wallet-sdk/src/UdunDispatchException.php',
     'UnhandledMatchError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
     'ValueError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
     'Webmozart\\Assert\\Assert' => $vendorDir . '/webmozart/assert/src/Assert.php',

+ 1 - 0
vendor/composer/autoload_namespaces.php

@@ -6,5 +6,6 @@ $vendorDir = dirname(__DIR__);
 $baseDir = dirname($vendorDir);
 
 return array(
+    'Pimple' => array($vendorDir . '/pimple/pimple/src'),
     'HTMLPurifier' => array($vendorDir . '/ezyang/htmlpurifier/library'),
 );

+ 3 - 0
vendor/composer/autoload_psr4.php

@@ -14,6 +14,7 @@ return array(
     'Whoops\\' => array($vendorDir . '/filp/whoops/src/Whoops'),
     'WechatPay\\GuzzleMiddleware\\' => array($vendorDir . '/wechatpay/wechatpay-guzzle-middleware/src'),
     'Webmozart\\Assert\\' => array($vendorDir . '/webmozart/assert/src'),
+    'Udun\\Dispatch\\' => array($vendorDir . '/uduncloud/udun-wallet-sdk/src'),
     'TijsVerkoyen\\CssToInlineStyles\\' => array($vendorDir . '/tijsverkoyen/css-to-inline-styles/src'),
     'Tightenco\\Collect\\' => array($vendorDir . '/tightenco/collect/src/Collect'),
     'Tests\\' => array($baseDir . '/tests'),
@@ -89,6 +90,7 @@ return array(
     'Jaeger\\' => array($vendorDir . '/jaeger/g-http/src'),
     'Illuminate\\Support\\' => array($vendorDir . '/laravel/framework/src/Illuminate/Macroable', $vendorDir . '/laravel/framework/src/Illuminate/Collections'),
     'Illuminate\\' => array($vendorDir . '/laravel/framework/src/Illuminate'),
+    'Hanson\\Foundation\\' => array($vendorDir . '/hanson/foundation-sdk/src'),
     'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'),
     'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'),
     'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'),
@@ -106,6 +108,7 @@ return array(
     'Doctrine\\Instantiator\\' => array($vendorDir . '/doctrine/instantiator/src/Doctrine/Instantiator'),
     'Doctrine\\Inflector\\' => array($vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector'),
     'Doctrine\\Common\\Lexer\\' => array($vendorDir . '/doctrine/lexer/lib/Doctrine/Common/Lexer'),
+    'Doctrine\\Common\\Cache\\' => array($vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache'),
     'Dflydev\\DotAccessData\\' => array($vendorDir . '/dflydev/dot-access-data/src'),
     'DeepCopy\\' => array($vendorDir . '/myclabs/deep-copy/src/DeepCopy'),
     'Database\\Seeders\\' => array($baseDir . '/database/seeders'),

+ 95 - 0
vendor/composer/autoload_static.php

@@ -76,6 +76,10 @@ class ComposerStaticInit235680d5acdc65329fb3070b347a2165
             'WechatPay\\GuzzleMiddleware\\' => 27,
             'Webmozart\\Assert\\' => 17,
         ),
+        'U' => 
+        array (
+            'Udun\\Dispatch\\' => 14,
+        ),
         'T' => 
         array (
             'TijsVerkoyen\\CssToInlineStyles\\' => 31,
@@ -184,6 +188,10 @@ class ComposerStaticInit235680d5acdc65329fb3070b347a2165
             'Illuminate\\Support\\' => 19,
             'Illuminate\\' => 11,
         ),
+        'H' => 
+        array (
+            'Hanson\\Foundation\\' => 18,
+        ),
         'G' => 
         array (
             'GuzzleHttp\\Psr7\\' => 16,
@@ -212,6 +220,7 @@ class ComposerStaticInit235680d5acdc65329fb3070b347a2165
             'Doctrine\\Instantiator\\' => 22,
             'Doctrine\\Inflector\\' => 19,
             'Doctrine\\Common\\Lexer\\' => 22,
+            'Doctrine\\Common\\Cache\\' => 22,
             'Dflydev\\DotAccessData\\' => 22,
             'DeepCopy\\' => 9,
             'Database\\Seeders\\' => 17,
@@ -286,6 +295,10 @@ class ComposerStaticInit235680d5acdc65329fb3070b347a2165
         array (
             0 => __DIR__ . '/..' . '/webmozart/assert/src',
         ),
+        'Udun\\Dispatch\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/uduncloud/udun-wallet-sdk/src',
+        ),
         'TijsVerkoyen\\CssToInlineStyles\\' => 
         array (
             0 => __DIR__ . '/..' . '/tijsverkoyen/css-to-inline-styles/src',
@@ -588,6 +601,10 @@ class ComposerStaticInit235680d5acdc65329fb3070b347a2165
         array (
             0 => __DIR__ . '/..' . '/laravel/framework/src/Illuminate',
         ),
+        'Hanson\\Foundation\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/hanson/foundation-sdk/src',
+        ),
         'GuzzleHttp\\Psr7\\' => 
         array (
             0 => __DIR__ . '/..' . '/guzzlehttp/psr7/src',
@@ -656,6 +673,10 @@ class ComposerStaticInit235680d5acdc65329fb3070b347a2165
         array (
             0 => __DIR__ . '/..' . '/doctrine/lexer/lib/Doctrine/Common/Lexer',
         ),
+        'Doctrine\\Common\\Cache\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache',
+        ),
         'Dflydev\\DotAccessData\\' => 
         array (
             0 => __DIR__ . '/..' . '/dflydev/dot-access-data/src',
@@ -775,6 +796,13 @@ class ComposerStaticInit235680d5acdc65329fb3070b347a2165
     );
 
     public static $prefixesPsr0 = array (
+        'P' => 
+        array (
+            'Pimple' => 
+            array (
+                0 => __DIR__ . '/..' . '/pimple/pimple/src',
+            ),
+        ),
         'H' => 
         array (
             'HTMLPurifier' => 
@@ -1443,6 +1471,7 @@ class ComposerStaticInit235680d5acdc65329fb3070b347a2165
         'App\\Services\\Api\\MessageService' => __DIR__ . '/../..' . '/app/Services/Api/MessageService.php',
         'App\\Services\\BaseService' => __DIR__ . '/../..' . '/app/Services/BaseService.php',
         'App\\Services\\CallService' => __DIR__ . '/../..' . '/app/Services/CallService.php',
+        'App\\Services\\CityService' => __DIR__ . '/../..' . '/app/Services/CityService.php',
         'App\\Services\\Common\\ActionLogService' => __DIR__ . '/../..' . '/app/Services/Common/ActionLogService.php',
         'App\\Services\\Common\\AdService' => __DIR__ . '/../..' . '/app/Services/Common/AdService.php',
         'App\\Services\\Common\\AdSortService' => __DIR__ . '/../..' . '/app/Services/Common/AdSortService.php',
@@ -1466,6 +1495,7 @@ class ComposerStaticInit235680d5acdc65329fb3070b347a2165
         'App\\Services\\RedisService' => __DIR__ . '/../..' . '/app/Services/RedisService.php',
         'App\\Services\\SmsService' => __DIR__ . '/../..' . '/app/Services/SmsService.php',
         'App\\Services\\ToolService' => __DIR__ . '/../..' . '/app/Services/ToolService.php',
+        'App\\Services\\UdunpayService' => __DIR__ . '/../..' . '/app/Services/UdunpayService.php',
         'Asm89\\Stack\\Cors' => __DIR__ . '/..' . '/asm89/stack-cors/src/Cors.php',
         'Asm89\\Stack\\CorsService' => __DIR__ . '/..' . '/asm89/stack-cors/src/CorsService.php',
         'Attribute' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
@@ -1660,6 +1690,42 @@ class ComposerStaticInit235680d5acdc65329fb3070b347a2165
         'Dflydev\\DotAccessData\\Exception\\InvalidPathException' => __DIR__ . '/..' . '/dflydev/dot-access-data/src/Exception/InvalidPathException.php',
         'Dflydev\\DotAccessData\\Exception\\MissingPathException' => __DIR__ . '/..' . '/dflydev/dot-access-data/src/Exception/MissingPathException.php',
         'Dflydev\\DotAccessData\\Util' => __DIR__ . '/..' . '/dflydev/dot-access-data/src/Util.php',
+        'Doctrine\\Common\\Cache\\ApcCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/ApcCache.php',
+        'Doctrine\\Common\\Cache\\ApcuCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/ApcuCache.php',
+        'Doctrine\\Common\\Cache\\ArrayCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/ArrayCache.php',
+        'Doctrine\\Common\\Cache\\Cache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/Cache.php',
+        'Doctrine\\Common\\Cache\\CacheProvider' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/CacheProvider.php',
+        'Doctrine\\Common\\Cache\\ChainCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/ChainCache.php',
+        'Doctrine\\Common\\Cache\\ClearableCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/ClearableCache.php',
+        'Doctrine\\Common\\Cache\\CouchbaseBucketCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseBucketCache.php',
+        'Doctrine\\Common\\Cache\\CouchbaseCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseCache.php',
+        'Doctrine\\Common\\Cache\\ExtMongoDBCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/ExtMongoDBCache.php',
+        'Doctrine\\Common\\Cache\\FileCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php',
+        'Doctrine\\Common\\Cache\\FilesystemCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/FilesystemCache.php',
+        'Doctrine\\Common\\Cache\\FlushableCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/FlushableCache.php',
+        'Doctrine\\Common\\Cache\\InvalidCacheId' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/InvalidCacheId.php',
+        'Doctrine\\Common\\Cache\\LegacyMongoDBCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/LegacyMongoDBCache.php',
+        'Doctrine\\Common\\Cache\\MemcacheCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/MemcacheCache.php',
+        'Doctrine\\Common\\Cache\\MemcachedCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/MemcachedCache.php',
+        'Doctrine\\Common\\Cache\\MongoDBCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/MongoDBCache.php',
+        'Doctrine\\Common\\Cache\\MultiDeleteCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/MultiDeleteCache.php',
+        'Doctrine\\Common\\Cache\\MultiGetCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/MultiGetCache.php',
+        'Doctrine\\Common\\Cache\\MultiOperationCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/MultiOperationCache.php',
+        'Doctrine\\Common\\Cache\\MultiPutCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/MultiPutCache.php',
+        'Doctrine\\Common\\Cache\\PhpFileCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/PhpFileCache.php',
+        'Doctrine\\Common\\Cache\\PredisCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/PredisCache.php',
+        'Doctrine\\Common\\Cache\\Psr6\\CacheAdapter' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/CacheAdapter.php',
+        'Doctrine\\Common\\Cache\\Psr6\\CacheItem' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/CacheItem.php',
+        'Doctrine\\Common\\Cache\\Psr6\\DoctrineProvider' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/DoctrineProvider.php',
+        'Doctrine\\Common\\Cache\\Psr6\\InvalidArgument' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/InvalidArgument.php',
+        'Doctrine\\Common\\Cache\\Psr6\\TypedCacheItem' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/TypedCacheItem.php',
+        'Doctrine\\Common\\Cache\\RedisCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/RedisCache.php',
+        'Doctrine\\Common\\Cache\\SQLite3Cache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/SQLite3Cache.php',
+        'Doctrine\\Common\\Cache\\Version' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/Version.php',
+        'Doctrine\\Common\\Cache\\VoidCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/VoidCache.php',
+        'Doctrine\\Common\\Cache\\WinCacheCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/WinCacheCache.php',
+        'Doctrine\\Common\\Cache\\XcacheCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/XcacheCache.php',
+        'Doctrine\\Common\\Cache\\ZendDataCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/ZendDataCache.php',
         'Doctrine\\Common\\Lexer\\AbstractLexer' => __DIR__ . '/..' . '/doctrine/lexer/lib/Doctrine/Common/Lexer/AbstractLexer.php',
         'Doctrine\\Inflector\\CachedWordInflector' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/CachedWordInflector.php',
         'Doctrine\\Inflector\\GenericLanguageInflectorFactory' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/GenericLanguageInflectorFactory.php',
@@ -2894,6 +2960,12 @@ class ComposerStaticInit235680d5acdc65329fb3070b347a2165
         'Hamcrest\\Type\\IsString' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Type/IsString.php',
         'Hamcrest\\Util' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Util.php',
         'Hamcrest\\Xml\\HasXPath' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Xml/HasXPath.php',
+        'Hanson\\Foundation\\AbstractAPI' => __DIR__ . '/..' . '/hanson/foundation-sdk/src/AbstractAPI.php',
+        'Hanson\\Foundation\\AbstractAccessToken' => __DIR__ . '/..' . '/hanson/foundation-sdk/src/AbstractAccessToken.php',
+        'Hanson\\Foundation\\Exception\\HttpException' => __DIR__ . '/..' . '/hanson/foundation-sdk/src/Exception/HttpException.php',
+        'Hanson\\Foundation\\Foundation' => __DIR__ . '/..' . '/hanson/foundation-sdk/src/Foundation.php',
+        'Hanson\\Foundation\\Http' => __DIR__ . '/..' . '/hanson/foundation-sdk/src/Http.php',
+        'Hanson\\Foundation\\Log' => __DIR__ . '/..' . '/hanson/foundation-sdk/src/Log.php',
         'ICallbackNamed' => __DIR__ . '/..' . '/jaeger/phpquery-single/phpQuery.php',
         'Illuminate\\Auth\\Access\\AuthorizationException' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Auth/Access/AuthorizationException.php',
         'Illuminate\\Auth\\Access\\Events\\GateEvaluated' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Auth/Access/Events/GateEvaluated.php',
@@ -6051,6 +6123,24 @@ class ComposerStaticInit235680d5acdc65329fb3070b347a2165
         'PhpParser\\PrettyPrinterAbstract' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php',
         'PhpParser\\PrettyPrinter\\Standard' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/PrettyPrinter/Standard.php',
         'PhpToken' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
+        'Pimple\\Container' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Container.php',
+        'Pimple\\Exception\\ExpectedInvokableException' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Exception/ExpectedInvokableException.php',
+        'Pimple\\Exception\\FrozenServiceException' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Exception/FrozenServiceException.php',
+        'Pimple\\Exception\\InvalidServiceIdentifierException' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Exception/InvalidServiceIdentifierException.php',
+        'Pimple\\Exception\\UnknownIdentifierException' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Exception/UnknownIdentifierException.php',
+        'Pimple\\Psr11\\Container' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Psr11/Container.php',
+        'Pimple\\Psr11\\ServiceLocator' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Psr11/ServiceLocator.php',
+        'Pimple\\ServiceIterator' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/ServiceIterator.php',
+        'Pimple\\ServiceProviderInterface' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/ServiceProviderInterface.php',
+        'Pimple\\Tests\\Fixtures\\Invokable' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Tests/Fixtures/Invokable.php',
+        'Pimple\\Tests\\Fixtures\\NonInvokable' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Tests/Fixtures/NonInvokable.php',
+        'Pimple\\Tests\\Fixtures\\PimpleServiceProvider' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Tests/Fixtures/PimpleServiceProvider.php',
+        'Pimple\\Tests\\Fixtures\\Service' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Tests/Fixtures/Service.php',
+        'Pimple\\Tests\\PimpleServiceProviderInterfaceTest' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Tests/PimpleServiceProviderInterfaceTest.php',
+        'Pimple\\Tests\\PimpleTest' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Tests/PimpleTest.php',
+        'Pimple\\Tests\\Psr11\\ContainerTest' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Tests/Psr11/ContainerTest.php',
+        'Pimple\\Tests\\Psr11\\ServiceLocatorTest' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Tests/Psr11/ServiceLocatorTest.php',
+        'Pimple\\Tests\\ServiceIteratorTest' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Tests/ServiceIteratorTest.php',
         'Psr\\Cache\\CacheException' => __DIR__ . '/..' . '/psr/cache/src/CacheException.php',
         'Psr\\Cache\\CacheItemInterface' => __DIR__ . '/..' . '/psr/cache/src/CacheItemInterface.php',
         'Psr\\Cache\\CacheItemPoolInterface' => __DIR__ . '/..' . '/psr/cache/src/CacheItemPoolInterface.php',
@@ -7622,6 +7712,11 @@ class ComposerStaticInit235680d5acdc65329fb3070b347a2165
         'TijsVerkoyen\\CssToInlineStyles\\Css\\Property\\Property' => __DIR__ . '/..' . '/tijsverkoyen/css-to-inline-styles/src/Css/Property/Property.php',
         'TijsVerkoyen\\CssToInlineStyles\\Css\\Rule\\Processor' => __DIR__ . '/..' . '/tijsverkoyen/css-to-inline-styles/src/Css/Rule/Processor.php',
         'TijsVerkoyen\\CssToInlineStyles\\Css\\Rule\\Rule' => __DIR__ . '/..' . '/tijsverkoyen/css-to-inline-styles/src/Css/Rule/Rule.php',
+        'Udun\\Dispatch\\Api' => __DIR__ . '/..' . '/uduncloud/udun-wallet-sdk/src/Api.php',
+        'Udun\\Dispatch\\Clients' => __DIR__ . '/..' . '/uduncloud/udun-wallet-sdk/src/Clients.php',
+        'Udun\\Dispatch\\ClientsServiceProvider' => __DIR__ . '/..' . '/uduncloud/udun-wallet-sdk/src/ClientsServiceProvider.php',
+        'Udun\\Dispatch\\UdunDispatch' => __DIR__ . '/..' . '/uduncloud/udun-wallet-sdk/src/UdunDispatch.php',
+        'Udun\\Dispatch\\UdunDispatchException' => __DIR__ . '/..' . '/uduncloud/udun-wallet-sdk/src/UdunDispatchException.php',
         'UnhandledMatchError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
         'ValueError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
         'Webmozart\\Assert\\Assert' => __DIR__ . '/..' . '/webmozart/assert/src/Assert.php',

+ 279 - 0
vendor/composer/installed.json

@@ -1439,6 +1439,114 @@
             "install-path": "../dflydev/dot-access-data"
         },
         {
+            "name": "doctrine/cache",
+            "version": "1.13.0",
+            "version_normalized": "1.13.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/doctrine/cache.git",
+                "reference": "56cd022adb5514472cb144c087393c1821911d09"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/doctrine/cache/zipball/56cd022adb5514472cb144c087393c1821911d09",
+                "reference": "56cd022adb5514472cb144c087393c1821911d09",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": "~7.1 || ^8.0"
+            },
+            "conflict": {
+                "doctrine/common": ">2.2,<2.4"
+            },
+            "require-dev": {
+                "alcaeus/mongo-php-adapter": "^1.1",
+                "cache/integration-tests": "dev-master",
+                "doctrine/coding-standard": "^9",
+                "mongodb/mongodb": "^1.1",
+                "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
+                "predis/predis": "~1.0",
+                "psr/cache": "^1.0 || ^2.0 || ^3.0",
+                "symfony/cache": "^4.4 || ^5.4 || ^6",
+                "symfony/var-exporter": "^4.4 || ^5.4 || ^6"
+            },
+            "suggest": {
+                "alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver"
+            },
+            "time": "2022-05-20T20:06:54+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Guilherme Blanco",
+                    "email": "guilhermeblanco@gmail.com"
+                },
+                {
+                    "name": "Roman Borschel",
+                    "email": "roman@code-factory.org"
+                },
+                {
+                    "name": "Benjamin Eberlei",
+                    "email": "kontakt@beberlei.de"
+                },
+                {
+                    "name": "Jonathan Wage",
+                    "email": "jonwage@gmail.com"
+                },
+                {
+                    "name": "Johannes Schmitt",
+                    "email": "schmittjoh@gmail.com"
+                }
+            ],
+            "description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.",
+            "homepage": "https://www.doctrine-project.org/projects/cache.html",
+            "keywords": [
+                "abstraction",
+                "apcu",
+                "cache",
+                "caching",
+                "couchdb",
+                "memcached",
+                "php",
+                "redis",
+                "xcache"
+            ],
+            "support": {
+                "issues": "https://github.com/doctrine/cache/issues",
+                "source": "https://github.com/doctrine/cache/tree/1.13.0"
+            },
+            "funding": [
+                {
+                    "url": "https://www.doctrine-project.org/sponsorship.html",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://www.patreon.com/phpdoctrine",
+                    "type": "patreon"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcache",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "../doctrine/cache"
+        },
+        {
             "name": "doctrine/inflector",
             "version": "2.0.8",
             "version_normalized": "2.0.8.0",
@@ -2990,6 +3098,63 @@
             "install-path": "../hamcrest/hamcrest-php"
         },
         {
+            "name": "hanson/foundation-sdk",
+            "version": "5.0.2",
+            "version_normalized": "5.0.2.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/Hanson/foundation-sdk.git",
+                "reference": "cffcef228937105b8c87c1376548b56f3e0564a4"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/Hanson/foundation-sdk/zipball/cffcef228937105b8c87c1376548b56f3e0564a4",
+                "reference": "cffcef228937105b8c87c1376548b56f3e0564a4",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "doctrine/cache": "^1.6",
+                "ext-curl": "*",
+                "guzzlehttp/guzzle": "^6.2|^7.0",
+                "monolog/monolog": "^1.22|^2.0|^3.0",
+                "php": "^7.0|^8.0",
+                "pimple/pimple": "^3.0",
+                "symfony/http-foundation": "^3.3|^4.0|^5.0|^6.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^9.3"
+            },
+            "time": "2023-05-31T05:51:32+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Hanson\\Foundation\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "HanSon",
+                    "email": "h@hanc.cc"
+                }
+            ],
+            "support": {
+                "issues": "https://github.com/Hanson/foundation-sdk/issues",
+                "source": "https://github.com/Hanson/foundation-sdk/tree/5.0.2"
+            },
+            "install-path": "../hanson/foundation-sdk"
+        },
+        {
             "name": "jaeger/g-http",
             "version": "V1.7.2",
             "version_normalized": "1.7.2.0",
@@ -5906,6 +6071,68 @@
             "install-path": "../phpunit/phpunit"
         },
         {
+            "name": "pimple/pimple",
+            "version": "v3.5.0",
+            "version_normalized": "3.5.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/silexphp/Pimple.git",
+                "reference": "a94b3a4db7fb774b3d78dad2315ddc07629e1bed"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/silexphp/Pimple/zipball/a94b3a4db7fb774b3d78dad2315ddc07629e1bed",
+                "reference": "a94b3a4db7fb774b3d78dad2315ddc07629e1bed",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.2.5",
+                "psr/container": "^1.1 || ^2.0"
+            },
+            "require-dev": {
+                "symfony/phpunit-bridge": "^5.4@dev"
+            },
+            "time": "2021-10-28T11:13:42+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.4.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-0": {
+                    "Pimple": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                }
+            ],
+            "description": "Pimple, a simple Dependency Injection Container",
+            "homepage": "https://pimple.symfony.com",
+            "keywords": [
+                "container",
+                "dependency injection"
+            ],
+            "support": {
+                "source": "https://github.com/silexphp/Pimple/tree/v3.5.0"
+            },
+            "install-path": "../pimple/pimple"
+        },
+        {
             "name": "psr/cache",
             "version": "2.0.0",
             "version_normalized": "2.0.0.0",
@@ -10941,6 +11168,58 @@
             "install-path": "../tijsverkoyen/css-to-inline-styles"
         },
         {
+            "name": "uduncloud/udun-wallet-sdk",
+            "version": "1.0.0",
+            "version_normalized": "1.0.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/uduncloud/udun-sdk-php.git",
+                "reference": "026af997276590542e29f281cfadf4e97c157087"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/uduncloud/udun-sdk-php/zipball/026af997276590542e29f281cfadf4e97c157087",
+                "reference": "026af997276590542e29f281cfadf4e97c157087",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "hanson/foundation-sdk": "^5.0",
+                "php": ">=7.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^9.5"
+            },
+            "time": "2022-07-29T09:37:18+00:00",
+            "type": "1",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Udun\\Dispatch\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "udun wallet"
+                }
+            ],
+            "description": "udun-wallet-sdk",
+            "support": {
+                "issues": "https://github.com/uduncloud/udun-sdk-php/issues",
+                "source": "https://github.com/uduncloud/udun-sdk-php/tree/v1.0.0"
+            },
+            "install-path": "../uduncloud/udun-wallet-sdk"
+        },
+        {
             "name": "vlucas/phpdotenv",
             "version": "v5.6.0",
             "version_normalized": "5.6.0.0",

+ 38 - 2
vendor/composer/installed.php

@@ -3,7 +3,7 @@
         'name' => 'laravel/laravel',
         'pretty_version' => 'dev-master',
         'version' => 'dev-master',
-        'reference' => 'b333ef08fed916a6ef0954572716620ca154d692',
+        'reference' => '48ae00d994dc5e50047f285ae30578d29001eb33',
         'type' => 'project',
         'install_path' => __DIR__ . '/../../',
         'aliases' => array(),
@@ -238,6 +238,15 @@
             'aliases' => array(),
             'dev_requirement' => false,
         ),
+        'doctrine/cache' => array(
+            'pretty_version' => '1.13.0',
+            'version' => '1.13.0.0',
+            'reference' => '56cd022adb5514472cb144c087393c1821911d09',
+            'type' => 'library',
+            'install_path' => __DIR__ . '/../doctrine/cache',
+            'aliases' => array(),
+            'dev_requirement' => false,
+        ),
         'doctrine/inflector' => array(
             'pretty_version' => '2.0.8',
             'version' => '2.0.8.0',
@@ -429,6 +438,15 @@
             'aliases' => array(),
             'dev_requirement' => true,
         ),
+        'hanson/foundation-sdk' => array(
+            'pretty_version' => '5.0.2',
+            'version' => '5.0.2.0',
+            'reference' => 'cffcef228937105b8c87c1376548b56f3e0564a4',
+            'type' => 'library',
+            'install_path' => __DIR__ . '/../hanson/foundation-sdk',
+            'aliases' => array(),
+            'dev_requirement' => false,
+        ),
         'illuminate/auth' => array(
             'dev_requirement' => false,
             'replaced' => array(
@@ -660,7 +678,7 @@
         'laravel/laravel' => array(
             'pretty_version' => 'dev-master',
             'version' => 'dev-master',
-            'reference' => 'b333ef08fed916a6ef0954572716620ca154d692',
+            'reference' => '48ae00d994dc5e50047f285ae30578d29001eb33',
             'type' => 'project',
             'install_path' => __DIR__ . '/../../',
             'aliases' => array(),
@@ -978,6 +996,15 @@
             'aliases' => array(),
             'dev_requirement' => true,
         ),
+        'pimple/pimple' => array(
+            'pretty_version' => 'v3.5.0',
+            'version' => '3.5.0.0',
+            'reference' => 'a94b3a4db7fb774b3d78dad2315ddc07629e1bed',
+            'type' => 'library',
+            'install_path' => __DIR__ . '/../pimple/pimple',
+            'aliases' => array(),
+            'dev_requirement' => false,
+        ),
         'psr/cache' => array(
             'pretty_version' => '2.0.0',
             'version' => '2.0.0.0',
@@ -1682,6 +1709,15 @@
             'aliases' => array(),
             'dev_requirement' => false,
         ),
+        'uduncloud/udun-wallet-sdk' => array(
+            'pretty_version' => '1.0.0',
+            'version' => '1.0.0.0',
+            'reference' => '026af997276590542e29f281cfadf4e97c157087',
+            'type' => '1',
+            'install_path' => __DIR__ . '/../uduncloud/udun-wallet-sdk',
+            'aliases' => array(),
+            'dev_requirement' => false,
+        ),
         'vlucas/phpdotenv' => array(
             'pretty_version' => 'v5.6.0',
             'version' => '5.6.0.0',

+ 19 - 0
vendor/doctrine/cache/LICENSE

@@ -0,0 +1,19 @@
+Copyright (c) 2006-2015 Doctrine Project
+
+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.

+ 13 - 0
vendor/doctrine/cache/README.md

@@ -0,0 +1,13 @@
+# Doctrine Cache
+
+[![Build Status](https://github.com/doctrine/cache/workflows/Continuous%20Integration/badge.svg)](https://github.com/doctrine/cache/actions)
+[![Code Coverage](https://codecov.io/gh/doctrine/cache/branch/1.10.x/graph/badge.svg)](https://codecov.io/gh/doctrine/cache/branch/1.10.x)
+
+[![Latest Stable Version](https://img.shields.io/packagist/v/doctrine/cache.svg?style=flat-square)](https://packagist.org/packages/doctrine/cache)
+[![Total Downloads](https://img.shields.io/packagist/dt/doctrine/cache.svg?style=flat-square)](https://packagist.org/packages/doctrine/cache)
+
+Cache component extracted from the Doctrine Common project. [Documentation](https://www.doctrine-project.org/projects/doctrine-cache/en/current/index.html)
+
+This library is deprecated and will no longer receive bug fixes from the
+Doctrine Project. Please use a different cache library, preferably PSR-6 or
+PSR-16 instead.

+ 15 - 0
vendor/doctrine/cache/UPGRADE-1.11.md

@@ -0,0 +1,15 @@
+# Upgrade to 1.11
+
+doctrine/cache will no longer be maintained and all cache implementations have
+been marked as deprecated. These implementations will be removed in 2.0, which
+will only contain interfaces to provide a lightweight package for backward
+compatibility.
+
+There are two new classes to use in the `Doctrine\Common\Cache\Psr6` namespace:
+* The `CacheAdapter` class allows using any Doctrine Cache as PSR-6 cache. This
+  is useful to provide a forward compatibility layer in libraries that accept
+  Doctrine cache implementations and switch to PSR-6.
+* The `DoctrineProvider` class allows using any PSR-6 cache as Doctrine cache.
+  This implementation is designed for libraries that leak the cache and want to
+  switch to allowing PSR-6 implementations. This class is design to be used
+  during the transition phase of sunsetting doctrine/cache support.

+ 16 - 0
vendor/doctrine/cache/UPGRADE-1.4.md

@@ -0,0 +1,16 @@
+# Upgrade to 1.4
+
+## Minor BC Break: `Doctrine\Common\Cache\FileCache#$extension` is now `private`.
+
+If you need to override the value of `Doctrine\Common\Cache\FileCache#$extension`, then use the
+second parameter of `Doctrine\Common\Cache\FileCache#__construct()` instead of overriding
+the property in your own implementation.
+
+## Minor BC Break: file based caches paths changed
+
+`Doctrine\Common\Cache\FileCache`, `Doctrine\Common\Cache\PhpFileCache` and
+`Doctrine\Common\Cache\FilesystemCache` are using a different cache paths structure.
+
+If you rely on warmed up caches for deployments, consider that caches generated
+with `doctrine/cache` `<1.4` are not compatible with the new directory structure,
+and will be ignored.

+ 56 - 0
vendor/doctrine/cache/composer.json

@@ -0,0 +1,56 @@
+{
+    "name": "doctrine/cache",
+    "type": "library",
+    "description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.",
+    "keywords": [
+        "php",
+        "cache",
+        "caching",
+        "abstraction",
+        "redis",
+        "memcached",
+        "couchdb",
+        "xcache",
+        "apcu"
+    ],
+    "homepage": "https://www.doctrine-project.org/projects/cache.html",
+    "license": "MIT",
+    "authors": [
+        {"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"},
+        {"name": "Roman Borschel", "email": "roman@code-factory.org"},
+        {"name": "Benjamin Eberlei", "email": "kontakt@beberlei.de"},
+        {"name": "Jonathan Wage", "email": "jonwage@gmail.com"},
+        {"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"}
+    ],
+    "require": {
+        "php": "~7.1 || ^8.0"
+    },
+    "require-dev": {
+        "alcaeus/mongo-php-adapter": "^1.1",
+        "mongodb/mongodb": "^1.1",
+        "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
+        "predis/predis":   "~1.0",
+        "doctrine/coding-standard": "^9",
+        "psr/cache": "^1.0 || ^2.0 || ^3.0",
+        "cache/integration-tests": "dev-master",
+        "symfony/cache": "^4.4 || ^5.4 || ^6",
+        "symfony/var-exporter": "^4.4 || ^5.4 || ^6"
+    },
+    "suggest": {
+        "alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver"
+    },
+    "conflict": {
+        "doctrine/common": ">2.2,<2.4"
+    },
+    "autoload": {
+        "psr-4": { "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" }
+    },
+    "autoload-dev": {
+        "psr-4": { "Doctrine\\Tests\\": "tests/Doctrine/Tests" }
+    },
+    "config": {
+        "allow-plugins": {
+            "dealerdirect/phpcodesniffer-composer-installer": true
+        }
+    }
+}

+ 106 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/ApcCache.php

@@ -0,0 +1,106 @@
+<?php
+
+namespace Doctrine\Common\Cache;
+
+use function apc_cache_info;
+use function apc_clear_cache;
+use function apc_delete;
+use function apc_exists;
+use function apc_fetch;
+use function apc_sma_info;
+use function apc_store;
+
+use const PHP_VERSION_ID;
+
+/**
+ * APC cache provider.
+ *
+ * @deprecated since version 1.6, use ApcuCache instead
+ *
+ * @link       www.doctrine-project.org
+ */
+class ApcCache extends CacheProvider
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        return apc_fetch($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        return apc_exists($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        return apc_store($id, $data, $lifeTime);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDelete($id)
+    {
+        // apc_delete returns false if the id does not exist
+        return apc_delete($id) || ! apc_exists($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFlush()
+    {
+        return apc_clear_cache() && apc_clear_cache('user');
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetchMultiple(array $keys)
+    {
+        return apc_fetch($keys) ?: [];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
+    {
+        $result = apc_store($keysAndValues, null, $lifetime);
+
+        return empty($result);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doGetStats()
+    {
+        $info = apc_cache_info('', true);
+        $sma  = apc_sma_info();
+
+        // @TODO - Temporary fix @see https://github.com/krakjoe/apcu/pull/42
+        if (PHP_VERSION_ID >= 50500) {
+            $info['num_hits']   = $info['num_hits'] ?? $info['nhits'];
+            $info['num_misses'] = $info['num_misses'] ?? $info['nmisses'];
+            $info['start_time'] = $info['start_time'] ?? $info['stime'];
+        }
+
+        return [
+            Cache::STATS_HITS             => $info['num_hits'],
+            Cache::STATS_MISSES           => $info['num_misses'],
+            Cache::STATS_UPTIME           => $info['start_time'],
+            Cache::STATS_MEMORY_USAGE     => $info['mem_size'],
+            Cache::STATS_MEMORY_AVAILABLE => $sma['avail_mem'],
+        ];
+    }
+}

+ 108 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/ApcuCache.php

@@ -0,0 +1,108 @@
+<?php
+
+namespace Doctrine\Common\Cache;
+
+use function apcu_cache_info;
+use function apcu_clear_cache;
+use function apcu_delete;
+use function apcu_exists;
+use function apcu_fetch;
+use function apcu_sma_info;
+use function apcu_store;
+use function count;
+
+/**
+ * APCu cache provider.
+ *
+ * @deprecated Deprecated without replacement in doctrine/cache 1.11. This class will be dropped in 2.0
+ *
+ * @link   www.doctrine-project.org
+ */
+class ApcuCache extends CacheProvider
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        return apcu_fetch($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        return apcu_exists($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        return apcu_store($id, $data, $lifeTime);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDelete($id)
+    {
+        // apcu_delete returns false if the id does not exist
+        return apcu_delete($id) || ! apcu_exists($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDeleteMultiple(array $keys)
+    {
+        $result = apcu_delete($keys);
+
+        return $result !== false && count($result) !== count($keys);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFlush()
+    {
+        return apcu_clear_cache();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetchMultiple(array $keys)
+    {
+        return apcu_fetch($keys) ?: [];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
+    {
+        $result = apcu_store($keysAndValues, null, $lifetime);
+
+        return empty($result);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doGetStats()
+    {
+        $info = apcu_cache_info(true);
+        $sma  = apcu_sma_info();
+
+        return [
+            Cache::STATS_HITS             => $info['num_hits'],
+            Cache::STATS_MISSES           => $info['num_misses'],
+            Cache::STATS_UPTIME           => $info['start_time'],
+            Cache::STATS_MEMORY_USAGE     => $info['mem_size'],
+            Cache::STATS_MEMORY_AVAILABLE => $sma['avail_mem'],
+        ];
+    }
+}

+ 115 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/ArrayCache.php

@@ -0,0 +1,115 @@
+<?php
+
+namespace Doctrine\Common\Cache;
+
+use function time;
+
+/**
+ * Array cache driver.
+ *
+ * @deprecated Deprecated without replacement in doctrine/cache 1.11. This class will be dropped in 2.0
+ *
+ * @link   www.doctrine-project.org
+ */
+class ArrayCache extends CacheProvider
+{
+    /** @psalm-var array<string, array{mixed, int|bool}>> $data each element being a tuple of [$data, $expiration], where the expiration is int|bool */
+    private $data = [];
+
+    /** @var int */
+    private $hitsCount = 0;
+
+    /** @var int */
+    private $missesCount = 0;
+
+    /** @var int */
+    private $upTime;
+
+    /**
+     * {@inheritdoc}
+     */
+    public function __construct()
+    {
+        $this->upTime = time();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        if (! $this->doContains($id)) {
+            $this->missesCount += 1;
+
+            return false;
+        }
+
+        $this->hitsCount += 1;
+
+        return $this->data[$id][0];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        if (! isset($this->data[$id])) {
+            return false;
+        }
+
+        $expiration = $this->data[$id][1];
+
+        if ($expiration && $expiration < time()) {
+            $this->doDelete($id);
+
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        $this->data[$id] = [$data, $lifeTime ? time() + $lifeTime : false];
+
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDelete($id)
+    {
+        unset($this->data[$id]);
+
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFlush()
+    {
+        $this->data = [];
+
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doGetStats()
+    {
+        return [
+            Cache::STATS_HITS             => $this->hitsCount,
+            Cache::STATS_MISSES           => $this->missesCount,
+            Cache::STATS_UPTIME           => $this->upTime,
+            Cache::STATS_MEMORY_USAGE     => null,
+            Cache::STATS_MEMORY_AVAILABLE => null,
+        ];
+    }
+}

+ 90 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/Cache.php

@@ -0,0 +1,90 @@
+<?php
+
+namespace Doctrine\Common\Cache;
+
+/**
+ * Interface for cache drivers.
+ *
+ * @link   www.doctrine-project.org
+ */
+interface Cache
+{
+    public const STATS_HITS             = 'hits';
+    public const STATS_MISSES           = 'misses';
+    public const STATS_UPTIME           = 'uptime';
+    public const STATS_MEMORY_USAGE     = 'memory_usage';
+    public const STATS_MEMORY_AVAILABLE = 'memory_available';
+    /**
+     * Only for backward compatibility (may be removed in next major release)
+     *
+     * @deprecated
+     */
+    public const STATS_MEMORY_AVAILIABLE = 'memory_available';
+
+    /**
+     * Fetches an entry from the cache.
+     *
+     * @param string $id The id of the cache entry to fetch.
+     *
+     * @return mixed The cached data or FALSE, if no cache entry exists for the given id.
+     */
+    public function fetch($id);
+
+    /**
+     * Tests if an entry exists in the cache.
+     *
+     * @param string $id The cache id of the entry to check for.
+     *
+     * @return bool TRUE if a cache entry exists for the given cache id, FALSE otherwise.
+     */
+    public function contains($id);
+
+    /**
+     * Puts data into the cache.
+     *
+     * If a cache entry with the given id already exists, its data will be replaced.
+     *
+     * @param string $id       The cache id.
+     * @param mixed  $data     The cache entry/data.
+     * @param int    $lifeTime The lifetime in number of seconds for this cache entry.
+     *                         If zero (the default), the entry never expires (although it may be deleted from the cache
+     *                         to make place for other entries).
+     *
+     * @return bool TRUE if the entry was successfully stored in the cache, FALSE otherwise.
+     */
+    public function save($id, $data, $lifeTime = 0);
+
+    /**
+     * Deletes a cache entry.
+     *
+     * @param string $id The cache id.
+     *
+     * @return bool TRUE if the cache entry was successfully deleted, FALSE otherwise.
+     *              Deleting a non-existing entry is considered successful.
+     */
+    public function delete($id);
+
+    /**
+     * Retrieves cached information from the data store.
+     *
+     * The server's statistics array has the following values:
+     *
+     * - <b>hits</b>
+     * Number of keys that have been requested and found present.
+     *
+     * - <b>misses</b>
+     * Number of items that have been requested and not found.
+     *
+     * - <b>uptime</b>
+     * Time that the server is running.
+     *
+     * - <b>memory_usage</b>
+     * Memory used by this server to store items.
+     *
+     * - <b>memory_available</b>
+     * Memory allowed to use for storage.
+     *
+     * @return mixed[]|null An associative array with server's statistics if available, NULL otherwise.
+     */
+    public function getStats();
+}

+ 325 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/CacheProvider.php

@@ -0,0 +1,325 @@
+<?php
+
+namespace Doctrine\Common\Cache;
+
+use function array_combine;
+use function array_key_exists;
+use function array_map;
+use function sprintf;
+
+/**
+ * Base class for cache provider implementations.
+ */
+abstract class CacheProvider implements Cache, FlushableCache, ClearableCache, MultiOperationCache
+{
+    public const DOCTRINE_NAMESPACE_CACHEKEY = 'DoctrineNamespaceCacheKey[%s]';
+
+    /**
+     * The namespace to prefix all cache ids with.
+     *
+     * @var string
+     */
+    private $namespace = '';
+
+    /**
+     * The namespace version.
+     *
+     * @var int|null
+     */
+    private $namespaceVersion;
+
+    /**
+     * Sets the namespace to prefix all cache ids with.
+     *
+     * @param string $namespace
+     *
+     * @return void
+     */
+    public function setNamespace($namespace)
+    {
+        $this->namespace        = (string) $namespace;
+        $this->namespaceVersion = null;
+    }
+
+    /**
+     * Retrieves the namespace that prefixes all cache ids.
+     *
+     * @return string
+     */
+    public function getNamespace()
+    {
+        return $this->namespace;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function fetch($id)
+    {
+        return $this->doFetch($this->getNamespacedId($id));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function fetchMultiple(array $keys)
+    {
+        if (empty($keys)) {
+            return [];
+        }
+
+        // note: the array_combine() is in place to keep an association between our $keys and the $namespacedKeys
+        $namespacedKeys = array_combine($keys, array_map([$this, 'getNamespacedId'], $keys));
+        $items          = $this->doFetchMultiple($namespacedKeys);
+        $foundItems     = [];
+
+        // no internal array function supports this sort of mapping: needs to be iterative
+        // this filters and combines keys in one pass
+        foreach ($namespacedKeys as $requestedKey => $namespacedKey) {
+            if (! isset($items[$namespacedKey]) && ! array_key_exists($namespacedKey, $items)) {
+                continue;
+            }
+
+            $foundItems[$requestedKey] = $items[$namespacedKey];
+        }
+
+        return $foundItems;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function saveMultiple(array $keysAndValues, $lifetime = 0)
+    {
+        $namespacedKeysAndValues = [];
+        foreach ($keysAndValues as $key => $value) {
+            $namespacedKeysAndValues[$this->getNamespacedId($key)] = $value;
+        }
+
+        return $this->doSaveMultiple($namespacedKeysAndValues, $lifetime);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function contains($id)
+    {
+        return $this->doContains($this->getNamespacedId($id));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function save($id, $data, $lifeTime = 0)
+    {
+        return $this->doSave($this->getNamespacedId($id), $data, $lifeTime);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function deleteMultiple(array $keys)
+    {
+        return $this->doDeleteMultiple(array_map([$this, 'getNamespacedId'], $keys));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function delete($id)
+    {
+        return $this->doDelete($this->getNamespacedId($id));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getStats()
+    {
+        return $this->doGetStats();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function flushAll()
+    {
+        return $this->doFlush();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function deleteAll()
+    {
+        $namespaceCacheKey = $this->getNamespaceCacheKey();
+        $namespaceVersion  = $this->getNamespaceVersion() + 1;
+
+        if ($this->doSave($namespaceCacheKey, $namespaceVersion)) {
+            $this->namespaceVersion = $namespaceVersion;
+
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Prefixes the passed id with the configured namespace value.
+     *
+     * @param string $id The id to namespace.
+     *
+     * @return string The namespaced id.
+     */
+    private function getNamespacedId(string $id): string
+    {
+        $namespaceVersion = $this->getNamespaceVersion();
+
+        return sprintf('%s[%s][%s]', $this->namespace, $id, $namespaceVersion);
+    }
+
+    /**
+     * Returns the namespace cache key.
+     */
+    private function getNamespaceCacheKey(): string
+    {
+        return sprintf(self::DOCTRINE_NAMESPACE_CACHEKEY, $this->namespace);
+    }
+
+    /**
+     * Returns the namespace version.
+     */
+    private function getNamespaceVersion(): int
+    {
+        if ($this->namespaceVersion !== null) {
+            return $this->namespaceVersion;
+        }
+
+        $namespaceCacheKey      = $this->getNamespaceCacheKey();
+        $this->namespaceVersion = (int) $this->doFetch($namespaceCacheKey) ?: 1;
+
+        return $this->namespaceVersion;
+    }
+
+    /**
+     * Default implementation of doFetchMultiple. Each driver that supports multi-get should owerwrite it.
+     *
+     * @param string[] $keys Array of keys to retrieve from cache
+     *
+     * @return mixed[] Array of values retrieved for the given keys.
+     */
+    protected function doFetchMultiple(array $keys)
+    {
+        $returnValues = [];
+
+        foreach ($keys as $key) {
+            $item = $this->doFetch($key);
+            if ($item === false && ! $this->doContains($key)) {
+                continue;
+            }
+
+            $returnValues[$key] = $item;
+        }
+
+        return $returnValues;
+    }
+
+    /**
+     * Fetches an entry from the cache.
+     *
+     * @param string $id The id of the cache entry to fetch.
+     *
+     * @return mixed|false The cached data or FALSE, if no cache entry exists for the given id.
+     */
+    abstract protected function doFetch($id);
+
+    /**
+     * Tests if an entry exists in the cache.
+     *
+     * @param string $id The cache id of the entry to check for.
+     *
+     * @return bool TRUE if a cache entry exists for the given cache id, FALSE otherwise.
+     */
+    abstract protected function doContains($id);
+
+    /**
+     * Default implementation of doSaveMultiple. Each driver that supports multi-put should override it.
+     *
+     * @param mixed[] $keysAndValues Array of keys and values to save in cache
+     * @param int     $lifetime      The lifetime. If != 0, sets a specific lifetime for these
+     *                               cache entries (0 => infinite lifeTime).
+     *
+     * @return bool TRUE if the operation was successful, FALSE if it wasn't.
+     */
+    protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
+    {
+        $success = true;
+
+        foreach ($keysAndValues as $key => $value) {
+            if ($this->doSave($key, $value, $lifetime)) {
+                continue;
+            }
+
+            $success = false;
+        }
+
+        return $success;
+    }
+
+    /**
+     * Puts data into the cache.
+     *
+     * @param string $id       The cache id.
+     * @param string $data     The cache entry/data.
+     * @param int    $lifeTime The lifetime. If != 0, sets a specific lifetime for this
+     *                           cache entry (0 => infinite lifeTime).
+     *
+     * @return bool TRUE if the entry was successfully stored in the cache, FALSE otherwise.
+     */
+    abstract protected function doSave($id, $data, $lifeTime = 0);
+
+    /**
+     * Default implementation of doDeleteMultiple. Each driver that supports multi-delete should override it.
+     *
+     * @param string[] $keys Array of keys to delete from cache
+     *
+     * @return bool TRUE if the operation was successful, FALSE if it wasn't
+     */
+    protected function doDeleteMultiple(array $keys)
+    {
+        $success = true;
+
+        foreach ($keys as $key) {
+            if ($this->doDelete($key)) {
+                continue;
+            }
+
+            $success = false;
+        }
+
+        return $success;
+    }
+
+    /**
+     * Deletes a cache entry.
+     *
+     * @param string $id The cache id.
+     *
+     * @return bool TRUE if the cache entry was successfully deleted, FALSE otherwise.
+     */
+    abstract protected function doDelete($id);
+
+    /**
+     * Flushes all cache entries.
+     *
+     * @return bool TRUE if the cache entries were successfully flushed, FALSE otherwise.
+     */
+    abstract protected function doFlush();
+
+    /**
+     * Retrieves cached information from the data store.
+     *
+     * @return mixed[]|null An associative array with server's statistics if available, NULL otherwise.
+     */
+    abstract protected function doGetStats();
+}

+ 198 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/ChainCache.php

@@ -0,0 +1,198 @@
+<?php
+
+namespace Doctrine\Common\Cache;
+
+use Traversable;
+
+use function array_values;
+use function count;
+use function iterator_to_array;
+
+/**
+ * Cache provider that allows to easily chain multiple cache providers
+ *
+ * @deprecated Deprecated without replacement in doctrine/cache 1.11. This class will be dropped in 2.0
+ */
+class ChainCache extends CacheProvider
+{
+    /** @var CacheProvider[] */
+    private $cacheProviders = [];
+
+    /** @var int */
+    private $defaultLifeTimeForDownstreamCacheProviders = 0;
+
+    /**
+     * @param CacheProvider[] $cacheProviders
+     */
+    public function __construct($cacheProviders = [])
+    {
+        $this->cacheProviders = $cacheProviders instanceof Traversable
+            ? iterator_to_array($cacheProviders, false)
+            : array_values($cacheProviders);
+    }
+
+    public function setDefaultLifeTimeForDownstreamCacheProviders(int $defaultLifeTimeForDownstreamCacheProviders): void
+    {
+        $this->defaultLifeTimeForDownstreamCacheProviders = $defaultLifeTimeForDownstreamCacheProviders;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function setNamespace($namespace)
+    {
+        parent::setNamespace($namespace);
+
+        foreach ($this->cacheProviders as $cacheProvider) {
+            $cacheProvider->setNamespace($namespace);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function doFetch($id)
+    {
+        foreach ($this->cacheProviders as $key => $cacheProvider) {
+            if ($cacheProvider->doContains($id)) {
+                $value = $cacheProvider->doFetch($id);
+
+                // We populate all the previous cache layers (that are assumed to be faster)
+                for ($subKey = $key - 1; $subKey >= 0; $subKey--) {
+                    $this->cacheProviders[$subKey]->doSave($id, $value, $this->defaultLifeTimeForDownstreamCacheProviders);
+                }
+
+                return $value;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetchMultiple(array $keys)
+    {
+        /** @var CacheProvider[] $traversedProviders */
+        $traversedProviders = [];
+        $keysCount          = count($keys);
+        $fetchedValues      = [];
+
+        foreach ($this->cacheProviders as $key => $cacheProvider) {
+            $fetchedValues = $cacheProvider->doFetchMultiple($keys);
+
+            // We populate all the previous cache layers (that are assumed to be faster)
+            if (count($fetchedValues) === $keysCount) {
+                foreach ($traversedProviders as $previousCacheProvider) {
+                    $previousCacheProvider->doSaveMultiple($fetchedValues, $this->defaultLifeTimeForDownstreamCacheProviders);
+                }
+
+                return $fetchedValues;
+            }
+
+            $traversedProviders[] = $cacheProvider;
+        }
+
+        return $fetchedValues;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function doContains($id)
+    {
+        foreach ($this->cacheProviders as $cacheProvider) {
+            if ($cacheProvider->doContains($id)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        $stored = true;
+
+        foreach ($this->cacheProviders as $cacheProvider) {
+            $stored = $cacheProvider->doSave($id, $data, $lifeTime) && $stored;
+        }
+
+        return $stored;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
+    {
+        $stored = true;
+
+        foreach ($this->cacheProviders as $cacheProvider) {
+            $stored = $cacheProvider->doSaveMultiple($keysAndValues, $lifetime) && $stored;
+        }
+
+        return $stored;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function doDelete($id)
+    {
+        $deleted = true;
+
+        foreach ($this->cacheProviders as $cacheProvider) {
+            $deleted = $cacheProvider->doDelete($id) && $deleted;
+        }
+
+        return $deleted;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDeleteMultiple(array $keys)
+    {
+        $deleted = true;
+
+        foreach ($this->cacheProviders as $cacheProvider) {
+            $deleted = $cacheProvider->doDeleteMultiple($keys) && $deleted;
+        }
+
+        return $deleted;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function doFlush()
+    {
+        $flushed = true;
+
+        foreach ($this->cacheProviders as $cacheProvider) {
+            $flushed = $cacheProvider->doFlush() && $flushed;
+        }
+
+        return $flushed;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function doGetStats()
+    {
+        // We return all the stats from all adapters
+        $stats = [];
+
+        foreach ($this->cacheProviders as $cacheProvider) {
+            $stats[] = $cacheProvider->doGetStats();
+        }
+
+        return $stats;
+    }
+}

+ 21 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/ClearableCache.php

@@ -0,0 +1,21 @@
+<?php
+
+namespace Doctrine\Common\Cache;
+
+/**
+ * Interface for cache that can be flushed.
+ *
+ * Intended to be used for partial clearing of a cache namespace. For a more
+ * global "flushing", see {@see FlushableCache}.
+ *
+ * @link   www.doctrine-project.org
+ */
+interface ClearableCache
+{
+    /**
+     * Deletes all cache entries in the current cache namespace.
+     *
+     * @return bool TRUE if the cache entries were successfully deleted, FALSE otherwise.
+     */
+    public function deleteAll();
+}

+ 200 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseBucketCache.php

@@ -0,0 +1,200 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Doctrine\Common\Cache;
+
+use Couchbase\Bucket;
+use Couchbase\Document;
+use Couchbase\Exception;
+use RuntimeException;
+
+use function phpversion;
+use function serialize;
+use function sprintf;
+use function substr;
+use function time;
+use function unserialize;
+use function version_compare;
+
+/**
+ * Couchbase ^2.3.0 cache provider.
+ *
+ * @deprecated Deprecated without replacement in doctrine/cache 1.11. This class will be dropped in 2.0
+ */
+final class CouchbaseBucketCache extends CacheProvider
+{
+    private const MINIMUM_VERSION = '2.3.0';
+
+    private const KEY_NOT_FOUND = 13;
+
+    private const MAX_KEY_LENGTH = 250;
+
+    private const THIRTY_DAYS_IN_SECONDS = 2592000;
+
+    /** @var Bucket */
+    private $bucket;
+
+    public function __construct(Bucket $bucket)
+    {
+        if (version_compare(phpversion('couchbase'), self::MINIMUM_VERSION) < 0) {
+            // Manager is required to flush cache and pull stats.
+            throw new RuntimeException(sprintf('ext-couchbase:^%s is required.', self::MINIMUM_VERSION));
+        }
+
+        $this->bucket = $bucket;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        $id = $this->normalizeKey($id);
+
+        try {
+            $document = $this->bucket->get($id);
+        } catch (Exception $e) {
+            return false;
+        }
+
+        if ($document instanceof Document && $document->value !== false) {
+            return unserialize($document->value);
+        }
+
+        return false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        $id = $this->normalizeKey($id);
+
+        try {
+            $document = $this->bucket->get($id);
+        } catch (Exception $e) {
+            return false;
+        }
+
+        if ($document instanceof Document) {
+            return ! $document->error;
+        }
+
+        return false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        $id = $this->normalizeKey($id);
+
+        $lifeTime = $this->normalizeExpiry($lifeTime);
+
+        try {
+            $encoded = serialize($data);
+
+            $document = $this->bucket->upsert($id, $encoded, [
+                'expiry' => (int) $lifeTime,
+            ]);
+        } catch (Exception $e) {
+            return false;
+        }
+
+        if ($document instanceof Document) {
+            return ! $document->error;
+        }
+
+        return false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDelete($id)
+    {
+        $id = $this->normalizeKey($id);
+
+        try {
+            $document = $this->bucket->remove($id);
+        } catch (Exception $e) {
+            return $e->getCode() === self::KEY_NOT_FOUND;
+        }
+
+        if ($document instanceof Document) {
+            return ! $document->error;
+        }
+
+        return false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFlush()
+    {
+        $manager = $this->bucket->manager();
+
+        // Flush does not return with success or failure, and must be enabled per bucket on the server.
+        // Store a marker item so that we will know if it was successful.
+        $this->doSave(__METHOD__, true, 60);
+
+        $manager->flush();
+
+        if ($this->doContains(__METHOD__)) {
+            $this->doDelete(__METHOD__);
+
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doGetStats()
+    {
+        $manager          = $this->bucket->manager();
+        $stats            = $manager->info();
+        $nodes            = $stats['nodes'];
+        $node             = $nodes[0];
+        $interestingStats = $node['interestingStats'];
+
+        return [
+            Cache::STATS_HITS   => $interestingStats['get_hits'],
+            Cache::STATS_MISSES => $interestingStats['cmd_get'] - $interestingStats['get_hits'],
+            Cache::STATS_UPTIME => $node['uptime'],
+            Cache::STATS_MEMORY_USAGE     => $interestingStats['mem_used'],
+            Cache::STATS_MEMORY_AVAILABLE => $node['memoryFree'],
+        ];
+    }
+
+    private function normalizeKey(string $id): string
+    {
+        $normalized = substr($id, 0, self::MAX_KEY_LENGTH);
+
+        if ($normalized === false) {
+            return $id;
+        }
+
+        return $normalized;
+    }
+
+    /**
+     * Expiry treated as a unix timestamp instead of an offset if expiry is greater than 30 days.
+     *
+     * @src https://developer.couchbase.com/documentation/server/4.1/developer-guide/expiry.html
+     */
+    private function normalizeExpiry(int $expiry): int
+    {
+        if ($expiry > self::THIRTY_DAYS_IN_SECONDS) {
+            return time() + $expiry;
+        }
+
+        return $expiry;
+    }
+}

+ 106 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseCache.php

@@ -0,0 +1,106 @@
+<?php
+
+namespace Doctrine\Common\Cache;
+
+use Couchbase;
+
+use function explode;
+use function time;
+
+/**
+ * Couchbase cache provider.
+ *
+ * @deprecated Couchbase SDK 1.x is now deprecated. Use \Doctrine\Common\Cache\CouchbaseBucketCache instead.
+ * https://developer.couchbase.com/documentation/server/current/sdk/php/compatibility-versions-features.html
+ *
+ * @link   www.doctrine-project.org
+ */
+class CouchbaseCache extends CacheProvider
+{
+    /** @var Couchbase|null */
+    private $couchbase;
+
+    /**
+     * Sets the Couchbase instance to use.
+     *
+     * @return void
+     */
+    public function setCouchbase(Couchbase $couchbase)
+    {
+        $this->couchbase = $couchbase;
+    }
+
+    /**
+     * Gets the Couchbase instance used by the cache.
+     *
+     * @return Couchbase|null
+     */
+    public function getCouchbase()
+    {
+        return $this->couchbase;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        return $this->couchbase->get($id) ?: false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        return $this->couchbase->get($id) !== null;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        if ($lifeTime > 30 * 24 * 3600) {
+            $lifeTime = time() + $lifeTime;
+        }
+
+        return $this->couchbase->set($id, $data, (int) $lifeTime);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDelete($id)
+    {
+        return $this->couchbase->delete($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFlush()
+    {
+        return $this->couchbase->flush();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doGetStats()
+    {
+        $stats   = $this->couchbase->getStats();
+        $servers = $this->couchbase->getServers();
+        $server  = explode(':', $servers[0]);
+        $key     = $server[0] . ':11210';
+        $stats   = $stats[$key];
+
+        return [
+            Cache::STATS_HITS   => $stats['get_hits'],
+            Cache::STATS_MISSES => $stats['get_misses'],
+            Cache::STATS_UPTIME => $stats['uptime'],
+            Cache::STATS_MEMORY_USAGE     => $stats['bytes'],
+            Cache::STATS_MEMORY_AVAILABLE => $stats['limit_maxbytes'],
+        ];
+    }
+}

+ 199 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/ExtMongoDBCache.php

@@ -0,0 +1,199 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Doctrine\Common\Cache;
+
+use DateTime;
+use MongoDB\BSON\Binary;
+use MongoDB\BSON\UTCDateTime;
+use MongoDB\Collection;
+use MongoDB\Database;
+use MongoDB\Driver\Exception\Exception;
+use MongoDB\Model\BSONDocument;
+
+use function serialize;
+use function time;
+use function unserialize;
+
+/**
+ * MongoDB cache provider for ext-mongodb
+ *
+ * @deprecated Deprecated without replacement in doctrine/cache 1.11. This class will be dropped in 2.0
+ */
+class ExtMongoDBCache extends CacheProvider
+{
+    /** @var Database */
+    private $database;
+
+    /** @var Collection */
+    private $collection;
+
+    /** @var bool */
+    private $expirationIndexCreated = false;
+
+    /**
+     * This provider will default to the write concern and read preference
+     * options set on the Database instance (or inherited from MongoDB or
+     * Client). Using an unacknowledged write concern (< 1) may make the return
+     * values of delete() and save() unreliable. Reading from secondaries may
+     * make contain() and fetch() unreliable.
+     *
+     * @see http://www.php.net/manual/en/mongo.readpreferences.php
+     * @see http://www.php.net/manual/en/mongo.writeconcerns.php
+     */
+    public function __construct(Collection $collection)
+    {
+        // Ensure there is no typemap set - we want to use our own
+        $this->collection = $collection->withOptions(['typeMap' => null]);
+        $this->database   = new Database($collection->getManager(), $collection->getDatabaseName());
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        $document = $this->collection->findOne(['_id' => $id], [MongoDBCache::DATA_FIELD, MongoDBCache::EXPIRATION_FIELD]);
+
+        if ($document === null) {
+            return false;
+        }
+
+        if ($this->isExpired($document)) {
+            $this->createExpirationIndex();
+            $this->doDelete($id);
+
+            return false;
+        }
+
+        return unserialize($document[MongoDBCache::DATA_FIELD]->getData());
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        $document = $this->collection->findOne(['_id' => $id], [MongoDBCache::EXPIRATION_FIELD]);
+
+        if ($document === null) {
+            return false;
+        }
+
+        if ($this->isExpired($document)) {
+            $this->createExpirationIndex();
+            $this->doDelete($id);
+
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        try {
+            $this->collection->updateOne(
+                ['_id' => $id],
+                [
+                    '$set' => [
+                        MongoDBCache::EXPIRATION_FIELD => ($lifeTime > 0 ? new UTCDateTime((time() + $lifeTime) * 1000) : null),
+                        MongoDBCache::DATA_FIELD => new Binary(serialize($data), Binary::TYPE_GENERIC),
+                    ],
+                ],
+                ['upsert' => true]
+            );
+        } catch (Exception $e) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDelete($id)
+    {
+        try {
+            $this->collection->deleteOne(['_id' => $id]);
+        } catch (Exception $e) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFlush()
+    {
+        try {
+            // Use remove() in lieu of drop() to maintain any collection indexes
+            $this->collection->deleteMany([]);
+        } catch (Exception $e) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doGetStats()
+    {
+        $uptime      = null;
+        $memoryUsage = null;
+
+        try {
+            $serverStatus = $this->database->command([
+                'serverStatus' => 1,
+                'locks' => 0,
+                'metrics' => 0,
+                'recordStats' => 0,
+                'repl' => 0,
+            ])->toArray()[0];
+            $uptime       = $serverStatus['uptime'] ?? null;
+        } catch (Exception $e) {
+        }
+
+        try {
+            $collStats   = $this->database->command(['collStats' => $this->collection->getCollectionName()])->toArray()[0];
+            $memoryUsage = $collStats['size'] ?? null;
+        } catch (Exception $e) {
+        }
+
+        return [
+            Cache::STATS_HITS => null,
+            Cache::STATS_MISSES => null,
+            Cache::STATS_UPTIME => $uptime,
+            Cache::STATS_MEMORY_USAGE => $memoryUsage,
+            Cache::STATS_MEMORY_AVAILABLE  => null,
+        ];
+    }
+
+    /**
+     * Check if the document is expired.
+     */
+    private function isExpired(BSONDocument $document): bool
+    {
+        return isset($document[MongoDBCache::EXPIRATION_FIELD]) &&
+            $document[MongoDBCache::EXPIRATION_FIELD] instanceof UTCDateTime &&
+            $document[MongoDBCache::EXPIRATION_FIELD]->toDateTime() < new DateTime();
+    }
+
+    private function createExpirationIndex(): void
+    {
+        if ($this->expirationIndexCreated) {
+            return;
+        }
+
+        $this->collection->createIndex([MongoDBCache::EXPIRATION_FIELD => 1], ['background' => true, 'expireAfterSeconds' => 0]);
+    }
+}

+ 292 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php

@@ -0,0 +1,292 @@
+<?php
+
+namespace Doctrine\Common\Cache;
+
+use FilesystemIterator;
+use InvalidArgumentException;
+use Iterator;
+use RecursiveDirectoryIterator;
+use RecursiveIteratorIterator;
+use SplFileInfo;
+
+use function bin2hex;
+use function chmod;
+use function defined;
+use function disk_free_space;
+use function file_exists;
+use function file_put_contents;
+use function gettype;
+use function hash;
+use function is_dir;
+use function is_int;
+use function is_writable;
+use function mkdir;
+use function pathinfo;
+use function realpath;
+use function rename;
+use function rmdir;
+use function sprintf;
+use function strlen;
+use function strrpos;
+use function substr;
+use function tempnam;
+use function unlink;
+
+use const DIRECTORY_SEPARATOR;
+use const PATHINFO_DIRNAME;
+
+/**
+ * Base file cache driver.
+ *
+ * @deprecated Deprecated without replacement in doctrine/cache 1.11. This class will be dropped in 2.0
+ */
+abstract class FileCache extends CacheProvider
+{
+    /**
+     * The cache directory.
+     *
+     * @var string
+     */
+    protected $directory;
+
+    /**
+     * The cache file extension.
+     *
+     * @var string
+     */
+    private $extension;
+
+    /** @var int */
+    private $umask;
+
+    /** @var int */
+    private $directoryStringLength;
+
+    /** @var int */
+    private $extensionStringLength;
+
+    /** @var bool */
+    private $isRunningOnWindows;
+
+    /**
+     * @param string $directory The cache directory.
+     * @param string $extension The cache file extension.
+     * @param int    $umask
+     *
+     * @throws InvalidArgumentException
+     */
+    public function __construct($directory, $extension = '', $umask = 0002)
+    {
+        // YES, this needs to be *before* createPathIfNeeded()
+        if (! is_int($umask)) {
+            throw new InvalidArgumentException(sprintf(
+                'The umask parameter is required to be integer, was: %s',
+                gettype($umask)
+            ));
+        }
+
+        $this->umask = $umask;
+
+        if (! $this->createPathIfNeeded($directory)) {
+            throw new InvalidArgumentException(sprintf(
+                'The directory "%s" does not exist and could not be created.',
+                $directory
+            ));
+        }
+
+        if (! is_writable($directory)) {
+            throw new InvalidArgumentException(sprintf(
+                'The directory "%s" is not writable.',
+                $directory
+            ));
+        }
+
+        // YES, this needs to be *after* createPathIfNeeded()
+        $this->directory = realpath($directory);
+        $this->extension = (string) $extension;
+
+        $this->directoryStringLength = strlen($this->directory);
+        $this->extensionStringLength = strlen($this->extension);
+        $this->isRunningOnWindows    = defined('PHP_WINDOWS_VERSION_BUILD');
+    }
+
+    /**
+     * Gets the cache directory.
+     *
+     * @return string
+     */
+    public function getDirectory()
+    {
+        return $this->directory;
+    }
+
+    /**
+     * Gets the cache file extension.
+     *
+     * @return string
+     */
+    public function getExtension()
+    {
+        return $this->extension;
+    }
+
+    /**
+     * @param string $id
+     *
+     * @return string
+     */
+    protected function getFilename($id)
+    {
+        $hash = hash('sha256', $id);
+
+        // This ensures that the filename is unique and that there are no invalid chars in it.
+        if (
+            $id === ''
+            || ((strlen($id) * 2 + $this->extensionStringLength) > 255)
+            || ($this->isRunningOnWindows && ($this->directoryStringLength + 4 + strlen($id) * 2 + $this->extensionStringLength) > 258)
+        ) {
+            // Most filesystems have a limit of 255 chars for each path component. On Windows the the whole path is limited
+            // to 260 chars (including terminating null char). Using long UNC ("\\?\" prefix) does not work with the PHP API.
+            // And there is a bug in PHP (https://bugs.php.net/bug.php?id=70943) with path lengths of 259.
+            // So if the id in hex representation would surpass the limit, we use the hash instead. The prefix prevents
+            // collisions between the hash and bin2hex.
+            $filename = '_' . $hash;
+        } else {
+            $filename = bin2hex($id);
+        }
+
+        return $this->directory
+            . DIRECTORY_SEPARATOR
+            . substr($hash, 0, 2)
+            . DIRECTORY_SEPARATOR
+            . $filename
+            . $this->extension;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDelete($id)
+    {
+        $filename = $this->getFilename($id);
+
+        return @unlink($filename) || ! file_exists($filename);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFlush()
+    {
+        foreach ($this->getIterator() as $name => $file) {
+            if ($file->isDir()) {
+                // Remove the intermediate directories which have been created to balance the tree. It only takes effect
+                // if the directory is empty. If several caches share the same directory but with different file extensions,
+                // the other ones are not removed.
+                @rmdir($name);
+            } elseif ($this->isFilenameEndingWithExtension($name)) {
+                // If an extension is set, only remove files which end with the given extension.
+                // If no extension is set, we have no other choice than removing everything.
+                @unlink($name);
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doGetStats()
+    {
+        $usage = 0;
+        foreach ($this->getIterator() as $name => $file) {
+            if ($file->isDir() || ! $this->isFilenameEndingWithExtension($name)) {
+                continue;
+            }
+
+            $usage += $file->getSize();
+        }
+
+        $free = disk_free_space($this->directory);
+
+        return [
+            Cache::STATS_HITS               => null,
+            Cache::STATS_MISSES             => null,
+            Cache::STATS_UPTIME             => null,
+            Cache::STATS_MEMORY_USAGE       => $usage,
+            Cache::STATS_MEMORY_AVAILABLE   => $free,
+        ];
+    }
+
+    /**
+     * Create path if needed.
+     *
+     * @return bool TRUE on success or if path already exists, FALSE if path cannot be created.
+     */
+    private function createPathIfNeeded(string $path): bool
+    {
+        if (! is_dir($path)) {
+            if (@mkdir($path, 0777 & (~$this->umask), true) === false && ! is_dir($path)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Writes a string content to file in an atomic way.
+     *
+     * @param string $filename Path to the file where to write the data.
+     * @param string $content  The content to write
+     *
+     * @return bool TRUE on success, FALSE if path cannot be created, if path is not writable or an any other error.
+     */
+    protected function writeFile(string $filename, string $content): bool
+    {
+        $filepath = pathinfo($filename, PATHINFO_DIRNAME);
+
+        if (! $this->createPathIfNeeded($filepath)) {
+            return false;
+        }
+
+        if (! is_writable($filepath)) {
+            return false;
+        }
+
+        $tmpFile = tempnam($filepath, 'swap');
+        @chmod($tmpFile, 0666 & (~$this->umask));
+
+        if (file_put_contents($tmpFile, $content) !== false) {
+            @chmod($tmpFile, 0666 & (~$this->umask));
+            if (@rename($tmpFile, $filename)) {
+                return true;
+            }
+
+            @unlink($tmpFile);
+        }
+
+        return false;
+    }
+
+    /**
+     * @return Iterator<string, SplFileInfo>
+     */
+    private function getIterator(): Iterator
+    {
+        return new RecursiveIteratorIterator(
+            new RecursiveDirectoryIterator($this->directory, FilesystemIterator::SKIP_DOTS),
+            RecursiveIteratorIterator::CHILD_FIRST
+        );
+    }
+
+    /**
+     * @param string $name The filename
+     */
+    private function isFilenameEndingWithExtension(string $name): bool
+    {
+        return $this->extension === ''
+            || strrpos($name, $this->extension) === strlen($name) - $this->extensionStringLength;
+    }
+}

+ 105 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/FilesystemCache.php

@@ -0,0 +1,105 @@
+<?php
+
+namespace Doctrine\Common\Cache;
+
+use function fclose;
+use function fgets;
+use function fopen;
+use function is_file;
+use function serialize;
+use function time;
+use function unserialize;
+
+use const PHP_EOL;
+
+/**
+ * Filesystem cache driver.
+ *
+ * @deprecated Deprecated without replacement in doctrine/cache 1.11. This class will be dropped in 2.0
+ */
+class FilesystemCache extends FileCache
+{
+    public const EXTENSION = '.doctrinecache.data';
+
+    /**
+     * {@inheritdoc}
+     */
+    public function __construct($directory, $extension = self::EXTENSION, $umask = 0002)
+    {
+        parent::__construct($directory, $extension, $umask);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        $data     = '';
+        $lifetime = -1;
+        $filename = $this->getFilename($id);
+
+        if (! is_file($filename)) {
+            return false;
+        }
+
+        $resource = fopen($filename, 'r');
+        $line     = fgets($resource);
+
+        if ($line !== false) {
+            $lifetime = (int) $line;
+        }
+
+        if ($lifetime !== 0 && $lifetime < time()) {
+            fclose($resource);
+
+            return false;
+        }
+
+        while (($line = fgets($resource)) !== false) {
+            $data .= $line;
+        }
+
+        fclose($resource);
+
+        return unserialize($data);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        $lifetime = -1;
+        $filename = $this->getFilename($id);
+
+        if (! is_file($filename)) {
+            return false;
+        }
+
+        $resource = fopen($filename, 'r');
+        $line     = fgets($resource);
+
+        if ($line !== false) {
+            $lifetime = (int) $line;
+        }
+
+        fclose($resource);
+
+        return $lifetime === 0 || $lifetime > time();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        if ($lifeTime > 0) {
+            $lifeTime = time() + $lifeTime;
+        }
+
+        $data     = serialize($data);
+        $filename = $this->getFilename($id);
+
+        return $this->writeFile($filename, $lifeTime . PHP_EOL . $data);
+    }
+}

+ 18 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/FlushableCache.php

@@ -0,0 +1,18 @@
+<?php
+
+namespace Doctrine\Common\Cache;
+
+/**
+ * Interface for cache that can be flushed.
+ *
+ * @link   www.doctrine-project.org
+ */
+interface FlushableCache
+{
+    /**
+     * Flushes all cache entries, globally.
+     *
+     * @return bool TRUE if the cache entries were successfully flushed, FALSE otherwise.
+     */
+    public function flushAll();
+}

+ 38 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/InvalidCacheId.php

@@ -0,0 +1,38 @@
+<?php
+declare(strict_types=1);
+
+namespace Doctrine\Common\Cache;
+
+use InvalidArgumentException;
+
+use function sprintf;
+
+/**
+ * @deprecated Deprecated without replacement in doctrine/cache 1.11. This class will be dropped in 2.0
+ */
+final class InvalidCacheId extends InvalidArgumentException
+{
+    /**
+     * @param mixed $id
+     */
+    public static function exceedsMaxLength($id, int $maxLength): self
+    {
+        return new self(sprintf('Cache id "%s" exceeds maximum length %d', $id, $maxLength));
+    }
+
+    /**
+     * @param mixed $id
+     */
+    public static function containsUnauthorizedCharacter($id, string $character): self
+    {
+        return new self(sprintf('Cache id "%s" contains unauthorized character "%s"', $id, $character));
+    }
+
+    /**
+     * @param mixed $id
+     */
+    public static function containsControlCharacter($id): self
+    {
+        return new self(sprintf('Cache id "%s" contains at least one control character', $id));
+    }
+}

+ 177 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/LegacyMongoDBCache.php

@@ -0,0 +1,177 @@
+<?php
+
+namespace Doctrine\Common\Cache;
+
+use MongoBinData;
+use MongoCollection;
+use MongoCursorException;
+use MongoDate;
+
+use function serialize;
+use function time;
+use function trigger_error;
+use function unserialize;
+
+use const E_USER_DEPRECATED;
+
+/**
+ * MongoDB cache provider.
+ *
+ * @deprecated Deprecated without replacement in doctrine/cache 1.11. This class will be dropped in 2.0
+ */
+class LegacyMongoDBCache extends CacheProvider
+{
+    /** @var MongoCollection */
+    private $collection;
+
+    /** @var bool */
+    private $expirationIndexCreated = false;
+
+    /**
+     * This provider will default to the write concern and read preference
+     * options set on the MongoCollection instance (or inherited from MongoDB or
+     * MongoClient). Using an unacknowledged write concern (< 1) may make the
+     * return values of delete() and save() unreliable. Reading from secondaries
+     * may make contain() and fetch() unreliable.
+     *
+     * @see http://www.php.net/manual/en/mongo.readpreferences.php
+     * @see http://www.php.net/manual/en/mongo.writeconcerns.php
+     */
+    public function __construct(MongoCollection $collection)
+    {
+        @trigger_error('Using the legacy MongoDB cache provider is deprecated and will be removed in 2.0', E_USER_DEPRECATED);
+        $this->collection = $collection;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        $document = $this->collection->findOne(['_id' => $id], [MongoDBCache::DATA_FIELD, MongoDBCache::EXPIRATION_FIELD]);
+
+        if ($document === null) {
+            return false;
+        }
+
+        if ($this->isExpired($document)) {
+            $this->createExpirationIndex();
+            $this->doDelete($id);
+
+            return false;
+        }
+
+        return unserialize($document[MongoDBCache::DATA_FIELD]->bin);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        $document = $this->collection->findOne(['_id' => $id], [MongoDBCache::EXPIRATION_FIELD]);
+
+        if ($document === null) {
+            return false;
+        }
+
+        if ($this->isExpired($document)) {
+            $this->createExpirationIndex();
+            $this->doDelete($id);
+
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        try {
+            $result = $this->collection->update(
+                ['_id' => $id],
+                [
+                    '$set' => [
+                        MongoDBCache::EXPIRATION_FIELD => ($lifeTime > 0 ? new MongoDate(time() + $lifeTime) : null),
+                        MongoDBCache::DATA_FIELD => new MongoBinData(serialize($data), MongoBinData::BYTE_ARRAY),
+                    ],
+                ],
+                ['upsert' => true, 'multiple' => false]
+            );
+        } catch (MongoCursorException $e) {
+            return false;
+        }
+
+        return ($result['ok'] ?? 1) == 1;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDelete($id)
+    {
+        $result = $this->collection->remove(['_id' => $id]);
+
+        return ($result['ok'] ?? 1) == 1;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFlush()
+    {
+        // Use remove() in lieu of drop() to maintain any collection indexes
+        $result = $this->collection->remove();
+
+        return ($result['ok'] ?? 1) == 1;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doGetStats()
+    {
+        $serverStatus = $this->collection->db->command([
+            'serverStatus' => 1,
+            'locks' => 0,
+            'metrics' => 0,
+            'recordStats' => 0,
+            'repl' => 0,
+        ]);
+
+        $collStats = $this->collection->db->command(['collStats' => 1]);
+
+        return [
+            Cache::STATS_HITS => null,
+            Cache::STATS_MISSES => null,
+            Cache::STATS_UPTIME => $serverStatus['uptime'] ?? null,
+            Cache::STATS_MEMORY_USAGE => $collStats['size'] ?? null,
+            Cache::STATS_MEMORY_AVAILABLE  => null,
+        ];
+    }
+
+    /**
+     * Check if the document is expired.
+     *
+     * @param mixed[] $document
+     */
+    private function isExpired(array $document): bool
+    {
+        return isset($document[MongoDBCache::EXPIRATION_FIELD]) &&
+            $document[MongoDBCache::EXPIRATION_FIELD] instanceof MongoDate &&
+            $document[MongoDBCache::EXPIRATION_FIELD]->sec < time();
+    }
+
+    private function createExpirationIndex(): void
+    {
+        if ($this->expirationIndexCreated) {
+            return;
+        }
+
+        $this->expirationIndexCreated = true;
+        $this->collection->createIndex([MongoDBCache::EXPIRATION_FIELD => 1], ['background' => true, 'expireAfterSeconds' => 0]);
+    }
+}

+ 105 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/MemcacheCache.php

@@ -0,0 +1,105 @@
+<?php
+
+namespace Doctrine\Common\Cache;
+
+use Memcache;
+
+use function time;
+
+/**
+ * Memcache cache provider.
+ *
+ * @deprecated Deprecated without replacement in doctrine/cache 1.11. This class will be dropped in 2.0
+ *
+ * @link   www.doctrine-project.org
+ */
+class MemcacheCache extends CacheProvider
+{
+    /** @var Memcache|null */
+    private $memcache;
+
+    /**
+     * Sets the memcache instance to use.
+     *
+     * @return void
+     */
+    public function setMemcache(Memcache $memcache)
+    {
+        $this->memcache = $memcache;
+    }
+
+    /**
+     * Gets the memcache instance used by the cache.
+     *
+     * @return Memcache|null
+     */
+    public function getMemcache()
+    {
+        return $this->memcache;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        return $this->memcache->get($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        $flags = null;
+        $this->memcache->get($id, $flags);
+
+        //if memcache has changed the value of "flags", it means the value exists
+        return $flags !== null;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        if ($lifeTime > 30 * 24 * 3600) {
+            $lifeTime = time() + $lifeTime;
+        }
+
+        return $this->memcache->set($id, $data, 0, (int) $lifeTime);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDelete($id)
+    {
+        // Memcache::delete() returns false if entry does not exist
+        return $this->memcache->delete($id) || ! $this->doContains($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFlush()
+    {
+        return $this->memcache->flush();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doGetStats()
+    {
+        $stats = $this->memcache->getStats();
+
+        return [
+            Cache::STATS_HITS   => $stats['get_hits'],
+            Cache::STATS_MISSES => $stats['get_misses'],
+            Cache::STATS_UPTIME => $stats['uptime'],
+            Cache::STATS_MEMORY_USAGE     => $stats['bytes'],
+            Cache::STATS_MEMORY_AVAILABLE => $stats['limit_maxbytes'],
+        ];
+    }
+}

+ 173 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/MemcachedCache.php

@@ -0,0 +1,173 @@
+<?php
+
+namespace Doctrine\Common\Cache;
+
+use Memcached;
+
+use function array_keys;
+use function preg_match;
+use function strlen;
+use function strpos;
+use function time;
+
+/**
+ * Memcached cache provider.
+ *
+ * @deprecated Deprecated without replacement in doctrine/cache 1.11. This class will be dropped in 2.0
+ *
+ * @link   www.doctrine-project.org
+ */
+class MemcachedCache extends CacheProvider
+{
+    public const CACHE_ID_MAX_LENGTH = 250;
+
+    /** @var Memcached|null */
+    private $memcached;
+
+    /**
+     * Sets the memcache instance to use.
+     *
+     * @return void
+     */
+    public function setMemcached(Memcached $memcached)
+    {
+        $this->memcached = $memcached;
+    }
+
+    /**
+     * Gets the memcached instance used by the cache.
+     *
+     * @return Memcached|null
+     */
+    public function getMemcached()
+    {
+        return $this->memcached;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        return $this->memcached->get($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetchMultiple(array $keys)
+    {
+        return $this->memcached->getMulti($keys) ?: [];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
+    {
+        foreach (array_keys($keysAndValues) as $id) {
+            $this->validateCacheId($id);
+        }
+
+        if ($lifetime > 30 * 24 * 3600) {
+            $lifetime = time() + $lifetime;
+        }
+
+        return $this->memcached->setMulti($keysAndValues, $lifetime);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        $this->memcached->get($id);
+
+        return $this->memcached->getResultCode() === Memcached::RES_SUCCESS;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        $this->validateCacheId($id);
+
+        if ($lifeTime > 30 * 24 * 3600) {
+            $lifeTime = time() + $lifeTime;
+        }
+
+        return $this->memcached->set($id, $data, (int) $lifeTime);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDeleteMultiple(array $keys)
+    {
+        return $this->memcached->deleteMulti($keys)
+            || $this->memcached->getResultCode() === Memcached::RES_NOTFOUND;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDelete($id)
+    {
+        return $this->memcached->delete($id)
+            || $this->memcached->getResultCode() === Memcached::RES_NOTFOUND;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFlush()
+    {
+        return $this->memcached->flush();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doGetStats()
+    {
+        $stats   = $this->memcached->getStats();
+        $servers = $this->memcached->getServerList();
+        $key     = $servers[0]['host'] . ':' . $servers[0]['port'];
+        $stats   = $stats[$key];
+
+        return [
+            Cache::STATS_HITS   => $stats['get_hits'],
+            Cache::STATS_MISSES => $stats['get_misses'],
+            Cache::STATS_UPTIME => $stats['uptime'],
+            Cache::STATS_MEMORY_USAGE     => $stats['bytes'],
+            Cache::STATS_MEMORY_AVAILABLE => $stats['limit_maxbytes'],
+        ];
+    }
+
+    /**
+     * Validate the cache id
+     *
+     * @see https://github.com/memcached/memcached/blob/1.5.12/doc/protocol.txt#L41-L49
+     *
+     * @param string $id
+     *
+     * @return void
+     *
+     * @throws InvalidCacheId
+     */
+    private function validateCacheId($id)
+    {
+        if (strlen($id) > self::CACHE_ID_MAX_LENGTH) {
+            throw InvalidCacheId::exceedsMaxLength($id, self::CACHE_ID_MAX_LENGTH);
+        }
+
+        if (strpos($id, ' ') !== false) {
+            throw InvalidCacheId::containsUnauthorizedCharacter($id, ' ');
+        }
+
+        if (preg_match('/[\t\r\n]/', $id) === 1) {
+            throw InvalidCacheId::containsControlCharacter($id);
+        }
+    }
+}

+ 116 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/MongoDBCache.php

@@ -0,0 +1,116 @@
+<?php
+
+namespace Doctrine\Common\Cache;
+
+use InvalidArgumentException;
+use MongoCollection;
+use MongoDB\Collection;
+
+use function trigger_error;
+
+use const E_USER_DEPRECATED;
+
+/**
+ * MongoDB cache provider.
+ *
+ * @deprecated Deprecated without replacement in doctrine/cache 1.11. This class will be dropped in 2.0
+ */
+class MongoDBCache extends CacheProvider
+{
+    /**
+     * The data field will store the serialized PHP value.
+     */
+    public const DATA_FIELD = 'd';
+
+    /**
+     * The expiration field will store a MongoDate value indicating when the
+     * cache entry should expire.
+     *
+     * With MongoDB 2.2+, entries can be automatically deleted by MongoDB by
+     * indexing this field with the "expireAfterSeconds" option equal to zero.
+     * This will direct MongoDB to regularly query for and delete any entries
+     * whose date is older than the current time. Entries without a date value
+     * in this field will be ignored.
+     *
+     * The cache provider will also check dates on its own, in case expired
+     * entries are fetched before MongoDB's TTLMonitor pass can expire them.
+     *
+     * @see http://docs.mongodb.org/manual/tutorial/expire-data/
+     */
+    public const EXPIRATION_FIELD = 'e';
+
+    /** @var CacheProvider */
+    private $provider;
+
+    /**
+     * This provider will default to the write concern and read preference
+     * options set on the collection instance (or inherited from MongoDB or
+     * MongoClient). Using an unacknowledged write concern (< 1) may make the
+     * return values of delete() and save() unreliable. Reading from secondaries
+     * may make contain() and fetch() unreliable.
+     *
+     * @see http://www.php.net/manual/en/mongo.readpreferences.php
+     * @see http://www.php.net/manual/en/mongo.writeconcerns.php
+     *
+     * @param MongoCollection|Collection $collection
+     */
+    public function __construct($collection)
+    {
+        if ($collection instanceof MongoCollection) {
+            @trigger_error('Using a MongoCollection instance for creating a cache adapter is deprecated and will be removed in 2.0', E_USER_DEPRECATED);
+            $this->provider = new LegacyMongoDBCache($collection);
+        } elseif ($collection instanceof Collection) {
+            $this->provider = new ExtMongoDBCache($collection);
+        } else {
+            throw new InvalidArgumentException('Invalid collection given - expected a MongoCollection or MongoDB\Collection instance');
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        return $this->provider->doFetch($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        return $this->provider->doContains($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        return $this->provider->doSave($id, $data, $lifeTime);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDelete($id)
+    {
+        return $this->provider->doDelete($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFlush()
+    {
+        return $this->provider->doFlush();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doGetStats()
+    {
+        return $this->provider->doGetStats();
+    }
+}

+ 22 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/MultiDeleteCache.php

@@ -0,0 +1,22 @@
+<?php
+
+namespace Doctrine\Common\Cache;
+
+/**
+ * Interface for cache drivers that allows to put many items at once.
+ *
+ * @deprecated
+ *
+ * @link   www.doctrine-project.org
+ */
+interface MultiDeleteCache
+{
+    /**
+     * Deletes several cache entries.
+     *
+     * @param string[] $keys Array of keys to delete from cache
+     *
+     * @return bool TRUE if the operation was successful, FALSE if it wasn't.
+     */
+    public function deleteMultiple(array $keys);
+}

+ 23 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/MultiGetCache.php

@@ -0,0 +1,23 @@
+<?php
+
+namespace Doctrine\Common\Cache;
+
+/**
+ * Interface for cache drivers that allows to get many items at once.
+ *
+ * @deprecated
+ *
+ * @link   www.doctrine-project.org
+ */
+interface MultiGetCache
+{
+    /**
+     * Returns an associative array of values for keys is found in cache.
+     *
+     * @param string[] $keys Array of keys to retrieve from cache
+     *
+     * @return mixed[] Array of retrieved values, indexed by the specified keys.
+     *                 Values that couldn't be retrieved are not contained in this array.
+     */
+    public function fetchMultiple(array $keys);
+}

+ 12 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/MultiOperationCache.php

@@ -0,0 +1,12 @@
+<?php
+
+namespace Doctrine\Common\Cache;
+
+/**
+ * Interface for cache drivers that supports multiple items manipulation.
+ *
+ * @link   www.doctrine-project.org
+ */
+interface MultiOperationCache extends MultiGetCache, MultiDeleteCache, MultiPutCache
+{
+}

+ 24 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/MultiPutCache.php

@@ -0,0 +1,24 @@
+<?php
+
+namespace Doctrine\Common\Cache;
+
+/**
+ * Interface for cache drivers that allows to put many items at once.
+ *
+ * @deprecated
+ *
+ * @link   www.doctrine-project.org
+ */
+interface MultiPutCache
+{
+    /**
+     * Returns a boolean value indicating if the operation succeeded.
+     *
+     * @param mixed[] $keysAndValues Array of keys and values to save in cache
+     * @param int     $lifetime      The lifetime. If != 0, sets a specific lifetime for these
+     *                               cache entries (0 => infinite lifeTime).
+     *
+     * @return bool TRUE if the operation was successful, FALSE if it wasn't.
+     */
+    public function saveMultiple(array $keysAndValues, $lifetime = 0);
+}

+ 120 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/PhpFileCache.php

@@ -0,0 +1,120 @@
+<?php
+
+namespace Doctrine\Common\Cache;
+
+use function is_object;
+use function method_exists;
+use function restore_error_handler;
+use function serialize;
+use function set_error_handler;
+use function sprintf;
+use function time;
+use function var_export;
+
+/**
+ * Php file cache driver.
+ *
+ * @deprecated Deprecated without replacement in doctrine/cache 1.11. This class will be dropped in 2.0
+ */
+class PhpFileCache extends FileCache
+{
+    public const EXTENSION = '.doctrinecache.php';
+
+    /**
+     * @var callable
+     *
+     * This is cached in a local static variable to avoid instantiating a closure each time we need an empty handler
+     */
+    private static $emptyErrorHandler;
+
+    /**
+     * {@inheritdoc}
+     */
+    public function __construct($directory, $extension = self::EXTENSION, $umask = 0002)
+    {
+        parent::__construct($directory, $extension, $umask);
+
+        self::$emptyErrorHandler = static function () {
+        };
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        $value = $this->includeFileForId($id);
+
+        if ($value === null) {
+            return false;
+        }
+
+        if ($value['lifetime'] !== 0 && $value['lifetime'] < time()) {
+            return false;
+        }
+
+        return $value['data'];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        $value = $this->includeFileForId($id);
+
+        if ($value === null) {
+            return false;
+        }
+
+        return $value['lifetime'] === 0 || $value['lifetime'] > time();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        if ($lifeTime > 0) {
+            $lifeTime = time() + $lifeTime;
+        }
+
+        $filename = $this->getFilename($id);
+
+        $value = [
+            'lifetime'  => $lifeTime,
+            'data'      => $data,
+        ];
+
+        if (is_object($data) && method_exists($data, '__set_state')) {
+            $value = var_export($value, true);
+            $code  = sprintf('<?php return %s;', $value);
+        } else {
+            $value = var_export(serialize($value), true);
+            $code  = sprintf('<?php return unserialize(%s);', $value);
+        }
+
+        return $this->writeFile($filename, $code);
+    }
+
+    /**
+     * @return mixed[]|null
+     */
+    private function includeFileForId(string $id): ?array
+    {
+        $fileName = $this->getFilename($id);
+
+        // note: error suppression is still faster than `file_exists`, `is_file` and `is_readable`
+        set_error_handler(self::$emptyErrorHandler);
+
+        $value = include $fileName;
+
+        restore_error_handler();
+
+        if (! isset($value['lifetime'])) {
+            return null;
+        }
+
+        return $value;
+    }
+}

+ 147 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/PredisCache.php

@@ -0,0 +1,147 @@
+<?php
+
+namespace Doctrine\Common\Cache;
+
+use Predis\ClientInterface;
+
+use function array_combine;
+use function array_filter;
+use function array_map;
+use function array_values;
+use function call_user_func_array;
+use function serialize;
+use function unserialize;
+
+/**
+ * Predis cache provider.
+ *
+ * @deprecated Deprecated without replacement in doctrine/cache 1.11. This class will be dropped in 2.0
+ */
+class PredisCache extends CacheProvider
+{
+    /** @var ClientInterface */
+    private $client;
+
+    public function __construct(ClientInterface $client)
+    {
+        $this->client = $client;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        $result = $this->client->get($id);
+        if ($result === null) {
+            return false;
+        }
+
+        return unserialize($result);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetchMultiple(array $keys)
+    {
+        $fetchedItems = call_user_func_array([$this->client, 'mget'], array_values($keys));
+
+        return array_map('unserialize', array_filter(array_combine($keys, $fetchedItems)));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
+    {
+        if ($lifetime) {
+            $success = true;
+
+            // Keys have lifetime, use SETEX for each of them
+            foreach ($keysAndValues as $key => $value) {
+                $response = (string) $this->client->setex($key, $lifetime, serialize($value));
+
+                if ($response == 'OK') {
+                    continue;
+                }
+
+                $success = false;
+            }
+
+            return $success;
+        }
+
+        // No lifetime, use MSET
+        $response = $this->client->mset(array_map(static function ($value) {
+            return serialize($value);
+        }, $keysAndValues));
+
+        return (string) $response == 'OK';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        return (bool) $this->client->exists($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        $data = serialize($data);
+        if ($lifeTime > 0) {
+            $response = $this->client->setex($id, $lifeTime, $data);
+        } else {
+            $response = $this->client->set($id, $data);
+        }
+
+        return $response === true || $response == 'OK';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDelete($id)
+    {
+        return $this->client->del($id) >= 0;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDeleteMultiple(array $keys)
+    {
+        return $this->client->del($keys) >= 0;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFlush()
+    {
+        $response = $this->client->flushdb();
+
+        return $response === true || $response == 'OK';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doGetStats()
+    {
+        $info = $this->client->info();
+
+        return [
+            Cache::STATS_HITS              => $info['Stats']['keyspace_hits'],
+            Cache::STATS_MISSES            => $info['Stats']['keyspace_misses'],
+            Cache::STATS_UPTIME            => $info['Server']['uptime_in_seconds'],
+            Cache::STATS_MEMORY_USAGE      => $info['Memory']['used_memory'],
+            Cache::STATS_MEMORY_AVAILABLE  => false,
+        ];
+    }
+}

+ 340 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/CacheAdapter.php

@@ -0,0 +1,340 @@
+<?php
+
+namespace Doctrine\Common\Cache\Psr6;
+
+use Doctrine\Common\Cache\Cache;
+use Doctrine\Common\Cache\ClearableCache;
+use Doctrine\Common\Cache\MultiDeleteCache;
+use Doctrine\Common\Cache\MultiGetCache;
+use Doctrine\Common\Cache\MultiPutCache;
+use Psr\Cache\CacheItemInterface;
+use Psr\Cache\CacheItemPoolInterface;
+use Symfony\Component\Cache\DoctrineProvider as SymfonyDoctrineProvider;
+
+use function array_key_exists;
+use function assert;
+use function count;
+use function current;
+use function get_class;
+use function gettype;
+use function is_object;
+use function is_string;
+use function microtime;
+use function sprintf;
+use function strpbrk;
+
+use const PHP_VERSION_ID;
+
+final class CacheAdapter implements CacheItemPoolInterface
+{
+    private const RESERVED_CHARACTERS = '{}()/\@:';
+
+    /** @var Cache */
+    private $cache;
+
+    /** @var array<CacheItem|TypedCacheItem> */
+    private $deferredItems = [];
+
+    public static function wrap(Cache $cache): CacheItemPoolInterface
+    {
+        if ($cache instanceof DoctrineProvider && ! $cache->getNamespace()) {
+            return $cache->getPool();
+        }
+
+        if ($cache instanceof SymfonyDoctrineProvider && ! $cache->getNamespace()) {
+            $getPool = function () {
+                // phpcs:ignore Squiz.Scope.StaticThisUsage.Found
+                return $this->pool;
+            };
+
+            return $getPool->bindTo($cache, SymfonyDoctrineProvider::class)();
+        }
+
+        return new self($cache);
+    }
+
+    private function __construct(Cache $cache)
+    {
+        $this->cache = $cache;
+    }
+
+    /** @internal */
+    public function getCache(): Cache
+    {
+        return $this->cache;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getItem($key): CacheItemInterface
+    {
+        assert(self::validKey($key));
+
+        if (isset($this->deferredItems[$key])) {
+            $this->commit();
+        }
+
+        $value = $this->cache->fetch($key);
+
+        if (PHP_VERSION_ID >= 80000) {
+            if ($value !== false) {
+                return new TypedCacheItem($key, $value, true);
+            }
+
+            return new TypedCacheItem($key, null, false);
+        }
+
+        if ($value !== false) {
+            return new CacheItem($key, $value, true);
+        }
+
+        return new CacheItem($key, null, false);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getItems(array $keys = []): array
+    {
+        if ($this->deferredItems) {
+            $this->commit();
+        }
+
+        assert(self::validKeys($keys));
+
+        $values = $this->doFetchMultiple($keys);
+        $items  = [];
+
+        if (PHP_VERSION_ID >= 80000) {
+            foreach ($keys as $key) {
+                if (array_key_exists($key, $values)) {
+                    $items[$key] = new TypedCacheItem($key, $values[$key], true);
+                } else {
+                    $items[$key] = new TypedCacheItem($key, null, false);
+                }
+            }
+
+            return $items;
+        }
+
+        foreach ($keys as $key) {
+            if (array_key_exists($key, $values)) {
+                $items[$key] = new CacheItem($key, $values[$key], true);
+            } else {
+                $items[$key] = new CacheItem($key, null, false);
+            }
+        }
+
+        return $items;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function hasItem($key): bool
+    {
+        assert(self::validKey($key));
+
+        if (isset($this->deferredItems[$key])) {
+            $this->commit();
+        }
+
+        return $this->cache->contains($key);
+    }
+
+    public function clear(): bool
+    {
+        $this->deferredItems = [];
+
+        if (! $this->cache instanceof ClearableCache) {
+            return false;
+        }
+
+        return $this->cache->deleteAll();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function deleteItem($key): bool
+    {
+        assert(self::validKey($key));
+        unset($this->deferredItems[$key]);
+
+        return $this->cache->delete($key);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function deleteItems(array $keys): bool
+    {
+        foreach ($keys as $key) {
+            assert(self::validKey($key));
+            unset($this->deferredItems[$key]);
+        }
+
+        return $this->doDeleteMultiple($keys);
+    }
+
+    public function save(CacheItemInterface $item): bool
+    {
+        return $this->saveDeferred($item) && $this->commit();
+    }
+
+    public function saveDeferred(CacheItemInterface $item): bool
+    {
+        if (! $item instanceof CacheItem && ! $item instanceof TypedCacheItem) {
+            return false;
+        }
+
+        $this->deferredItems[$item->getKey()] = $item;
+
+        return true;
+    }
+
+    public function commit(): bool
+    {
+        if (! $this->deferredItems) {
+            return true;
+        }
+
+        $now         = microtime(true);
+        $itemsCount  = 0;
+        $byLifetime  = [];
+        $expiredKeys = [];
+
+        foreach ($this->deferredItems as $key => $item) {
+            $lifetime = ($item->getExpiry() ?? $now) - $now;
+
+            if ($lifetime < 0) {
+                $expiredKeys[] = $key;
+
+                continue;
+            }
+
+            ++$itemsCount;
+            $byLifetime[(int) $lifetime][$key] = $item->get();
+        }
+
+        $this->deferredItems = [];
+
+        switch (count($expiredKeys)) {
+            case 0:
+                break;
+            case 1:
+                $this->cache->delete(current($expiredKeys));
+                break;
+            default:
+                $this->doDeleteMultiple($expiredKeys);
+                break;
+        }
+
+        if ($itemsCount === 1) {
+            return $this->cache->save($key, $item->get(), (int) $lifetime);
+        }
+
+        $success = true;
+        foreach ($byLifetime as $lifetime => $values) {
+            $success = $this->doSaveMultiple($values, $lifetime) && $success;
+        }
+
+        return $success;
+    }
+
+    public function __destruct()
+    {
+        $this->commit();
+    }
+
+    /**
+     * @param mixed $key
+     */
+    private static function validKey($key): bool
+    {
+        if (! is_string($key)) {
+            throw new InvalidArgument(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key)));
+        }
+
+        if ($key === '') {
+            throw new InvalidArgument('Cache key length must be greater than zero.');
+        }
+
+        if (strpbrk($key, self::RESERVED_CHARACTERS) !== false) {
+            throw new InvalidArgument(sprintf('Cache key "%s" contains reserved characters "%s".', $key, self::RESERVED_CHARACTERS));
+        }
+
+        return true;
+    }
+
+    /**
+     * @param mixed[] $keys
+     */
+    private static function validKeys(array $keys): bool
+    {
+        foreach ($keys as $key) {
+            self::validKey($key);
+        }
+
+        return true;
+    }
+
+    /**
+     * @param mixed[] $keys
+     */
+    private function doDeleteMultiple(array $keys): bool
+    {
+        if ($this->cache instanceof MultiDeleteCache) {
+            return $this->cache->deleteMultiple($keys);
+        }
+
+        $success = true;
+        foreach ($keys as $key) {
+            $success = $this->cache->delete($key) && $success;
+        }
+
+        return $success;
+    }
+
+    /**
+     * @param mixed[] $keys
+     *
+     * @return mixed[]
+     */
+    private function doFetchMultiple(array $keys): array
+    {
+        if ($this->cache instanceof MultiGetCache) {
+            return $this->cache->fetchMultiple($keys);
+        }
+
+        $values = [];
+        foreach ($keys as $key) {
+            $value = $this->cache->fetch($key);
+            if (! $value) {
+                continue;
+            }
+
+            $values[$key] = $value;
+        }
+
+        return $values;
+    }
+
+    /**
+     * @param mixed[] $keysAndValues
+     */
+    private function doSaveMultiple(array $keysAndValues, int $lifetime = 0): bool
+    {
+        if ($this->cache instanceof MultiPutCache) {
+            return $this->cache->saveMultiple($keysAndValues, $lifetime);
+        }
+
+        $success = true;
+        foreach ($keysAndValues as $key => $value) {
+            $success = $this->cache->save($key, $value, $lifetime) && $success;
+        }
+
+        return $success;
+    }
+}

+ 118 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/CacheItem.php

@@ -0,0 +1,118 @@
+<?php
+
+namespace Doctrine\Common\Cache\Psr6;
+
+use DateInterval;
+use DateTime;
+use DateTimeInterface;
+use Psr\Cache\CacheItemInterface;
+use TypeError;
+
+use function get_class;
+use function gettype;
+use function is_int;
+use function is_object;
+use function microtime;
+use function sprintf;
+
+final class CacheItem implements CacheItemInterface
+{
+    /** @var string */
+    private $key;
+    /** @var mixed */
+    private $value;
+    /** @var bool */
+    private $isHit;
+    /** @var float|null */
+    private $expiry;
+
+    /**
+     * @internal
+     *
+     * @param mixed $data
+     */
+    public function __construct(string $key, $data, bool $isHit)
+    {
+        $this->key   = $key;
+        $this->value = $data;
+        $this->isHit = $isHit;
+    }
+
+    public function getKey(): string
+    {
+        return $this->key;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @return mixed
+     */
+    public function get()
+    {
+        return $this->value;
+    }
+
+    public function isHit(): bool
+    {
+        return $this->isHit;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function set($value): self
+    {
+        $this->value = $value;
+
+        return $this;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function expiresAt($expiration): self
+    {
+        if ($expiration === null) {
+            $this->expiry = null;
+        } elseif ($expiration instanceof DateTimeInterface) {
+            $this->expiry = (float) $expiration->format('U.u');
+        } else {
+            throw new TypeError(sprintf(
+                'Expected $expiration to be an instance of DateTimeInterface or null, got %s',
+                is_object($expiration) ? get_class($expiration) : gettype($expiration)
+            ));
+        }
+
+        return $this;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function expiresAfter($time): self
+    {
+        if ($time === null) {
+            $this->expiry = null;
+        } elseif ($time instanceof DateInterval) {
+            $this->expiry = microtime(true) + DateTime::createFromFormat('U', 0)->add($time)->format('U.u');
+        } elseif (is_int($time)) {
+            $this->expiry = $time + microtime(true);
+        } else {
+            throw new TypeError(sprintf(
+                'Expected $time to be either an integer, an instance of DateInterval or null, got %s',
+                is_object($time) ? get_class($time) : gettype($time)
+            ));
+        }
+
+        return $this;
+    }
+
+    /**
+     * @internal
+     */
+    public function getExpiry(): ?float
+    {
+        return $this->expiry;
+    }
+}

+ 135 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/DoctrineProvider.php

@@ -0,0 +1,135 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Doctrine\Common\Cache\Psr6;
+
+use Doctrine\Common\Cache\Cache;
+use Doctrine\Common\Cache\CacheProvider;
+use Psr\Cache\CacheItemPoolInterface;
+use Symfony\Component\Cache\Adapter\DoctrineAdapter as SymfonyDoctrineAdapter;
+use Symfony\Contracts\Service\ResetInterface;
+
+use function rawurlencode;
+
+/**
+ * This class was copied from the Symfony Framework, see the original copyright
+ * notice above. The code is distributed subject to the license terms in
+ * https://github.com/symfony/symfony/blob/ff0cf61278982539c49e467db9ab13cbd342f76d/LICENSE
+ */
+final class DoctrineProvider extends CacheProvider
+{
+    /** @var CacheItemPoolInterface */
+    private $pool;
+
+    public static function wrap(CacheItemPoolInterface $pool): Cache
+    {
+        if ($pool instanceof CacheAdapter) {
+            return $pool->getCache();
+        }
+
+        if ($pool instanceof SymfonyDoctrineAdapter) {
+            $getCache = function () {
+                // phpcs:ignore Squiz.Scope.StaticThisUsage.Found
+                return $this->provider;
+            };
+
+            return $getCache->bindTo($pool, SymfonyDoctrineAdapter::class)();
+        }
+
+        return new self($pool);
+    }
+
+    private function __construct(CacheItemPoolInterface $pool)
+    {
+        $this->pool = $pool;
+    }
+
+    /** @internal */
+    public function getPool(): CacheItemPoolInterface
+    {
+        return $this->pool;
+    }
+
+    public function reset(): void
+    {
+        if ($this->pool instanceof ResetInterface) {
+            $this->pool->reset();
+        }
+
+        $this->setNamespace($this->getNamespace());
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        $item = $this->pool->getItem(rawurlencode($id));
+
+        return $item->isHit() ? $item->get() : false;
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return bool
+     */
+    protected function doContains($id)
+    {
+        return $this->pool->hasItem(rawurlencode($id));
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return bool
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        $item = $this->pool->getItem(rawurlencode($id));
+
+        if (0 < $lifeTime) {
+            $item->expiresAfter($lifeTime);
+        }
+
+        return $this->pool->save($item->set($data));
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return bool
+     */
+    protected function doDelete($id)
+    {
+        return $this->pool->deleteItem(rawurlencode($id));
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return bool
+     */
+    protected function doFlush()
+    {
+        return $this->pool->clear();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return array|null
+     */
+    protected function doGetStats()
+    {
+        return null;
+    }
+}

+ 13 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/InvalidArgument.php

@@ -0,0 +1,13 @@
+<?php
+
+namespace Doctrine\Common\Cache\Psr6;
+
+use InvalidArgumentException;
+use Psr\Cache\InvalidArgumentException as PsrInvalidArgumentException;
+
+/**
+ * @internal
+ */
+final class InvalidArgument extends InvalidArgumentException implements PsrInvalidArgumentException
+{
+}

+ 99 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/TypedCacheItem.php

@@ -0,0 +1,99 @@
+<?php
+
+namespace Doctrine\Common\Cache\Psr6;
+
+use DateInterval;
+use DateTime;
+use DateTimeInterface;
+use Psr\Cache\CacheItemInterface;
+use TypeError;
+
+use function get_debug_type;
+use function is_int;
+use function microtime;
+use function sprintf;
+
+final class TypedCacheItem implements CacheItemInterface
+{
+    private ?float $expiry = null;
+
+    /**
+     * @internal
+     */
+    public function __construct(
+        private string $key,
+        private mixed $value,
+        private bool $isHit,
+    ) {
+    }
+
+    public function getKey(): string
+    {
+        return $this->key;
+    }
+
+    public function get(): mixed
+    {
+        return $this->value;
+    }
+
+    public function isHit(): bool
+    {
+        return $this->isHit;
+    }
+
+    public function set(mixed $value): static
+    {
+        $this->value = $value;
+
+        return $this;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function expiresAt($expiration): static
+    {
+        if ($expiration === null) {
+            $this->expiry = null;
+        } elseif ($expiration instanceof DateTimeInterface) {
+            $this->expiry = (float) $expiration->format('U.u');
+        } else {
+            throw new TypeError(sprintf(
+                'Expected $expiration to be an instance of DateTimeInterface or null, got %s',
+                get_debug_type($expiration)
+            ));
+        }
+
+        return $this;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function expiresAfter($time): static
+    {
+        if ($time === null) {
+            $this->expiry = null;
+        } elseif ($time instanceof DateInterval) {
+            $this->expiry = microtime(true) + DateTime::createFromFormat('U', 0)->add($time)->format('U.u');
+        } elseif (is_int($time)) {
+            $this->expiry = $time + microtime(true);
+        } else {
+            throw new TypeError(sprintf(
+                'Expected $time to be either an integer, an instance of DateInterval or null, got %s',
+                get_debug_type($time)
+            ));
+        }
+
+        return $this;
+    }
+
+    /**
+     * @internal
+     */
+    public function getExpiry(): ?float
+    {
+        return $this->expiry;
+    }
+}

+ 186 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/RedisCache.php

@@ -0,0 +1,186 @@
+<?php
+
+namespace Doctrine\Common\Cache;
+
+use Redis;
+
+use function array_combine;
+use function array_diff_key;
+use function array_fill_keys;
+use function array_filter;
+use function array_keys;
+use function count;
+use function defined;
+use function extension_loaded;
+use function is_bool;
+
+/**
+ * Redis cache provider.
+ *
+ * @deprecated Deprecated without replacement in doctrine/cache 1.11. This class will be dropped in 2.0
+ *
+ * @link   www.doctrine-project.org
+ */
+class RedisCache extends CacheProvider
+{
+    /** @var Redis|null */
+    private $redis;
+
+    /**
+     * Sets the redis instance to use.
+     *
+     * @return void
+     */
+    public function setRedis(Redis $redis)
+    {
+        $redis->setOption(Redis::OPT_SERIALIZER, $this->getSerializerValue());
+        $this->redis = $redis;
+    }
+
+    /**
+     * Gets the redis instance used by the cache.
+     *
+     * @return Redis|null
+     */
+    public function getRedis()
+    {
+        return $this->redis;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        return $this->redis->get($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetchMultiple(array $keys)
+    {
+        $fetchedItems = array_combine($keys, $this->redis->mget($keys));
+
+        // Redis mget returns false for keys that do not exist. So we need to filter those out unless it's the real data.
+        $keysToFilter = array_keys(array_filter($fetchedItems, static function ($item): bool {
+            return $item === false;
+        }));
+
+        if ($keysToFilter) {
+            $multi = $this->redis->multi(Redis::PIPELINE);
+            foreach ($keysToFilter as $key) {
+                $multi->exists($key);
+            }
+
+            $existItems     = array_filter($multi->exec());
+            $missedItemKeys = array_diff_key($keysToFilter, $existItems);
+            $fetchedItems   = array_diff_key($fetchedItems, array_fill_keys($missedItemKeys, true));
+        }
+
+        return $fetchedItems;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
+    {
+        if ($lifetime) {
+            // Keys have lifetime, use SETEX for each of them
+            $multi = $this->redis->multi(Redis::PIPELINE);
+            foreach ($keysAndValues as $key => $value) {
+                $multi->setex($key, $lifetime, $value);
+            }
+
+            $succeeded = array_filter($multi->exec());
+
+            return count($succeeded) == count($keysAndValues);
+        }
+
+        // No lifetime, use MSET
+        return (bool) $this->redis->mset($keysAndValues);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        $exists = $this->redis->exists($id);
+
+        if (is_bool($exists)) {
+            return $exists;
+        }
+
+        return $exists > 0;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        if ($lifeTime > 0) {
+            return $this->redis->setex($id, $lifeTime, $data);
+        }
+
+        return $this->redis->set($id, $data);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDelete($id)
+    {
+        return $this->redis->del($id) >= 0;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDeleteMultiple(array $keys)
+    {
+        return $this->redis->del($keys) >= 0;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFlush()
+    {
+        return $this->redis->flushDB();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doGetStats()
+    {
+        $info = $this->redis->info();
+
+        return [
+            Cache::STATS_HITS   => $info['keyspace_hits'],
+            Cache::STATS_MISSES => $info['keyspace_misses'],
+            Cache::STATS_UPTIME => $info['uptime_in_seconds'],
+            Cache::STATS_MEMORY_USAGE      => $info['used_memory'],
+            Cache::STATS_MEMORY_AVAILABLE  => false,
+        ];
+    }
+
+    /**
+     * Returns the serializer constant to use. If Redis is compiled with
+     * igbinary support, that is used. Otherwise the default PHP serializer is
+     * used.
+     *
+     * @return int One of the Redis::SERIALIZER_* constants
+     */
+    protected function getSerializerValue()
+    {
+        if (defined('Redis::SERIALIZER_IGBINARY') && extension_loaded('igbinary')) {
+            return Redis::SERIALIZER_IGBINARY;
+        }
+
+        return Redis::SERIALIZER_PHP;
+    }
+}

+ 210 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/SQLite3Cache.php

@@ -0,0 +1,210 @@
+<?php
+
+namespace Doctrine\Common\Cache;
+
+use SQLite3;
+use SQLite3Result;
+
+use function array_search;
+use function implode;
+use function serialize;
+use function sprintf;
+use function time;
+use function unserialize;
+
+use const SQLITE3_ASSOC;
+use const SQLITE3_BLOB;
+use const SQLITE3_TEXT;
+
+/**
+ * SQLite3 cache provider.
+ *
+ * @deprecated Deprecated without replacement in doctrine/cache 1.11. This class will be dropped in 2.0
+ */
+class SQLite3Cache extends CacheProvider
+{
+    /**
+     * The ID field will store the cache key.
+     */
+    public const ID_FIELD = 'k';
+
+    /**
+     * The data field will store the serialized PHP value.
+     */
+    public const DATA_FIELD = 'd';
+
+    /**
+     * The expiration field will store a date value indicating when the
+     * cache entry should expire.
+     */
+    public const EXPIRATION_FIELD = 'e';
+
+    /** @var SQLite3 */
+    private $sqlite;
+
+    /** @var string */
+    private $table;
+
+    /**
+     * Calling the constructor will ensure that the database file and table
+     * exist and will create both if they don't.
+     *
+     * @param string $table
+     */
+    public function __construct(SQLite3 $sqlite, $table)
+    {
+        $this->sqlite = $sqlite;
+        $this->table  = (string) $table;
+
+        $this->ensureTableExists();
+    }
+
+    private function ensureTableExists(): void
+    {
+        $this->sqlite->exec(
+            sprintf(
+                'CREATE TABLE IF NOT EXISTS %s(%s TEXT PRIMARY KEY NOT NULL, %s BLOB, %s INTEGER)',
+                $this->table,
+                static::ID_FIELD,
+                static::DATA_FIELD,
+                static::EXPIRATION_FIELD
+            )
+        );
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        $item = $this->findById($id);
+
+        if (! $item) {
+            return false;
+        }
+
+        return unserialize($item[self::DATA_FIELD]);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        return $this->findById($id, false) !== null;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        $statement = $this->sqlite->prepare(sprintf(
+            'INSERT OR REPLACE INTO %s (%s) VALUES (:id, :data, :expire)',
+            $this->table,
+            implode(',', $this->getFields())
+        ));
+
+        $statement->bindValue(':id', $id);
+        $statement->bindValue(':data', serialize($data), SQLITE3_BLOB);
+        $statement->bindValue(':expire', $lifeTime > 0 ? time() + $lifeTime : null);
+
+        return $statement->execute() instanceof SQLite3Result;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDelete($id)
+    {
+        [$idField] = $this->getFields();
+
+        $statement = $this->sqlite->prepare(sprintf(
+            'DELETE FROM %s WHERE %s = :id',
+            $this->table,
+            $idField
+        ));
+
+        $statement->bindValue(':id', $id);
+
+        return $statement->execute() instanceof SQLite3Result;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFlush()
+    {
+        return $this->sqlite->exec(sprintf('DELETE FROM %s', $this->table));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doGetStats()
+    {
+        // no-op.
+    }
+
+    /**
+     * Find a single row by ID.
+     *
+     * @param mixed $id
+     *
+     * @return mixed[]|null
+     */
+    private function findById($id, bool $includeData = true): ?array
+    {
+        [$idField] = $fields = $this->getFields();
+
+        if (! $includeData) {
+            $key = array_search(static::DATA_FIELD, $fields);
+            unset($fields[$key]);
+        }
+
+        $statement = $this->sqlite->prepare(sprintf(
+            'SELECT %s FROM %s WHERE %s = :id LIMIT 1',
+            implode(',', $fields),
+            $this->table,
+            $idField
+        ));
+
+        $statement->bindValue(':id', $id, SQLITE3_TEXT);
+
+        $item = $statement->execute()->fetchArray(SQLITE3_ASSOC);
+
+        if ($item === false) {
+            return null;
+        }
+
+        if ($this->isExpired($item)) {
+            $this->doDelete($id);
+
+            return null;
+        }
+
+        return $item;
+    }
+
+    /**
+     * Gets an array of the fields in our table.
+     *
+     * @psalm-return array{string, string, string}
+     */
+    private function getFields(): array
+    {
+        return [static::ID_FIELD, static::DATA_FIELD, static::EXPIRATION_FIELD];
+    }
+
+    /**
+     * Check if the item is expired.
+     *
+     * @param mixed[] $item
+     */
+    private function isExpired(array $item): bool
+    {
+        return isset($item[static::EXPIRATION_FIELD]) &&
+            $item[self::EXPIRATION_FIELD] !== null &&
+            $item[self::EXPIRATION_FIELD] < time();
+    }
+}

+ 11 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/Version.php

@@ -0,0 +1,11 @@
+<?php
+
+namespace Doctrine\Common\Cache;
+
+/**
+ * @deprecated Deprecated without replacement in doctrine/cache 1.11. This class will be dropped in 2.0
+ */
+class Version
+{
+    public const VERSION = '1.9.0-DEV';
+}

+ 61 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/VoidCache.php

@@ -0,0 +1,61 @@
+<?php
+
+namespace Doctrine\Common\Cache;
+
+/**
+ * Void cache driver. The cache could be of use in tests where you don`t need to cache anything.
+ *
+ * @deprecated Deprecated without replacement in doctrine/cache 1.11. This class will be dropped in 2.0
+ *
+ * @link   www.doctrine-project.org
+ */
+class VoidCache extends CacheProvider
+{
+    /**
+     * {@inheritDoc}
+     */
+    protected function doFetch($id)
+    {
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function doContains($id)
+    {
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function doDelete($id)
+    {
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function doFlush()
+    {
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function doGetStats()
+    {
+        return;
+    }
+}

+ 108 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/WinCacheCache.php

@@ -0,0 +1,108 @@
+<?php
+
+namespace Doctrine\Common\Cache;
+
+use function count;
+use function is_array;
+use function wincache_ucache_clear;
+use function wincache_ucache_delete;
+use function wincache_ucache_exists;
+use function wincache_ucache_get;
+use function wincache_ucache_info;
+use function wincache_ucache_meminfo;
+use function wincache_ucache_set;
+
+/**
+ * WinCache cache provider.
+ *
+ * @deprecated Deprecated without replacement in doctrine/cache 1.11. This class will be dropped in 2.0
+ *
+ * @link   www.doctrine-project.org
+ */
+class WinCacheCache extends CacheProvider
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        return wincache_ucache_get($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        return wincache_ucache_exists($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        return wincache_ucache_set($id, $data, $lifeTime);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDelete($id)
+    {
+        return wincache_ucache_delete($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFlush()
+    {
+        return wincache_ucache_clear();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetchMultiple(array $keys)
+    {
+        return wincache_ucache_get($keys);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
+    {
+        $result = wincache_ucache_set($keysAndValues, null, $lifetime);
+
+        return empty($result);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDeleteMultiple(array $keys)
+    {
+        $result = wincache_ucache_delete($keys);
+
+        return is_array($result) && count($result) !== count($keys);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doGetStats()
+    {
+        $info    = wincache_ucache_info();
+        $meminfo = wincache_ucache_meminfo();
+
+        return [
+            Cache::STATS_HITS             => $info['total_hit_count'],
+            Cache::STATS_MISSES           => $info['total_miss_count'],
+            Cache::STATS_UPTIME           => $info['total_cache_uptime'],
+            Cache::STATS_MEMORY_USAGE     => $meminfo['memory_total'],
+            Cache::STATS_MEMORY_AVAILABLE => $meminfo['memory_free'],
+        ];
+    }
+}

+ 106 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/XcacheCache.php

@@ -0,0 +1,106 @@
+<?php
+
+namespace Doctrine\Common\Cache;
+
+use BadMethodCallException;
+
+use function ini_get;
+use function serialize;
+use function unserialize;
+use function xcache_clear_cache;
+use function xcache_get;
+use function xcache_info;
+use function xcache_isset;
+use function xcache_set;
+use function xcache_unset;
+
+use const XC_TYPE_VAR;
+
+/**
+ * Xcache cache driver.
+ *
+ * @deprecated
+ *
+ * @link   www.doctrine-project.org
+ */
+class XcacheCache extends CacheProvider
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        return $this->doContains($id) ? unserialize(xcache_get($id)) : false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        return xcache_isset($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        return xcache_set($id, serialize($data), (int) $lifeTime);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDelete($id)
+    {
+        return xcache_unset($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFlush()
+    {
+        $this->checkAuthorization();
+
+        xcache_clear_cache(XC_TYPE_VAR);
+
+        return true;
+    }
+
+    /**
+     * Checks that xcache.admin.enable_auth is Off.
+     *
+     * @return void
+     *
+     * @throws BadMethodCallException When xcache.admin.enable_auth is On.
+     */
+    protected function checkAuthorization()
+    {
+        if (ini_get('xcache.admin.enable_auth')) {
+            throw new BadMethodCallException(
+                'To use all features of \Doctrine\Common\Cache\XcacheCache, '
+                . 'you must set "xcache.admin.enable_auth" to "Off" in your php.ini.'
+            );
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doGetStats()
+    {
+        $this->checkAuthorization();
+
+        $info = xcache_info(XC_TYPE_VAR, 0);
+
+        return [
+            Cache::STATS_HITS   => $info['hits'],
+            Cache::STATS_MISSES => $info['misses'],
+            Cache::STATS_UPTIME => null,
+            Cache::STATS_MEMORY_USAGE      => $info['size'],
+            Cache::STATS_MEMORY_AVAILABLE  => $info['avail'],
+        ];
+    }
+}

+ 71 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/ZendDataCache.php

@@ -0,0 +1,71 @@
+<?php
+
+namespace Doctrine\Common\Cache;
+
+use function zend_shm_cache_clear;
+use function zend_shm_cache_delete;
+use function zend_shm_cache_fetch;
+use function zend_shm_cache_store;
+
+/**
+ * Zend Data Cache cache driver.
+ *
+ * @deprecated Deprecated without replacement in doctrine/cache 1.11. This class will be dropped in 2.0
+ *
+ * @link   www.doctrine-project.org
+ */
+class ZendDataCache extends CacheProvider
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        return zend_shm_cache_fetch($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        return zend_shm_cache_fetch($id) !== false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        return zend_shm_cache_store($id, $data, $lifeTime);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDelete($id)
+    {
+        return zend_shm_cache_delete($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFlush()
+    {
+        $namespace = $this->getNamespace();
+        if (empty($namespace)) {
+            return zend_shm_cache_clear();
+        }
+
+        return zend_shm_cache_clear($namespace);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doGetStats()
+    {
+        return null;
+    }
+}

+ 8 - 0
vendor/hanson/foundation-sdk/.gitignore

@@ -0,0 +1,8 @@
+composer.phar
+/vendor/
+/.idea/
+composer.lock
+
+# Commit your application's lock file http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file
+# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
+# composer.lock

+ 21 - 0
vendor/hanson/foundation-sdk/LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017 HanSon
+
+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.

+ 25 - 0
vendor/hanson/foundation-sdk/README.md

@@ -0,0 +1,25 @@
+# foundation-sdk
+To create a sdk easiler!
+
+[![Latest Stable Version](https://poser.pugx.org/hanson/foundation-sdk/v/stable)](https://packagist.org/packages/hanson/foundation-sdk)
+[![Total Downloads](https://poser.pugx.org/hanson/foundation-sdk/downloads)](https://packagist.org/packages/hanson/foundation-sdk)
+[![Latest Unstable Version](https://poser.pugx.org/hanson/foundation-sdk/v/unstable)](https://packagist.org/packages/hanson/foundation-sdk)
+[![License](https://poser.pugx.org/hanson/foundation-sdk/license)](https://packagist.org/packages/hanson/foundation-sdk)
+[![Monthly Downloads](https://poser.pugx.org/hanson/foundation-sdk/d/monthly)](https://packagist.org/packages/hanson/foundation-sdk)
+[![Daily Downloads](https://poser.pugx.org/hanson/foundation-sdk/d/daily)](https://packagist.org/packages/hanson/foundation-sdk)
+
+## What's inside Foundation-sdk
+
+- [pimple](https://github.com/silexphp/Pimple) (Container)
+- Http
+- Log
+
+## 安装要求
+
+php 7 以上(需要PHP5的可移步到其他人维护的仓库 https://github.com/CodeNauhc/foundation-sdk/tree/php5)
+
+## 中文实例教程
+
+[SDK 开发高级版!揭开 Foundation-SDK 的神秘面纱](https://learnku.com/articles/15038/sdk-development-advanced-edition-uncover-the-mysterious-veil-of-foundation-sdk)
+
+[干货!手把手教你写 SDK !](https://learnku.com/articles/14995/dried-food-hand-in-hand-to-teach-you-to-write-sdk)

+ 27 - 0
vendor/hanson/foundation-sdk/composer.json

@@ -0,0 +1,27 @@
+{
+    "name": "hanson/foundation-sdk",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "HanSon",
+            "email": "h@hanc.cc"
+        }
+    ],
+    "require": {
+        "php": "^7.0|^8.0",
+        "pimple/pimple": "^3.0",
+        "doctrine/cache": "^1.6",
+        "symfony/http-foundation": "^3.3|^4.0|^5.0|^6.0",
+        "guzzlehttp/guzzle": "^6.2|^7.0",
+        "monolog/monolog": "^1.22|^2.0|^3.0",
+        "ext-curl": "*"
+    },
+    "autoload": {
+        "psr-4": {
+            "Hanson\\Foundation\\": "src/"
+        }
+    },
+    "require-dev": {
+        "phpunit/phpunit": "^9.3"
+    }
+}

+ 61 - 0
vendor/hanson/foundation-sdk/src/AbstractAPI.php

@@ -0,0 +1,61 @@
+<?php
+
+namespace Hanson\Foundation;
+
+use Psr\Http\Message\RequestInterface;
+
+abstract class AbstractAPI
+{
+
+    /**
+     * Http instance.
+     *
+     * @var Http
+     */
+    protected $http;
+
+    /**
+     * @return Http
+     */
+    public function getHttp()
+    {
+        if (is_null($this->http)) {
+            $this->http = new Http();
+        }
+
+        if (count($this->http->getMiddlewares()) === 0) {
+            $this->middlewares();
+        }
+
+        return $this->http;
+    }
+
+    /**
+     * add headers.
+     *
+     * @param $headers
+     *
+     * @return \Closure
+     */
+    protected function headerMiddleware($headers)
+    {
+        return function (callable $handler) use ($headers) {
+            return function (RequestInterface $request, array $options) use ($handler, $headers) {
+                foreach ($headers as $key => $header) {
+                    $request = $request->withHeader($key, $header);
+                }
+
+                return $handler($request, $options);
+            };
+        };
+    }
+
+    /**
+     * Push guzzle middleware before request.
+     *
+     * @return mixed
+     */
+    public function middlewares()
+    {
+    }
+}

+ 237 - 0
vendor/hanson/foundation-sdk/src/AbstractAccessToken.php

@@ -0,0 +1,237 @@
+<?php
+
+namespace Hanson\Foundation;
+
+use Doctrine\Common\Cache\Cache;
+use Doctrine\Common\Cache\FilesystemCache;
+
+abstract class AbstractAccessToken
+{
+    /**
+     * App id.
+     *
+     * @var string
+     */
+    protected $appId;
+
+    /**
+     * App secret.
+     *
+     * @var string
+     */
+    protected $secret;
+
+    /**
+     * Cache key.
+     *
+     * @var string
+     */
+    protected $cacheKey;
+
+    /**
+     * Cache.
+     *
+     * @var Cache
+     */
+    protected $cache;
+
+    /**
+     * Cache key prefix.
+     *
+     * @var string
+     */
+    protected $prefix;
+
+    /**
+     * Response Json key name of token.
+     *
+     * @var string
+     */
+    protected $tokenJsonKey;
+
+    /**
+     * Response Json key name of expires in.
+     *
+     * @var string
+     */
+    protected $expiresJsonKey;
+
+    /**
+     * @var Http
+     */
+    protected $http;
+
+    /**
+     * @var Foundation
+     */
+    protected $app;
+
+    /**
+     * Token string.
+     *
+     * @var string
+     */
+    protected $token;
+
+    /**
+     * AbstractAccessToken constructor.
+     * @param  Foundation  $app
+     */
+    public function __construct(Foundation $app)
+    {
+        $this->app = $app;
+    }
+
+    /**
+     * @param  mixed  $token
+     * @param  int  $expires
+     * @return $this
+     */
+    public function setToken($token, $expires = 86400)
+    {
+        if ($expires) {
+            $this->getCache()->save($this->getCacheKey(), $token, $expires);
+        }
+
+        $this->token = $token;
+
+        return $this;
+    }
+
+    /**
+     * Get token from cache.
+     *
+     * @param  bool  $forceRefresh
+     *
+     * @return string
+     */
+    public function getToken($forceRefresh = false)
+    {
+        $cached = $this->getCache()->fetch($this->getCacheKey()) ?: $this->token;
+
+        if ($forceRefresh || empty($cached)) {
+
+            $result = $this->getTokenFromServer();
+
+            $this->checkTokenResponse($result);
+
+            $this->setToken(
+                $token = $result[$this->tokenJsonKey],
+                $this->expiresJsonKey ? $result[$this->expiresJsonKey] : null
+            );
+
+            return $token;
+        }
+
+        return $cached;
+    }
+
+    /**
+     * Get token from remote server.
+     *
+     * @return mixed
+     */
+    abstract public function getTokenFromServer();
+
+    /**
+     * Throw exception if token is invalid.
+     *
+     * @param $result
+     * @return mixed
+     */
+    abstract public function checkTokenResponse($result);
+
+    /**
+     * @param  mixed  $appId
+     */
+    public function setAppId($appId)
+    {
+        $this->appId = $appId;
+    }
+
+    /**
+     * @return mixed
+     */
+    public function getAppId()
+    {
+        return $this->appId;
+    }
+
+    /**
+     * @param  string  $secret
+     */
+    public function setSecret($secret)
+    {
+        $this->secret = $secret;
+    }
+
+    /**
+     * @return mixed
+     */
+    public function getSecret()
+    {
+        return $this->secret;
+    }
+
+    /**
+     * Set cache instance.
+     *
+     * @param  \Doctrine\Common\Cache\Cache  $cache
+     *
+     * @return AbstractAccessToken
+     */
+    public function setCache(Cache $cache)
+    {
+        $this->cache = $cache;
+
+        return $this;
+    }
+
+    /**
+     * Return the cache manager.
+     *
+     * @return \Doctrine\Common\Cache\Cache
+     */
+    public function getCache()
+    {
+        return $this->cache ?: $this->cache = new FilesystemCache(sys_get_temp_dir());
+    }
+
+    /**
+     * Return the cache key mix with appId.
+     *
+     * @return string
+     */
+    public function getCacheKey()
+    {
+        if (is_null($this->cacheKey)) {
+            return $this->prefix.$this->appId;
+        }
+
+        return $this->cacheKey;
+    }
+
+    /**
+     * Return the http instance.
+     *
+     * @return Http
+     */
+    public function getHttp()
+    {
+        return $this->http ?? $this->app->http;
+    }
+
+    /**
+     * Set the http instance.
+     *
+     * @param  Http  $http
+     *
+     * @return $this
+     */
+    public function setHttp($http)
+    {
+        $this->http = $http;
+
+        return $this;
+    }
+}

+ 11 - 0
vendor/hanson/foundation-sdk/src/Exception/HttpException.php

@@ -0,0 +1,11 @@
+<?php
+
+
+namespace Hanson\Foundation\Exception;
+
+use Exception;
+
+class HttpException extends Exception
+{
+
+}

+ 147 - 0
vendor/hanson/foundation-sdk/src/Foundation.php

@@ -0,0 +1,147 @@
+<?php
+
+
+namespace Hanson\Foundation;
+
+
+use Doctrine\Common\Cache\Cache;
+use Doctrine\Common\Cache\FilesystemCache;
+use Monolog\Handler\HandlerInterface;
+use Monolog\Handler\NullHandler;
+use Monolog\Handler\StreamHandler;
+use Monolog\Logger;
+use Pimple\Container;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Class Foundation
+ * @property-read Http $http
+ * @package Hanson\Foundation
+ */
+class Foundation extends Container
+{
+
+    /**
+     * an array of service providers.
+     *
+     * @var
+     */
+    protected $providers = [];
+
+    protected $config;
+
+    public function __construct($config)
+    {
+        parent::__construct();
+
+        $this->setConfig($config);
+
+        if ($this->config['debug'] ?? false) {
+            error_reporting(E_ALL);
+        }
+
+        $this->registerBase();
+        $this->registerProviders();
+        $this->initializeLogger();
+    }
+
+    /**
+     * Register basic providers.
+     */
+    private function registerBase()
+    {
+        $this['request'] = function () {
+            return Request::createFromGlobals();
+        };
+
+        $this['http'] = function () {
+            return new Http();
+        };
+
+        if ($cache = $this->getConfig()['cache'] ?? null and $cache instanceof Cache) {
+            $this['cache'] = $this->getConfig()['cache'];
+        } else {
+            $this['cache'] = function () {
+                return new FilesystemCache(sys_get_temp_dir());
+            };
+        }
+    }
+
+    /**
+     * Initialize logger.
+     */
+    private function initializeLogger()
+    {
+        if (Log::hasLogger()) {
+            return;
+        }
+
+        $logger = new Logger($this->getConfig()['log']['name'] ?? 'foundation');
+
+        if (!$this->getConfig()['debug'] ?? false || defined('PHPUNIT_RUNNING')) {
+            $logger->pushHandler(new NullHandler());
+        } elseif (($this->getConfig()['log']['handler'] ?? null) instanceof HandlerInterface) {
+            $logger->pushHandler($this->getConfig()['log']['handler']);
+        } elseif ($logFile = $this->getConfig()['log']['file'] ?? null) {
+            $logger->pushHandler(new StreamHandler(
+                $logFile,
+                $this->getConfig()['log']['level'] ?? Logger::WARNING,
+                true,
+                $this->getConfig()['log']['permission'] ?? null
+            ));
+        }
+
+        Log::setLogger($logger);
+    }
+
+    /**
+     * Register providers.
+     */
+    protected function registerProviders()
+    {
+        foreach ($this->providers as $provider) {
+            $this->register(new $provider());
+        }
+    }
+
+    public function setConfig(array $config)
+    {
+        $this->config = $config;
+    }
+
+    public function getConfig($key = null)
+    {
+        return $key ? ($this->config[$key] ?? null) : $this->config;
+    }
+
+    /**
+     * Magic get access.
+     *
+     * @param  string  $id
+     *
+     * @return mixed
+     */
+    public function __get($id)
+    {
+        return $this->offsetGet($id);
+    }
+
+    /**
+     * Magic set access.
+     *
+     * @param  string  $id
+     * @param  mixed  $value
+     */
+    public function __set($id, $value)
+    {
+        $this->offsetSet($id, $value);
+    }
+
+    public function rebind(string $id, $value)
+    {
+        $this->offsetUnset($id);
+        $this->offsetSet($id, $value);
+
+        return $this;
+    }
+}

+ 300 - 0
vendor/hanson/foundation-sdk/src/Http.php

@@ -0,0 +1,300 @@
+<?php
+
+namespace Hanson\Foundation;
+
+use GuzzleHttp\Client as HttpClient;
+use GuzzleHttp\HandlerStack;
+use Hanson\Foundation\Exception\HttpException;
+use Psr\Http\Message\ResponseInterface;
+
+/**
+ * Class Http.
+ */
+class Http
+{
+    /**
+     * Used to identify handler defined by client code
+     * Maybe useful in the future.
+     */
+    const USER_DEFINED_HANDLER = 'userDefined';
+
+    /**
+     * Http client.
+     *
+     * @var HttpClient
+     */
+    protected $client;
+
+    /**
+     * The middlewares.
+     *
+     * @var array
+     */
+    protected $middlewares = [];
+
+    protected $stack;
+
+    /**
+     * Guzzle client default settings.
+     *
+     * @var array
+     */
+    protected static $defaults = [
+        'curl' => [
+            CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4,
+        ],
+    ];
+
+    /**
+     * Set guzzle default settings.
+     *
+     * @param  array  $defaults
+     */
+    public static function setDefaultOptions($defaults = [])
+    {
+        self::$defaults = $defaults;
+    }
+
+    /**
+     * Return current guzzle default settings.
+     *
+     * @return array
+     */
+    public static function getDefaultOptions()
+    {
+        return self::$defaults;
+    }
+
+    /**
+     * GET request.
+     *
+     * @param  string  $url
+     * @param  array  $options
+     *
+     * @return ResponseInterface
+     *
+     * @throws HttpException
+     */
+    public function get($url, array $options = [])
+    {
+        return $this->request('GET', $url, ['query' => $options]);
+    }
+
+    /**
+     * POST request.
+     *
+     * @param  string  $url
+     * @param  array  $form
+     *
+     * @return ResponseInterface
+     */
+    public function post($url, array $form = [])
+    {
+        return $this->request('POST', $url, ['form_params' => $form]);
+    }
+
+    /**
+     * JSON request.
+     *
+     * @param  string  $url
+     * @param        $query
+     *
+     * @return ResponseInterface
+     */
+    public function json($url, $query = [])
+    {
+        return $this->request('POST', $url, ['json' => $query]);
+    }
+
+    /**
+     * Upload file.
+     *
+     * @param  string  $url
+     * @param  array  $files
+     * @param  array  $form
+     * @param  array  $queries
+     *
+     * @return ResponseInterface
+     */
+    public function upload($url, array $queries = [], array $files = [], array $form = [])
+    {
+        $multipart = [];
+
+        foreach ($files as $name => $path) {
+            if (is_array($path)) {
+                foreach ($path as $item) {
+                    $multipart[] = [
+                            'name' => $name.'[]',
+                        ] + $this->fileToMultipart($item);
+                }
+            } else {
+                $multipart[] = [
+                        'name' => $name,
+                    ] + $this->fileToMultipart($path);
+            }
+        }
+
+        foreach ($form as $name => $contents) {
+            $multipart = array_merge($multipart, $this->normalizeMultipartField($name, $contents));
+        }
+
+        return $this->request('POST', $url, ['query' => $queries, 'multipart' => $multipart]);
+    }
+
+    /**
+     * @param  string  $name
+     * @param  mixed  $contents
+     *
+     * @return array
+     */
+    public function normalizeMultipartField(string $name, $contents)
+    {
+        $field = [];
+        if (!is_array($contents)) {
+            return [compact('name', 'contents')];
+        } else {
+            foreach ($contents as $key => $value) {
+                $key = sprintf('%s[%s]', $name, $key);
+                $field = array_merge($field, is_array($value) ? $this->normalizeMultipartField($key, $value) : [
+                    [
+                        'name' => $key, 'contents' => $value
+                    ]
+                ]);
+            }
+        }
+        return $field;
+    }
+
+    private function fileToMultipart($file)
+    {
+        if (is_array($file)) {
+            return $file;
+        } elseif (@file_exists($file)) {
+            return ['contents' => fopen($file, 'r')];
+        } elseif (filter_var($file, FILTER_VALIDATE_URL)) {
+            return ['contents' => file_get_contents($file)];
+        } else {
+            return ['contents' => $file];
+        }
+    }
+
+    /**
+     * Set GuzzleHttp\Client.
+     *
+     * @param  \GuzzleHttp\Client  $client
+     *
+     * @return Http
+     */
+    public function setClient(HttpClient $client)
+    {
+        $this->client = $client;
+
+        return $this;
+    }
+
+    /**
+     * Return GuzzleHttp\Client instance.
+     *
+     * @return \GuzzleHttp\Client
+     */
+    public function getClient()
+    {
+        if (!($this->client instanceof HttpClient)) {
+            $this->client = new HttpClient();
+        }
+
+        return $this->client;
+    }
+
+    /**
+     * Add a middleware.
+     *
+     * @param  callable  $middleware
+     *
+     * @return $this
+     */
+    public function addMiddleware(callable $middleware)
+    {
+        array_push($this->middlewares, $middleware);
+
+        return $this;
+    }
+
+    /**
+     * Return all middlewares.
+     *
+     * @return array
+     */
+    public function getMiddlewares()
+    {
+        return $this->middlewares;
+    }
+
+    /**
+     * Make a request.
+     *
+     * @param  string  $url
+     * @param  string  $method
+     * @param  array  $options
+     *
+     * @return ResponseInterface
+     */
+    public function request($method, $url, $options = [])
+    {
+        $method = strtoupper($method);
+
+        $options = array_merge(self::$defaults, $options);
+
+        Log::debug('Client Request:', compact('url', 'method', 'options'));
+
+        $options['handler'] = $this->getHandler();
+
+        $response = $this->getClient()->request($method, $url, $options);
+
+        Log::debug('API response:', [
+            'Status' => $response->getStatusCode(),
+            'Reason' => $response->getReasonPhrase(),
+            'Headers' => $response->getHeaders(),
+            'Body' => strval($response->getBody()),
+        ]);
+
+        return $response;
+    }
+
+    /**
+     * Build a handler.
+     *
+     * @return HandlerStack
+     */
+    public function getHandler()
+    {
+        if ($this->stack) {
+            return $this->stack;
+        }
+
+        $stack = HandlerStack::create();
+
+        foreach ($this->middlewares as $middleware) {
+            $stack->push($middleware);
+        }
+
+        if (isset(static::$defaults['handler']) && is_callable(static::$defaults['handler'])) {
+            $stack->push(static::$defaults['handler'], self::USER_DEFINED_HANDLER);
+        }
+
+        $this->stack = $stack;
+
+        return $stack;
+    }
+
+    public function addHandler($guzzleHandler)
+    {
+        $stack = $this->getHandler();
+
+        $stack->setHandler(is_string($guzzleHandler) ? new $guzzleHandler() : $guzzleHandler);
+
+        $this->stack = $stack;
+
+        return $this;
+    }
+}

+ 104 - 0
vendor/hanson/foundation-sdk/src/Log.php

@@ -0,0 +1,104 @@
+<?php
+
+namespace Hanson\Foundation;
+
+use Monolog\Handler\ErrorLogHandler;
+use Monolog\Handler\NullHandler;
+use Monolog\Logger;
+use Psr\Log\LoggerInterface;
+
+/**
+ * Class Log.
+ *
+ * @method static debug($message, $context = null)
+ * @method static info($message, $context = null)
+ * @method static notice($message, $context = null)
+ * @method static warning($message, $context = null)
+ * @method static error($message, $context = null)
+ * @method static critical($message, $context = null)
+ * @method static alert($message, $context = null)
+ * @method static emergency($message, $context = null)
+ */
+class Log
+{
+    /**
+     * Logger instance.
+     *
+     * @var \Psr\Log\LoggerInterface
+     */
+    protected static $logger;
+
+    /**
+     * Return the logger instance.
+     *
+     * @return \Psr\Log\LoggerInterface
+     */
+    public static function getLogger()
+    {
+        return self::$logger ?: self::$logger = self::createDefaultLogger();
+    }
+
+    /**
+     * Set logger.
+     *
+     * @param \Psr\Log\LoggerInterface $logger
+     */
+    public static function setLogger(LoggerInterface $logger)
+    {
+        self::$logger = $logger;
+    }
+
+    /**
+     * Tests if logger exists.
+     *
+     * @return bool
+     */
+    public static function hasLogger()
+    {
+        return self::$logger ? true : false;
+    }
+
+    /**
+     * Forward call.
+     *
+     * @param string $method
+     * @param array  $args
+     *
+     * @return mixed
+     */
+    public static function __callStatic($method, $args)
+    {
+        return forward_static_call_array([self::getLogger(), $method], $args);
+    }
+
+    /**
+     * Forward call.
+     *
+     * @param string $method
+     * @param array  $args
+     *
+     * @return mixed
+     */
+    public function __call($method, $args)
+    {
+        return call_user_func_array([self::getLogger(), $method], $args);
+    }
+
+    /**
+     * Make a default log instance.
+     *
+     * @return \Monolog\Logger
+     */
+    private static function createDefaultLogger()
+    {
+        $log = new Logger('Foundation');
+
+        if (defined('PHPUNIT_RUNNING') || php_sapi_name() === 'cli') {
+            $log->pushHandler(new NullHandler());
+        } else {
+            $log->pushHandler(new ErrorLogHandler());
+        }
+
+        return $log;
+    }
+}

+ 19 - 0
vendor/hanson/foundation-sdk/tests/HttpTest.php

@@ -0,0 +1,19 @@
+<?php
+
+namespace Hanson\Foundation;
+
+use GuzzleHttp\Handler\MockHandler;
+use PHPUnit\Framework\TestCase;
+
+class HttpTest extends TestCase
+{
+    public function testAddHandler()
+    {
+        $http = new Http();
+
+        $stack = $http->addHandler(new MockHandler());
+
+        var_dump($stack);
+    }
+}
+

+ 47 - 0
vendor/pimple/pimple/.github/workflows/tests.yml

@@ -0,0 +1,47 @@
+name: "Tests"
+
+on:
+  - pull_request
+  - push
+
+jobs:
+  test:
+    name: PHP ${{ matrix.php }} - ${{ matrix.dependencies }}
+    runs-on: ubuntu-latest
+    strategy:
+      fail-fast: false
+      matrix:
+        php:
+          - "7.2"
+          - "7.3"
+          - "7.4"
+          - "8.0"
+          - "8.1"
+        dependencies:
+          - "psr/container:^1.1"
+          - "psr/container:^2.0"
+
+    steps:
+      - name: Checkout Code
+        uses: actions/checkout@v2
+
+      - name: Setup PHP ${{ matrix.php }}
+        uses: shivammathur/setup-php@v2
+        with:
+          php-version: ${{ matrix.php }}
+          ini-values: display_errors=off, log_errors=on
+          extensions: :xdebug
+        env:
+          # https://github.com/shivammathur/setup-php/issues/407#issuecomment-773675741
+          fail-fast: true
+
+      - name: Validate composer.json
+        run: composer validate --strict --no-check-lock
+
+      - name: Install dependencies +${{ matrix.dependencies }}
+        run: |
+          composer require --no-update ${{ matrix.dependencies }}
+          composer update --prefer-dist --no-progress
+
+      - name: Run PHPUnit tests
+        run: vendor/bin/simple-phpunit --verbose

+ 4 - 0
vendor/pimple/pimple/.gitignore

@@ -0,0 +1,4 @@
+phpunit.xml
+.phpunit.result.cache
+composer.lock
+/vendor/

+ 20 - 0
vendor/pimple/pimple/.php_cs.dist

@@ -0,0 +1,20 @@
+<?php
+
+return PhpCsFixer\Config::create()
+    ->setRules([
+        '@Symfony' => true,
+        '@Symfony:risky' => true,
+        '@PHPUnit75Migration:risky' => true,
+        'php_unit_dedicate_assert' => true,
+        'array_syntax' => ['syntax' => 'short'],
+        'php_unit_fqcn_annotation' => true,
+        'no_unreachable_default_argument_value' => false,
+        'braces' => ['allow_single_line_closure' => true],
+        'heredoc_to_nowdoc' => false,
+        'ordered_imports' => true,
+        'phpdoc_types_order' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'],
+        'native_function_invocation' => ['include' => ['@compiler_optimized'], 'scope' => 'all'],
+    ])
+    ->setRiskyAllowed(true)
+    ->setFinder(PhpCsFixer\Finder::create()->in(__DIR__.'/src'))
+;

+ 72 - 0
vendor/pimple/pimple/CHANGELOG

@@ -0,0 +1,72 @@
+* 3.4.0 (2021-03-06)
+
+ * Implement version 1.1 of PSR-11
+
+* 3.3.1 (2020-11-24)
+
+ * Add support for PHP 8
+
+* 3.3.0 (2020-03-03)
+
+ * Drop PHP extension
+ * Bump min PHP version to 7.2.5
+
+* 3.2.3 (2018-01-21)
+
+ * prefixed all function calls with \ for extra speed
+
+* 3.2.2 (2017-07-23)
+
+ * reverted extending a protected closure throws an exception (deprecated it instead)
+
+* 3.2.1 (2017-07-17)
+
+ * fixed PHP error
+
+* 3.2.0 (2017-07-17)
+
+ * added a PSR-11 service locator
+ * added a PSR-11 wrapper
+ * added ServiceIterator
+ * fixed extending a protected closure (now throws InvalidServiceIdentifierException)
+
+* 3.1.0 (2017-07-03)
+
+ * deprecated the C extension
+ * added support for PSR-11 exceptions
+
+* 3.0.2 (2015-09-11)
+
+ * refactored the C extension
+ * minor non-significant changes
+
+* 3.0.1 (2015-07-30)
+
+ * simplified some code
+ * fixed a segfault in the C extension
+
+* 3.0.0 (2014-07-24)
+
+ * removed the Pimple class alias (use Pimple\Container instead)
+
+* 2.1.1 (2014-07-24)
+
+ * fixed compiler warnings for the C extension
+ * fixed code when dealing with circular references
+
+* 2.1.0 (2014-06-24)
+
+ * moved the Pimple to Pimple\Container (with a BC layer -- Pimple is now a
+   deprecated alias which will be removed in Pimple 3.0)
+ * added Pimple\ServiceProviderInterface (and Pimple::register())
+
+* 2.0.0 (2014-02-10)
+
+ * changed extend to automatically re-assign the extended service and keep it as shared or factory
+   (to keep BC, extend still returns the extended service)
+ * changed services to be shared by default (use factory() for factory
+   services)
+
+* 1.0.0
+
+ * initial version

+ 19 - 0
vendor/pimple/pimple/LICENSE

@@ -0,0 +1,19 @@
+Copyright (c) 2009-2020 Fabien Potencier
+
+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.

+ 332 - 0
vendor/pimple/pimple/README.rst

@@ -0,0 +1,332 @@
+Pimple
+======
+
+.. caution::
+
+    Pimple is now closed for changes. No new features will be added and no
+    cosmetic changes will be accepted either. The only accepted changes are
+    compatibility with newer PHP versions and security issue fixes.
+
+.. caution::
+
+    This is the documentation for Pimple 3.x. If you are using Pimple 1.x, read
+    the `Pimple 1.x documentation`_. Reading the Pimple 1.x code is also a good
+    way to learn more about how to create a simple Dependency Injection
+    Container (recent versions of Pimple are more focused on performance).
+
+Pimple is a small Dependency Injection Container for PHP.
+
+Installation
+------------
+
+Before using Pimple in your project, add it to your ``composer.json`` file:
+
+.. code-block:: bash
+
+    $ ./composer.phar require pimple/pimple "^3.0"
+
+Usage
+-----
+
+Creating a container is a matter of creating a ``Container`` instance:
+
+.. code-block:: php
+
+    use Pimple\Container;
+
+    $container = new Container();
+
+As many other dependency injection containers, Pimple manages two different
+kind of data: **services** and **parameters**.
+
+Defining Services
+~~~~~~~~~~~~~~~~~
+
+A service is an object that does something as part of a larger system. Examples
+of services: a database connection, a templating engine, or a mailer. Almost
+any **global** object can be a service.
+
+Services are defined by **anonymous functions** that return an instance of an
+object:
+
+.. code-block:: php
+
+    // define some services
+    $container['session_storage'] = function ($c) {
+        return new SessionStorage('SESSION_ID');
+    };
+
+    $container['session'] = function ($c) {
+        return new Session($c['session_storage']);
+    };
+
+Notice that the anonymous function has access to the current container
+instance, allowing references to other services or parameters.
+
+As objects are only created when you get them, the order of the definitions
+does not matter.
+
+Using the defined services is also very easy:
+
+.. code-block:: php
+
+    // get the session object
+    $session = $container['session'];
+
+    // the above call is roughly equivalent to the following code:
+    // $storage = new SessionStorage('SESSION_ID');
+    // $session = new Session($storage);
+
+Defining Factory Services
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+By default, each time you get a service, Pimple returns the **same instance**
+of it. If you want a different instance to be returned for all calls, wrap your
+anonymous function with the ``factory()`` method
+
+.. code-block:: php
+
+    $container['session'] = $container->factory(function ($c) {
+        return new Session($c['session_storage']);
+    });
+
+Now, each call to ``$container['session']`` returns a new instance of the
+session.
+
+Defining Parameters
+~~~~~~~~~~~~~~~~~~~
+
+Defining a parameter allows to ease the configuration of your container from
+the outside and to store global values:
+
+.. code-block:: php
+
+    // define some parameters
+    $container['cookie_name'] = 'SESSION_ID';
+    $container['session_storage_class'] = 'SessionStorage';
+
+If you change the ``session_storage`` service definition like below:
+
+.. code-block:: php
+
+    $container['session_storage'] = function ($c) {
+        return new $c['session_storage_class']($c['cookie_name']);
+    };
+
+You can now easily change the cookie name by overriding the
+``cookie_name`` parameter instead of redefining the service
+definition.
+
+Protecting Parameters
+~~~~~~~~~~~~~~~~~~~~~
+
+Because Pimple sees anonymous functions as service definitions, you need to
+wrap anonymous functions with the ``protect()`` method to store them as
+parameters:
+
+.. code-block:: php
+
+    $container['random_func'] = $container->protect(function () {
+        return rand();
+    });
+
+Modifying Services after Definition
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In some cases you may want to modify a service definition after it has been
+defined. You can use the ``extend()`` method to define additional code to be
+run on your service just after it is created:
+
+.. code-block:: php
+
+    $container['session_storage'] = function ($c) {
+        return new $c['session_storage_class']($c['cookie_name']);
+    };
+
+    $container->extend('session_storage', function ($storage, $c) {
+        $storage->...();
+
+        return $storage;
+    });
+
+The first argument is the name of the service to extend, the second a function
+that gets access to the object instance and the container.
+
+Extending a Container
+~~~~~~~~~~~~~~~~~~~~~
+
+If you use the same libraries over and over, you might want to reuse some
+services from one project to the next one; package your services into a
+**provider** by implementing ``Pimple\ServiceProviderInterface``:
+
+.. code-block:: php
+
+    use Pimple\Container;
+
+    class FooProvider implements Pimple\ServiceProviderInterface
+    {
+        public function register(Container $pimple)
+        {
+            // register some services and parameters
+            // on $pimple
+        }
+    }
+
+Then, register the provider on a Container:
+
+.. code-block:: php
+
+    $pimple->register(new FooProvider());
+
+Fetching the Service Creation Function
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When you access an object, Pimple automatically calls the anonymous function
+that you defined, which creates the service object for you. If you want to get
+raw access to this function, you can use the ``raw()`` method:
+
+.. code-block:: php
+
+    $container['session'] = function ($c) {
+        return new Session($c['session_storage']);
+    };
+
+    $sessionFunction = $container->raw('session');
+
+PSR-11 compatibility
+--------------------
+
+For historical reasons, the ``Container`` class does not implement the PSR-11
+``ContainerInterface``. However, Pimple provides a helper class that will let
+you decouple your code from the Pimple container class.
+
+The PSR-11 container class
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``Pimple\Psr11\Container`` class lets you access the content of an
+underlying Pimple container using ``Psr\Container\ContainerInterface``
+methods:
+
+.. code-block:: php
+
+    use Pimple\Container;
+    use Pimple\Psr11\Container as PsrContainer;
+
+    $container = new Container();
+    $container['service'] = function ($c) {
+        return new Service();
+    };
+    $psr11 = new PsrContainer($container);
+
+    $controller = function (PsrContainer $container) {
+        $service = $container->get('service');
+    };
+    $controller($psr11);
+
+Using the PSR-11 ServiceLocator
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Sometimes, a service needs access to several other services without being sure
+that all of them will actually be used. In those cases, you may want the
+instantiation of the services to be lazy.
+
+The traditional solution is to inject the entire service container to get only
+the services really needed. However, this is not recommended because it gives
+services a too broad access to the rest of the application and it hides their
+actual dependencies.
+
+The ``ServiceLocator`` is intended to solve this problem by giving access to a
+set of predefined services while instantiating them only when actually needed.
+
+It also allows you to make your services available under a different name than
+the one used to register them. For instance, you may want to use an object
+that expects an instance of ``EventDispatcherInterface`` to be available under
+the name ``event_dispatcher`` while your event dispatcher has been
+registered under the name ``dispatcher``:
+
+.. code-block:: php
+
+    use Monolog\Logger;
+    use Pimple\Psr11\ServiceLocator;
+    use Psr\Container\ContainerInterface;
+    use Symfony\Component\EventDispatcher\EventDispatcher;
+
+    class MyService
+    {
+        /**
+         * "logger" must be an instance of Psr\Log\LoggerInterface
+         * "event_dispatcher" must be an instance of Symfony\Component\EventDispatcher\EventDispatcherInterface
+         */
+        private $services;
+
+        public function __construct(ContainerInterface $services)
+        {
+            $this->services = $services;
+        }
+    }
+
+    $container['logger'] = function ($c) {
+        return new Monolog\Logger();
+    };
+    $container['dispatcher'] = function () {
+        return new EventDispatcher();
+    };
+
+    $container['service'] = function ($c) {
+        $locator = new ServiceLocator($c, array('logger', 'event_dispatcher' => 'dispatcher'));
+
+        return new MyService($locator);
+    };
+
+Referencing a Collection of Services Lazily
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Passing a collection of services instances in an array may prove inefficient
+if the class that consumes the collection only needs to iterate over it at a
+later stage, when one of its method is called. It can also lead to problems
+if there is a circular dependency between one of the services stored in the
+collection and the class that consumes it.
+
+The ``ServiceIterator`` class helps you solve these issues. It receives a
+list of service names during instantiation and will retrieve the services
+when iterated over:
+
+.. code-block:: php
+
+    use Pimple\Container;
+    use Pimple\ServiceIterator;
+
+    class AuthorizationService
+    {
+        private $voters;
+
+        public function __construct($voters)
+        {
+            $this->voters = $voters;
+        }
+
+        public function canAccess($resource)
+        {
+            foreach ($this->voters as $voter) {
+                if (true === $voter->canAccess($resource)) {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+    }
+
+    $container = new Container();
+
+    $container['voter1'] = function ($c) {
+        return new SomeVoter();
+    }
+    $container['voter2'] = function ($c) {
+        return new SomeOtherVoter($c['auth']);
+    }
+    $container['auth'] = function ($c) {
+        return new AuthorizationService(new ServiceIterator($c, array('voter1', 'voter2'));
+    }
+
+.. _Pimple 1.x documentation: https://github.com/silexphp/Pimple/tree/1.1

+ 29 - 0
vendor/pimple/pimple/composer.json

@@ -0,0 +1,29 @@
+{
+    "name": "pimple/pimple",
+    "type": "library",
+    "description": "Pimple, a simple Dependency Injection Container",
+    "keywords": ["dependency injection", "container"],
+    "homepage": "https://pimple.symfony.com",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Fabien Potencier",
+            "email": "fabien@symfony.com"
+        }
+    ],
+    "require": {
+        "php": ">=7.2.5",
+        "psr/container": "^1.1 || ^2.0"
+    },
+    "require-dev": {
+        "symfony/phpunit-bridge": "^5.4@dev"
+    },
+    "autoload": {
+        "psr-0": { "Pimple": "src/" }
+    },
+    "extra": {
+        "branch-alias": {
+            "dev-master": "3.4.x-dev"
+        }
+    }
+}

+ 18 - 0
vendor/pimple/pimple/phpunit.xml.dist

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
+         backupGlobals="false"
+         colors="true"
+         bootstrap="vendor/autoload.php"
+>
+    <testsuites>
+        <testsuite name="Pimple Test Suite">
+            <directory>./src/Pimple/Tests</directory>
+        </testsuite>
+    </testsuites>
+
+    <listeners>
+        <listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener" />
+    </listeners>
+</phpunit>

+ 305 - 0
vendor/pimple/pimple/src/Pimple/Container.php

@@ -0,0 +1,305 @@
+<?php
+
+/*
+ * This file is part of Pimple.
+ *
+ * Copyright (c) 2009 Fabien Potencier
+ *
+ * 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.
+ */
+
+namespace Pimple;
+
+use Pimple\Exception\ExpectedInvokableException;
+use Pimple\Exception\FrozenServiceException;
+use Pimple\Exception\InvalidServiceIdentifierException;
+use Pimple\Exception\UnknownIdentifierException;
+
+/**
+ * Container main class.
+ *
+ * @author Fabien Potencier
+ */
+class Container implements \ArrayAccess
+{
+    private $values = [];
+    private $factories;
+    private $protected;
+    private $frozen = [];
+    private $raw = [];
+    private $keys = [];
+
+    /**
+     * Instantiates the container.
+     *
+     * Objects and parameters can be passed as argument to the constructor.
+     *
+     * @param array $values The parameters or objects
+     */
+    public function __construct(array $values = [])
+    {
+        $this->factories = new \SplObjectStorage();
+        $this->protected = new \SplObjectStorage();
+
+        foreach ($values as $key => $value) {
+            $this->offsetSet($key, $value);
+        }
+    }
+
+    /**
+     * Sets a parameter or an object.
+     *
+     * Objects must be defined as Closures.
+     *
+     * Allowing any PHP callable leads to difficult to debug problems
+     * as function names (strings) are callable (creating a function with
+     * the same name as an existing parameter would break your container).
+     *
+     * @param string $id    The unique identifier for the parameter or object
+     * @param mixed  $value The value of the parameter or a closure to define an object
+     *
+     * @return void
+     *
+     * @throws FrozenServiceException Prevent override of a frozen service
+     */
+    #[\ReturnTypeWillChange]
+    public function offsetSet($id, $value)
+    {
+        if (isset($this->frozen[$id])) {
+            throw new FrozenServiceException($id);
+        }
+
+        $this->values[$id] = $value;
+        $this->keys[$id] = true;
+    }
+
+    /**
+     * Gets a parameter or an object.
+     *
+     * @param string $id The unique identifier for the parameter or object
+     *
+     * @return mixed The value of the parameter or an object
+     *
+     * @throws UnknownIdentifierException If the identifier is not defined
+     */
+    #[\ReturnTypeWillChange]
+    public function offsetGet($id)
+    {
+        if (!isset($this->keys[$id])) {
+            throw new UnknownIdentifierException($id);
+        }
+
+        if (
+            isset($this->raw[$id])
+            || !\is_object($this->values[$id])
+            || isset($this->protected[$this->values[$id]])
+            || !\method_exists($this->values[$id], '__invoke')
+        ) {
+            return $this->values[$id];
+        }
+
+        if (isset($this->factories[$this->values[$id]])) {
+            return $this->values[$id]($this);
+        }
+
+        $raw = $this->values[$id];
+        $val = $this->values[$id] = $raw($this);
+        $this->raw[$id] = $raw;
+
+        $this->frozen[$id] = true;
+
+        return $val;
+    }
+
+    /**
+     * Checks if a parameter or an object is set.
+     *
+     * @param string $id The unique identifier for the parameter or object
+     *
+     * @return bool
+     */
+    #[\ReturnTypeWillChange]
+    public function offsetExists($id)
+    {
+        return isset($this->keys[$id]);
+    }
+
+    /**
+     * Unsets a parameter or an object.
+     *
+     * @param string $id The unique identifier for the parameter or object
+     *
+     * @return void
+     */
+    #[\ReturnTypeWillChange]
+    public function offsetUnset($id)
+    {
+        if (isset($this->keys[$id])) {
+            if (\is_object($this->values[$id])) {
+                unset($this->factories[$this->values[$id]], $this->protected[$this->values[$id]]);
+            }
+
+            unset($this->values[$id], $this->frozen[$id], $this->raw[$id], $this->keys[$id]);
+        }
+    }
+
+    /**
+     * Marks a callable as being a factory service.
+     *
+     * @param callable $callable A service definition to be used as a factory
+     *
+     * @return callable The passed callable
+     *
+     * @throws ExpectedInvokableException Service definition has to be a closure or an invokable object
+     */
+    public function factory($callable)
+    {
+        if (!\is_object($callable) || !\method_exists($callable, '__invoke')) {
+            throw new ExpectedInvokableException('Service definition is not a Closure or invokable object.');
+        }
+
+        $this->factories->attach($callable);
+
+        return $callable;
+    }
+
+    /**
+     * Protects a callable from being interpreted as a service.
+     *
+     * This is useful when you want to store a callable as a parameter.
+     *
+     * @param callable $callable A callable to protect from being evaluated
+     *
+     * @return callable The passed callable
+     *
+     * @throws ExpectedInvokableException Service definition has to be a closure or an invokable object
+     */
+    public function protect($callable)
+    {
+        if (!\is_object($callable) || !\method_exists($callable, '__invoke')) {
+            throw new ExpectedInvokableException('Callable is not a Closure or invokable object.');
+        }
+
+        $this->protected->attach($callable);
+
+        return $callable;
+    }
+
+    /**
+     * Gets a parameter or the closure defining an object.
+     *
+     * @param string $id The unique identifier for the parameter or object
+     *
+     * @return mixed The value of the parameter or the closure defining an object
+     *
+     * @throws UnknownIdentifierException If the identifier is not defined
+     */
+    public function raw($id)
+    {
+        if (!isset($this->keys[$id])) {
+            throw new UnknownIdentifierException($id);
+        }
+
+        if (isset($this->raw[$id])) {
+            return $this->raw[$id];
+        }
+
+        return $this->values[$id];
+    }
+
+    /**
+     * Extends an object definition.
+     *
+     * Useful when you want to extend an existing object definition,
+     * without necessarily loading that object.
+     *
+     * @param string   $id       The unique identifier for the object
+     * @param callable $callable A service definition to extend the original
+     *
+     * @return callable The wrapped callable
+     *
+     * @throws UnknownIdentifierException        If the identifier is not defined
+     * @throws FrozenServiceException            If the service is frozen
+     * @throws InvalidServiceIdentifierException If the identifier belongs to a parameter
+     * @throws ExpectedInvokableException        If the extension callable is not a closure or an invokable object
+     */
+    public function extend($id, $callable)
+    {
+        if (!isset($this->keys[$id])) {
+            throw new UnknownIdentifierException($id);
+        }
+
+        if (isset($this->frozen[$id])) {
+            throw new FrozenServiceException($id);
+        }
+
+        if (!\is_object($this->values[$id]) || !\method_exists($this->values[$id], '__invoke')) {
+            throw new InvalidServiceIdentifierException($id);
+        }
+
+        if (isset($this->protected[$this->values[$id]])) {
+            @\trigger_error(\sprintf('How Pimple behaves when extending protected closures will be fixed in Pimple 4. Are you sure "%s" should be protected?', $id), E_USER_DEPRECATED);
+        }
+
+        if (!\is_object($callable) || !\method_exists($callable, '__invoke')) {
+            throw new ExpectedInvokableException('Extension service definition is not a Closure or invokable object.');
+        }
+
+        $factory = $this->values[$id];
+
+        $extended = function ($c) use ($callable, $factory) {
+            return $callable($factory($c), $c);
+        };
+
+        if (isset($this->factories[$factory])) {
+            $this->factories->detach($factory);
+            $this->factories->attach($extended);
+        }
+
+        return $this[$id] = $extended;
+    }
+
+    /**
+     * Returns all defined value names.
+     *
+     * @return array An array of value names
+     */
+    public function keys()
+    {
+        return \array_keys($this->values);
+    }
+
+    /**
+     * Registers a service provider.
+     *
+     * @param array $values An array of values that customizes the provider
+     *
+     * @return static
+     */
+    public function register(ServiceProviderInterface $provider, array $values = [])
+    {
+        $provider->register($this);
+
+        foreach ($values as $key => $value) {
+            $this[$key] = $value;
+        }
+
+        return $this;
+    }
+}

+ 38 - 0
vendor/pimple/pimple/src/Pimple/Exception/ExpectedInvokableException.php

@@ -0,0 +1,38 @@
+<?php
+
+/*
+ * This file is part of Pimple.
+ *
+ * Copyright (c) 2009 Fabien Potencier
+ *
+ * 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.
+ */
+
+namespace Pimple\Exception;
+
+use Psr\Container\ContainerExceptionInterface;
+
+/**
+ * A closure or invokable object was expected.
+ *
+ * @author Pascal Luna <skalpa@zetareticuli.org>
+ */
+class ExpectedInvokableException extends \InvalidArgumentException implements ContainerExceptionInterface
+{
+}

+ 45 - 0
vendor/pimple/pimple/src/Pimple/Exception/FrozenServiceException.php

@@ -0,0 +1,45 @@
+<?php
+
+/*
+ * This file is part of Pimple.
+ *
+ * Copyright (c) 2009 Fabien Potencier
+ *
+ * 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.
+ */
+
+namespace Pimple\Exception;
+
+use Psr\Container\ContainerExceptionInterface;
+
+/**
+ * An attempt to modify a frozen service was made.
+ *
+ * @author Pascal Luna <skalpa@zetareticuli.org>
+ */
+class FrozenServiceException extends \RuntimeException implements ContainerExceptionInterface
+{
+    /**
+     * @param string $id Identifier of the frozen service
+     */
+    public function __construct($id)
+    {
+        parent::__construct(\sprintf('Cannot override frozen service "%s".', $id));
+    }
+}

+ 45 - 0
vendor/pimple/pimple/src/Pimple/Exception/InvalidServiceIdentifierException.php

@@ -0,0 +1,45 @@
+<?php
+
+/*
+ * This file is part of Pimple.
+ *
+ * Copyright (c) 2009 Fabien Potencier
+ *
+ * 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.
+ */
+
+namespace Pimple\Exception;
+
+use Psr\Container\NotFoundExceptionInterface;
+
+/**
+ * An attempt to perform an operation that requires a service identifier was made.
+ *
+ * @author Pascal Luna <skalpa@zetareticuli.org>
+ */
+class InvalidServiceIdentifierException extends \InvalidArgumentException implements NotFoundExceptionInterface
+{
+    /**
+     * @param string $id The invalid identifier
+     */
+    public function __construct($id)
+    {
+        parent::__construct(\sprintf('Identifier "%s" does not contain an object definition.', $id));
+    }
+}

+ 45 - 0
vendor/pimple/pimple/src/Pimple/Exception/UnknownIdentifierException.php

@@ -0,0 +1,45 @@
+<?php
+
+/*
+ * This file is part of Pimple.
+ *
+ * Copyright (c) 2009 Fabien Potencier
+ *
+ * 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.
+ */
+
+namespace Pimple\Exception;
+
+use Psr\Container\NotFoundExceptionInterface;
+
+/**
+ * The identifier of a valid service or parameter was expected.
+ *
+ * @author Pascal Luna <skalpa@zetareticuli.org>
+ */
+class UnknownIdentifierException extends \InvalidArgumentException implements NotFoundExceptionInterface
+{
+    /**
+     * @param string $id The unknown identifier
+     */
+    public function __construct($id)
+    {
+        parent::__construct(\sprintf('Identifier "%s" is not defined.', $id));
+    }
+}

+ 55 - 0
vendor/pimple/pimple/src/Pimple/Psr11/Container.php

@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * This file is part of Pimple.
+ *
+ * Copyright (c) 2009-2017 Fabien Potencier
+ *
+ * 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.
+ */
+
+namespace Pimple\Psr11;
+
+use Pimple\Container as PimpleContainer;
+use Psr\Container\ContainerInterface;
+
+/**
+ * PSR-11 compliant wrapper.
+ *
+ * @author Pascal Luna <skalpa@zetareticuli.org>
+ */
+final class Container implements ContainerInterface
+{
+    private $pimple;
+
+    public function __construct(PimpleContainer $pimple)
+    {
+        $this->pimple = $pimple;
+    }
+
+    public function get(string $id)
+    {
+        return $this->pimple[$id];
+    }
+
+    public function has(string $id): bool
+    {
+        return isset($this->pimple[$id]);
+    }
+}

+ 75 - 0
vendor/pimple/pimple/src/Pimple/Psr11/ServiceLocator.php

@@ -0,0 +1,75 @@
+<?php
+
+/*
+ * This file is part of Pimple.
+ *
+ * Copyright (c) 2009 Fabien Potencier
+ *
+ * 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.
+ */
+
+namespace Pimple\Psr11;
+
+use Pimple\Container as PimpleContainer;
+use Pimple\Exception\UnknownIdentifierException;
+use Psr\Container\ContainerInterface;
+
+/**
+ * Pimple PSR-11 service locator.
+ *
+ * @author Pascal Luna <skalpa@zetareticuli.org>
+ */
+class ServiceLocator implements ContainerInterface
+{
+    private $container;
+    private $aliases = [];
+
+    /**
+     * @param PimpleContainer $container The Container instance used to locate services
+     * @param array           $ids       Array of service ids that can be located. String keys can be used to define aliases
+     */
+    public function __construct(PimpleContainer $container, array $ids)
+    {
+        $this->container = $container;
+
+        foreach ($ids as $key => $id) {
+            $this->aliases[\is_int($key) ? $id : $key] = $id;
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function get(string $id)
+    {
+        if (!isset($this->aliases[$id])) {
+            throw new UnknownIdentifierException($id);
+        }
+
+        return $this->container[$this->aliases[$id]];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function has(string $id): bool
+    {
+        return isset($this->aliases[$id]) && isset($this->container[$this->aliases[$id]]);
+    }
+}

+ 89 - 0
vendor/pimple/pimple/src/Pimple/ServiceIterator.php

@@ -0,0 +1,89 @@
+<?php
+
+/*
+ * This file is part of Pimple.
+ *
+ * Copyright (c) 2009 Fabien Potencier
+ *
+ * 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.
+ */
+
+namespace Pimple;
+
+/**
+ * Lazy service iterator.
+ *
+ * @author Pascal Luna <skalpa@zetareticuli.org>
+ */
+final class ServiceIterator implements \Iterator
+{
+    private $container;
+    private $ids;
+
+    public function __construct(Container $container, array $ids)
+    {
+        $this->container = $container;
+        $this->ids = $ids;
+    }
+
+    /**
+     * @return void
+     */
+    #[\ReturnTypeWillChange]
+    public function rewind()
+    {
+        \reset($this->ids);
+    }
+
+    /**
+     * @return mixed
+     */
+    #[\ReturnTypeWillChange]
+    public function current()
+    {
+        return $this->container[\current($this->ids)];
+    }
+
+    /**
+     * @return mixed
+     */
+    #[\ReturnTypeWillChange]
+    public function key()
+    {
+        return \current($this->ids);
+    }
+
+    /**
+     * @return void
+     */
+    #[\ReturnTypeWillChange]
+    public function next()
+    {
+        \next($this->ids);
+    }
+
+    /**
+     * @return bool
+     */
+    #[\ReturnTypeWillChange]
+    public function valid()
+    {
+        return null !== \key($this->ids);
+    }
+}

+ 44 - 0
vendor/pimple/pimple/src/Pimple/ServiceProviderInterface.php

@@ -0,0 +1,44 @@
+<?php
+
+/*
+ * This file is part of Pimple.
+ *
+ * Copyright (c) 2009 Fabien Potencier
+ *
+ * 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.
+ */
+
+namespace Pimple;
+
+/**
+ * Pimple service provider interface.
+ *
+ * @author  Fabien Potencier
+ * @author  Dominik Zogg
+ */
+interface ServiceProviderInterface
+{
+    /**
+     * Registers services on the given container.
+     *
+     * This method should only be used to configure services and parameters.
+     * It should not get services.
+     */
+    public function register(Container $pimple);
+}

+ 38 - 0
vendor/pimple/pimple/src/Pimple/Tests/Fixtures/Invokable.php

@@ -0,0 +1,38 @@
+<?php
+
+/*
+ * This file is part of Pimple.
+ *
+ * Copyright (c) 2009 Fabien Potencier
+ *
+ * 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.
+ */
+
+namespace Pimple\Tests\Fixtures;
+
+class Invokable
+{
+    public function __invoke($value = null)
+    {
+        $service = new Service();
+        $service->value = $value;
+
+        return $service;
+    }
+}

+ 34 - 0
vendor/pimple/pimple/src/Pimple/Tests/Fixtures/NonInvokable.php

@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of Pimple.
+ *
+ * Copyright (c) 2009 Fabien Potencier
+ *
+ * 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.
+ */
+
+namespace Pimple\Tests\Fixtures;
+
+class NonInvokable
+{
+    public function __call($a, $b)
+    {
+    }
+}

+ 52 - 0
vendor/pimple/pimple/src/Pimple/Tests/Fixtures/PimpleServiceProvider.php

@@ -0,0 +1,52 @@
+<?php
+
+/*
+ * This file is part of Pimple.
+ *
+ * Copyright (c) 2009 Fabien Potencier
+ *
+ * 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.
+ */
+
+namespace Pimple\Tests\Fixtures;
+
+use Pimple\Container;
+use Pimple\ServiceProviderInterface;
+
+class PimpleServiceProvider implements ServiceProviderInterface
+{
+    /**
+     * Registers services on the given container.
+     *
+     * This method should only be used to configure services and parameters.
+     * It should not get services.
+     */
+    public function register(Container $pimple)
+    {
+        $pimple['param'] = 'value';
+
+        $pimple['service'] = function () {
+            return new Service();
+        };
+
+        $pimple['factory'] = $pimple->factory(function () {
+            return new Service();
+        });
+    }
+}

+ 35 - 0
vendor/pimple/pimple/src/Pimple/Tests/Fixtures/Service.php

@@ -0,0 +1,35 @@
+<?php
+
+/*
+ * This file is part of Pimple.
+ *
+ * Copyright (c) 2009 Fabien Potencier
+ *
+ * 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.
+ */
+
+namespace Pimple\Tests\Fixtures;
+
+/**
+ * @author  Igor Wiedler <igor@wiedler.ch>
+ */
+class Service
+{
+    public $value;
+}

+ 77 - 0
vendor/pimple/pimple/src/Pimple/Tests/PimpleServiceProviderInterfaceTest.php

@@ -0,0 +1,77 @@
+<?php
+
+/*
+ * This file is part of Pimple.
+ *
+ * Copyright (c) 2009 Fabien Potencier
+ *
+ * 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.
+ */
+
+namespace Pimple\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Pimple\Container;
+
+/**
+ * @author Dominik Zogg <dominik.zogg@gmail.com>
+ */
+class PimpleServiceProviderInterfaceTest extends TestCase
+{
+    public function testProvider()
+    {
+        $pimple = new Container();
+
+        $pimpleServiceProvider = new Fixtures\PimpleServiceProvider();
+        $pimpleServiceProvider->register($pimple);
+
+        $this->assertEquals('value', $pimple['param']);
+        $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $pimple['service']);
+
+        $serviceOne = $pimple['factory'];
+        $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceOne);
+
+        $serviceTwo = $pimple['factory'];
+        $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceTwo);
+
+        $this->assertNotSame($serviceOne, $serviceTwo);
+    }
+
+    public function testProviderWithRegisterMethod()
+    {
+        $pimple = new Container();
+
+        $pimple->register(new Fixtures\PimpleServiceProvider(), [
+            'anotherParameter' => 'anotherValue',
+        ]);
+
+        $this->assertEquals('value', $pimple['param']);
+        $this->assertEquals('anotherValue', $pimple['anotherParameter']);
+
+        $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $pimple['service']);
+
+        $serviceOne = $pimple['factory'];
+        $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceOne);
+
+        $serviceTwo = $pimple['factory'];
+        $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceTwo);
+
+        $this->assertNotSame($serviceOne, $serviceTwo);
+    }
+}

+ 610 - 0
vendor/pimple/pimple/src/Pimple/Tests/PimpleTest.php

@@ -0,0 +1,610 @@
+<?php
+
+/*
+ * This file is part of Pimple.
+ *
+ * Copyright (c) 2009 Fabien Potencier
+ *
+ * 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.
+ */
+
+namespace Pimple\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Pimple\Container;
+
+/**
+ * @author Igor Wiedler <igor@wiedler.ch>
+ */
+class PimpleTest extends TestCase
+{
+    public function testWithString()
+    {
+        $pimple = new Container();
+        $pimple['param'] = 'value';
+
+        $this->assertEquals('value', $pimple['param']);
+    }
+
+    public function testWithClosure()
+    {
+        $pimple = new Container();
+        $pimple['service'] = function () {
+            return new Fixtures\Service();
+        };
+
+        $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $pimple['service']);
+    }
+
+    public function testServicesShouldBeDifferent()
+    {
+        $pimple = new Container();
+        $pimple['service'] = $pimple->factory(function () {
+            return new Fixtures\Service();
+        });
+
+        $serviceOne = $pimple['service'];
+        $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceOne);
+
+        $serviceTwo = $pimple['service'];
+        $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceTwo);
+
+        $this->assertNotSame($serviceOne, $serviceTwo);
+    }
+
+    public function testShouldPassContainerAsParameter()
+    {
+        $pimple = new Container();
+        $pimple['service'] = function () {
+            return new Fixtures\Service();
+        };
+        $pimple['container'] = function ($container) {
+            return $container;
+        };
+
+        $this->assertNotSame($pimple, $pimple['service']);
+        $this->assertSame($pimple, $pimple['container']);
+    }
+
+    public function testIsset()
+    {
+        $pimple = new Container();
+        $pimple['param'] = 'value';
+        $pimple['service'] = function () {
+            return new Fixtures\Service();
+        };
+
+        $pimple['null'] = null;
+
+        $this->assertTrue(isset($pimple['param']));
+        $this->assertTrue(isset($pimple['service']));
+        $this->assertTrue(isset($pimple['null']));
+        $this->assertFalse(isset($pimple['non_existent']));
+    }
+
+    public function testConstructorInjection()
+    {
+        $params = ['param' => 'value'];
+        $pimple = new Container($params);
+
+        $this->assertSame($params['param'], $pimple['param']);
+    }
+
+    public function testOffsetGetValidatesKeyIsPresent()
+    {
+        $this->expectException(\Pimple\Exception\UnknownIdentifierException::class);
+        $this->expectExceptionMessage('Identifier "foo" is not defined.');
+
+        $pimple = new Container();
+        echo $pimple['foo'];
+    }
+
+    /**
+     * @group legacy
+     */
+    public function testLegacyOffsetGetValidatesKeyIsPresent()
+    {
+        $this->expectException(\InvalidArgumentException::class);
+        $this->expectExceptionMessage('Identifier "foo" is not defined.');
+
+        $pimple = new Container();
+        echo $pimple['foo'];
+    }
+
+    public function testOffsetGetHonorsNullValues()
+    {
+        $pimple = new Container();
+        $pimple['foo'] = null;
+        $this->assertNull($pimple['foo']);
+    }
+
+    public function testUnset()
+    {
+        $pimple = new Container();
+        $pimple['param'] = 'value';
+        $pimple['service'] = function () {
+            return new Fixtures\Service();
+        };
+
+        unset($pimple['param'], $pimple['service']);
+        $this->assertFalse(isset($pimple['param']));
+        $this->assertFalse(isset($pimple['service']));
+    }
+
+    /**
+     * @dataProvider serviceDefinitionProvider
+     */
+    public function testShare($service)
+    {
+        $pimple = new Container();
+        $pimple['shared_service'] = $service;
+
+        $serviceOne = $pimple['shared_service'];
+        $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceOne);
+
+        $serviceTwo = $pimple['shared_service'];
+        $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceTwo);
+
+        $this->assertSame($serviceOne, $serviceTwo);
+    }
+
+    /**
+     * @dataProvider serviceDefinitionProvider
+     */
+    public function testProtect($service)
+    {
+        $pimple = new Container();
+        $pimple['protected'] = $pimple->protect($service);
+
+        $this->assertSame($service, $pimple['protected']);
+    }
+
+    public function testGlobalFunctionNameAsParameterValue()
+    {
+        $pimple = new Container();
+        $pimple['global_function'] = 'strlen';
+        $this->assertSame('strlen', $pimple['global_function']);
+    }
+
+    public function testRaw()
+    {
+        $pimple = new Container();
+        $pimple['service'] = $definition = $pimple->factory(function () {
+            return 'foo';
+        });
+        $this->assertSame($definition, $pimple->raw('service'));
+    }
+
+    public function testRawHonorsNullValues()
+    {
+        $pimple = new Container();
+        $pimple['foo'] = null;
+        $this->assertNull($pimple->raw('foo'));
+    }
+
+    public function testFluentRegister()
+    {
+        $pimple = new Container();
+        $this->assertSame($pimple, $pimple->register($this->getMockBuilder('Pimple\ServiceProviderInterface')->getMock()));
+    }
+
+    public function testRawValidatesKeyIsPresent()
+    {
+        $this->expectException(\Pimple\Exception\UnknownIdentifierException::class);
+        $this->expectExceptionMessage('Identifier "foo" is not defined.');
+
+        $pimple = new Container();
+        $pimple->raw('foo');
+    }
+
+    /**
+     * @group legacy
+     */
+    public function testLegacyRawValidatesKeyIsPresent()
+    {
+        $this->expectException(\InvalidArgumentException::class);
+        $this->expectExceptionMessage('Identifier "foo" is not defined.');
+
+        $pimple = new Container();
+        $pimple->raw('foo');
+    }
+
+    /**
+     * @dataProvider serviceDefinitionProvider
+     */
+    public function testExtend($service)
+    {
+        $pimple = new Container();
+        $pimple['shared_service'] = function () {
+            return new Fixtures\Service();
+        };
+        $pimple['factory_service'] = $pimple->factory(function () {
+            return new Fixtures\Service();
+        });
+
+        $pimple->extend('shared_service', $service);
+        $serviceOne = $pimple['shared_service'];
+        $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceOne);
+        $serviceTwo = $pimple['shared_service'];
+        $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceTwo);
+        $this->assertSame($serviceOne, $serviceTwo);
+        $this->assertSame($serviceOne->value, $serviceTwo->value);
+
+        $pimple->extend('factory_service', $service);
+        $serviceOne = $pimple['factory_service'];
+        $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceOne);
+        $serviceTwo = $pimple['factory_service'];
+        $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceTwo);
+        $this->assertNotSame($serviceOne, $serviceTwo);
+        $this->assertNotSame($serviceOne->value, $serviceTwo->value);
+    }
+
+    public function testExtendDoesNotLeakWithFactories()
+    {
+        if (\extension_loaded('pimple')) {
+            $this->markTestSkipped('Pimple extension does not support this test');
+        }
+        $pimple = new Container();
+
+        $pimple['foo'] = $pimple->factory(function () {
+            return;
+        });
+        $pimple['foo'] = $pimple->extend('foo', function ($foo, $pimple) {
+            return;
+        });
+        unset($pimple['foo']);
+
+        $p = new \ReflectionProperty($pimple, 'values');
+        $p->setAccessible(true);
+        $this->assertEmpty($p->getValue($pimple));
+
+        $p = new \ReflectionProperty($pimple, 'factories');
+        $p->setAccessible(true);
+        $this->assertCount(0, $p->getValue($pimple));
+    }
+
+    public function testExtendValidatesKeyIsPresent()
+    {
+        $this->expectException(\Pimple\Exception\UnknownIdentifierException::class);
+        $this->expectExceptionMessage('Identifier "foo" is not defined.');
+
+        $pimple = new Container();
+        $pimple->extend('foo', function () {
+        });
+    }
+
+    /**
+     * @group legacy
+     */
+    public function testLegacyExtendValidatesKeyIsPresent()
+    {
+        $this->expectException(\InvalidArgumentException::class);
+        $this->expectExceptionMessage('Identifier "foo" is not defined.');
+
+        $pimple = new Container();
+        $pimple->extend('foo', function () {
+        });
+    }
+
+    public function testKeys()
+    {
+        $pimple = new Container();
+        $pimple['foo'] = 123;
+        $pimple['bar'] = 123;
+
+        $this->assertEquals(['foo', 'bar'], $pimple->keys());
+    }
+
+    /** @test */
+    public function settingAnInvokableObjectShouldTreatItAsFactory()
+    {
+        $pimple = new Container();
+        $pimple['invokable'] = new Fixtures\Invokable();
+
+        $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $pimple['invokable']);
+    }
+
+    /** @test */
+    public function settingNonInvokableObjectShouldTreatItAsParameter()
+    {
+        $pimple = new Container();
+        $pimple['non_invokable'] = new Fixtures\NonInvokable();
+
+        $this->assertInstanceOf('Pimple\Tests\Fixtures\NonInvokable', $pimple['non_invokable']);
+    }
+
+    /**
+     * @dataProvider badServiceDefinitionProvider
+     */
+    public function testFactoryFailsForInvalidServiceDefinitions($service)
+    {
+        $this->expectException(\Pimple\Exception\ExpectedInvokableException::class);
+        $this->expectExceptionMessage('Service definition is not a Closure or invokable object.');
+
+        $pimple = new Container();
+        $pimple->factory($service);
+    }
+
+    /**
+     * @group legacy
+     * @dataProvider badServiceDefinitionProvider
+     */
+    public function testLegacyFactoryFailsForInvalidServiceDefinitions($service)
+    {
+        $this->expectException(\InvalidArgumentException::class);
+        $this->expectExceptionMessage('Service definition is not a Closure or invokable object.');
+
+        $pimple = new Container();
+        $pimple->factory($service);
+    }
+
+    /**
+     * @dataProvider badServiceDefinitionProvider
+     */
+    public function testProtectFailsForInvalidServiceDefinitions($service)
+    {
+        $this->expectException(\Pimple\Exception\ExpectedInvokableException::class);
+        $this->expectExceptionMessage('Callable is not a Closure or invokable object.');
+
+        $pimple = new Container();
+        $pimple->protect($service);
+    }
+
+    /**
+     * @group legacy
+     * @dataProvider badServiceDefinitionProvider
+     */
+    public function testLegacyProtectFailsForInvalidServiceDefinitions($service)
+    {
+        $this->expectException(\InvalidArgumentException::class);
+        $this->expectExceptionMessage('Callable is not a Closure or invokable object.');
+
+        $pimple = new Container();
+        $pimple->protect($service);
+    }
+
+    /**
+     * @dataProvider badServiceDefinitionProvider
+     */
+    public function testExtendFailsForKeysNotContainingServiceDefinitions($service)
+    {
+        $this->expectException(\Pimple\Exception\InvalidServiceIdentifierException::class);
+        $this->expectExceptionMessage('Identifier "foo" does not contain an object definition.');
+
+        $pimple = new Container();
+        $pimple['foo'] = $service;
+        $pimple->extend('foo', function () {
+        });
+    }
+
+    /**
+     * @group legacy
+     * @dataProvider badServiceDefinitionProvider
+     */
+    public function testLegacyExtendFailsForKeysNotContainingServiceDefinitions($service)
+    {
+        $this->expectException(\InvalidArgumentException::class);
+        $this->expectExceptionMessage('Identifier "foo" does not contain an object definition.');
+
+        $pimple = new Container();
+        $pimple['foo'] = $service;
+        $pimple->extend('foo', function () {
+        });
+    }
+
+    /**
+     * @group legacy
+     * @expectedDeprecation How Pimple behaves when extending protected closures will be fixed in Pimple 4. Are you sure "foo" should be protected?
+     */
+    public function testExtendingProtectedClosureDeprecation()
+    {
+        $pimple = new Container();
+        $pimple['foo'] = $pimple->protect(function () {
+            return 'bar';
+        });
+
+        $pimple->extend('foo', function ($value) {
+            return $value.'-baz';
+        });
+
+        $this->assertSame('bar-baz', $pimple['foo']);
+    }
+
+    /**
+     * @dataProvider badServiceDefinitionProvider
+     */
+    public function testExtendFailsForInvalidServiceDefinitions($service)
+    {
+        $this->expectException(\Pimple\Exception\ExpectedInvokableException::class);
+        $this->expectExceptionMessage('Extension service definition is not a Closure or invokable object.');
+
+        $pimple = new Container();
+        $pimple['foo'] = function () {
+        };
+        $pimple->extend('foo', $service);
+    }
+
+    /**
+     * @group legacy
+     * @dataProvider badServiceDefinitionProvider
+     */
+    public function testLegacyExtendFailsForInvalidServiceDefinitions($service)
+    {
+        $this->expectException(\InvalidArgumentException::class);
+        $this->expectExceptionMessage('Extension service definition is not a Closure or invokable object.');
+
+        $pimple = new Container();
+        $pimple['foo'] = function () {
+        };
+        $pimple->extend('foo', $service);
+    }
+
+    public function testExtendFailsIfFrozenServiceIsNonInvokable()
+    {
+        $this->expectException(\Pimple\Exception\FrozenServiceException::class);
+        $this->expectExceptionMessage('Cannot override frozen service "foo".');
+
+        $pimple = new Container();
+        $pimple['foo'] = function () {
+            return new Fixtures\NonInvokable();
+        };
+        $foo = $pimple['foo'];
+
+        $pimple->extend('foo', function () {
+        });
+    }
+
+    public function testExtendFailsIfFrozenServiceIsInvokable()
+    {
+        $this->expectException(\Pimple\Exception\FrozenServiceException::class);
+        $this->expectExceptionMessage('Cannot override frozen service "foo".');
+
+        $pimple = new Container();
+        $pimple['foo'] = function () {
+            return new Fixtures\Invokable();
+        };
+        $foo = $pimple['foo'];
+
+        $pimple->extend('foo', function () {
+        });
+    }
+
+    /**
+     * Provider for invalid service definitions.
+     */
+    public function badServiceDefinitionProvider()
+    {
+        return [
+          [123],
+          [new Fixtures\NonInvokable()],
+        ];
+    }
+
+    /**
+     * Provider for service definitions.
+     */
+    public function serviceDefinitionProvider()
+    {
+        return [
+            [function ($value) {
+                $service = new Fixtures\Service();
+                $service->value = $value;
+
+                return $service;
+            }],
+            [new Fixtures\Invokable()],
+        ];
+    }
+
+    public function testDefiningNewServiceAfterFreeze()
+    {
+        $pimple = new Container();
+        $pimple['foo'] = function () {
+            return 'foo';
+        };
+        $foo = $pimple['foo'];
+
+        $pimple['bar'] = function () {
+            return 'bar';
+        };
+        $this->assertSame('bar', $pimple['bar']);
+    }
+
+    public function testOverridingServiceAfterFreeze()
+    {
+        $this->expectException(\Pimple\Exception\FrozenServiceException::class);
+        $this->expectExceptionMessage('Cannot override frozen service "foo".');
+
+        $pimple = new Container();
+        $pimple['foo'] = function () {
+            return 'foo';
+        };
+        $foo = $pimple['foo'];
+
+        $pimple['foo'] = function () {
+            return 'bar';
+        };
+    }
+
+    /**
+     * @group legacy
+     */
+    public function testLegacyOverridingServiceAfterFreeze()
+    {
+        $this->expectException(\RuntimeException::class);
+        $this->expectExceptionMessage('Cannot override frozen service "foo".');
+
+        $pimple = new Container();
+        $pimple['foo'] = function () {
+            return 'foo';
+        };
+        $foo = $pimple['foo'];
+
+        $pimple['foo'] = function () {
+            return 'bar';
+        };
+    }
+
+    public function testRemovingServiceAfterFreeze()
+    {
+        $pimple = new Container();
+        $pimple['foo'] = function () {
+            return 'foo';
+        };
+        $foo = $pimple['foo'];
+
+        unset($pimple['foo']);
+        $pimple['foo'] = function () {
+            return 'bar';
+        };
+        $this->assertSame('bar', $pimple['foo']);
+    }
+
+    public function testExtendingService()
+    {
+        $pimple = new Container();
+        $pimple['foo'] = function () {
+            return 'foo';
+        };
+        $pimple['foo'] = $pimple->extend('foo', function ($foo, $app) {
+            return "$foo.bar";
+        });
+        $pimple['foo'] = $pimple->extend('foo', function ($foo, $app) {
+            return "$foo.baz";
+        });
+        $this->assertSame('foo.bar.baz', $pimple['foo']);
+    }
+
+    public function testExtendingServiceAfterOtherServiceFreeze()
+    {
+        $pimple = new Container();
+        $pimple['foo'] = function () {
+            return 'foo';
+        };
+        $pimple['bar'] = function () {
+            return 'bar';
+        };
+        $foo = $pimple['foo'];
+
+        $pimple['bar'] = $pimple->extend('bar', function ($bar, $app) {
+            return "$bar.baz";
+        });
+        $this->assertSame('bar.baz', $pimple['bar']);
+    }
+}

+ 76 - 0
vendor/pimple/pimple/src/Pimple/Tests/Psr11/ContainerTest.php

@@ -0,0 +1,76 @@
+<?php
+
+/*
+ * This file is part of Pimple.
+ *
+ * Copyright (c) 2009-2017 Fabien Potencier
+ *
+ * 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.
+ */
+
+namespace Pimple\Tests\Psr11;
+
+use PHPUnit\Framework\TestCase;
+use Pimple\Container;
+use Pimple\Psr11\Container as PsrContainer;
+use Pimple\Tests\Fixtures\Service;
+
+class ContainerTest extends TestCase
+{
+    public function testGetReturnsExistingService()
+    {
+        $pimple = new Container();
+        $pimple['service'] = function () {
+            return new Service();
+        };
+        $psr = new PsrContainer($pimple);
+
+        $this->assertSame($pimple['service'], $psr->get('service'));
+    }
+
+    public function testGetThrowsExceptionIfServiceIsNotFound()
+    {
+        $this->expectException(\Psr\Container\NotFoundExceptionInterface::class);
+        $this->expectExceptionMessage('Identifier "service" is not defined.');
+
+        $pimple = new Container();
+        $psr = new PsrContainer($pimple);
+
+        $psr->get('service');
+    }
+
+    public function testHasReturnsTrueIfServiceExists()
+    {
+        $pimple = new Container();
+        $pimple['service'] = function () {
+            return new Service();
+        };
+        $psr = new PsrContainer($pimple);
+
+        $this->assertTrue($psr->has('service'));
+    }
+
+    public function testHasReturnsFalseIfServiceDoesNotExist()
+    {
+        $pimple = new Container();
+        $psr = new PsrContainer($pimple);
+
+        $this->assertFalse($psr->has('service'));
+    }
+}

+ 131 - 0
vendor/pimple/pimple/src/Pimple/Tests/Psr11/ServiceLocatorTest.php

@@ -0,0 +1,131 @@
+<?php
+
+/*
+ * This file is part of Pimple.
+ *
+ * Copyright (c) 2009 Fabien Potencier
+ *
+ * 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.
+ */
+
+namespace Pimple\Tests\Psr11;
+
+use PHPUnit\Framework\TestCase;
+use Pimple\Container;
+use Pimple\Psr11\ServiceLocator;
+use Pimple\Tests\Fixtures;
+
+/**
+ * ServiceLocator test case.
+ *
+ * @author Pascal Luna <skalpa@zetareticuli.org>
+ */
+class ServiceLocatorTest extends TestCase
+{
+    public function testCanAccessServices()
+    {
+        $pimple = new Container();
+        $pimple['service'] = function () {
+            return new Fixtures\Service();
+        };
+        $locator = new ServiceLocator($pimple, ['service']);
+
+        $this->assertSame($pimple['service'], $locator->get('service'));
+    }
+
+    public function testCanAccessAliasedServices()
+    {
+        $pimple = new Container();
+        $pimple['service'] = function () {
+            return new Fixtures\Service();
+        };
+        $locator = new ServiceLocator($pimple, ['alias' => 'service']);
+
+        $this->assertSame($pimple['service'], $locator->get('alias'));
+    }
+
+    public function testCannotAccessAliasedServiceUsingRealIdentifier()
+    {
+        $this->expectException(\Pimple\Exception\UnknownIdentifierException::class);
+        $this->expectExceptionMessage('Identifier "service" is not defined.');
+
+        $pimple = new Container();
+        $pimple['service'] = function () {
+            return new Fixtures\Service();
+        };
+        $locator = new ServiceLocator($pimple, ['alias' => 'service']);
+
+        $service = $locator->get('service');
+    }
+
+    public function testGetValidatesServiceCanBeLocated()
+    {
+        $this->expectException(\Pimple\Exception\UnknownIdentifierException::class);
+        $this->expectExceptionMessage('Identifier "foo" is not defined.');
+
+        $pimple = new Container();
+        $pimple['service'] = function () {
+            return new Fixtures\Service();
+        };
+        $locator = new ServiceLocator($pimple, ['alias' => 'service']);
+
+        $service = $locator->get('foo');
+    }
+
+    public function testGetValidatesTargetServiceExists()
+    {
+        $this->expectException(\Pimple\Exception\UnknownIdentifierException::class);
+        $this->expectExceptionMessage('Identifier "invalid" is not defined.');
+
+        $pimple = new Container();
+        $pimple['service'] = function () {
+            return new Fixtures\Service();
+        };
+        $locator = new ServiceLocator($pimple, ['alias' => 'invalid']);
+
+        $service = $locator->get('alias');
+    }
+
+    public function testHasValidatesServiceCanBeLocated()
+    {
+        $pimple = new Container();
+        $pimple['service1'] = function () {
+            return new Fixtures\Service();
+        };
+        $pimple['service2'] = function () {
+            return new Fixtures\Service();
+        };
+        $locator = new ServiceLocator($pimple, ['service1']);
+
+        $this->assertTrue($locator->has('service1'));
+        $this->assertFalse($locator->has('service2'));
+    }
+
+    public function testHasChecksIfTargetServiceExists()
+    {
+        $pimple = new Container();
+        $pimple['service'] = function () {
+            return new Fixtures\Service();
+        };
+        $locator = new ServiceLocator($pimple, ['foo' => 'service', 'bar' => 'invalid']);
+
+        $this->assertTrue($locator->has('foo'));
+        $this->assertFalse($locator->has('bar'));
+    }
+}

+ 52 - 0
vendor/pimple/pimple/src/Pimple/Tests/ServiceIteratorTest.php

@@ -0,0 +1,52 @@
+<?php
+
+/*
+ * This file is part of Pimple.
+ *
+ * Copyright (c) 2009 Fabien Potencier
+ *
+ * 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.
+ */
+
+namespace Pimple\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Pimple\Container;
+use Pimple\ServiceIterator;
+use Pimple\Tests\Fixtures\Service;
+
+class ServiceIteratorTest extends TestCase
+{
+    public function testIsIterable()
+    {
+        $pimple = new Container();
+        $pimple['service1'] = function () {
+            return new Service();
+        };
+        $pimple['service2'] = function () {
+            return new Service();
+        };
+        $pimple['service3'] = function () {
+            return new Service();
+        };
+        $iterator = new ServiceIterator($pimple, ['service1', 'service2']);
+
+        $this->assertSame(['service1' => $pimple['service1'], 'service2' => $pimple['service2']], iterator_to_array($iterator));
+    }
+}

+ 1 - 0
vendor/uduncloud/udun-wallet-sdk/.gitignore

@@ -0,0 +1 @@
+/vendor

+ 111 - 0
vendor/uduncloud/udun-wallet-sdk/README.md

@@ -0,0 +1,111 @@
+# udun-sdk-php
+udun-sdk-php
+
+## 安装
+### 方式1:命令安装
+```php
+	composer require uduncloud/udun-wallet-sdk
+```
+
+### 方式2:composer 配置安装
+1,在composer.json添加如下配置
+```php
+{
+	"require":{
+		"uduncloud/udun-wallet-sdk": "^1.0"
+	}
+}
+```
+
+2,执行命令
+```
+	composer install
+```
+
+## 使用
+
+1,新建UdunController.php 
+```
+	use udun\Dispatch\UdunDispatch;
+
+	class UdunController{
+		protected $udunDispatch ;
+		public function __construct()
+	    {
+	       	// 控制器初始化
+	       	$this->initialize();
+	    }
+	    protected function initialize(){
+	    	$this->udunDispatch = new UdunDispatch([
+	            'merchant_no' => 30000, //商户号
+	            'api_key' => 'c789xxxxxxxxxxxxxxxxx388ecxxx',//apikey
+	            'gateway_address'=>'https://sig11.udun.io', //节点
+	            'callUrl'=>'https://localhost/callUrl', //回调地址
+	            'debug' => false  //调试模式
+	        ]);
+	    }
+	}
+```
+2,在需要使用到接口的类继承 UdunController
+
+```
+	##使用示例
+	namespace xxxx;
+	class Index extends UdunController{
+		//查询支持的交易对
+		public function supportCoins()
+	    {
+	    	$result =  $this->udunDispatch->supportCoins(true);
+	        return json($result);
+	    }
+
+
+	    //创建地址
+		public function createAddress()
+	    {
+	    	$result =  $this->udunDispatch->createAddress('195');
+	        return json($result);
+	    }
+
+	    //验证地址合法性
+		public function checkAddress()
+	    {
+	    	$result =  $this->udunDispatch->checkAddress('195','TEpK1aWkjDue6j8reeeMqG7hdJ5tRytyAF');
+	        return json($result);
+	    }
+
+	    //查询地址是否存在
+		public function existAddress()
+	    {
+	    	$result =  $this->udunDispatch->existAddress('195','TEpK1aWkjDue6j8reeeMqG7hdJ5tRytyAF');
+	        return json($result);
+	    }
+
+	    //申请提币
+		public function withdraw()
+	    {
+	    	$result =  $this->udunDispatch->withdraw('sn00001','195','195','TEpK1aWkjDue6j8reeeMqG7hdJ5tRytyAF',10);
+	        return json($result);
+	    }
+
+	    //交易回调
+		public function callback()
+	    {
+	    	$result =  $this->callback();
+	        return json($result);
+	    } 
+
+	}
+```
+
+
+## 其他
+
+```
+##curl: (35) OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to raw.githubusercontent.com:443
+如果提示以上错误需要添加ca证书
+##php.ini  打开ssl
+extension=php_openssl.dll;
+##证书路径
+openssl.cafile=D:\cacert.pem
+```

+ 24 - 0
vendor/uduncloud/udun-wallet-sdk/composer.json

@@ -0,0 +1,24 @@
+{
+    "name": "uduncloud/udun-wallet-sdk",
+    "description": "udun-wallet-sdk",
+    "version": "1.0.0",
+    "type": "1",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "udun wallet"
+        }
+    ],
+    "require": {
+        "hanson/foundation-sdk": "^5.0",
+        "php": ">=7.0"
+    },
+    "require-dev": {
+        "phpunit/phpunit": "^9.5"
+    },
+    "autoload": {
+        "psr-4": {
+            "Udun\\Dispatch\\": "src/"
+        }
+    }
+}

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 2799 - 0
vendor/uduncloud/udun-wallet-sdk/composer.lock


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 41 - 0
vendor/uduncloud/udun-wallet-sdk/demo/testApi.php


+ 70 - 0
vendor/uduncloud/udun-wallet-sdk/src/Api.php

@@ -0,0 +1,70 @@
+<?php
+namespace Udun\Dispatch;
+use Hanson\Foundation\AbstractAPI;
+class Api extends AbstractAPI
+{
+    //商户号
+    protected $merchant_no;   
+    //apikey      
+    protected $api_key;  
+    //节点地址           
+    protected $gateway_address;
+    //回调地址     
+    protected $callUrl;             
+    public function __construct( $merchant_no, string $api_key,string $gateway_address, string $callUrl)
+    {
+        $this->merchant_no = $merchant_no;
+        $this->api_key = $api_key;
+        $this->gateway_address = $gateway_address;
+        $this->callUrl = $callUrl;
+    }
+
+ 
+    /**
+     * @param string $method  
+     * @param array $params
+     * @return result
+     * @throws UdunDispatchException
+     */
+    public function request(string $method, array $body)
+    {
+    	$time = time();
+    	$nonce = rand(100000, 999999);
+        if($method=='/mch/support-coins'){
+            $body = json_encode($body);
+        }else{
+            $body = '['.json_encode($body).']';
+        }
+        
+        $sign = $this->signature($body,$time,$nonce);
+        $params = array(
+        	'timestamp' => $time,
+            'nonce' => $nonce,
+            'sign' => $sign,
+            'body' => $body
+        );
+        $http = $this->getHttp();
+        $response = $http->json($this->gateway_address. $method, $params);
+        $result = json_decode(strval($response->getBody()), true);
+        $this->checkErrorAndThrow($result);
+        return $result;
+    }
+
+    public function signature($body,$time,$nonce)
+    {
+        return md5($body.$this->api_key.$nonce.$time);
+    }
+
+    /**
+     * @param $result
+     * @throws UdunDispatchException
+     */
+    private function checkErrorAndThrow($result)
+    {
+        if (!$result || $result['code'] != 200) {
+            throw new UdunDispatchException($result['code'], $result['message']);
+        }
+    }
+}
+
+?>

+ 162 - 0
vendor/uduncloud/udun-wallet-sdk/src/Clients.php

@@ -0,0 +1,162 @@
+<?php
+namespace Udun\Dispatch;
+class Clients extends Api
+{
+	// 获取商户支持的币种信息
+	/**
+	 * showBalance	Boolean		是否查詢余額,false不獲取,true獲取
+	 * */
+    public function supportCoins($showBalance = true)
+    {
+        $body = array(
+            'merchantId' => $this->merchant_no,//商户号
+            'showBalance' => $showBalance
+        );
+        return $this->request('/mch/support-coins', $body);
+    }
+
+
+    /**
+     * 创建地址
+     * mainCoinType 主币种编号
+     * walletId 錢包編號,默認根據主錢包生成地址
+     * alias 地址別名 
+     */
+    public function createAddress($mainCoinType,$walletId=null,$alias=null)
+    {
+        $body = array(
+            'merchantId' => $this->merchant_no,
+            'mainCoinType' => $mainCoinType,
+            'callUrl' => $this->callUrl
+        );
+        if(!empty($walletId)){
+            $body['walletId']=$walletId;
+        }
+        if(!empty($alias)){
+            $body['alias']=$alias;
+        }
+        return $this->request('/mch/address/create', $body);
+    }
+
+    /**
+     * 验证地址的合法性
+     * mainCoinType 主币种编号
+     * address 地址
+     * 
+     * */
+    public function checkAddress($mainCoinType,$address)
+    {
+        $body = array(
+            'merchantId' => $this->merchant_no,//商户号
+            'mainCoinType' => $mainCoinType,
+            'address' => $address
+        );
+        return $this->request('/mch/check/address', $body);
+    }    
+
+
+    /**
+     * 验证地址是否存在
+     * mainCoinType 主币种编号
+     * address 地址
+     * 
+     * */
+    public function existAddress($mainCoinType,$address)
+    {
+        $body = array(
+            'merchantId' => $this->merchant_no,//商户号
+            'mainCoinType' => $mainCoinType,
+            'address' => $address
+        );
+        return $this->request('/mch/exist/address', $body);
+    }  
+
+
+    /**
+     * 申请提币
+     * businessId    业务编号,必须唯一
+     * mainCoinType  主币种编号
+     * coinType      子币种编号
+     * address       地址
+     * amount        提币数量
+     * memo          备注
+     * */
+    public function withdraw($businessId,$mainCoinType,$coinType,$address,$amount,$memo='')
+    {
+        $body = array(
+            'merchantId' => $this->merchant_no,//商户号
+            'mainCoinType' => $mainCoinType,
+            'coinType' => $coinType,
+            'address' => $address,
+            'businessId' => $businessId,
+            'amount' => $amount,
+            'callUrl' => $this->callUrl  //回调地址
+        );
+        if(!empty($memo)){
+            $body['memo']=$memo;
+        }
+        return $this->request('/mch/withdraw', $body);
+    } 
+
+
+
+    //自定义日志
+    function printLog($msg) {
+        if (!is_dir('log')){
+            mkdir('log',0777,true);
+        }
+        $path="log/".date('Y-m-d').".log";
+        file_put_contents($path, "【" . date('Y-m-d H:i:s') . "】" . $msg . "\r\n\r\n", FILE_APPEND);
+    }
+    //回调函数
+    public function callback(){
+        $body =  $_POST['body'];
+        $nonce = $_POST['nonce'];
+        $timestamp = $_POST['timestamp'];
+        $sign = $_POST['sign'];
+        //接收回调参数 用于日志记录
+        //$content = file_get_contents('php://input');
+        //$this->printLog("回调接收内容:".$content);
+        //验证签名
+        $signCheck = $this->signature($body,$timestamp,$nonce);
+        if ($sign != $signCheck) {
+            throw new UdunDispatchException(-1, '签名错误');
+            return ;
+        }
+        $body = json_decode($body);
+        //$this->printLog("回调接收内容(tradeType):".$body->tradeType);
+            //$body->tradeType 1充币回调 2提币回调
+        if ($body->tradeType == 1) {
+                
+            //$body->status 0待审核 1审核成功 2审核驳回 3交易成功 4交易失败
+            if($body->status == 3){
+                //业务处理 
+            }
+            //无论业务方处理成功与否(success,failed),回调都认为成功
+            return "success";
+
+        } elseif ($body->tradeType == 2) {
+            
+            //$body->status 0待审核 1审核成功 2审核驳回 3交易成功 4交易失败
+            if($body->status == 0){
+                //业务处理
+            }
+            else if($body->status == 1){
+                //业务处理
+            }
+            else if($body->status == 2){
+                //业务处理 
+            }
+            else if($body->status == 3){
+                //业务处理 
+            }
+            else if($body->status == 4){
+                //业务处理
+            }
+            //无论业务方处理成功与否(success,failed),回调都认为成功
+            return "success";
+        }
+    }
+
+}
+	

+ 26 - 0
vendor/uduncloud/udun-wallet-sdk/src/ClientsServiceProvider.php

@@ -0,0 +1,26 @@
+<?php
+
+namespace Udun\Dispatch;
+
+
+use Pimple\Container;
+use Pimple\ServiceProviderInterface;
+
+class ClientsServiceProvider implements ServiceProviderInterface
+{
+
+    /**
+     * Registers services on the given container.
+     *
+     * This method should only be used to configure services and parameters.
+     * It should not get services.
+     *
+     * @param Container $pimple A container instance
+     */
+    public function register(Container $pimple)
+    {
+        $pimple['clients'] = function ($pimple) {
+            return new Clients($pimple['config']->get('merchant_no'), $pimple['config']->get('api_key'), $pimple['config']->get('gateway_address'), $pimple['config']->get('callUrl'));
+        };
+    }
+}

+ 28 - 0
vendor/uduncloud/udun-wallet-sdk/src/UdunDispatch.php

@@ -0,0 +1,28 @@
+<?php
+
+
+namespace Udun\Dispatch;
+
+use Hanson\Foundation\Foundation;
+
+ 
+class UdunDispatch extends Foundation
+{
+
+    private $clients;
+
+    protected $providers = [
+        ClientsServiceProvider::class
+    ];
+
+    public function __construct($config)
+    {
+        parent::__construct($config);
+        $this->clients = new Clients($config['merchant_no'], $config['api_key'], $config['gateway_address'], $config['callUrl']);
+    }
+
+    public function __call($name, $arguments)
+    {
+        return $this->clients->{$name}(...$arguments);
+    }
+}

+ 0 - 0
vendor/uduncloud/udun-wallet-sdk/src/UdunDispatchException.php


Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác