Browse Source

更新google

王大坤 2 years ago
parent
commit
577e175234
100 changed files with 49896 additions and 4646 deletions
  1. 12 0
      .idea/codeception.xml
  2. 10 4
      .idea/new_api.iml
  3. 10 4
      .idea/php.xml
  4. 16 0
      .idea/phpspec.xml
  5. 41 0
      app/libs/google/Oauth.php
  6. 5 4
      composer.json
  7. 392 199
      composer.lock
  8. 6 0
      config/swdz.php
  9. 22 6
      vendor/adbario/php-dot-notation/src/Dot.php
  10. 5 4
      vendor/adbario/php-dot-notation/src/helpers.php
  11. 4 0
      vendor/alibabacloud/client/CHANGELOG.md
  12. 2 3
      vendor/alibabacloud/client/README-zh-CN.md
  13. 2 3
      vendor/alibabacloud/client/README.md
  14. 26 8
      vendor/alibabacloud/client/composer.json
  15. 1 1
      vendor/alibabacloud/client/src/AlibabaCloud.php
  16. 2 2
      vendor/alibabacloud/client/src/Credentials/Providers/EcsRamRoleProvider.php
  17. 2 2
      vendor/alibabacloud/client/src/Exception/ServerException.php
  18. 2 2
      vendor/alibabacloud/client/src/Functions.php
  19. 2 2
      vendor/alibabacloud/client/src/Log/LogFormatter.php
  20. 1 1
      vendor/alibabacloud/client/src/Request/Request.php
  21. 2 4
      vendor/alibabacloud/client/src/Request/RoaRequest.php
  22. 3 3
      vendor/alibabacloud/client/src/Request/Traits/RetryTrait.php
  23. 47 0
      vendor/alibabacloud/client/src/Support/Stringy.php
  24. 4 0
      vendor/alibabacloud/client/src/Traits/ArrayAccessTrait.php
  25. 2 2
      vendor/alibabacloud/client/src/Traits/ClientTrait.php
  26. 1 1
      vendor/alibabacloud/client/src/Traits/EndpointTrait.php
  27. 7 0
      vendor/alibabacloud/client/src/Traits/HasDataTrait.php
  28. 1 1
      vendor/alibabacloud/client/src/Traits/LogTrait.php
  29. 5 0
      vendor/aliyuncs/oss-sdk-php/CHANGELOG.md
  30. 65 0
      vendor/aliyuncs/oss-sdk-php/samples/BucketStat.php
  31. 76 0
      vendor/aliyuncs/oss-sdk-php/samples/CredentialsPhp.php
  32. 45 0
      vendor/aliyuncs/oss-sdk-php/samples/CredentialsProvider.php
  33. 63 0
      vendor/aliyuncs/oss-sdk-php/src/OSS/Credentials/Credentials.php
  34. 11 0
      vendor/aliyuncs/oss-sdk-php/src/OSS/Credentials/CredentialsProvider.php
  35. 35 0
      vendor/aliyuncs/oss-sdk-php/src/OSS/Credentials/StaticCredentialsProvider.php
  36. 1 1
      vendor/aliyuncs/oss-sdk-php/src/OSS/Http/RequestCore.php
  37. 246 0
      vendor/aliyuncs/oss-sdk-php/src/OSS/Model/BucketStat.php
  38. 92 29
      vendor/aliyuncs/oss-sdk-php/src/OSS/OssClient.php
  39. 43 17
      vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/GetBucketStatResultTest.php
  40. 148 0
      vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientTest.php
  41. 119 0
      vendor/bin/yaml-lint
  42. 20 2
      vendor/brick/math/CHANGELOG.md
  43. 0 17
      vendor/brick/math/SECURITY.md
  44. 3 3
      vendor/brick/math/composer.json
  45. 2 6
      vendor/brick/math/src/BigDecimal.php
  46. 16 3
      vendor/brick/math/src/BigInteger.php
  47. 1 3
      vendor/brick/math/src/BigNumber.php
  48. 4 7
      vendor/brick/math/src/BigRational.php
  49. 15 20
      vendor/brick/math/src/Internal/Calculator.php
  50. 0 6
      vendor/brick/math/src/Internal/Calculator/BcMathCalculator.php
  51. 1 3
      vendor/brick/math/src/Internal/Calculator/NativeCalculator.php
  52. 23452 6
      vendor/composer/autoload_classmap.php
  53. 4 3
      vendor/composer/autoload_files.php
  54. 9 4
      vendor/composer/autoload_psr4.php
  55. 23501 29
      vendor/composer/autoload_static.php
  56. 436 236
      vendor/composer/installed.json
  57. 272 203
      vendor/composer/installed.php
  58. 2 2
      vendor/composer/platform_check.php
  59. 0 180
      vendor/danielstjules/stringy/CHANGELOG.md
  60. 0 19
      vendor/danielstjules/stringy/LICENSE.txt
  61. 0 1082
      vendor/danielstjules/stringy/README.md
  62. 0 35
      vendor/danielstjules/stringy/composer.json
  63. 0 19
      vendor/danielstjules/stringy/src/Create.php
  64. 0 161
      vendor/danielstjules/stringy/src/StaticStringy.php
  65. 0 1986
      vendor/danielstjules/stringy/src/Stringy.php
  66. 4 4
      vendor/dingo/blueprint/composer.json
  67. 6 0
      vendor/doctrine/annotations/README.md
  68. 8 5
      vendor/doctrine/annotations/composer.json
  69. 1 1
      vendor/doctrine/annotations/docs/en/custom.rst
  70. 9 0
      vendor/doctrine/annotations/docs/en/index.rst
  71. 1 3
      vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation.php
  72. 2 2
      vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Enum.php
  73. 2 2
      vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/IgnoreAnnotation.php
  74. 2 2
      vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Target.php
  75. 3 8
      vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationException.php
  76. 1 3
      vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/CachedReader.php
  77. 16 2
      vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocLexer.php
  78. 30 11
      vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php
  79. 1 3
      vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/TokenParser.php
  80. 14 14
      vendor/doctrine/dbal/README.md
  81. 2 2
      vendor/doctrine/dbal/bin/doctrine-dbal.php
  82. 13 12
      vendor/doctrine/dbal/composer.json
  83. 37 0
      vendor/doctrine/dbal/src/ArrayParameterType.php
  84. 1 3
      vendor/doctrine/dbal/src/ArrayParameters/Exception.php
  85. 2 4
      vendor/doctrine/dbal/src/ArrayParameters/Exception/MissingNamedParameter.php
  86. 1 1
      vendor/doctrine/dbal/src/ArrayParameters/Exception/MissingPositionalParameter.php
  87. 12 21
      vendor/doctrine/dbal/src/Cache/ArrayResult.php
  88. 3 9
      vendor/doctrine/dbal/src/Cache/CacheException.php
  89. 8 15
      vendor/doctrine/dbal/src/Cache/QueryCacheProfile.php
  90. 64 9
      vendor/doctrine/dbal/src/Configuration.php
  91. 248 127
      vendor/doctrine/dbal/src/Connection.php
  92. 5 15
      vendor/doctrine/dbal/src/ConnectionException.php
  93. 15 4
      vendor/doctrine/dbal/src/Connections/PrimaryReadReplicaConnection.php
  94. 11 2
      vendor/doctrine/dbal/src/Driver.php
  95. 1 3
      vendor/doctrine/dbal/src/Driver/API/MySQL/ExceptionConverter.php
  96. 2 6
      vendor/doctrine/dbal/src/Driver/API/OCI/ExceptionConverter.php
  97. 3 7
      vendor/doctrine/dbal/src/Driver/API/PostgreSQL/ExceptionConverter.php
  98. 7 6
      vendor/doctrine/dbal/src/Driver/API/SQLite/ExceptionConverter.php
  99. 32 0
      vendor/doctrine/dbal/src/Driver/API/SQLite/UserDefinedFunctions.php
  100. 12 2
      vendor/doctrine/dbal/src/Driver/AbstractDB2Driver.php

+ 12 - 0
.idea/codeception.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Codeception">
+    <option name="configurations">
+      <list>
+        <Configuration>
+          <option name="path" value="$PROJECT_DIR$/tests" />
+        </Configuration>
+      </list>
+    </option>
+  </component>
+</project>

+ 10 - 4
.idea/new_api.iml

@@ -18,7 +18,6 @@
       <excludeFolder url="file://$MODULE_DIR$/vendor/brick/math" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/brick/math" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/clagiordano/weblibs-configmanager" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/clagiordano/weblibs-configmanager" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/composer" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/composer" />
-      <excludeFolder url="file://$MODULE_DIR$/vendor/danielstjules/stringy" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/dcat/easy-excel" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/dcat/easy-excel" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/dcat/laravel-admin" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/dcat/laravel-admin" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/dflydev/dot-access-data" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/dflydev/dot-access-data" />
@@ -39,9 +38,13 @@
       <excludeFolder url="file://$MODULE_DIR$/vendor/facade/ignition-contracts" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/facade/ignition-contracts" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/fakerphp/faker" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/fakerphp/faker" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/filp/whoops" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/filp/whoops" />
+      <excludeFolder url="file://$MODULE_DIR$/vendor/firebase/php-jwt" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/fruitcake/laravel-cors" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/fruitcake/laravel-cors" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/giggsey/libphonenumber-for-php" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/giggsey/libphonenumber-for-php" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/giggsey/locale" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/giggsey/locale" />
+      <excludeFolder url="file://$MODULE_DIR$/vendor/google/apiclient" />
+      <excludeFolder url="file://$MODULE_DIR$/vendor/google/apiclient-services" />
+      <excludeFolder url="file://$MODULE_DIR$/vendor/google/auth" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/graham-campbell/result-type" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/graham-campbell/result-type" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/guzzle" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/guzzle" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/promises" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/promises" />
@@ -85,6 +88,8 @@
       <excludeFolder url="file://$MODULE_DIR$/vendor/overtrue/laravel-wechat" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/overtrue/laravel-wechat" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/overtrue/socialite" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/overtrue/socialite" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/overtrue/wechat" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/overtrue/wechat" />
+      <excludeFolder url="file://$MODULE_DIR$/vendor/paragonie/constant_time_encoding" />
+      <excludeFolder url="file://$MODULE_DIR$/vendor/paragonie/random_compat" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/phar-io/manifest" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/phar-io/manifest" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/phar-io/version" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/phar-io/version" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/php-open-source-saver/jwt-auth" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/php-open-source-saver/jwt-auth" />
@@ -92,7 +97,8 @@
       <excludeFolder url="file://$MODULE_DIR$/vendor/phpdocumentor/reflection-docblock" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/phpdocumentor/reflection-docblock" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/phpdocumentor/type-resolver" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/phpdocumentor/type-resolver" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/phpoption/phpoption" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/phpoption/phpoption" />
-      <excludeFolder url="file://$MODULE_DIR$/vendor/phpspec/prophecy" />
+      <excludeFolder url="file://$MODULE_DIR$/vendor/phpseclib/phpseclib" />
+      <excludeFolder url="file://$MODULE_DIR$/vendor/phpstan/phpdoc-parser" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-code-coverage" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-code-coverage" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-file-iterator" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-file-iterator" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-invoker" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-invoker" />
@@ -103,6 +109,7 @@
       <excludeFolder url="file://$MODULE_DIR$/vendor/prettus/l5-repository" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/prettus/l5-repository" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/prettus/laravel-validation" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/prettus/laravel-validation" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/psr/cache" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/psr/cache" />
+      <excludeFolder url="file://$MODULE_DIR$/vendor/psr/clock" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/psr/container" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/psr/container" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/psr/event-dispatcher" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/psr/event-dispatcher" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-client" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-client" />
@@ -135,7 +142,6 @@
       <excludeFolder url="file://$MODULE_DIR$/vendor/socialiteproviders/weixin" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/socialiteproviders/weixin" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/spatie/eloquent-sortable" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/spatie/eloquent-sortable" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/spatie/laravel-package-tools" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/spatie/laravel-package-tools" />
-      <excludeFolder url="file://$MODULE_DIR$/vendor/stella-maris/clock" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/stomp-php/stomp-php" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/stomp-php/stomp-php" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/swiftmailer/swiftmailer" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/swiftmailer/swiftmailer" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/symfony/cache" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/symfony/cache" />
@@ -159,7 +165,6 @@
       <excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php72" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php72" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php73" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php73" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php80" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php80" />
-      <excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php81" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/symfony/process" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/symfony/process" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/symfony/psr-http-message-bridge" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/symfony/psr-http-message-bridge" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/symfony/routing" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/symfony/routing" />
@@ -169,6 +174,7 @@
       <excludeFolder url="file://$MODULE_DIR$/vendor/symfony/translation-contracts" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/symfony/translation-contracts" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/symfony/var-dumper" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/symfony/var-dumper" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/symfony/var-exporter" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/symfony/var-exporter" />
+      <excludeFolder url="file://$MODULE_DIR$/vendor/symfony/yaml" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/tencent/tls-sig-api-v2" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/tencent/tls-sig-api-v2" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/tencentcloud/tencentcloud-sdk-php" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/tencentcloud/tencentcloud-sdk-php" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/theseer/tokenizer" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/theseer/tokenizer" />

+ 10 - 4
.idea/php.xml

@@ -13,7 +13,6 @@
   <component name="PhpIncludePathManager">
   <component name="PhpIncludePathManager">
     <include_path>
     <include_path>
       <path value="$PROJECT_DIR$/vendor/symfony/http-kernel" />
       <path value="$PROJECT_DIR$/vendor/symfony/http-kernel" />
-      <path value="$PROJECT_DIR$/vendor/symfony/polyfill-php81" />
       <path value="$PROJECT_DIR$/vendor/symfony/http-foundation" />
       <path value="$PROJECT_DIR$/vendor/symfony/http-foundation" />
       <path value="$PROJECT_DIR$/vendor/symfony/var-dumper" />
       <path value="$PROJECT_DIR$/vendor/symfony/var-dumper" />
       <path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher" />
       <path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher" />
@@ -58,7 +57,6 @@
       <path value="$PROJECT_DIR$/vendor/socialiteproviders/weixin" />
       <path value="$PROJECT_DIR$/vendor/socialiteproviders/weixin" />
       <path value="$PROJECT_DIR$/vendor/dingo/blueprint" />
       <path value="$PROJECT_DIR$/vendor/dingo/blueprint" />
       <path value="$PROJECT_DIR$/vendor/dflydev/dot-access-data" />
       <path value="$PROJECT_DIR$/vendor/dflydev/dot-access-data" />
-      <path value="$PROJECT_DIR$/vendor/stella-maris/clock" />
       <path value="$PROJECT_DIR$/vendor/socialiteproviders/facebook" />
       <path value="$PROJECT_DIR$/vendor/socialiteproviders/facebook" />
       <path value="$PROJECT_DIR$/vendor/opis/closure" />
       <path value="$PROJECT_DIR$/vendor/opis/closure" />
       <path value="$PROJECT_DIR$/vendor/adbario/php-dot-notation" />
       <path value="$PROJECT_DIR$/vendor/adbario/php-dot-notation" />
@@ -118,8 +116,6 @@
       <path value="$PROJECT_DIR$/vendor/facade/ignition" />
       <path value="$PROJECT_DIR$/vendor/facade/ignition" />
       <path value="$PROJECT_DIR$/vendor/facade/ignition-contracts" />
       <path value="$PROJECT_DIR$/vendor/facade/ignition-contracts" />
       <path value="$PROJECT_DIR$/vendor/facade/flare-client-php" />
       <path value="$PROJECT_DIR$/vendor/facade/flare-client-php" />
-      <path value="$PROJECT_DIR$/vendor/phpspec/prophecy" />
-      <path value="$PROJECT_DIR$/vendor/danielstjules/stringy" />
       <path value="$PROJECT_DIR$/vendor/php-open-source-saver/jwt-auth" />
       <path value="$PROJECT_DIR$/vendor/php-open-source-saver/jwt-auth" />
       <path value="$PROJECT_DIR$/vendor/monolog/monolog" />
       <path value="$PROJECT_DIR$/vendor/monolog/monolog" />
       <path value="$PROJECT_DIR$/vendor/dragonmantank/cron-expression" />
       <path value="$PROJECT_DIR$/vendor/dragonmantank/cron-expression" />
@@ -182,6 +178,16 @@
       <path value="$PROJECT_DIR$/vendor/symfony/service-contracts" />
       <path value="$PROJECT_DIR$/vendor/symfony/service-contracts" />
       <path value="$PROJECT_DIR$/vendor/symfony/translation-contracts" />
       <path value="$PROJECT_DIR$/vendor/symfony/translation-contracts" />
       <path value="$PROJECT_DIR$/vendor/composer" />
       <path value="$PROJECT_DIR$/vendor/composer" />
+      <path value="$PROJECT_DIR$/vendor/psr/clock" />
+      <path value="$PROJECT_DIR$/vendor/symfony/yaml" />
+      <path value="$PROJECT_DIR$/vendor/phpstan/phpdoc-parser" />
+      <path value="$PROJECT_DIR$/vendor/firebase/php-jwt" />
+      <path value="$PROJECT_DIR$/vendor/paragonie/random_compat" />
+      <path value="$PROJECT_DIR$/vendor/phpseclib/phpseclib" />
+      <path value="$PROJECT_DIR$/vendor/paragonie/constant_time_encoding" />
+      <path value="$PROJECT_DIR$/vendor/google/auth" />
+      <path value="$PROJECT_DIR$/vendor/google/apiclient" />
+      <path value="$PROJECT_DIR$/vendor/google/apiclient-services" />
     </include_path>
     </include_path>
   </component>
   </component>
   <component name="PhpProjectSharedConfiguration" php_language_level="7.3" />
   <component name="PhpProjectSharedConfiguration" php_language_level="7.3" />

+ 16 - 0
.idea/phpspec.xml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="PHPSpec">
+    <suites>
+      <PhpSpecSuiteConfiguration>
+        <option name="myPath" value="$PROJECT_DIR$" />
+      </PhpSpecSuiteConfiguration>
+      <PhpSpecSuiteConfiguration>
+        <option name="myPath" value="$PROJECT_DIR$" />
+      </PhpSpecSuiteConfiguration>
+      <PhpSpecSuiteConfiguration>
+        <option name="myPath" value="$PROJECT_DIR$" />
+      </PhpSpecSuiteConfiguration>
+    </suites>
+  </component>
+</project>

+ 41 - 0
app/libs/google/Oauth.php

@@ -0,0 +1,41 @@
+<?php
+
+namespace App\libs\google;
+
+use Google\Client;
+use Illuminate\Support\Facades\Config;
+
+class Oauth
+{
+    public function __construct()
+    {
+        $this->config = Config::get('swdz.goodle');
+        $this->client = new Client([
+            'client_id' => $this->config['client_id'],
+            'client_secret' => $this->config['client_secret'],
+            'redirect_uri' => $this->config['redirect_uri'],
+            'scopes' => $this->config['scopes']
+        ]);
+    }
+
+    /**
+     * APP通过code换取用户信息
+     *
+     * @return array|false
+     * @throws \Psr\Container\ContainerExceptionInterface
+     * @throws \Psr\Container\NotFoundExceptionInterface
+     */
+    public function appAuth(){
+        $code = request()->get('code', null);
+        return $this->client->verifyIdToken($code);
+    }
+
+    /**
+     * WEB打开授权页面(待补充)
+     *
+     * @return void
+     */
+    public function webAuth(){
+
+    }
+}

+ 5 - 4
composer.json

@@ -6,12 +6,16 @@
     "license": "MIT",
     "license": "MIT",
     "require": {
     "require": {
         "php": "^7.3|^8.0",
         "php": "^7.3|^8.0",
+        "ext-curl": "*",
+        "ext-json": "*",
+        "ext-openssl": "*",
         "alibabacloud/iot": "^1.8",
         "alibabacloud/iot": "^1.8",
         "api-ecosystem-for-laravel/dingo-api": "^v3.1.1",
         "api-ecosystem-for-laravel/dingo-api": "^v3.1.1",
         "dcat/easy-excel": "^1.0",
         "dcat/easy-excel": "^1.0",
         "dcat/laravel-admin": "2.*",
         "dcat/laravel-admin": "2.*",
         "fruitcake/laravel-cors": "^2.0",
         "fruitcake/laravel-cors": "^2.0",
         "giggsey/libphonenumber-for-php": "^8.12",
         "giggsey/libphonenumber-for-php": "^8.12",
+        "google/apiclient": "^2.15",
         "guzzlehttp/guzzle": "^7.0.1",
         "guzzlehttp/guzzle": "^7.0.1",
         "iidestiny/laravel-filesystem-oss": "2.1",
         "iidestiny/laravel-filesystem-oss": "2.1",
         "jormin/laravel-ddoc": "^1.1",
         "jormin/laravel-ddoc": "^1.1",
@@ -29,10 +33,7 @@
         "socialiteproviders/weixin": "^4.1",
         "socialiteproviders/weixin": "^4.1",
         "stomp-php/stomp-php": "^5.0",
         "stomp-php/stomp-php": "^5.0",
         "tencent/tls-sig-api-v2": "1.0",
         "tencent/tls-sig-api-v2": "1.0",
-        "tencentcloud/tencentcloud-sdk-php": "^3.0",
-        "ext-curl": "*",
-        "ext-json": "*",
-        "ext-openssl": "*"
+        "tencentcloud/tencentcloud-sdk-php": "^3.0"
     },
     },
     "require-dev": {
     "require-dev": {
         "facade/ignition": "^2.5",
         "facade/ignition": "^2.5",

File diff suppressed because it is too large
+ 392 - 199
composer.lock


+ 6 - 0
config/swdz.php

@@ -10,4 +10,10 @@ return [
         // accessToken 储存驱动 db|redis
         // accessToken 储存驱动 db|redis
         'token_drive'   => 'db'
         'token_drive'   => 'db'
     ],
     ],
+    'goodle' => [
+        'client_id' => '521103626174-tvkfskvjnou2uonp90fm4mvg4b0h1ioe.apps.googleusercontent.com',
+        'client_secret' => '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',
+        'redirect_uri' => 'https://t11.9026.com/api/auth/callback',//网页授权使用
+        'scopes' => ['email', 'profile']
+    ]
 ];
 ];

+ 22 - 6
vendor/adbario/php-dot-notation/src/Dot.php

@@ -29,14 +29,25 @@ class Dot implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable
      */
      */
     protected $items = [];
     protected $items = [];
 
 
+
+    /**
+     * The delimiter (alternative to a '.') to be used.
+     *
+     * @var string
+     */
+    protected $delimiter = '.';
+
+
     /**
     /**
      * Create a new Dot instance
      * Create a new Dot instance
      *
      *
      * @param mixed $items
      * @param mixed $items
+     * @param string $delimiter
      */
      */
-    public function __construct($items = [])
+    public function __construct($items = [], $delimiter = '.')
     {
     {
         $this->items = $this->getArrayItems($items);
         $this->items = $this->getArrayItems($items);
+        $this->delimiter = strlen($delimiter) ? $delimiter : '.';
     }
     }
 
 
     /**
     /**
@@ -104,7 +115,7 @@ class Dot implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable
             }
             }
 
 
             $items = &$this->items;
             $items = &$this->items;
-            $segments = explode('.', $key);
+            $segments = explode($this->delimiter, $key);
             $lastSegment = array_pop($segments);
             $lastSegment = array_pop($segments);
 
 
             foreach ($segments as $segment) {
             foreach ($segments as $segment) {
@@ -148,6 +159,10 @@ class Dot implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable
             $items = $this->items;
             $items = $this->items;
         }
         }
 
 
+        if (!func_num_args()) {
+            $delimiter = $this->delimiter;
+        }
+
         foreach ($items as $key => $value) {
         foreach ($items as $key => $value) {
             if (is_array($value) && !empty($value)) {
             if (is_array($value) && !empty($value)) {
                 $flatten = array_merge(
                 $flatten = array_merge(
@@ -179,13 +194,13 @@ class Dot implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable
             return $this->items[$key];
             return $this->items[$key];
         }
         }
 
 
-        if (strpos($key, '.') === false) {
+        if (strpos($key, $this->delimiter) === false) {
             return $default;
             return $default;
         }
         }
 
 
         $items = $this->items;
         $items = $this->items;
 
 
-        foreach (explode('.', $key) as $segment) {
+        foreach (explode($this->delimiter, $key) as $segment) {
             if (!is_array($items) || !$this->exists($items, $segment)) {
             if (!is_array($items) || !$this->exists($items, $segment)) {
                 return $default;
                 return $default;
             }
             }
@@ -234,7 +249,7 @@ class Dot implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable
                 continue;
                 continue;
             }
             }
 
 
-            foreach (explode('.', $key) as $segment) {
+            foreach (explode($this->delimiter, $key) as $segment) {
                 if (!is_array($items) || !$this->exists($items, $segment)) {
                 if (!is_array($items) || !$this->exists($items, $segment)) {
                     return false;
                     return false;
                 }
                 }
@@ -446,7 +461,7 @@ class Dot implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable
 
 
         $items = &$this->items;
         $items = &$this->items;
 
 
-        foreach (explode('.', $keys) as $key) {
+        foreach (explode($this->delimiter, $keys) as $key) {
             if (!isset($items[$key]) || !is_array($items[$key])) {
             if (!isset($items[$key]) || !is_array($items[$key])) {
                 $items[$key] = [];
                 $items[$key] = [];
             }
             }
@@ -600,6 +615,7 @@ class Dot implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable
      *
      *
      * @return array
      * @return array
      */
      */
+    #[\ReturnTypeWillChange]
     public function jsonSerialize()
     public function jsonSerialize()
     {
     {
         return $this->items;
         return $this->items;

+ 5 - 4
vendor/adbario/php-dot-notation/src/helpers.php

@@ -11,13 +11,14 @@ use Adbar\Dot;
 
 
 if (! function_exists('dot')) {
 if (! function_exists('dot')) {
     /**
     /**
-     * Create a new Dot object with the given items
+     * Create a new Dot object with the given items and optional delimiter
      *
      *
-     * @param  mixed $items
+     * @param  mixed  $items
+     * @param  string $delimiter
      * @return \Adbar\Dot
      * @return \Adbar\Dot
      */
      */
-    function dot($items)
+    function dot($items, $delimiter = '.')
     {
     {
-        return new Dot($items);
+        return new Dot($items, $delimiter);
     }
     }
 }
 }

+ 4 - 0
vendor/alibabacloud/client/CHANGELOG.md

@@ -1,5 +1,9 @@
 # CHANGELOG
 # CHANGELOG
 
 
+## 1.5.32 - 2022-12-08
+
+- Support PHP versions: From 5.5 up to 8.1
+
 ## 1.5.31 - 2021-05-13
 ## 1.5.31 - 2021-05-13
 
 
 - Deprecate `\GuzzleHttp\Psr7\parse_query` method
 - Deprecate `\GuzzleHttp\Psr7\parse_query` method

+ 2 - 3
vendor/alibabacloud/client/README-zh-CN.md

@@ -6,9 +6,8 @@
 [![composer.lock](https://poser.pugx.org/alibabacloud/client/composerlock)](https://packagist.org/packages/alibabacloud/client)
 [![composer.lock](https://poser.pugx.org/alibabacloud/client/composerlock)](https://packagist.org/packages/alibabacloud/client)
 [![Total Downloads](https://poser.pugx.org/alibabacloud/client/downloads)](https://packagist.org/packages/alibabacloud/client)
 [![Total Downloads](https://poser.pugx.org/alibabacloud/client/downloads)](https://packagist.org/packages/alibabacloud/client)
 [![License](https://poser.pugx.org/alibabacloud/client/license)](https://packagist.org/packages/alibabacloud/client)
 [![License](https://poser.pugx.org/alibabacloud/client/license)](https://packagist.org/packages/alibabacloud/client)
-[![codecov](https://codecov.io/gh/aliyun/openapi-sdk-php-client/branch/master/graph/badge.svg)](https://codecov.io/gh/aliyun/openapi-sdk-php-client)
-[![Travis Build Status](https://travis-ci.org/aliyun/openapi-sdk-php-client.svg?branch=master)](https://travis-ci.org/aliyun/openapi-sdk-php-client)
-[![Appveyor Build Status](https://ci.appveyor.com/api/projects/status/qb8j3lhg8349k0hk/branch/master?svg=true)](https://ci.appveyor.com/project/aliyun/openapi-sdk-php-client/branch/master)
+[![codecov](https://codecov.io/gh/aliyun/openapi-sdk-php-client/branch/master/graph/badge.svg?token=90Yd5Bne3S)](https://codecov.io/gh/aliyun/openapi-sdk-php-client)
+[![PHP Version Require](http://poser.pugx.org/alibabacloud/client/require/php)](https://packagist.org/packages/alibabacloud/client)
 
 
 
 
 ![](https://aliyunsdk-pages.alicdn.com/icons/AlibabaCloud.svg)
 ![](https://aliyunsdk-pages.alicdn.com/icons/AlibabaCloud.svg)

+ 2 - 3
vendor/alibabacloud/client/README.md

@@ -6,9 +6,8 @@ English | [简体中文](/README-zh-CN.md)
 [![composer.lock](https://poser.pugx.org/alibabacloud/client/composerlock)](https://packagist.org/packages/alibabacloud/client)
 [![composer.lock](https://poser.pugx.org/alibabacloud/client/composerlock)](https://packagist.org/packages/alibabacloud/client)
 [![Total Downloads](https://poser.pugx.org/alibabacloud/client/downloads)](https://packagist.org/packages/alibabacloud/client)
 [![Total Downloads](https://poser.pugx.org/alibabacloud/client/downloads)](https://packagist.org/packages/alibabacloud/client)
 [![License](https://poser.pugx.org/alibabacloud/client/license)](https://packagist.org/packages/alibabacloud/client)
 [![License](https://poser.pugx.org/alibabacloud/client/license)](https://packagist.org/packages/alibabacloud/client)
-[![codecov](https://codecov.io/gh/aliyun/openapi-sdk-php-client/branch/master/graph/badge.svg)](https://codecov.io/gh/aliyun/openapi-sdk-php-client)
-[![Travis Build Status](https://travis-ci.org/aliyun/openapi-sdk-php-client.svg?branch=master)](https://travis-ci.org/aliyun/openapi-sdk-php-client)
-[![Appveyor Build Status](https://ci.appveyor.com/api/projects/status/qb8j3lhg8349k0hk/branch/master?svg=true)](https://ci.appveyor.com/project/aliyun/openapi-sdk-php-client/branch/master)
+[![codecov](https://codecov.io/gh/aliyun/openapi-sdk-php-client/branch/master/graph/badge.svg?token=90Yd5Bne3S)](https://codecov.io/gh/aliyun/openapi-sdk-php-client)
+[![PHP Version Require](http://poser.pugx.org/alibabacloud/client/require/php)](https://packagist.org/packages/alibabacloud/client)
 
 
 
 
 ![](https://aliyunsdk-pages.alicdn.com/icons/AlibabaCloud.svg)
 ![](https://aliyunsdk-pages.alicdn.com/icons/AlibabaCloud.svg)

+ 26 - 8
vendor/alibabacloud/client/composer.json

@@ -35,9 +35,8 @@
     "ext-simplexml": "*",
     "ext-simplexml": "*",
     "ext-xmlwriter": "*",
     "ext-xmlwriter": "*",
     "guzzlehttp/guzzle": "^6.3|^7.0",
     "guzzlehttp/guzzle": "^6.3|^7.0",
-    "danielstjules/stringy": "^3.1",
     "mtdowling/jmespath.php": "^2.5",
     "mtdowling/jmespath.php": "^2.5",
-    "adbario/php-dot-notation": "^2.2",
+    "adbario/php-dot-notation": "^2.4.1",
     "clagiordano/weblibs-configmanager": "^1.0"
     "clagiordano/weblibs-configmanager": "^1.0"
   },
   },
   "require-dev": {
   "require-dev": {
@@ -49,7 +48,7 @@
     "drupal/coder": "^8.3",
     "drupal/coder": "^8.3",
     "symfony/dotenv": "^3.4",
     "symfony/dotenv": "^3.4",
     "league/climate": "^3.2.4",
     "league/climate": "^3.2.4",
-    "phpunit/phpunit": "^5.7.27|^6.1",
+    "phpunit/phpunit": "^5.7|^6.6|^7.5|^8.5|^9.5",
     "monolog/monolog": "^1.24",
     "monolog/monolog": "^1.24",
     "composer/composer": "^1.8",
     "composer/composer": "^1.8",
     "mikey179/vfsstream": "^1.6",
     "mikey179/vfsstream": "^1.6",
@@ -73,7 +72,10 @@
   },
   },
   "config": {
   "config": {
     "preferred-install": "dist",
     "preferred-install": "dist",
-    "optimize-autoloader": true
+    "optimize-autoloader": true,
+    "allow-plugins": {
+      "dealerdirect/phpcodesniffer-composer-installer": true
+    }
   },
   },
   "minimum-stability": "dev",
   "minimum-stability": "dev",
   "prefer-stable": true,
   "prefer-stable": true,
@@ -95,13 +97,29 @@
     "test": [
     "test": [
       "phpunit --colors=always"
       "phpunit --colors=always"
     ],
     ],
-    "unit": [
+    "test4HighVersion": [
+      "@clearCache",
+      "phpunit --testsuite=Test4HighVersion --colors=always"
+    ],
+    "test4LowVersion": [
+      "@clearCache",
+      "phpunit --testsuite=Test4LowVersion --colors=always"
+    ],
+    "unit4HighVersion": [
+      "@clearCache",
+      "phpunit --testsuite=Unit4HighVersion --colors=always"
+    ],
+    "unit4LowVersion": [
+      "@clearCache",
+      "phpunit --testsuite=Unit4LowVersion --colors=always"
+    ],
+    "feature4HighVersion": [
       "@clearCache",
       "@clearCache",
-      "phpunit --testsuite=Unit --colors=always"
+      "phpunit --testsuite=Feature4HighVersion --colors=always"
     ],
     ],
-    "feature": [
+    "feature4LowVersion": [
       "@clearCache",
       "@clearCache",
-      "phpunit --testsuite=Feature --colors=always"
+      "phpunit --testsuite=Feature4LowVersion --colors=always"
     ],
     ],
     "coverage": "open cache/coverage/index.html",
     "coverage": "open cache/coverage/index.html",
     "clearCache": "rm -rf cache/*",
     "clearCache": "rm -rf cache/*",

+ 1 - 1
vendor/alibabacloud/client/src/AlibabaCloud.php

@@ -30,7 +30,7 @@ class AlibabaCloud
     /**
     /**
      * Version of the Client
      * Version of the Client
      */
      */
-    const VERSION = '1.5.29';
+    const VERSION = '1.5.32';
 
 
     /**
     /**
      * This static method can directly call the specific service.
      * This static method can directly call the specific service.

+ 2 - 2
vendor/alibabacloud/client/src/Credentials/Providers/EcsRamRoleProvider.php

@@ -3,7 +3,7 @@
 namespace AlibabaCloud\Client\Credentials\Providers;
 namespace AlibabaCloud\Client\Credentials\Providers;
 
 
 use Exception;
 use Exception;
-use Stringy\Stringy;
+use AlibabaCloud\Client\Support\Stringy;
 use AlibabaCloud\Client\SDK;
 use AlibabaCloud\Client\SDK;
 use AlibabaCloud\Client\Result\Result;
 use AlibabaCloud\Client\Result\Result;
 use Psr\Http\Message\ResponseInterface;
 use Psr\Http\Message\ResponseInterface;
@@ -112,7 +112,7 @@ class EcsRamRoleProvider extends Provider
         try {
         try {
             return RpcRequest::createClient()->request('GET', $url, $options);
             return RpcRequest::createClient()->request('GET', $url, $options);
         } catch (GuzzleException $exception) {
         } catch (GuzzleException $exception) {
-            if (Stringy::create($exception->getMessage())->contains('timed')) {
+            if (Stringy::contains($exception->getMessage(), 'timed')) {
                 $message = 'Timeout or instance does not belong to Alibaba Cloud';
                 $message = 'Timeout or instance does not belong to Alibaba Cloud';
             } else {
             } else {
                 $message = $exception->getMessage();
                 $message = $exception->getMessage();

+ 2 - 2
vendor/alibabacloud/client/src/Exception/ServerException.php

@@ -2,7 +2,7 @@
 
 
 namespace AlibabaCloud\Client\Exception;
 namespace AlibabaCloud\Client\Exception;
 
 
-use Stringy\Stringy;
+use AlibabaCloud\Client\Support\Stringy;
 use RuntimeException;
 use RuntimeException;
 use AlibabaCloud\Client\SDK;
 use AlibabaCloud\Client\SDK;
 use AlibabaCloud\Client\Result\Result;
 use AlibabaCloud\Client\Result\Result;
@@ -83,7 +83,7 @@ class ServerException extends AlibabaCloudException
     private function distinguishSignatureErrors()
     private function distinguishSignatureErrors()
     {
     {
         if ($this->result->getRequest()
         if ($this->result->getRequest()
-            && Stringy::create($this->errorMessage)->contains($this->result->getRequest()->stringToSign())) {
+            && Stringy::contains($this->errorMessage, $this->result->getRequest()->stringToSign())) {
             $this->errorCode    = 'InvalidAccessKeySecret';
             $this->errorCode    = 'InvalidAccessKeySecret';
             $this->errorMessage = 'Specified Access Key Secret is not valid.';
             $this->errorMessage = 'Specified Access Key Secret is not valid.';
         }
         }

+ 2 - 2
vendor/alibabacloud/client/src/Functions.php

@@ -3,7 +3,7 @@
 namespace AlibabaCloud\Client;
 namespace AlibabaCloud\Client;
 
 
 use Closure;
 use Closure;
-use Stringy\Stringy;
+use AlibabaCloud\Client\Support\Stringy;
 use League\CLImate\CLImate;
 use League\CLImate\CLImate;
 use AlibabaCloud\Client\Exception\ClientException;
 use AlibabaCloud\Client\Exception\ClientException;
 
 
@@ -60,7 +60,7 @@ function inOpenBasedir($filename, $throwException = false)
 function inDir($filename, array $dirs)
 function inDir($filename, array $dirs)
 {
 {
     foreach ($dirs as $dir) {
     foreach ($dirs as $dir) {
-        if (!Stringy::create($dir)->endsWith(DIRECTORY_SEPARATOR)) {
+        if (!Stringy::endsWith($dir, DIRECTORY_SEPARATOR)) {
             $dir .= DIRECTORY_SEPARATOR;
             $dir .= DIRECTORY_SEPARATOR;
         }
         }
 
 

+ 2 - 2
vendor/alibabacloud/client/src/Log/LogFormatter.php

@@ -37,14 +37,14 @@ class LogFormatter
      */
      */
     public function __construct($template)
     public function __construct($template)
     {
     {
-        parent::__construct($template);
+        // parent::__construct($template);
         self::$logStartTime = microtime(true);
         self::$logStartTime = microtime(true);
         $this->template     = $template;
         $this->template     = $template;
         $timezone           = new DateTimeZone(date_default_timezone_get() ?: 'UTC');
         $timezone           = new DateTimeZone(date_default_timezone_get() ?: 'UTC');
         if (PHP_VERSION_ID < 70100) {
         if (PHP_VERSION_ID < 70100) {
             self::$ts = DateTime::createFromFormat('U.u', sprintf('%.6F', microtime(true)), $timezone);
             self::$ts = DateTime::createFromFormat('U.u', sprintf('%.6F', microtime(true)), $timezone);
         } else {
         } else {
-            self::$ts = new DateTime(null, $timezone);
+            self::$ts = new DateTime('now', $timezone);
         }
         }
     }
     }
 
 

+ 1 - 1
vendor/alibabacloud/client/src/Request/Request.php

@@ -113,7 +113,7 @@ abstract class Request implements ArrayAccess
         $this->options['timeout']         = self::TIMEOUT;
         $this->options['timeout']         = self::TIMEOUT;
 
 
         // Turn on debug mode based on environment variable.
         // Turn on debug mode based on environment variable.
-        if (strtolower(\AlibabaCloud\Client\env('DEBUG')) === 'sdk') {
+        if (null !== \AlibabaCloud\Client\env('DEBUG') && strtolower(\AlibabaCloud\Client\env('DEBUG')) === 'sdk') {
             $this->options['debug'] = true;
             $this->options['debug'] = true;
         }
         }
 
 

+ 2 - 4
vendor/alibabacloud/client/src/Request/RoaRequest.php

@@ -3,7 +3,7 @@
 namespace AlibabaCloud\Client\Request;
 namespace AlibabaCloud\Client\Request;
 
 
 use Exception;
 use Exception;
-use Stringy\Stringy;
+use AlibabaCloud\Client\Support\Stringy;
 use RuntimeException;
 use RuntimeException;
 use AlibabaCloud\Client\SDK;
 use AlibabaCloud\Client\SDK;
 use AlibabaCloud\Client\Encode;
 use AlibabaCloud\Client\Encode;
@@ -98,9 +98,7 @@ class RoaRequest extends Request
      */
      */
     private function encodeBody(array $params)
     private function encodeBody(array $params)
     {
     {
-        $stringy = Stringy::create($this->options['headers']['Content-Type']);
-
-        if ($stringy->contains('application/json', false)) {
+        if (Stringy::contains($this->options['headers']['Content-Type'], 'application/json', false)) {
             $this->options['body']                   = json_encode($params);
             $this->options['body']                   = json_encode($params);
             $this->options['headers']['Content-MD5'] = base64_encode(md5($this->options['body'], true));
             $this->options['headers']['Content-MD5'] = base64_encode(md5($this->options['body'], true));
 
 

+ 3 - 3
vendor/alibabacloud/client/src/Request/Traits/RetryTrait.php

@@ -3,7 +3,7 @@
 namespace AlibabaCloud\Client\Request\Traits;
 namespace AlibabaCloud\Client\Request\Traits;
 
 
 use Exception;
 use Exception;
-use Stringy\Stringy;
+use AlibabaCloud\Client\Support\Stringy;
 use AlibabaCloud\Client\Result\Result;
 use AlibabaCloud\Client\Result\Result;
 use AlibabaCloud\Client\Filter\ClientFilter;
 use AlibabaCloud\Client\Filter\ClientFilter;
 use AlibabaCloud\Client\Exception\ClientException;
 use AlibabaCloud\Client\Exception\ClientException;
@@ -109,7 +109,7 @@ trait RetryTrait
         }
         }
 
 
         foreach ($this->serverRetryStrings as $message) {
         foreach ($this->serverRetryStrings as $message) {
-            if (Stringy::create($result->getBody())->contains($message)) {
+            if (Stringy::contains($result->getBody(), $message)) {
                 $this->serverRetry--;
                 $this->serverRetry--;
 
 
                 return true;
                 return true;
@@ -137,7 +137,7 @@ trait RetryTrait
         }
         }
 
 
         foreach ($this->clientRetryStrings as $message) {
         foreach ($this->clientRetryStrings as $message) {
-            if (Stringy::create($exception->getMessage())->contains($message)) {
+            if (Stringy::contains($exception->getMessage(), $message)) {
                 $this->clientRetry--;
                 $this->clientRetry--;
 
 
                 return true;
                 return true;

+ 47 - 0
vendor/alibabacloud/client/src/Support/Stringy.php

@@ -0,0 +1,47 @@
+<?php
+
+namespace AlibabaCloud\Client\Support;
+
+/**
+ * Class Stringy
+ *
+ * @package AlibabaCloud\Client\Support
+ */
+class Stringy
+{
+
+    private static function _value($value, $default = '')
+    {
+        return null === $value ? $default : $value;
+    }
+
+    /**
+     * @param string $str
+     * @param string $substr
+     *
+     * @return bool
+     */
+    public static function contains($str, $substr)
+    {
+        return false !== strpos(self::_value($str), self::_value($substr));
+    }
+
+    /**
+     * @param string $str
+     * @param string $substr
+     *
+     * @return bool
+     */
+    public static function endsWith($str, $substr)
+    {
+        $str      = self::_value($str);
+        $substr = self::_value($substr);
+        $length = \strlen($substr);
+        if (!$length) {
+            return true;
+        }
+
+        return substr($str, -$length) === $substr;
+    }
+
+}

+ 4 - 0
vendor/alibabacloud/client/src/Traits/ArrayAccessTrait.php

@@ -17,6 +17,7 @@ trait ArrayAccessTrait
      *
      *
      * @return mixed|null
      * @return mixed|null
      */
      */
+    #[\ReturnTypeWillChange]
     public function & offsetGet($offset)
     public function & offsetGet($offset)
     {
     {
         if (isset($this->data[$offset])) {
         if (isset($this->data[$offset])) {
@@ -32,6 +33,7 @@ trait ArrayAccessTrait
      * @param string       $offset
      * @param string       $offset
      * @param string|mixed $value
      * @param string|mixed $value
      */
      */
+    #[\ReturnTypeWillChange]
     public function offsetSet($offset, $value)
     public function offsetSet($offset, $value)
     {
     {
         $this->data[$offset] = $value;
         $this->data[$offset] = $value;
@@ -42,6 +44,7 @@ trait ArrayAccessTrait
      *
      *
      * @return bool
      * @return bool
      */
      */
+    #[\ReturnTypeWillChange]
     public function offsetExists($offset)
     public function offsetExists($offset)
     {
     {
         return isset($this->data[$offset]);
         return isset($this->data[$offset]);
@@ -50,6 +53,7 @@ trait ArrayAccessTrait
     /**
     /**
      * @param string $offset
      * @param string $offset
      */
      */
+    #[\ReturnTypeWillChange]
     public function offsetUnset($offset)
     public function offsetUnset($offset)
     {
     {
         unset($this->data[$offset]);
         unset($this->data[$offset]);

+ 2 - 2
vendor/alibabacloud/client/src/Traits/ClientTrait.php

@@ -182,14 +182,14 @@ trait ClientTrait
      */
      */
     public static function accessKeyClient($accessKeyId, $accessKeySecret)
     public static function accessKeyClient($accessKeyId, $accessKeySecret)
     {
     {
-        if (strpos($accessKeyId, ' ') !== false) {
+        if (null === $accessKeyId || strpos($accessKeyId, ' ') !== false) {
             throw new ClientException(
             throw new ClientException(
                 'AccessKey ID format is invalid',
                 'AccessKey ID format is invalid',
                 SDK::INVALID_ARGUMENT
                 SDK::INVALID_ARGUMENT
             );
             );
         }
         }
 
 
-        if (strpos($accessKeySecret, ' ') !== false) {
+        if (null === $accessKeySecret || strpos($accessKeySecret, ' ') !== false) {
             throw new ClientException(
             throw new ClientException(
                 'AccessKey Secret format is invalid',
                 'AccessKey Secret format is invalid',
                 SDK::INVALID_ARGUMENT
                 SDK::INVALID_ARGUMENT

+ 1 - 1
vendor/alibabacloud/client/src/Traits/EndpointTrait.php

@@ -64,7 +64,7 @@ trait EndpointTrait
         if (self::resolveHostByStatic($productCode, $global)) {
         if (self::resolveHostByStatic($productCode, $global)) {
             return true;
             return true;
         }
         }
-        $productCode = strtolower($productCode);
+        $productCode = null !== $productCode? strtolower($productCode) : null;
         return (bool)Config::get("endpoints.{$productCode}.{$global}");
         return (bool)Config::get("endpoints.{$productCode}.{$global}");
     }
     }
 
 

+ 7 - 0
vendor/alibabacloud/client/src/Traits/HasDataTrait.php

@@ -131,6 +131,7 @@ trait HasDataTrait
      *
      *
      * @return bool
      * @return bool
      */
      */
+    #[\ReturnTypeWillChange]
     public function offsetExists($key)
     public function offsetExists($key)
     {
     {
         return $this->dot->has($key);
         return $this->dot->has($key);
@@ -143,6 +144,7 @@ trait HasDataTrait
      *
      *
      * @return mixed
      * @return mixed
      */
      */
+    #[\ReturnTypeWillChange]
     public function offsetGet($key)
     public function offsetGet($key)
     {
     {
         return $this->dot->offsetGet($key);
         return $this->dot->offsetGet($key);
@@ -154,6 +156,7 @@ trait HasDataTrait
      * @param int|string|null $key
      * @param int|string|null $key
      * @param mixed           $value
      * @param mixed           $value
      */
      */
+    #[\ReturnTypeWillChange]
     public function offsetSet($key, $value)
     public function offsetSet($key, $value)
     {
     {
         $this->dot->offsetSet($key, $value);
         $this->dot->offsetSet($key, $value);
@@ -164,6 +167,7 @@ trait HasDataTrait
      *
      *
      * @param int|string $key
      * @param int|string $key
      */
      */
+    #[\ReturnTypeWillChange]
     public function offsetUnset($key)
     public function offsetUnset($key)
     {
     {
         $this->delete($key);
         $this->delete($key);
@@ -192,6 +196,7 @@ trait HasDataTrait
      *
      *
      * @return int
      * @return int
      */
      */
+    #[\ReturnTypeWillChange]
     public function count($key = null)
     public function count($key = null)
     {
     {
         return $this->dot->count($key);
         return $this->dot->count($key);
@@ -202,6 +207,7 @@ trait HasDataTrait
      *
      *
      * @return ArrayIterator
      * @return ArrayIterator
      */
      */
+    #[\ReturnTypeWillChange]
     public function getIterator()
     public function getIterator()
     {
     {
         return $this->dot->getIterator();
         return $this->dot->getIterator();
@@ -212,6 +218,7 @@ trait HasDataTrait
      *
      *
      * @return array
      * @return array
      */
      */
+    #[\ReturnTypeWillChange]
     public function jsonSerialize()
     public function jsonSerialize()
     {
     {
         return $this->dot->jsonSerialize();
         return $this->dot->jsonSerialize();

+ 1 - 1
vendor/alibabacloud/client/src/Traits/LogTrait.php

@@ -55,7 +55,7 @@ trait LogTrait
         if (PHP_VERSION_ID < 70100) {
         if (PHP_VERSION_ID < 70100) {
             self::$ts = DateTime::createFromFormat('U.u', sprintf('%.6F', microtime(true)), $timezone);
             self::$ts = DateTime::createFromFormat('U.u', sprintf('%.6F', microtime(true)), $timezone);
         } else {
         } else {
-            self::$ts = new DateTime(null, $timezone);
+            self::$ts = new DateTime('now', $timezone);
         }
         }
     }
     }
 
 

+ 5 - 0
vendor/aliyuncs/oss-sdk-php/CHANGELOG.md

@@ -1,5 +1,10 @@
 # ChangeLog - Aliyun OSS SDK for PHP
 # ChangeLog - Aliyun OSS SDK for PHP
 
 
+## v2.6.0 / 2022-08-03
+* Added: support credentials provider.
+* Fixed: compatible with swoole curl handler.
+* Added: support more bucket stat info.
+
 ## v2.5.0 / 2022-05-13
 ## v2.5.0 / 2022-05-13
 * Added: support bucket transfer acceleration.
 * Added: support bucket transfer acceleration.
 * Added: support bucket cname token.
 * Added: support bucket cname token.

+ 65 - 0
vendor/aliyuncs/oss-sdk-php/samples/BucketStat.php

@@ -0,0 +1,65 @@
+<?php
+require_once __DIR__ . '/Common.php';
+
+use OSS\OssClient;
+use OSS\Core\OssException;
+$ossClient = Common::getOssClient();
+if (is_null($ossClient)) exit(1);
+$bucket = Common::getBucketName();
+
+//******************************* Simple Usage****************************************************************
+
+// Get Bucket Stat
+$stat = $ossClient->getBucketStat($bucket);
+Common::println("Bucket ".$bucket." current storage is:".$stat->getStorage().PHP_EOL);
+Common::println("Bucket ".$bucket." object count is:".$stat->getObjectCount().PHP_EOL);
+Common::println("Bucket ".$bucket." multipart upload count is:".$stat->getMultipartUploadCount().PHP_EOL);
+Common::println("Bucket ".$bucket." live channel count is:".$stat->getLiveChannelCount().PHP_EOL);
+Common::println("Bucket ".$bucket." last modified time is:".$stat->getLastModifiedTime().PHP_EOL);
+Common::println("Bucket ".$bucket." standard storage is:".$stat->getStandardStorage().PHP_EOL);
+Common::println("Bucket ".$bucket." standard object count is:".$stat->getStandardObjectCount().PHP_EOL);
+Common::println("Bucket ".$bucket." infrequent access storage is:".$stat->getInfrequentAccessStorage().PHP_EOL);
+Common::println("Bucket ".$bucket." infrequent access real storage is:".$stat->getInfrequentAccessRealStorage().PHP_EOL);
+Common::println("Bucket ".$bucket." infrequent access object count is:".$stat->getInfrequentAccessObjectCount().PHP_EOL);
+Common::println("Bucket ".$bucket." archive storage is:".$stat->getArchiveStorage().PHP_EOL);
+Common::println("Bucket ".$bucket." archive real storage is:".$stat->getArchiveRealStorage().PHP_EOL);
+Common::println("Bucket ".$bucket." archive object count is:".$stat->getArchiveObjectCount().PHP_EOL);
+Common::println("Bucket ".$bucket." cold archive storage is:".$stat->getColdArchiveStorage().PHP_EOL);
+Common::println("Bucket ".$bucket." cold archive real storage is:".$stat->getColdArchiveRealStorage().PHP_EOL);
+Common::println("Bucket ".$bucket." cold archive object count is:".$stat->getColdArchiveObjectCount().PHP_EOL);
+
+//******************************* For complete usage, see the following functions ****************************************************
+getBucketStat($ossClient,$bucket);
+/**
+ * get bucket stat
+ * @param OssClient $ossClient OssClient instance
+ * @param string $bucket Name of the bucket to create
+ * @return null
+ */
+function getBucketStat($ossClient, $bucket)
+{
+    try {
+        $stat = $ossClient->getBucketStat($bucket);
+    } catch (OssException $e) {
+        printf(__FUNCTION__ . ": FAILED\n");
+        printf($e->getMessage() . "\n");
+        return;
+    }
+    printf("Bucket ".$bucket." current storage is:".$stat->getStorage().PHP_EOL);
+    printf("Bucket ".$bucket." object count is:".$stat->getObjectCount().PHP_EOL);
+    printf("Bucket ".$bucket." multipart upload count is:".$stat->getMultipartUploadCount().PHP_EOL);
+    printf("Bucket ".$bucket." live channel count is:".$stat->getLiveChannelCount().PHP_EOL);
+    printf("Bucket ".$bucket." last modified time is:".$stat->getLastModifiedTime().PHP_EOL);
+    printf("Bucket ".$bucket." standard storage is:".$stat->getStandardStorage().PHP_EOL);
+    printf("Bucket ".$bucket." standard object count is:".$stat->getStandardObjectCount().PHP_EOL);
+    printf("Bucket ".$bucket." infrequent access storage is:".$stat->getInfrequentAccessStorage().PHP_EOL);
+    printf("Bucket ".$bucket." infrequent access real storage is:".$stat->getInfrequentAccessRealStorage().PHP_EOL);
+    printf("Bucket ".$bucket." infrequent access object count is:".$stat->getInfrequentAccessObjectCount().PHP_EOL);
+    printf("Bucket ".$bucket." archive storage is:".$stat->getArchiveStorage().PHP_EOL);
+    printf("Bucket ".$bucket." archive real storage is:".$stat->getArchiveRealStorage().PHP_EOL);
+    printf("Bucket ".$bucket." archive object count is:".$stat->getArchiveObjectCount().PHP_EOL);
+    printf("Bucket ".$bucket." cold archive storage is:".$stat->getColdArchiveStorage().PHP_EOL);
+    printf("Bucket ".$bucket." cold archive real storage is:".$stat->getColdArchiveRealStorage().PHP_EOL);
+    printf("Bucket ".$bucket." cold archive object count is:".$stat->getColdArchiveObjectCount().PHP_EOL);
+    print(__FUNCTION__ . ": OK" . "\n");
+}

+ 76 - 0
vendor/aliyuncs/oss-sdk-php/samples/CredentialsPhp.php

@@ -0,0 +1,76 @@
+<?php
+
+//=============================================================================
+
+//How to use credentials-php to access oss
+
+// step 1:Install credentials-php  composer require alibabacloud/credentials
+require_once __DIR__ . '/Common.php';
+
+use OSS\OssClient;
+use OSS\Core\OssException;
+use OSS\Credentials\CredentialsProvider;
+use AlibabaCloud\Credentials\Credential;
+use OSS\Credentials\StaticCredentialsProvider;
+
+// public provider conversion class
+class AlibabaCloudCredentialsWrapper implements CredentialsProvider{
+    /**
+     * @var Credential
+     */
+    private $warpper;
+    public function __construct($credential){
+        $this->warpper = $credential;
+    }
+    public function getCredentials(){
+        $ak = $this->warpper->getAccessKeyId();
+        $sk = $this->warpper->getAccessKeySecret();
+        $token = $this->warpper->getSecurityToken();
+        return new StaticCredentialsProvider($ak, $sk, $token);
+    }
+}
+
+$bucket = Common::getBucketName();
+
+//AccessKey Credentials demo
+$credential = new Credential(array(
+    'type'              => 'access_key',
+    'access_key_id'     => '<access_key_id>',
+    'access_key_secret' => '<accessKey_secret>',
+));
+$providerWarpper = new AlibabaCloudCredentialsWrapper($credential);
+$config = array(
+    'provider' => $providerWarpper,
+    'endpoint'=> '<endpoint>'
+);
+try {
+    $ossClient = new OssClient($config);
+    $ossClient->putObject($bucket,'c.file','hi oss,this is credentials test of access key');
+    $result = $ossClient->getObject($bucket,'c.file');
+    var_dump($result);
+} catch (OssException $e) {
+    printf($e->getMessage() . "\n");
+    return;
+}
+
+
+// EcsRamRole Credentials demo
+$ecsRamRole = new Credential(array(
+    'type'      => 'ecs_ram_role',
+    'role_name' => 'EcsRamRoleOssTest',
+));
+$providerWarpper = new AlibabaCloudCredentialsWrapper($ecsRamRole);
+$bucket = 'oss-bucket-cd-yp-test';
+$config = array(
+    'provider' => $providerWarpper,
+    'endpoint'=> '<endpoint>'
+);
+try {
+    $ossClient = new OssClient($config);
+    $ossClient->putObject($bucket,'c.file','hi oss,this is credentials test of EcsRamRole');
+    $result = $ossClient->getObject($bucket,'c.file');
+    var_dump($result);
+} catch (OssException $e) {
+    printf($e->getMessage() . "\n");
+    return;
+}

+ 45 - 0
vendor/aliyuncs/oss-sdk-php/samples/CredentialsProvider.php

@@ -0,0 +1,45 @@
+<?php
+require_once __DIR__ . '/Common.php';
+
+use OSS\OssClient;
+use OSS\Core\OssException;
+use OSS\Credentials\StaticCredentialsProvider;
+$bucket = Common::getBucketName();
+
+// Access Key Provider demo
+$id = '<access_key_id>';
+$secret = '<accessKey_secret>';
+$provider = new StaticCredentialsProvider($id,$secret);
+$config = array(
+    'provider' => $provider,
+    'endpoint'=>'<endpoint>'
+);
+try {
+    $ossClient = new OssClient($config);
+    $ossClient->putObject($bucket,'c.file','hi oss,this is credentials test of access key provider');
+    $result = $ossClient->getObject($bucket,'c.file');
+    var_dump($result);
+} catch (OssException $e) {
+    printf($e->getMessage() . "\n");
+    return;
+}
+
+// Sts provider demo
+$id = '<access_key_id>';
+$secret = '<accessKey_secret>';
+$token = '<security_token>';
+$provider = new StaticCredentialsProvider($id,$secret,$token);
+$config = array(
+    'provider' => $provider,
+    'endpoint'=> "<endpoint>"
+);
+
+try {
+    $ossClient = new OssClient($config);
+    $ossClient->putObject($bucket,'c.file','hi oss,this is credentials test of sts provider');
+    $result = $ossClient->getObject($bucket,'c.file');
+    var_dump($result);
+} catch (OssException $e) {
+    printf($e->getMessage() . "\n");
+    return;
+}

+ 63 - 0
vendor/aliyuncs/oss-sdk-php/src/OSS/Credentials/Credentials.php

@@ -0,0 +1,63 @@
+<?php
+
+
+namespace OSS\Credentials;
+
+use OSS\Core\OssException;
+
+/**
+ * Basic implementation of the OSS Credentials that allows callers to
+ * pass in the OSS Access Key and OSS Secret Access Key in the constructor.
+ */
+class Credentials
+{
+    private $key;
+    private $secret;
+    private $token;
+
+    /**
+     * Constructor a new BasicOSSCredentials object, with the specified OSS
+     * access key and OSS secret key
+     *
+     * @param string $key     OSS access key ID
+     * @param string $secret  OSS secret access key
+     * @param string $token   Security token to use
+     */
+    public function __construct($key, $secret, $token = null)
+    {
+        if (empty($key)) {
+            throw new OssException("access key id is empty");
+        }
+        if (empty($secret)) {
+            throw new OssException("access key secret is empty");
+        }
+        $this->key = trim($key);
+        $this->secret = trim($secret);
+        $this->token = $token;
+    }
+
+
+    /**
+     * @return string
+     */
+    public function getAccessKeyId()
+    {
+        return $this->key;
+    }
+
+    /**
+     * @return string
+     */
+    public function getAccessKeySecret()
+    {
+        return $this->secret;
+    }
+
+    /**
+     * @return string|null
+     */
+    public function getSecurityToken()
+    {
+        return $this->token;
+    }
+}

+ 11 - 0
vendor/aliyuncs/oss-sdk-php/src/OSS/Credentials/CredentialsProvider.php

@@ -0,0 +1,11 @@
+<?php
+namespace OSS\Credentials;
+
+interface CredentialsProvider
+{
+
+    /**
+     * @return Credentials
+     */
+    public function getCredentials();
+}

+ 35 - 0
vendor/aliyuncs/oss-sdk-php/src/OSS/Credentials/StaticCredentialsProvider.php

@@ -0,0 +1,35 @@
+<?php
+namespace OSS\Credentials;
+
+/**
+ * Basic implementation of the OSS Credentials interface that allows callers to
+ * pass in the OSS Access Key Id and OSS Secret Access Key in the constructor.
+ */
+class StaticCredentialsProvider implements CredentialsProvider
+{
+
+    /**
+     * @var Credentials
+     */
+    private $credentials;
+    /**
+     * Constructs a new StaticCredentialsProvider object, with the specified OSS
+     * access key and OSS secret key
+     *
+     * @param string $key     OSS access key ID
+     * @param string $secret  OSS access key secret
+     * @param string $token   Security token to use
+     */
+    public function __construct($key, $secret, $token = null)
+    {
+        $this->credentials = new Credentials($key, $secret, $token);
+    }
+
+    /**
+     * @return Credentials
+     */
+    public function getCredentials()
+    {
+        return $this->credentials;
+    }
+}

+ 1 - 1
vendor/aliyuncs/oss-sdk-php/src/OSS/Http/RequestCore.php

@@ -789,7 +789,7 @@ class RequestCore
         }
         }
 
 
         // As long as this came back as a valid resource or CurlHandle instance...
         // As long as this came back as a valid resource or CurlHandle instance...
-        if (is_resource($curl_handle) || (is_object($curl_handle) && get_class($curl_handle) === 'CurlHandle')) {
+        if (is_resource($curl_handle) || (is_object($curl_handle) && in_array(get_class($curl_handle),array('CurlHandle','Swoole\Curl\Handler', 'Swoole\Coroutine\Curl\Handle'),true))) {
             // Determine what's what.
             // Determine what's what.
             $header_size = curl_getinfo($curl_handle, CURLINFO_HEADER_SIZE);
             $header_size = curl_getinfo($curl_handle, CURLINFO_HEADER_SIZE);
             $this->response_headers = substr($this->response, 0, $header_size);
             $this->response_headers = substr($this->response, 0, $header_size);

+ 246 - 0
vendor/aliyuncs/oss-sdk-php/src/OSS/Model/BucketStat.php

@@ -41,6 +41,135 @@ class BucketStat
         return $this->multipartUploadCount;
         return $this->multipartUploadCount;
     }
     }
 
 
+    /**
+     * Get live channel count
+     *
+     * @return int
+     */
+    public function getLiveChannelCount()
+    {
+        return $this->liveChannelCount;
+    }
+
+    /**
+     * Get last modified time
+     *
+     * @return int
+     */
+    public function getLastModifiedTime()
+    {
+        return $this->lastModifiedTime;
+    }
+
+    /**
+     * Get standard storage
+     *
+     * @return int
+     */
+    public function getStandardStorage()
+    {
+        return $this->standardStorage;
+    }
+
+    /**
+     * Get standard object count
+     *
+     * @return int
+     */
+    public function getStandardObjectCount()
+    {
+        return $this->standardObjectCount;
+    }
+
+    /**
+     * Get infrequent access storage
+     *
+     * @return int
+     */
+    public function getInfrequentAccessStorage()
+    {
+        return $this->infrequentAccessStorage;
+    }
+
+    /**
+     * Get infrequent access real storage
+     *
+     * @return int
+     */
+    public function getInfrequentAccessRealStorage()
+    {
+        return $this->infrequentAccessRealStorage;
+    }
+
+    /**
+     * Get infrequent access object count
+     *
+     * @return int
+     */
+    public function getInfrequentAccessObjectCount()
+    {
+        return $this->infrequentAccessObjectCount;
+    }
+
+    /**
+     * Get archive storage
+     *
+     * @return int
+     */
+    public function getArchiveStorage()
+    {
+        return $this->archiveStorage;
+    }
+
+    /**
+     * Get archive real storage
+     *
+     * @return int
+     */
+    public function getArchiveRealStorage()
+    {
+        return $this->archiveRealStorage;
+    }
+    /**
+     * Get archive object count
+     *
+     * @return int
+     */
+    public function getArchiveObjectCount()
+    {
+        return $this->archiveObjectCount;
+    }
+
+    /**
+     * Get cold archive storage
+     *
+     * @return int
+     */
+    public function getColdArchiveStorage()
+    {
+        return $this->coldArchiveStorage;
+    }
+
+    /**
+     * Get cold archive real storage
+     *
+     * @return int
+     */
+    public function getColdArchiveRealStorage()
+    {
+        return $this->coldArchiveRealStorage;
+    }
+
+    /**
+     * Get cold archive object count
+     *
+     * @return int
+     */
+    public function getColdArchiveObjectCount()
+    {
+        return $this->coldArchiveObjectCount;
+    }
+
     /**
     /**
      * Parse stat from the xml.
      * Parse stat from the xml.
      *
      *
@@ -60,6 +189,45 @@ class BucketStat
         if (isset($xml->MultipartUploadCount) ) {
         if (isset($xml->MultipartUploadCount) ) {
             $this->multipartUploadCount = intval($xml->MultipartUploadCount);
             $this->multipartUploadCount = intval($xml->MultipartUploadCount);
         }
         }
+        if (isset($xml->LiveChannelCount) ) {
+            $this->liveChannelCount = intval($xml->LiveChannelCount);
+        }
+        if (isset($xml->LastModifiedTime) ) {
+            $this->lastModifiedTime = intval($xml->LastModifiedTime);
+        }
+        if (isset($xml->StandardStorage) ) {
+            $this->standardStorage = intval($xml->StandardStorage);
+        }
+        if (isset($xml->StandardObjectCount) ) {
+            $this->standardObjectCount = intval($xml->StandardObjectCount);
+        }
+        if (isset($xml->InfrequentAccessStorage) ) {
+            $this->infrequentAccessStorage = intval($xml->InfrequentAccessStorage);
+        }
+        if (isset($xml->InfrequentAccessRealStorage) ) {
+            $this->infrequentAccessRealStorage = intval($xml->InfrequentAccessRealStorage);
+        }
+        if (isset($xml->InfrequentAccessObjectCount) ) {
+            $this->infrequentAccessObjectCount = intval($xml->InfrequentAccessObjectCount);
+        }
+        if (isset($xml->ArchiveStorage) ) {
+            $this->archiveStorage = intval($xml->ArchiveStorage);
+        }
+        if (isset($xml->ArchiveRealStorage) ) {
+            $this->archiveRealStorage = intval($xml->ArchiveRealStorage);
+        }
+        if (isset($xml->ArchiveObjectCount) ) {
+            $this->archiveObjectCount = intval($xml->ArchiveObjectCount);
+        }
+        if (isset($xml->ColdArchiveStorage) ) {
+            $this->coldArchiveStorage = intval($xml->ColdArchiveStorage);
+        }
+        if (isset($xml->ColdArchiveRealStorage) ) {
+            $this->coldArchiveRealStorage = intval($xml->ColdArchiveRealStorage);
+        }
+        if (isset($xml->ColdArchiveObjectCount) ) {
+            $this->coldArchiveObjectCount = intval($xml->ColdArchiveObjectCount);
+        }
     }
     }
     
     
     /**
     /**
@@ -82,4 +250,82 @@ class BucketStat
      */
      */
     private $multipartUploadCount;
     private $multipartUploadCount;
 
 
+    /**
+     * live channel count
+     * @var int
+     */
+    private $liveChannelCount;
+
+    /**
+     * last modified time
+     * @var int
+     */
+    private $lastModifiedTime;
+
+    /**
+     * standard storage
+     * @var int
+     */
+    private $standardStorage;
+
+    /**
+     * standard object count
+     * @var int
+     */
+    private $standardObjectCount;
+
+    /**
+     * infrequent access storage
+     * @var int
+     */
+    private $infrequentAccessStorage;
+
+    /**
+     * infrequent access real storage
+     * @var int
+     */
+    private $infrequentAccessRealStorage;
+
+    /**
+     * infrequent access object Count
+     * @var int
+     */
+    private $infrequentAccessObjectCount;
+
+    /**
+     * archive storage
+     * @var int
+     */
+    private $archiveStorage;
+
+    /**
+     * archive real storage
+     * @var int
+     */
+    private $archiveRealStorage;
+
+    /**
+     * archive object count
+     * @var int
+     */
+    private $archiveObjectCount;
+
+    /**
+     * cold archive storage
+     * @var int
+     */
+    private $coldArchiveStorage;
+
+    /**
+     * cold archive real storage
+     * @var int
+     */
+    private $coldArchiveRealStorage;
+
+    /**
+     * cold archive object count
+     * @var int
+     */
+    private $coldArchiveObjectCount;
+
 }
 }

+ 92 - 29
vendor/aliyuncs/oss-sdk-php/src/OSS/OssClient.php

@@ -3,6 +3,9 @@ namespace OSS;
 
 
 use OSS\Core\MimeTypes;
 use OSS\Core\MimeTypes;
 use OSS\Core\OssException;
 use OSS\Core\OssException;
+use OSS\Credentials\Credentials;
+use OSS\Credentials\CredentialsProvider;
+use OSS\Credentials\StaticCredentialsProvider;
 use OSS\Http\RequestCore;
 use OSS\Http\RequestCore;
 use OSS\Http\RequestCore_Exception;
 use OSS\Http\RequestCore_Exception;
 use OSS\Http\ResponseCore;
 use OSS\Http\ResponseCore;
@@ -89,12 +92,25 @@ use OSS\Result\GetBucketCnameTokenResult;
  */
  */
 class OssClient
 class OssClient
 {
 {
+
+    /**
+     * OssClient constructor.
+     */
+    public function __construct()
+    {
+        $argNum = func_num_args();
+        $args = func_get_args();
+        if($argNum == 1 && is_array($args[0])){
+            call_user_func_array(array($this,'__initNewClient'),$args);
+        }else{
+            call_user_func_array(array($this,'__initClient'),$args);
+        }
+    }
+
     /**
     /**
-     * Constructor
-     *
      * There're a few different ways to create an OssClient object:
      * There're a few different ways to create an OssClient object:
      * 1. Most common one from access Id, access Key and the endpoint: $ossClient = new OssClient($id, $key, $endpoint)
      * 1. Most common one from access Id, access Key and the endpoint: $ossClient = new OssClient($id, $key, $endpoint)
-     * 2. If the endpoint is the CName (such as www.testoss.com, make sure it's CName binded in the OSS console), 
+     * 2. If the endpoint is the CName (such as www.testoss.com, make sure it's CName binded in the OSS console),
      *    uses $ossClient = new OssClient($id, $key, $endpoint, true)
      *    uses $ossClient = new OssClient($id, $key, $endpoint, true)
      * 3. If using Alicloud's security token service (STS), then the AccessKeyId, AccessKeySecret and STS token are all got from STS.
      * 3. If using Alicloud's security token service (STS), then the AccessKeyId, AccessKeySecret and STS token are all got from STS.
      * Use this: $ossClient = new OssClient($id, $key, $endpoint, false, $token)
      * Use this: $ossClient = new OssClient($id, $key, $endpoint, false, $token)
@@ -108,7 +124,7 @@ class OssClient
      * @param string $requestProxy
      * @param string $requestProxy
      * @throws OssException
      * @throws OssException
      */
      */
-    public function __construct($accessKeyId, $accessKeySecret, $endpoint, $isCName = false, $securityToken = NULL, $requestProxy = NULL)
+    private function __initClient($accessKeyId, $accessKeySecret, $endpoint, $isCName = false, $securityToken = NULL, $requestProxy = NULL)
     {
     {
         $accessKeyId = trim($accessKeyId);
         $accessKeyId = trim($accessKeyId);
         $accessKeySecret = trim($accessKeySecret);
         $accessKeySecret = trim($accessKeySecret);
@@ -120,17 +136,36 @@ class OssClient
         if (empty($accessKeySecret)) {
         if (empty($accessKeySecret)) {
             throw new OssException("access key secret is empty");
             throw new OssException("access key secret is empty");
         }
         }
+        $provider = new StaticCredentialsProvider($accessKeyId,$accessKeySecret,$securityToken);
+        $config = array(
+            'endpoint'              => $endpoint,
+            'cname'                 => $isCName,
+            'request_proxy'         => $requestProxy,
+            'provider'              => $provider
+        );
+        $this->__initNewClient($config);
+    }
+
+    /**
+     * @param array $config
+     * @throws OssException
+     */
+    private function __initNewClient($config=array()){
+        $isCName = isset($config['cname']) ? $config['cname']: false;
+        $endpoint = isset($config['endpoint']) ? $config['endpoint'] : '';
+        $requestProxy = isset($config['request_proxy']) ? $config['request_proxy']: null;
+        $provider = isset($config['provider']) ? $config['provider'] : '';
         if (empty($endpoint)) {
         if (empty($endpoint)) {
             throw new OssException("endpoint is empty");
             throw new OssException("endpoint is empty");
         }
         }
         $this->hostname = $this->checkEndpoint($endpoint, $isCName);
         $this->hostname = $this->checkEndpoint($endpoint, $isCName);
-        $this->accessKeyId = $accessKeyId;
-        $this->accessKeySecret = $accessKeySecret;
-        $this->securityToken = $securityToken;
         $this->requestProxy = $requestProxy;
         $this->requestProxy = $requestProxy;
+        if(!$provider instanceof CredentialsProvider){
+            throw new OssException("provider must be an instance of CredentialsProvider");
+        }
+        $this->provider = $provider;
         self::checkEnv();
         self::checkEnv();
     }
     }
-
     /**
     /**
      * Lists the Bucket [GetService]. Not applicable if the endpoint is CName (because CName must be binded to a specific bucket).
      * Lists the Bucket [GetService]. Not applicable if the endpoint is CName (because CName must be binded to a specific bucket).
      *
      *
@@ -877,9 +912,12 @@ class OssClient
         $resource = '/' . $bucket . '/' . $channelName;
         $resource = '/' . $bucket . '/' . $channelName;
 
 
         $string_to_sign = $expires . "\n" . $cano_params . $resource;
         $string_to_sign = $expires . "\n" . $cano_params . $resource;
-        $signature = base64_encode(hash_hmac('sha1', $string_to_sign, $this->accessKeySecret, true));
+        $cred = $this->provider->getCredentials();
+        $this->checkCredentials($cred);
 
 
-        $query_items[] = 'OSSAccessKeyId=' . rawurlencode($this->accessKeyId);
+        $signature = base64_encode(hash_hmac('sha1', $string_to_sign, $cred->getAccessKeySecret(), true));
+
+        $query_items[] = 'OSSAccessKeyId=' . rawurlencode($cred->getAccessKeyId());
         $query_items[] = 'Expires=' . rawurlencode($expires);
         $query_items[] = 'Expires=' . rawurlencode($expires);
         $query_items[] = 'Signature=' . rawurlencode($signature);
         $query_items[] = 'Signature=' . rawurlencode($signature);
 
 
@@ -912,9 +950,12 @@ class OssClient
         $resource = '/' . $bucket . '/' . $channelName;
         $resource = '/' . $bucket . '/' . $channelName;
 
 
         $string_to_sign = $expiration . "\n" . $cano_params . $resource;
         $string_to_sign = $expiration . "\n" . $cano_params . $resource;
-        $signature = base64_encode(hash_hmac('sha1', $string_to_sign, $this->accessKeySecret, true));
+        $cred = $this->provider->getCredentials();
+        $this->checkCredentials($cred);
+
+        $signature = base64_encode(hash_hmac('sha1', $string_to_sign, $cred->getAccessKeySecret(), true));
 
 
-        $query_items[] = 'OSSAccessKeyId=' . rawurlencode($this->accessKeyId);
+        $query_items[] = 'OSSAccessKeyId=' . rawurlencode($cred->getAccessKeyId());
         $query_items[] = 'Expires=' . rawurlencode($expiration);
         $query_items[] = 'Expires=' . rawurlencode($expiration);
         $query_items[] = 'Signature=' . rawurlencode($signature);
         $query_items[] = 'Signature=' . rawurlencode($signature);
 
 
@@ -2967,13 +3008,16 @@ class OssClient
         $this->authPrecheckObjectEncoding($options);
         $this->authPrecheckObjectEncoding($options);
         //Validates ACL
         //Validates ACL
         $this->authPrecheckAcl($options);
         $this->authPrecheckAcl($options);
+        $cred = $this->provider->getCredentials();
+        $this->checkCredentials($cred);
+
         // Should https or http be used?
         // Should https or http be used?
         $scheme = $this->useSSL ? 'https://' : 'http://';
         $scheme = $this->useSSL ? 'https://' : 'http://';
         // gets the host name. If the host name is public domain or private domain, form a third level domain by prefixing the bucket name on the domain name.
         // gets the host name. If the host name is public domain or private domain, form a third level domain by prefixing the bucket name on the domain name.
         $hostname = $this->generateHostname($options[self::OSS_BUCKET]);
         $hostname = $this->generateHostname($options[self::OSS_BUCKET]);
         $string_to_sign = '';
         $string_to_sign = '';
-        $headers = $this->generateHeaders($options, $hostname);
-        $signable_query_string_params = $this->generateSignableQueryStringParam($options);
+        $headers = $this->generateHeaders($options, $hostname,$cred);
+        $signable_query_string_params = $this->generateSignableQueryStringParam($options,$cred);
         $signable_query_string = OssUtil::toQueryString($signable_query_string_params);
         $signable_query_string = OssUtil::toQueryString($signable_query_string_params);
         $resource_uri = $this->generateResourceUri($options);
         $resource_uri = $this->generateResourceUri($options);
         //Generates the URL (add query parameters)
         //Generates the URL (add query parameters)
@@ -3086,12 +3130,11 @@ class OssClient
         // Sort the strings to be signed.
         // Sort the strings to be signed.
         $string_to_sign_ordered .= $this->stringToSignSorted($signable_resource);
         $string_to_sign_ordered .= $this->stringToSignSorted($signable_resource);
 
 
-
-        $signature = base64_encode(hash_hmac('sha1', $string_to_sign_ordered, $this->accessKeySecret, true));
-        $request->add_header('Authorization', 'OSS ' . $this->accessKeyId . ':' . $signature);
+        $signature = base64_encode(hash_hmac('sha1', $string_to_sign_ordered,$cred->getAccessKeySecret(), true));
+        $request->add_header('Authorization', 'OSS ' . $cred->getAccessKeyId() . ':' . $signature);
 
 
         if (isset($options[self::OSS_PREAUTH]) && (integer)$options[self::OSS_PREAUTH] > 0) {
         if (isset($options[self::OSS_PREAUTH]) && (integer)$options[self::OSS_PREAUTH] > 0) {
-            $signed_url = $requestUrl . $conjunction . self::OSS_URL_ACCESS_KEY_ID . '=' . rawurlencode($this->accessKeyId) . '&' . self::OSS_URL_EXPIRES . '=' . $options[self::OSS_PREAUTH] . '&' . self::OSS_URL_SIGNATURE . '=' . rawurlencode($signature);
+            $signed_url = $requestUrl . $conjunction . self::OSS_URL_ACCESS_KEY_ID . '=' . rawurlencode($cred->getAccessKeyId()) . '&' . self::OSS_URL_EXPIRES . '=' . $options[self::OSS_PREAUTH] . '&' . self::OSS_URL_SIGNATURE . '=' . rawurlencode($signature);
             return $signed_url;
             return $signed_url;
         } elseif (isset($options[self::OSS_PREAUTH])) {
         } elseif (isset($options[self::OSS_PREAUTH])) {
             return $requestUrl;
             return $requestUrl;
@@ -3301,9 +3344,10 @@ class OssClient
      * Generates the signalbe query string parameters in array type
      * Generates the signalbe query string parameters in array type
      *
      *
      * @param array $options
      * @param array $options
+     * @param Credentials $cred
      * @return array
      * @return array
      */
      */
-    private function generateSignableQueryStringParam($options)
+    private function generateSignableQueryStringParam($options,$cred)
     {
     {
         $signableQueryStringParams = array();
         $signableQueryStringParams = array();
         $signableList = array(
         $signableList = array(
@@ -3337,8 +3381,8 @@ class OssClient
             }
             }
         }
         }
 
 
-        if ($this->enableStsInUrl && (!is_null($this->securityToken))) {
-            $signableQueryStringParams["security-token"] = $this->securityToken;
+        if ($this->enableStsInUrl && (!empty($cred->getSecurityToken()))) {
+            $signableQueryStringParams["security-token"] = $cred->getSecurityToken();
         }
         }
 
 
         return $signableQueryStringParams;
         return $signableQueryStringParams;
@@ -3420,9 +3464,10 @@ class OssClient
      *
      *
      * @param mixed $options
      * @param mixed $options
      * @param string $hostname hostname
      * @param string $hostname hostname
+     * @param Credentials $cred
      * @return array
      * @return array
      */
      */
-    private function generateHeaders($options, $hostname)
+    private function generateHeaders($options, $hostname,$cred)
     {
     {
         $headers = array(
         $headers = array(
             self::OSS_CONTENT_MD5 => '',
             self::OSS_CONTENT_MD5 => '',
@@ -3435,8 +3480,8 @@ class OssClient
         }
         }
 
 
         //Add stsSecurityToken
         //Add stsSecurityToken
-        if ((!is_null($this->securityToken)) && (!$this->enableStsInUrl)) {
-            $headers[self::OSS_SECURITY_TOKEN] = $this->securityToken;
+        if ((!empty($cred->getSecurityToken())) && (!$this->enableStsInUrl)) {
+            $headers[self::OSS_SECURITY_TOKEN] = $cred->getSecurityToken();
         }
         }
         //Merge HTTP headers
         //Merge HTTP headers
         if (isset($options[self::OSS_HEADERS])) {
         if (isset($options[self::OSS_HEADERS])) {
@@ -3487,6 +3532,23 @@ class OssClient
         return $ret_endpoint;
         return $ret_endpoint;
     }
     }
 
 
+    /**
+     * @param Credentials $credential
+     * @return OssException
+     */
+    private function checkCredentials($credential)
+    {
+        if (empty($credential)) {
+            throw new OssException("credentials is empty.");
+        }
+        if (empty($credential->getAccessKeyId())) {
+            throw new OssException("access key id is empty");
+        }
+        if (empty($credential->getAccessKeySecret())) {
+            throw new OssException("access key secret is empty");
+        }
+    }
+
     /**
     /**
      * Check if all dependent extensions are installed correctly.
      * Check if all dependent extensions are installed correctly.
      * For now only "curl" is needed.
      * For now only "curl" is needed.
@@ -3664,8 +3726,8 @@ class OssClient
     );
     );
     // OssClient version information
     // OssClient version information
     const OSS_NAME = "aliyun-sdk-php";
     const OSS_NAME = "aliyun-sdk-php";
-    const OSS_VERSION = "2.5.0";
-    const OSS_BUILD = "20220513";
+    const OSS_VERSION = "2.6.0";
+    const OSS_BUILD = "20220803";
     const OSS_AUTHOR = "";
     const OSS_AUTHOR = "";
     const OSS_OPTIONS_ORIGIN = 'Origin';
     const OSS_OPTIONS_ORIGIN = 'Origin';
     const OSS_OPTIONS_REQUEST_METHOD = 'Access-Control-Request-Method';
     const OSS_OPTIONS_REQUEST_METHOD = 'Access-Control-Request-Method';
@@ -3679,10 +3741,11 @@ class OssClient
     // user's domain type. It could be one of the four: OSS_HOST_TYPE_NORMAL, OSS_HOST_TYPE_IP, OSS_HOST_TYPE_SPECIAL, OSS_HOST_TYPE_CNAME
     // user's domain type. It could be one of the four: OSS_HOST_TYPE_NORMAL, OSS_HOST_TYPE_IP, OSS_HOST_TYPE_SPECIAL, OSS_HOST_TYPE_CNAME
     private $hostType = self::OSS_HOST_TYPE_NORMAL;
     private $hostType = self::OSS_HOST_TYPE_NORMAL;
     private $requestProxy = null;
     private $requestProxy = null;
-    private $accessKeyId;
-    private $accessKeySecret;
+    /**
+     * @var CredentialsProvider
+     */
+    private $provider;
     private $hostname;
     private $hostname;
-    private $securityToken;
     private $enableStsInUrl = false;
     private $enableStsInUrl = false;
     private $timeout = 0;
     private $timeout = 0;
     private $connectTimeout = 0;
     private $connectTimeout = 0;

+ 43 - 17
vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/GetBucketStatResultTest.php

@@ -9,20 +9,33 @@ use OSS\Http\ResponseCore;
 class GetBucketStatResultTest extends \PHPUnit\Framework\TestCase
 class GetBucketStatResultTest extends \PHPUnit\Framework\TestCase
 {
 {
 
 
-    private $validXml = <<<BBBB
-        <?xml version="1.0" ?>
-        <BucketStat>
-            <Storage>100</Storage>
-            <ObjectCount>200</ObjectCount>
-            <MultipartUploadCount>10</MultipartUploadCount>
-        </BucketStat>
-        BBBB;
-
-    private $invalidXml = <<<BBBB
-        <?xml version="1.0" ?>
-        <BucketStat>
-        </BucketStat>
-        BBBB;
+private $validXml = <<<BBBB
+<?xml version="1.0" encoding="UTF-8"?>
+<BucketStat>
+  <Storage>1600</Storage>
+  <ObjectCount>230</ObjectCount>
+  <MultipartUploadCount>40</MultipartUploadCount>
+  <LiveChannelCount>4</LiveChannelCount>
+  <LastModifiedTime>1643341269</LastModifiedTime>
+  <StandardStorage>430</StandardStorage>
+  <StandardObjectCount>66</StandardObjectCount>
+  <InfrequentAccessStorage>2359296</InfrequentAccessStorage>
+  <InfrequentAccessRealStorage>360</InfrequentAccessRealStorage>
+  <InfrequentAccessObjectCount>54</InfrequentAccessObjectCount>
+  <ArchiveStorage>2949120</ArchiveStorage>
+  <ArchiveRealStorage>450</ArchiveRealStorage>
+  <ArchiveObjectCount>74</ArchiveObjectCount>
+  <ColdArchiveStorage>2359296</ColdArchiveStorage>
+  <ColdArchiveRealStorage>360</ColdArchiveRealStorage>
+  <ColdArchiveObjectCount>36</ColdArchiveObjectCount>
+</BucketStat>
+BBBB;
+
+private $invalidXml = <<<BBBB
+<?xml version="1.0" ?>
+<BucketStat>
+</BucketStat>
+BBBB;
 
 
     public function testParseValidXml()
     public function testParseValidXml()
     {
     {
@@ -32,9 +45,22 @@ class GetBucketStatResultTest extends \PHPUnit\Framework\TestCase
         $this->assertNotNull($result->getData());
         $this->assertNotNull($result->getData());
         $this->assertNotNull($result->getRawResponse());
         $this->assertNotNull($result->getRawResponse());
         $stat = $result->getData();
         $stat = $result->getData();
-        $this->assertEquals(100, $stat->getStorage());
-        $this->assertEquals(200, $stat->getObjectCount());
-        $this->assertEquals(10, $stat->getMultipartUploadCount());
+        $this->assertEquals(1600, $stat->getStorage());
+        $this->assertEquals(230, $stat->getObjectCount());
+        $this->assertEquals(40, $stat->getMultipartUploadCount());
+        $this->assertEquals(4, $stat->getLiveChannelCount());
+        $this->assertEquals(1643341269, $stat->getLastModifiedTime());
+        $this->assertEquals(430, $stat->getStandardStorage());
+        $this->assertEquals(66, $stat->getStandardObjectCount());
+        $this->assertEquals(2359296, $stat->getInfrequentAccessStorage());
+        $this->assertEquals(360, $stat->getInfrequentAccessRealStorage());
+        $this->assertEquals(54, $stat->getInfrequentAccessObjectCount());
+        $this->assertEquals(2949120, $stat->getArchiveStorage());
+        $this->assertEquals(450, $stat->getArchiveRealStorage());
+        $this->assertEquals(74, $stat->getArchiveObjectCount());
+        $this->assertEquals(2359296, $stat->getColdArchiveStorage());
+        $this->assertEquals(360, $stat->getColdArchiveRealStorage());
+        $this->assertEquals(36, $stat->getColdArchiveObjectCount());
     }
     }
 
 
     public function testParseNullXml()
     public function testParseNullXml()

+ 148 - 0
vendor/aliyuncs/oss-sdk-php/tests/OSS/Tests/OssClientTest.php

@@ -4,6 +4,79 @@ namespace OSS\Tests;
 
 
 use OSS\Core\OssException;
 use OSS\Core\OssException;
 use OSS\OssClient;
 use OSS\OssClient;
+use OSS\Credentials\Credentials;
+use OSS\Credentials\CredentialsProvider;
+use OSS\Credentials\StaticCredentialsProvider;
+
+class TestEmptyIdCredentials extends Credentials
+{
+    public function __construct()
+    {
+    }
+
+    public function getAccessKeyId()
+    {
+        return '';
+    }
+
+    public function getAccessKeySecret()
+    {
+        return 'secret';
+    }
+
+    public function getSecurityToken()
+    {
+        return null;
+    }
+}
+
+class TestEmptySecretCredentials extends Credentials
+{
+    public function __construct()
+    {
+    }
+
+    public function getAccessKeyId()
+    {
+        return 'id';
+    }
+
+    public function getAccessKeySecret()
+    {
+        return '';
+    }
+
+    public function getSecurityToken()
+    {
+        return null;
+    }
+}
+
+
+class TestCredentialsProvider implements CredentialsProvider
+{
+    private $credentials;
+    public function __construct($flag)
+    {
+        if ($flag == 2) {
+            $this->credentials =  new TestEmptyIdCredentials();
+        }
+        else if ($flag == 1) {
+            $this->credentials =  new TestEmptySecretCredentials();
+        }
+        else {
+            $this->credentials = null;
+        }
+    }
+
+    /**
+     * @return Credentials
+     */
+    public function getCredentials()
+    {
+        return $this->credentials;
+    }
+}
 
 
 
 
 class OssClientTest extends TestOssClientBase
 class OssClientTest extends TestOssClientBase
@@ -343,4 +416,79 @@ class OssClientTest extends TestOssClientBase
             $this->assertFalse(true);
             $this->assertFalse(true);
         }
         }
     }
     }
+
+    public function testEmptyCredentials()
+    {
+        // empty case, should throw exception
+        try {
+            $id = '';
+            $secret = 'accessKey_secret';
+            $provider = new StaticCredentialsProvider($id, $secret);
+            $config = array(
+                'provider' => $provider,
+                'endpoint'=>'http://oss-cn-hangzhou.aliyuncs.com'
+            );
+            $ossClient = new OssClient($config);
+            $this->assertFalse(true);
+        } catch (OssException $e) {
+            $this->assertEquals('access key id is empty', $e->getMessage());
+        }
+
+        // empty case, should throw exception
+        try {
+            $id = 'id';
+            $secret = '';
+            $provider = new StaticCredentialsProvider($id, $secret);
+            $config = array(
+                'provider' => $provider,
+                'endpoint'=>'http://oss-cn-hangzhou.aliyuncs.com'
+            );
+            $ossClient = new OssClient($config);
+            $this->assertFalse(true);
+        } catch (OssException $e) {
+            $this->assertEquals('access key secret is empty', $e->getMessage());
+        }
+
+        // empty case, should throw exception
+        try {
+            $provider = new TestCredentialsProvider(0);
+            $config = array(
+                'provider' => $provider,
+                'endpoint'=>'http://oss-cn-hangzhou.aliyuncs.com'
+            );
+            $ossClient = new OssClient($config);
+            $ossClient->getBucketAcl("bucket");
+            $this->assertFalse(true);
+        } catch (OssException $e) {
+            $this->assertEquals('credentials is empty.', $e->getMessage());
+        }
+
+        // empty case, should throw exception
+        try {
+            $provider = new TestCredentialsProvider(1);
+            $config = array(
+                'provider' => $provider,
+                'endpoint'=>'http://oss-cn-hangzhou.aliyuncs.com'
+            );
+            $ossClient = new OssClient($config);
+            $ossClient->getBucketAcl("bucket");
+            $this->assertFalse(true);
+        } catch (OssException $e) {
+            $this->assertEquals('access key secret is empty', $e->getMessage());
+        }
+
+        // empty case, should throw exception
+        try {
+            $provider = new TestCredentialsProvider(2);
+            $config = array(
+                'provider' => $provider,
+                'endpoint'=>'http://oss-cn-hangzhou.aliyuncs.com'
+            );
+            $ossClient = new OssClient($config);
+            $ossClient->getBucketAcl("bucket");
+            $this->assertFalse(true);
+        } catch (OssException $e) {
+            $this->assertEquals('access key id is empty', $e->getMessage());
+        }
+    }
 }
 }

+ 119 - 0
vendor/bin/yaml-lint

@@ -0,0 +1,119 @@
+#!/usr/bin/env php
+<?php
+
+/**
+ * Proxy PHP file generated by Composer
+ *
+ * This file includes the referenced bin path (../symfony/yaml/Resources/bin/yaml-lint)
+ * using a stream wrapper to prevent the shebang from being output on PHP<8
+ *
+ * @generated
+ */
+
+namespace Composer;
+
+$GLOBALS['_composer_bin_dir'] = __DIR__;
+$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
+
+if (PHP_VERSION_ID < 80000) {
+    if (!class_exists('Composer\BinProxyWrapper')) {
+        /**
+         * @internal
+         */
+        final class BinProxyWrapper
+        {
+            private $handle;
+            private $position;
+            private $realpath;
+
+            public function stream_open($path, $mode, $options, &$opened_path)
+            {
+                // get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
+                $opened_path = substr($path, 17);
+                $this->realpath = realpath($opened_path) ?: $opened_path;
+                $opened_path = $this->realpath;
+                $this->handle = fopen($this->realpath, $mode);
+                $this->position = 0;
+
+                return (bool) $this->handle;
+            }
+
+            public function stream_read($count)
+            {
+                $data = fread($this->handle, $count);
+
+                if ($this->position === 0) {
+                    $data = preg_replace('{^#!.*\r?\n}', '', $data);
+                }
+
+                $this->position += strlen($data);
+
+                return $data;
+            }
+
+            public function stream_cast($castAs)
+            {
+                return $this->handle;
+            }
+
+            public function stream_close()
+            {
+                fclose($this->handle);
+            }
+
+            public function stream_lock($operation)
+            {
+                return $operation ? flock($this->handle, $operation) : true;
+            }
+
+            public function stream_seek($offset, $whence)
+            {
+                if (0 === fseek($this->handle, $offset, $whence)) {
+                    $this->position = ftell($this->handle);
+                    return true;
+                }
+
+                return false;
+            }
+
+            public function stream_tell()
+            {
+                return $this->position;
+            }
+
+            public function stream_eof()
+            {
+                return feof($this->handle);
+            }
+
+            public function stream_stat()
+            {
+                return array();
+            }
+
+            public function stream_set_option($option, $arg1, $arg2)
+            {
+                return true;
+            }
+
+            public function url_stat($path, $flags)
+            {
+                $path = substr($path, 17);
+                if (file_exists($path)) {
+                    return stat($path);
+                }
+
+                return false;
+            }
+        }
+    }
+
+    if (
+        (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))
+        || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
+    ) {
+        return include("phpvfscomposer://" . __DIR__ . '/..'.'/symfony/yaml/Resources/bin/yaml-lint');
+    }
+}
+
+return include __DIR__ . '/..'.'/symfony/yaml/Resources/bin/yaml-lint';

+ 20 - 2
vendor/brick/math/CHANGELOG.md

@@ -2,11 +2,29 @@
 
 
 All notable changes to this project will be documented in this file.
 All notable changes to this project will be documented in this file.
 
 
+## [0.10.2](https://github.com/brick/math/releases/tag/0.10.2) - 2022-08-11
+
+👌 **Improvements**
+
+- `BigRational::toFloat()` now simplifies the fraction before performing division (#73) thanks to @olsavmic
+
+## [0.10.1](https://github.com/brick/math/releases/tag/0.10.1) - 2022-08-02
+
+✨ **New features**
+
+- `BigInteger::gcdMultiple()` returns the GCD of multiple `BigInteger` numbers
+
+## [0.10.0](https://github.com/brick/math/releases/tag/0.10.0) - 2022-06-18
+
+💥 **Breaking changes**
+
+- Minimum PHP version is now 7.4
+
 ## [0.9.3](https://github.com/brick/math/releases/tag/0.9.3) - 2021-08-15
 ## [0.9.3](https://github.com/brick/math/releases/tag/0.9.3) - 2021-08-15
 
 
 🚀 **Compatibility with PHP 8.1**
 🚀 **Compatibility with PHP 8.1**
 
 
-- Support for custom object serialization; this removes a warning on PHP 8.1 due to the `Serializable` interface being deprecated (thanks @TRowbotham)
+- Support for custom object serialization; this removes a warning on PHP 8.1 due to the `Serializable` interface being deprecated (#60) thanks @TRowbotham
 
 
 ## [0.9.2](https://github.com/brick/math/releases/tag/0.9.2) - 2021-01-20
 ## [0.9.2](https://github.com/brick/math/releases/tag/0.9.2) - 2021-01-20
 
 
@@ -16,7 +34,7 @@ All notable changes to this project will be documented in this file.
 
 
 ## [0.9.1](https://github.com/brick/math/releases/tag/0.9.1) - 2020-08-19
 ## [0.9.1](https://github.com/brick/math/releases/tag/0.9.1) - 2020-08-19
 
 
-✨ New features
+✨ **New features**
 
 
 - `BigInteger::not()` returns the bitwise `NOT` value
 - `BigInteger::not()` returns the bitwise `NOT` value
 
 

+ 0 - 17
vendor/brick/math/SECURITY.md

@@ -1,17 +0,0 @@
-# Security Policy
-
-## Supported Versions
-
-Only the last two release streams are supported.
-
-| Version | Supported          |
-| ------- | ------------------ |
-| 0.9.x   | :white_check_mark: |
-| 0.8.x   | :white_check_mark: |
-| < 0.8   | :x:                |
-
-## Reporting a Vulnerability
-
-To report a security vulnerability, please use the
-[Tidelift security contact](https://tidelift.com/security).
-Tidelift will coordinate the fix and disclosure.

+ 3 - 3
vendor/brick/math/composer.json

@@ -14,13 +14,13 @@
     ],
     ],
     "license": "MIT",
     "license": "MIT",
     "require": {
     "require": {
-        "php": "^7.1 || ^8.0",
+        "php": "^7.4 || ^8.0",
         "ext-json": "*"
         "ext-json": "*"
     },
     },
     "require-dev": {
     "require-dev": {
-        "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.0",
+        "phpunit/phpunit": "^9.0",
         "php-coveralls/php-coveralls": "^2.2",
         "php-coveralls/php-coveralls": "^2.2",
-        "vimeo/psalm": "4.9.2"
+        "vimeo/psalm": "4.25.0"
     },
     },
     "autoload": {
     "autoload": {
         "psr-4": {
         "psr-4": {

+ 2 - 6
vendor/brick/math/src/BigDecimal.php

@@ -22,19 +22,15 @@ final class BigDecimal extends BigNumber
      * This is a string of digits with an optional leading minus sign.
      * This is a string of digits with an optional leading minus sign.
      * No leading zero must be present.
      * No leading zero must be present.
      * No leading minus sign must be present if the value is 0.
      * No leading minus sign must be present if the value is 0.
-     *
-     * @var string
      */
      */
-    private $value;
+    private string $value;
 
 
     /**
     /**
      * The scale (number of digits after the decimal point) of this decimal number.
      * The scale (number of digits after the decimal point) of this decimal number.
      *
      *
      * This must be zero or more.
      * This must be zero or more.
-     *
-     * @var int
      */
      */
-    private $scale;
+    private int $scale;
 
 
     /**
     /**
      * Protected constructor. Use a factory method to obtain an instance.
      * Protected constructor. Use a factory method to obtain an instance.

+ 16 - 3
vendor/brick/math/src/BigInteger.php

@@ -26,10 +26,8 @@ final class BigInteger extends BigNumber
      *
      *
      * No leading zeros must be present.
      * No leading zeros must be present.
      * No leading minus sign must be present if the number is zero.
      * No leading minus sign must be present if the number is zero.
-     *
-     * @var string
      */
      */
-    private $value;
+    private string $value;
 
 
     /**
     /**
      * Protected constructor. Use a factory method to obtain an instance.
      * Protected constructor. Use a factory method to obtain an instance.
@@ -361,6 +359,21 @@ final class BigInteger extends BigNumber
         return $ten;
         return $ten;
     }
     }
 
 
+    public static function gcdMultiple(BigInteger $a, BigInteger ...$n): BigInteger
+    {
+        $result = $a;
+
+        foreach ($n as $next) {
+            $result = $result->gcd($next);
+
+            if ($result->isEqualTo(1)) {
+                return $result;
+            }
+        }
+
+        return $result;
+    }
+
     /**
     /**
      * Returns the sum of this number and the given one.
      * Returns the sum of this number and the given one.
      *
      *

+ 1 - 3
vendor/brick/math/src/BigNumber.php

@@ -81,9 +81,7 @@ abstract class BigNumber implements \Serializable, \JsonSerializable
             $throw();
             $throw();
         }
         }
 
 
-        $getMatch = static function(string $value) use ($matches) : ?string {
-            return isset($matches[$value]) && $matches[$value] !== '' ? $matches[$value] : null;
-        };
+        $getMatch = static fn(string $value): ?string => (($matches[$value] ?? '') !== '') ? $matches[$value] : null;
 
 
         $sign        = $getMatch('sign');
         $sign        = $getMatch('sign');
         $numerator   = $getMatch('numerator');
         $numerator   = $getMatch('numerator');

+ 4 - 7
vendor/brick/math/src/BigRational.php

@@ -20,17 +20,13 @@ final class BigRational extends BigNumber
 {
 {
     /**
     /**
      * The numerator.
      * The numerator.
-     *
-     * @var BigInteger
      */
      */
-    private $numerator;
+    private BigInteger $numerator;
 
 
     /**
     /**
      * The denominator. Always strictly positive.
      * The denominator. Always strictly positive.
-     *
-     * @var BigInteger
      */
      */
-    private $denominator;
+    private BigInteger $denominator;
 
 
     /**
     /**
      * Protected constructor. Use a factory method to obtain an instance.
      * Protected constructor. Use a factory method to obtain an instance.
@@ -433,7 +429,8 @@ final class BigRational extends BigNumber
      */
      */
     public function toFloat() : float
     public function toFloat() : float
     {
     {
-        return $this->numerator->toFloat() / $this->denominator->toFloat();
+        $simplified = $this->simplified();
+        return $simplified->numerator->toFloat() / $simplified->denominator->toFloat();
     }
     }
 
 
     /**
     /**

+ 15 - 20
vendor/brick/math/src/Internal/Calculator.php

@@ -34,10 +34,8 @@ abstract class Calculator
 
 
     /**
     /**
      * The Calculator instance in use.
      * The Calculator instance in use.
-     *
-     * @var Calculator|null
      */
      */
-    private static $instance;
+    private static ?Calculator $instance = null;
 
 
     /**
     /**
      * Sets the Calculator instance to use.
      * Sets the Calculator instance to use.
@@ -234,7 +232,7 @@ abstract class Calculator
      * @param string $a The dividend.
      * @param string $a The dividend.
      * @param string $b The divisor, must not be zero.
      * @param string $b The divisor, must not be zero.
      *
      *
-     * @return string[] An array containing the quotient and remainder.
+     * @return array{string, string} An array containing the quotient and remainder.
      */
      */
     abstract public function divQR(string $a, string $b) : array;
     abstract public function divQR(string $a, string $b) : array;
 
 
@@ -283,9 +281,7 @@ abstract class Calculator
             $modVal = $this->mod($x, $m);
             $modVal = $this->mod($x, $m);
         }
         }
 
 
-        $x = '0';
-        $y = '0';
-        $g = $this->gcdExtended($modVal, $m, $x, $y);
+        [$g, $x] = $this->gcdExtended($modVal, $m);
 
 
         if ($g !== '1') {
         if ($g !== '1') {
             return null;
             return null;
@@ -329,24 +325,21 @@ abstract class Calculator
         return $this->gcd($b, $this->divR($a, $b));
         return $this->gcd($b, $this->divR($a, $b));
     }
     }
 
 
-    private function gcdExtended(string $a, string $b, string &$x, string &$y) : string
+    /**
+     * @return array{string, string, string} GCD, X, Y
+     */
+    private function gcdExtended(string $a, string $b) : array
     {
     {
         if ($a === '0') {
         if ($a === '0') {
-            $x = '0';
-            $y = '1';
-
-            return $b;
+            return [$b, '0', '1'];
         }
         }
 
 
-        $x1 = '0';
-        $y1 = '0';
-
-        $gcd = $this->gcdExtended($this->mod($b, $a), $a, $x1, $y1);
+        [$gcd, $x1, $y1] = $this->gcdExtended($this->mod($b, $a), $a);
 
 
         $x = $this->sub($y1, $this->mul($this->divQ($b, $a), $x1));
         $x = $this->sub($y1, $this->mul($this->divQ($b, $a), $x1));
         $y = $x1;
         $y = $x1;
 
 
-        return $gcd;
+        return [$gcd, $x, $y];
     }
     }
 
 
     /**
     /**
@@ -493,6 +486,8 @@ abstract class Calculator
      *
      *
      * @throws \InvalidArgumentException  If the rounding mode is invalid.
      * @throws \InvalidArgumentException  If the rounding mode is invalid.
      * @throws RoundingNecessaryException If RoundingMode::UNNECESSARY is provided but rounding is necessary.
      * @throws RoundingNecessaryException If RoundingMode::UNNECESSARY is provided but rounding is necessary.
+     *
+     * @psalm-suppress ImpureFunctionCall
      */
      */
     final public function divRound(string $a, string $b, int $roundingMode) : string
     final public function divRound(string $a, string $b, int $roundingMode) : string
     {
     {
@@ -616,9 +611,9 @@ abstract class Calculator
     /**
     /**
      * Performs a bitwise operation on a decimal number.
      * Performs a bitwise operation on a decimal number.
      *
      *
-     * @param string $operator The operator to use, must be "and", "or" or "xor".
-     * @param string $a        The left operand.
-     * @param string $b        The right operand.
+     * @param 'and'|'or'|'xor' $operator The operator to use.
+     * @param string           $a        The left operand.
+     * @param string           $b        The right operand.
      *
      *
      * @return string
      * @return string
      */
      */

+ 0 - 6
vendor/brick/math/src/Internal/Calculator/BcMathCalculator.php

@@ -94,9 +94,6 @@ class BcMathCalculator extends Calculator
 
 
     /**
     /**
      * {@inheritdoc}
      * {@inheritdoc}
-     *
-     * @psalm-suppress InvalidNullableReturnType
-     * @psalm-suppress NullableReturnStatement
      */
      */
     public function modPow(string $base, string $exp, string $mod) : string
     public function modPow(string $base, string $exp, string $mod) : string
     {
     {
@@ -105,9 +102,6 @@ class BcMathCalculator extends Calculator
 
 
     /**
     /**
      * {@inheritDoc}
      * {@inheritDoc}
-     *
-     * @psalm-suppress NullableReturnStatement
-     * @psalm-suppress InvalidNullableReturnType
      */
      */
     public function sqrt(string $n) : string
     public function sqrt(string $n) : string
     {
     {

+ 1 - 3
vendor/brick/math/src/Internal/Calculator/NativeCalculator.php

@@ -22,10 +22,8 @@ class NativeCalculator extends Calculator
      * For addition, it is assumed that an extra digit can hold a carry (1) without overflowing.
      * For addition, it is assumed that an extra digit can hold a carry (1) without overflowing.
      * Example: 32-bit: max number 1,999,999,999 (9 digits + carry)
      * Example: 32-bit: max number 1,999,999,999 (9 digits + carry)
      *          64-bit: max number 1,999,999,999,999,999,999 (18 digits + carry)
      *          64-bit: max number 1,999,999,999,999,999,999 (18 digits + carry)
-     *
-     * @var int
      */
      */
-    private $maxDigits;
+    private int $maxDigits;
 
 
     /**
     /**
      * Class constructor.
      * Class constructor.

File diff suppressed because it is too large
+ 23452 - 6
vendor/composer/autoload_classmap.php


+ 4 - 3
vendor/composer/autoload_files.php

@@ -6,8 +6,8 @@ $vendorDir = dirname(__DIR__);
 $baseDir = dirname($vendorDir);
 $baseDir = dirname($vendorDir);
 
 
 return array(
 return array(
-    'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
     '6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php',
     '6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php',
+    'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
     '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
     '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
     '7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
     '7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
     'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php',
     'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php',
@@ -21,16 +21,15 @@ return array(
     '8825ede83f2f289127722d4e842cf7e8' => $vendorDir . '/symfony/polyfill-intl-grapheme/bootstrap.php',
     '8825ede83f2f289127722d4e842cf7e8' => $vendorDir . '/symfony/polyfill-intl-grapheme/bootstrap.php',
     'b6b991a57620e2fb6b2f66f03fe9ddc2' => $vendorDir . '/symfony/string/Resources/functions.php',
     'b6b991a57620e2fb6b2f66f03fe9ddc2' => $vendorDir . '/symfony/string/Resources/functions.php',
     'a1105708a18b76903365ca1c4aa61b02' => $vendorDir . '/symfony/translation/Resources/functions.php',
     'a1105708a18b76903365ca1c4aa61b02' => $vendorDir . '/symfony/translation/Resources/functions.php',
-    '23c18046f52bef3eea034657bafda50f' => $vendorDir . '/symfony/polyfill-php81/bootstrap.php',
     'def43f6c87e4f8dfd0c9e1b1bab14fe8' => $vendorDir . '/symfony/polyfill-iconv/bootstrap.php',
     'def43f6c87e4f8dfd0c9e1b1bab14fe8' => $vendorDir . '/symfony/polyfill-iconv/bootstrap.php',
     'd767e4fc2dc52fe66584ab8c6684783e' => $vendorDir . '/adbario/php-dot-notation/src/helpers.php',
     'd767e4fc2dc52fe66584ab8c6684783e' => $vendorDir . '/adbario/php-dot-notation/src/helpers.php',
-    '65fec9ebcfbb3cbb4fd0d519687aea01' => $vendorDir . '/danielstjules/stringy/src/Create.php',
     'b067bc7112e384b61c701452d53a14a8' => $vendorDir . '/mtdowling/jmespath.php/src/JmesPath.php',
     'b067bc7112e384b61c701452d53a14a8' => $vendorDir . '/mtdowling/jmespath.php/src/JmesPath.php',
     '538ca81a9a966a6716601ecf48f4eaef' => $vendorDir . '/opis/closure/functions.php',
     '538ca81a9a966a6716601ecf48f4eaef' => $vendorDir . '/opis/closure/functions.php',
     'e39a8b23c42d4e1452234d762b03835a' => $vendorDir . '/ramsey/uuid/src/functions.php',
     'e39a8b23c42d4e1452234d762b03835a' => $vendorDir . '/ramsey/uuid/src/functions.php',
     '2c102faa651ef8ea5874edb585946bce' => $vendorDir . '/swiftmailer/swiftmailer/lib/swift_required.php',
     '2c102faa651ef8ea5874edb585946bce' => $vendorDir . '/swiftmailer/swiftmailer/lib/swift_required.php',
     '66453932bc1be9fb2f910a27947d11b6' => $vendorDir . '/alibabacloud/client/src/Functions.php',
     '66453932bc1be9fb2f910a27947d11b6' => $vendorDir . '/alibabacloud/client/src/Functions.php',
     '9cdd7b9056abc3081735233ba9dd9c7f' => $vendorDir . '/facade/flare-client-php/src/helpers.php',
     '9cdd7b9056abc3081735233ba9dd9c7f' => $vendorDir . '/facade/flare-client-php/src/helpers.php',
+    '1f87db08236948d07391152dccb70f04' => $vendorDir . '/google/apiclient-services/autoload.php',
     '265b4faa2b3a9766332744949e83bf97' => $vendorDir . '/laravel/framework/src/Illuminate/Collections/helpers.php',
     '265b4faa2b3a9766332744949e83bf97' => $vendorDir . '/laravel/framework/src/Illuminate/Collections/helpers.php',
     'c7a3c339e7e14b60e06a2d7fcce9476b' => $vendorDir . '/laravel/framework/src/Illuminate/Events/functions.php',
     'c7a3c339e7e14b60e06a2d7fcce9476b' => $vendorDir . '/laravel/framework/src/Illuminate/Events/functions.php',
     'f0906e6318348a765ffb6eb24e0d0938' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/helpers.php',
     'f0906e6318348a765ffb6eb24e0d0938' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/helpers.php',
@@ -38,10 +37,12 @@ return array(
     '6124b4c8570aa390c21fafd04a26c69f' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php',
     '6124b4c8570aa390c21fafd04a26c69f' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php',
     'f0e7e63bbb278a92db02393536748c5f' => $vendorDir . '/overtrue/wechat/src/Kernel/Support/Helpers.php',
     'f0e7e63bbb278a92db02393536748c5f' => $vendorDir . '/overtrue/wechat/src/Kernel/Support/Helpers.php',
     '6747f579ad6817f318cc3a7e7a0abb93' => $vendorDir . '/overtrue/wechat/src/Kernel/Helpers.php',
     '6747f579ad6817f318cc3a7e7a0abb93' => $vendorDir . '/overtrue/wechat/src/Kernel/Helpers.php',
+    'decc78cc4436b1292c6c0d151b19445c' => $vendorDir . '/phpseclib/phpseclib/phpseclib/bootstrap.php',
     '801c31d8ed748cfa537fa45402288c95' => $vendorDir . '/psy/psysh/src/functions.php',
     '801c31d8ed748cfa537fa45402288c95' => $vendorDir . '/psy/psysh/src/functions.php',
     '658bb4096adc969c7b632b99525cd486' => $vendorDir . '/api-ecosystem-for-laravel/dingo-api/src/helpers.php',
     '658bb4096adc969c7b632b99525cd486' => $vendorDir . '/api-ecosystem-for-laravel/dingo-api/src/helpers.php',
     '044fc72df35e84c745ee0d4120dc15d2' => $vendorDir . '/dcat/laravel-admin/src/Support/helpers.php',
     '044fc72df35e84c745ee0d4120dc15d2' => $vendorDir . '/dcat/laravel-admin/src/Support/helpers.php',
     'ed962a97bd972bc82007176b647d4e36' => $vendorDir . '/facade/ignition/src/helpers.php',
     'ed962a97bd972bc82007176b647d4e36' => $vendorDir . '/facade/ignition/src/helpers.php',
+    'a8d3953fd9959404dd22d3dfcd0a79f0' => $vendorDir . '/google/apiclient/src/aliases.php',
     'f960e77410032f236cef8c56617b313e' => $vendorDir . '/overtrue/laravel-lang/src/helpers.php',
     'f960e77410032f236cef8c56617b313e' => $vendorDir . '/overtrue/laravel-lang/src/helpers.php',
     'ec07570ca5a812141189b1fa81503674' => $vendorDir . '/phpunit/phpunit/src/Framework/Assert/Functions.php',
     'ec07570ca5a812141189b1fa81503674' => $vendorDir . '/phpunit/phpunit/src/Framework/Assert/Functions.php',
     'ff086428ca04349ca1a7b01ea2d9a650' => $baseDir . '/app/Helper/function.php',
     'ff086428ca04349ca1a7b01ea2d9a650' => $baseDir . '/app/Helper/function.php',

+ 9 - 4
vendor/composer/autoload_psr4.php

@@ -7,6 +7,7 @@ $baseDir = dirname($vendorDir);
 
 
 return array(
 return array(
     'voku\\' => array($vendorDir . '/voku/portable-ascii/src/voku'),
     'voku\\' => array($vendorDir . '/voku/portable-ascii/src/voku'),
+    'phpseclib3\\' => array($vendorDir . '/phpseclib/phpseclib/phpseclib'),
     'phpDocumentor\\Reflection\\' => array($vendorDir . '/phpdocumentor/reflection-common/src', $vendorDir . '/phpdocumentor/reflection-docblock/src', $vendorDir . '/phpdocumentor/type-resolver/src'),
     'phpDocumentor\\Reflection\\' => array($vendorDir . '/phpdocumentor/reflection-common/src', $vendorDir . '/phpdocumentor/reflection-docblock/src', $vendorDir . '/phpdocumentor/type-resolver/src'),
     'libphonenumber\\' => array($vendorDir . '/giggsey/libphonenumber-for-php/src'),
     'libphonenumber\\' => array($vendorDir . '/giggsey/libphonenumber-for-php/src'),
     'h4cc\\WKHTMLToPDF\\' => array($vendorDir . '/h4cc/wkhtmltopdf-amd64'),
     'h4cc\\WKHTMLToPDF\\' => array($vendorDir . '/h4cc/wkhtmltopdf-amd64'),
@@ -17,7 +18,6 @@ return array(
     'Tests\\' => array($baseDir . '/tests'),
     'Tests\\' => array($baseDir . '/tests'),
     'Tencent\\' => array($vendorDir . '/tencent/tls-sig-api-v2/src'),
     'Tencent\\' => array($vendorDir . '/tencent/tls-sig-api-v2/src'),
     'TencentCloud\\' => array($vendorDir . '/tencentcloud/tencentcloud-sdk-php/src/TencentCloud'),
     'TencentCloud\\' => array($vendorDir . '/tencentcloud/tencentcloud-sdk-php/src/TencentCloud'),
-    'Symfony\\Polyfill\\Php81\\' => array($vendorDir . '/symfony/polyfill-php81'),
     'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'),
     'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'),
     'Symfony\\Polyfill\\Php73\\' => array($vendorDir . '/symfony/polyfill-php73'),
     'Symfony\\Polyfill\\Php73\\' => array($vendorDir . '/symfony/polyfill-php73'),
     'Symfony\\Polyfill\\Php72\\' => array($vendorDir . '/symfony/polyfill-php72'),
     'Symfony\\Polyfill\\Php72\\' => array($vendorDir . '/symfony/polyfill-php72'),
@@ -31,6 +31,7 @@ return array(
     'Symfony\\Contracts\\Service\\' => array($vendorDir . '/symfony/service-contracts'),
     'Symfony\\Contracts\\Service\\' => array($vendorDir . '/symfony/service-contracts'),
     'Symfony\\Contracts\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher-contracts'),
     'Symfony\\Contracts\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher-contracts'),
     'Symfony\\Contracts\\Cache\\' => array($vendorDir . '/symfony/cache-contracts'),
     'Symfony\\Contracts\\Cache\\' => array($vendorDir . '/symfony/cache-contracts'),
+    'Symfony\\Component\\Yaml\\' => array($vendorDir . '/symfony/yaml'),
     'Symfony\\Component\\VarExporter\\' => array($vendorDir . '/symfony/var-exporter'),
     'Symfony\\Component\\VarExporter\\' => array($vendorDir . '/symfony/var-exporter'),
     'Symfony\\Component\\VarDumper\\' => array($vendorDir . '/symfony/var-dumper'),
     'Symfony\\Component\\VarDumper\\' => array($vendorDir . '/symfony/var-dumper'),
     'Symfony\\Component\\Translation\\' => array($vendorDir . '/symfony/translation'),
     'Symfony\\Component\\Translation\\' => array($vendorDir . '/symfony/translation'),
@@ -47,9 +48,7 @@ return array(
     'Symfony\\Component\\Console\\' => array($vendorDir . '/symfony/console'),
     'Symfony\\Component\\Console\\' => array($vendorDir . '/symfony/console'),
     'Symfony\\Component\\Cache\\' => array($vendorDir . '/symfony/cache'),
     'Symfony\\Component\\Cache\\' => array($vendorDir . '/symfony/cache'),
     'Symfony\\Bridge\\PsrHttpMessage\\' => array($vendorDir . '/symfony/psr-http-message-bridge'),
     'Symfony\\Bridge\\PsrHttpMessage\\' => array($vendorDir . '/symfony/psr-http-message-bridge'),
-    'Stringy\\' => array($vendorDir . '/danielstjules/stringy/src'),
     'Stomp\\' => array($vendorDir . '/stomp-php/stomp-php/src'),
     'Stomp\\' => array($vendorDir . '/stomp-php/stomp-php/src'),
-    'StellaMaris\\Clock\\' => array($vendorDir . '/stella-maris/clock/src'),
     'Spatie\\LaravelPackageTools\\' => array($vendorDir . '/spatie/laravel-package-tools/src'),
     'Spatie\\LaravelPackageTools\\' => array($vendorDir . '/spatie/laravel-package-tools/src'),
     'Spatie\\EloquentSortable\\' => array($vendorDir . '/spatie/eloquent-sortable/src'),
     'Spatie\\EloquentSortable\\' => array($vendorDir . '/spatie/eloquent-sortable/src'),
     'SocialiteProviders\\Weixin\\' => array($vendorDir . '/socialiteproviders/weixin'),
     'SocialiteProviders\\Weixin\\' => array($vendorDir . '/socialiteproviders/weixin'),
@@ -64,12 +63,14 @@ return array(
     'Psr\\Http\\Client\\' => array($vendorDir . '/psr/http-client/src'),
     'Psr\\Http\\Client\\' => array($vendorDir . '/psr/http-client/src'),
     'Psr\\EventDispatcher\\' => array($vendorDir . '/psr/event-dispatcher/src'),
     'Psr\\EventDispatcher\\' => array($vendorDir . '/psr/event-dispatcher/src'),
     'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
     'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
+    'Psr\\Clock\\' => array($vendorDir . '/psr/clock/src'),
     'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'),
     'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'),
-    'Prophecy\\' => array($vendorDir . '/phpspec/prophecy/src/Prophecy'),
     'Prettus\\Validator\\' => array($vendorDir . '/prettus/laravel-validation/src/Prettus/Validator'),
     'Prettus\\Validator\\' => array($vendorDir . '/prettus/laravel-validation/src/Prettus/Validator'),
     'Prettus\\Repository\\' => array($vendorDir . '/prettus/l5-repository/src/Prettus/Repository'),
     'Prettus\\Repository\\' => array($vendorDir . '/prettus/l5-repository/src/Prettus/Repository'),
     'PhpParser\\' => array($vendorDir . '/nikic/php-parser/lib/PhpParser'),
     'PhpParser\\' => array($vendorDir . '/nikic/php-parser/lib/PhpParser'),
     'PhpOption\\' => array($vendorDir . '/phpoption/phpoption/src/PhpOption'),
     'PhpOption\\' => array($vendorDir . '/phpoption/phpoption/src/PhpOption'),
+    'ParagonIE\\ConstantTime\\' => array($vendorDir . '/paragonie/constant_time_encoding/src'),
+    'PHPStan\\PhpDocParser\\' => array($vendorDir . '/phpstan/phpdoc-parser/src'),
     'PHPOpenSourceSaver\\JWTAuth\\' => array($vendorDir . '/php-open-source-saver/jwt-auth/src'),
     'PHPOpenSourceSaver\\JWTAuth\\' => array($vendorDir . '/php-open-source-saver/jwt-auth/src'),
     'Overtrue\\Socialite\\' => array($vendorDir . '/overtrue/socialite/src'),
     'Overtrue\\Socialite\\' => array($vendorDir . '/overtrue/socialite/src'),
     'Overtrue\\LaravelWeChat\\' => array($vendorDir . '/overtrue/laravel-wechat/src'),
     'Overtrue\\LaravelWeChat\\' => array($vendorDir . '/overtrue/laravel-wechat/src'),
@@ -105,8 +106,12 @@ return array(
     'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'),
     'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'),
     'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'),
     'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'),
     'GrahamCampbell\\ResultType\\' => array($vendorDir . '/graham-campbell/result-type/src'),
     'GrahamCampbell\\ResultType\\' => array($vendorDir . '/graham-campbell/result-type/src'),
+    'Google\\Service\\' => array($vendorDir . '/google/apiclient-services/src'),
+    'Google\\Auth\\' => array($vendorDir . '/google/auth/src'),
+    'Google\\' => array($vendorDir . '/google/apiclient/src'),
     'Giggsey\\Locale\\' => array($vendorDir . '/giggsey/locale/src'),
     'Giggsey\\Locale\\' => array($vendorDir . '/giggsey/locale/src'),
     'Fruitcake\\Cors\\' => array($vendorDir . '/fruitcake/laravel-cors/src'),
     'Fruitcake\\Cors\\' => array($vendorDir . '/fruitcake/laravel-cors/src'),
+    'Firebase\\JWT\\' => array($vendorDir . '/firebase/php-jwt/src'),
     'Faker\\' => array($vendorDir . '/fakerphp/faker/src/Faker'),
     'Faker\\' => array($vendorDir . '/fakerphp/faker/src/Faker'),
     'Facade\\Ignition\\' => array($vendorDir . '/facade/ignition/src'),
     'Facade\\Ignition\\' => array($vendorDir . '/facade/ignition/src'),
     'Facade\\IgnitionContracts\\' => array($vendorDir . '/facade/ignition-contracts/src'),
     'Facade\\IgnitionContracts\\' => array($vendorDir . '/facade/ignition-contracts/src'),

File diff suppressed because it is too large
+ 23501 - 29
vendor/composer/autoload_static.php


File diff suppressed because it is too large
+ 436 - 236
vendor/composer/installed.json


File diff suppressed because it is too large
+ 272 - 203
vendor/composer/installed.php


+ 2 - 2
vendor/composer/platform_check.php

@@ -4,8 +4,8 @@
 
 
 $issues = array();
 $issues = array();
 
 
-if (!(PHP_VERSION_ID >= 80002)) {
-    $issues[] = 'Your Composer dependencies require a PHP version ">= 8.0.2". You are running ' . PHP_VERSION . '.';
+if (!(PHP_VERSION_ID >= 80100)) {
+    $issues[] = 'Your Composer dependencies require a PHP version ">= 8.1.0". You are running ' . PHP_VERSION . '.';
 }
 }
 
 
 if ($issues) {
 if ($issues) {

+ 0 - 180
vendor/danielstjules/stringy/CHANGELOG.md

@@ -1,180 +0,0 @@
-### 3.1.0 (2017-06-11)
-* Add $language support to slugify
-* Add bg specific transliteration
-* ЬЪ/ьъ handling is now language-specific
-
-### 3.0.1 (2017-04-12)
-* Don't replace @ in toAscii
-* Use normal replacement for @ in slugify, e.g. user@home => user-home
-
-### 3.0.0 (2017-03-08)
-
-* Breaking change: added $language parameter to toAscii, before
-  $removeUnsupported
-* Breaking change: dropped PHP 5.3 support
-* Breaking change: any StaticStringy methods that previously returned instances
-  of Stringy now return strings
-
-### 2.4.0 (2017-03-02)
-
-* Add startsWithAny
-* Add endsWithAny
-* Add stripWhitespace
-* Fix error handling for unsupported encodings
-* Change private methods to protected for extending class
-* Fix safeTruncate for strings without spaces
-* Additional char support in toAscii, e.g. full width chars and wide
-  non-breaking space
-
-### 2.3.2 (2016-05-02)
-
-* Improve support without mbstring
-
-### 2.3.1 (2016-03-21)
-
-* Always use root namespace for mbstring functions
-
-### 2.3.0 (2016-03-19)
-
-* Add Persian characters in Stringy::charsArray()
-* Use symfony/polyfill-mbstring to avoid dependency on ext-mbstring
-
-### 2.2.0 (2015-12-20)
-
-* isJSON now returns false for empty strings
-* Update for German umlaut transformation
-* Use reflection to generate method list for StaticStringy
-* Added isBase64 method
-* Improved toAscii char coverage
-
-### 2.1.0 (2015-09-02)
-
-* Added simplified StaticStringy class
-* str in Stringy::create and constructor is now optional
-
-### 2.0.0 (2015-07-29)
-
- * Removed StaticStringy class
- * Added append, prepend, toBoolean, repeat, between, slice, split, and lines
- * camelize/upperCamelize now strip leading dashes and underscores
- * titleize converts to lowercase, thus no longer preserving acronyms
-
-### 1.10.0 (2015-07-22)
-
- * Added trimLeft, trimRight
- * Added support for unicode whitespace to trim
- * Added delimit
- * Added indexOf and indexOfLast
- * Added htmlEncode and htmlDecode
- * Added "Ç" in toAscii()
-
-### 1.9.0 (2015-02-09)
-
- * Added hasUpperCase and hasLowerCase
- * Added $removeUnsupported parameter to toAscii()
- * Improved toAscii support with additional Unicode spaces, Vietnamese chars,
-   and numerous other characters
- * Separated the charsArray from toAscii as a protected method that may be
-   extended by inheriting classes
- * Chars array is cached for better performance
-
-### 1.8.1 (2015-01-08)
-
- * Optimized chars()
- * Added "ä Ä Ö Ü"" in toAscii()
- * Added support for Unicode spaces in toAscii()
- * Replaced instances of self::create() with static::create()
- * Added missing test cases for safeTruncate() and longestCommonSuffix()
- * Updated Stringy\create() to avoid collision when it already exists
-
-### 1.8.0 (2015-01-03)
-
- * Listed ext-mbstring in composer.json
- * Added Stringy\create function for PHP 5.6
-
-### 1.7.0 (2014-10-14)
-
- * Added containsAll and containsAny
- * Light cleanup
-
-### 1.6.0 (2014-09-14)
-
- * Added toTitleCase
-
-### 1.5.2 (2014-07-09)
-
- * Announced support for HHVM
-
-### 1.5.1 (2014-04-19)
-
-  * Fixed toAscii() failing to remove remaining non-ascii characters
-  * Updated slugify() to treat dash and underscore as delimiters by default
-  * Updated slugify() to remove leading and trailing delimiter, if present
-
-### 1.5.0 (2014-03-19)
-
-  * Made both str and encoding protected, giving property access to subclasses
-  * Added getEncoding()
-  * Fixed isJSON() giving false negatives
-  * Cleaned up and simplified: replace(), collapseWhitespace(), underscored(),
-    dasherize(), pad(), padLeft(), padRight() and padBoth()
-  * Fixed handling consecutive invalid chars in slugify()
-  * Removed conflicting hard sign transliteration in toAscii()
-
-### 1.4.0 (2014-02-12)
-
-  * Implemented the IteratorAggregate interface, added chars()
-  * Renamed count() to countSubstr()
-  * Updated count() to implement Countable interface
-  * Implemented the ArrayAccess interface with positive and negative indices
-  * Switched from PSR-0 to PSR-4 autoloading
-
-### 1.3.0 (2013-12-16)
-
-  * Additional Bulgarian support for toAscii
-  * str property made private
-  * Constructor casts first argument to string
-  * Constructor throws an InvalidArgumentException when given an array
-  * Constructor throws an InvalidArgumentException when given an object without
-    a __toString method
-
-### 1.2.2 (2013-12-04)
-
-  * Updated create function to use late static binding
-  * Added optional $replacement param to slugify
-
-### 1.2.1 (2013-10-11)
-
-  * Cleaned up tests
-  * Added homepage to composer.json
-
-### 1.2.0 (2013-09-15)
-
-  * Fixed pad's use of InvalidArgumentException
-  * Fixed replace(). It now correctly treats regex special chars as normal chars
-  * Added additional Cyrillic letters to toAscii
-  * Added $caseSensitive to contains() and count()
-  * Added toLowerCase()
-  * Added toUpperCase()
-  * Added regexReplace()
-
-### 1.1.0 (2013-08-31)
-
-  * Fix for collapseWhitespace()
-  * Added isHexadecimal()
-  * Added constructor to Stringy\Stringy
-  * Added isSerialized()
-  * Added isJson()
-
-### 1.0.0 (2013-08-1)
-
-  * 1.0.0 release
-  * Added test coverage for Stringy::create and method chaining
-  * Added tests for returned type
-  * Fixed StaticStringy::replace(). It was returning a Stringy object instead of string
-  * Renamed standardize() to the more appropriate toAscii()
-  * Cleaned up comments and README
-
-### 1.0.0-rc.1 (2013-07-28)
-
-  * Release candidate

+ 0 - 19
vendor/danielstjules/stringy/LICENSE.txt

@@ -1,19 +0,0 @@
-Copyright (C) 2013 Daniel St. Jules
-
-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.

+ 0 - 1082
vendor/danielstjules/stringy/README.md

@@ -1,1082 +0,0 @@
-![Stringy](http://danielstjules.com/github/stringy-logo.png)
-
-A PHP string manipulation library with multibyte support. Compatible with PHP
-5.4+, PHP 7+, and HHVM.
-
-``` php
-s('string')->toTitleCase()->ensureRight('y') == 'Stringy'
-```
-
-Refer to the [1.x branch](https://github.com/danielstjules/Stringy/tree/1.x) or
-[2.x branch](https://github.com/danielstjules/Stringy/tree/2.x) for older
-documentation.
-
-[![Build Status](https://api.travis-ci.org/danielstjules/Stringy.svg?branch=master)](https://travis-ci.org/danielstjules/Stringy)
-[![Total Downloads](https://poser.pugx.org/danielstjules/stringy/downloads)](https://packagist.org/packages/danielstjules/stringy)
-[![License](https://poser.pugx.org/danielstjules/stringy/license)](https://packagist.org/packages/danielstjules/stringy)
-
-* [Why?](#why)
-* [Installation](#installation)
-* [OO and Chaining](#oo-and-chaining)
-* [Implemented Interfaces](#implemented-interfaces)
-* [PHP 5.6 Creation](#php-56-creation)
-* [StaticStringy](#staticstringy)
-* [Class methods](#class-methods)
-    * [create](#createmixed-str--encoding-)
-* [Instance methods](#instance-methods)
-<table>
-    <tr>
-        <td><a href="#appendstring-string">append</a></td>
-        <td><a href="#atint-index">at</a></td>
-        <td><a href="#betweenstring-start-string-end--int-offset">between</a></td>
-        <td><a href="#camelize">camelize</a></td>
-    </tr>
-    <tr>
-        <td><a href="#chars">chars</a></td>
-        <td><a href="#collapsewhitespace">collapseWhitespace</a></td>
-        <td><a href="#containsstring-needle--boolean-casesensitive--true-">contains</a></td>
-        <td><a href="#containsallarray-needles--boolean-casesensitive--true-">containsAll</a></td>
-    </tr>
-    <tr>
-        <td><a href="#containsanyarray-needles--boolean-casesensitive--true-">containsAny</a></td>
-        <td><a href="#countsubstrstring-substring--boolean-casesensitive--true-">countSubstr</a></td>
-        <td><a href="#dasherize">dasherize</a></td>
-        <td><a href="#delimitint-delimiter">delimit</a></td>
-    </tr>
-    <tr>
-        <td><a href="#endswithstring-substring--boolean-casesensitive--true-">endsWith</a></td>
-        <td><a href="#endswithanystring-substrings--boolean-casesensitive--true-">endsWithAny</a></td>
-        <td><a href="#ensureleftstring-substring">ensureLeft</a></td>
-        <td><a href="#ensurerightstring-substring">ensureRight</a></td>
-    </tr>
-    <tr>
-        <td><a href="#firstint-n">first</a></td>
-        <td><a href="#getencoding">getEncoding</a></td>
-        <td><a href="#haslowercase">hasLowerCase</a></td>
-        <td><a href="#hasuppercase">hasUpperCase</a></td>
-    </tr>
-    <tr>
-        <td><a href="#htmldecode">htmlDecode</a></td>
-        <td><a href="#htmlencode">htmlEncode</a></td>
-        <td><a href="#humanize">humanize</a></td>
-        <td><a href="#indexofstring-needle--offset--0-">indexOf</a></td>
-    </tr>
-    <tr>
-        <td><a href="#indexoflaststring-needle--offset--0-">indexOfLast</a></td>
-        <td><a href="#insertint-index-string-substring">insert</a></td>
-        <td><a href="#isalpha">isAlpha</a></td>
-        <td><a href="#isalphanumeric">isAlphanumeric</a></td>
-    </tr>
-    <tr>
-        <td><a href="#isbase64">isBase64</a></td>
-        <td><a href="#isblank">isBlank</a></td>
-        <td><a href="#ishexadecimal">isHexadecimal</a></td>
-        <td><a href="#isjson">isJson</a></td>
-    </tr>
-    <tr>
-        <td><a href="#islowercase">isLowerCase</a></td>
-        <td><a href="#isserialized">isSerialized</a></td>
-        <td><a href="#isuppercase">isUpperCase</a></td>
-        <td><a href="#lastint-n">last</a></td>
-    </tr>
-    <tr>
-        <td><a href="#length">length</a></td>
-        <td><a href="#lines">lines</a></td>
-        <td><a href="#longestcommonprefixstring-otherstr">longestCommonPrefix</a></td>
-        <td><a href="#longestcommonsuffixstring-otherstr">longestCommonSuffix</a></td>
-    </tr>
-    <tr>
-        <td><a href="#longestcommonsubstringstring-otherstr">longestCommonSubstring</a></td>
-        <td><a href="#lowercasefirst">lowerCaseFirst</a></td>
-        <td><a href="#padint-length--string-padstr-----string-padtype--right-">pad</a></td>
-        <td><a href="#padbothint-length--string-padstr----">padBoth</a></td>
-    </tr>
-    <tr>
-        <td><a href="#padleftint-length--string-padstr----">padLeft</a></td>
-        <td><a href="#padrightint-length--string-padstr----">padRight</a></td>
-        <td><a href="#prependstring-string">prepend</a></td>
-        <td><a href="#regexreplacestring-pattern-string-replacement--string-options--msr">regexReplace</a></td>
-    </tr>
-    <tr>
-        <td><a href="#removeleftstring-substring">removeLeft</a></td>
-        <td><a href="#removerightstring-substring">removeRight</a></td>
-        <td><a href="#repeatint-multiplier">repeat</a></td>
-        <td><a href="#replacestring-search-string-replacement">replace</a></td>
-    </tr>
-    <tr>
-        <td><a href="#reverse">reverse</a></td>
-        <td><a href="#safetruncateint-length--string-substring---">safeTruncate</a></td>
-        <td><a href="#shuffle">shuffle</a></td>
-        <td><a href="#slugify-string-replacement-----string-language--en">slugify</a></td>
-    </tr>
-    <tr>
-        <td><a href="#sliceint-start--int-end-">slice</a></td>
-        <td><a href="#splitstring-pattern--int-limit-">split</a></td>
-        <td><a href="#startswithstring-substring--boolean-casesensitive--true-">startsWith</a></td>
-        <td><a href="#startswithanystring-substrings--boolean-casesensitive--true-">startsWithAny</a></td>
-    </tr>
-    <tr>
-        <td><a href="#stripwhitespace">stripWhitespace</a></td>
-        <td><a href="#substrint-start--int-length-">substr</a></td>
-        <td><a href="#surroundstring-substring">surround</a></td>
-        <td><a href="#swapcase">swapCase</a></td>
-    </tr>
-    <tr>
-        <td><a href="#tidy">tidy</a></td>
-        <td><a href="#titleize-array-ignore">titleize</a></td>
-        <td><a href="#toascii-string-language--en--bool-removeunsupported--true-">toAscii</a></td>
-        <td><a href="#toboolean">toBoolean</a></td>
-    </tr>
-    <tr>
-        <td><a href="#tolowercase">toLowerCase</a></td>
-        <td><a href="#tospaces-tablength--4-">toSpaces</a></td>
-        <td><a href="#totabs-tablength--4-">toTabs</a></td>
-        <td><a href="#totitlecase">toTitleCase</a></td>
-    </tr>
-    <tr>
-        <td><a href="#touppercase">toUpperCase</a></td>
-        <td><a href="#trim-string-chars">trim</a></td>
-        <td><a href="#trimleft-string-chars">trimLeft</a></td>
-        <td><a href="#trimright-string-chars">trimRight</a></td>
-    </tr>
-    <tr>
-        <td><a href="#truncateint-length--string-substring---">truncate</a></td>
-        <td><a href="#underscored">underscored</a></td>
-        <td><a href="#uppercamelize">upperCamelize</a></td>
-        <td><a href="#uppercasefirst">upperCaseFirst</a></td>
-    </tr>
-</table>
-
-* [Extensions](#extensions)
-* [Tests](#tests)
-* [License](#license)
-
-## Why?
-
-In part due to a lack of multibyte support (including UTF-8) across many of
-PHP's standard string functions. But also to offer an OO wrapper around the
-`mbstring` module's multibyte-compatible functions. Stringy handles some quirks,
-provides additional functionality, and hopefully makes strings a little easier
-to work with!
-
-```php
-// Standard library
-strtoupper('fòôbàř');       // 'FòôBàř'
-strlen('fòôbàř');           // 10
-
-// mbstring
-mb_strtoupper('fòôbàř');    // 'FÒÔBÀŘ'
-mb_strlen('fòôbàř');        // '6'
-
-// Stringy
-s('fòôbàř')->toUpperCase(); // 'FÒÔBÀŘ'
-s('fòôbàř')->length();      // '6'
-```
-
-## Installation
-
-If you're using Composer to manage dependencies, you can include the following
-in your composer.json file:
-
-```json
-"require": {
-    "danielstjules/stringy": "~3.1.0"
-}
-```
-
-Then, after running `composer update` or `php composer.phar update`, you can
-load the class using Composer's autoloading:
-
-```php
-require 'vendor/autoload.php';
-```
-
-Otherwise, you can simply require the file directly:
-
-```php
-require_once 'path/to/Stringy/src/Stringy.php';
-```
-
-And in either case, I'd suggest using an alias.
-
-```php
-use Stringy\Stringy as S;
-```
-
-Please note that Stringy relies on the `mbstring` module for its underlying
-multibyte support. If the module is not found, Stringy will use
-[symfony/polyfill-mbstring](https://github.com/symfony/polyfill-mbstring).
-ex-mbstring is a non-default, but very common module. For example, with debian
-and ubuntu, it's included in libapache2-mod-php5, php5-cli, and php5-fpm. For
-OSX users, it's a default for any version of PHP installed with homebrew.
-If compiling PHP from scratch, it can be included with the
-`--enable-mbstring` flag.
-
-## OO and Chaining
-
-The library offers OO method chaining, as seen below:
-
-```php
-use Stringy\Stringy as S;
-echo S::create('fòô     bàř')->collapseWhitespace()->swapCase(); // 'FÒÔ BÀŘ'
-```
-
-`Stringy\Stringy` has a __toString() method, which returns the current string
-when the object is used in a string context, ie:
-`(string) S::create('foo')  // 'foo'`
-
-## Implemented Interfaces
-
-`Stringy\Stringy` implements the `IteratorAggregate` interface, meaning that
-`foreach` can be used with an instance of the class:
-
-``` php
-$stringy = S::create('fòôbàř');
-foreach ($stringy as $char) {
-    echo $char;
-}
-// 'fòôbàř'
-```
-
-It implements the `Countable` interface, enabling the use of `count()` to
-retrieve the number of characters in the string:
-
-``` php
-$stringy = S::create('fòô');
-count($stringy);  // 3
-```
-
-Furthermore, the `ArrayAccess` interface has been implemented. As a result,
-`isset()` can be used to check if a character at a specific index exists. And
-since `Stringy\Stringy` is immutable, any call to `offsetSet` or `offsetUnset`
-will throw an exception. `offsetGet` has been implemented, however, and accepts
-both positive and negative indexes. Invalid indexes result in an
-`OutOfBoundsException`.
-
-``` php
-$stringy = S::create('bàř');
-echo $stringy[2];     // 'ř'
-echo $stringy[-2];    // 'à'
-isset($stringy[-4]);  // false
-
-$stringy[3];          // OutOfBoundsException
-$stringy[2] = 'a';    // Exception
-```
-
-## PHP 5.6 Creation
-
-As of PHP 5.6, [`use function`](https://wiki.php.net/rfc/use_function) is
-available for importing functions. Stringy exposes a namespaced function,
-`Stringy\create`, which emits the same behaviour as `Stringy\Stringy::create()`.
-If running PHP 5.6, or another runtime that supports the `use function` syntax,
-you can take advantage of an even simpler API as seen below:
-
-``` php
-use function Stringy\create as s;
-
-// Instead of: S::create('fòô     bàř')
-s('fòô     bàř')->collapseWhitespace()->swapCase();
-```
-
-## StaticStringy
-
-All methods listed under "Instance methods" are available as part of a static
-wrapper. For StaticStringy methods, the optional encoding is expected to be the
-last argument. The return value is not cast, and may thus be of type Stringy,
-integer, boolean, etc.
-
-```php
-use Stringy\StaticStringy as S;
-
-// Translates to Stringy::create('fòôbàř')->slice(0, 3);
-// Returns a Stringy object with the string "fòô"
-S::slice('fòôbàř', 0, 3);
-```
-
-## Class methods
-
-##### create(mixed $str [, $encoding ])
-
-Creates a Stringy object and assigns both str and encoding properties
-the supplied values. $str is cast to a string prior to assignment, and if
-$encoding is not specified, it defaults to mb_internal_encoding(). It
-then returns the initialized object. Throws an InvalidArgumentException
-if the first argument is an array or object without a __toString method.
-
-```php
-$stringy = S::create('fòôbàř'); // 'fòôbàř'
-```
-
-## Instance Methods
-
-Stringy objects are immutable. All examples below make use of PHP 5.6
-function importing, and PHP 5.4 short array syntax. They also assume the
-encoding returned by mb_internal_encoding() is UTF-8. For further details,
-see the documentation for the create method above, as well as the notes
-on PHP 5.6 creation.
-
-##### append(string $string)
-
-Returns a new string with $string appended.
-
-```php
-s('fòô')->append('bàř'); // 'fòôbàř'
-```
-
-##### at(int $index)
-
-Returns the character at $index, with indexes starting at 0.
-
-```php
-s('fòôbàř')->at(3); // 'b'
-```
-
-##### between(string $start, string $end [, int $offset])
-
-Returns the substring between $start and $end, if found, or an empty
-string. An optional offset may be supplied from which to begin the
-search for the start string.
-
-```php
-s('{foo} and {bar}')->between('{', '}'); // 'foo'
-```
-
-##### camelize()
-
-Returns a camelCase version of the string. Trims surrounding spaces,
-capitalizes letters following digits, spaces, dashes and underscores,
-and removes spaces, dashes, as well as underscores.
-
-```php
-s('Camel-Case')->camelize(); // 'camelCase'
-```
-
-##### chars()
-
-Returns an array consisting of the characters in the string.
-
-```php
-s('fòôbàř')->chars(); // ['f', 'ò', 'ô', 'b', 'à', 'ř']
-```
-
-##### collapseWhitespace()
-
-Trims the string and replaces consecutive whitespace characters with a
-single space. This includes tabs and newline characters, as well as
-multibyte whitespace such as the thin space and ideographic space.
-
-```php
-s('   Ο     συγγραφέας  ')->collapseWhitespace(); // 'Ο συγγραφέας'
-```
-
-##### contains(string $needle [, boolean $caseSensitive = true ])
-
-Returns true if the string contains $needle, false otherwise. By default,
-the comparison is case-sensitive, but can be made insensitive
-by setting $caseSensitive to false.
-
-```php
-s('Ο συγγραφέας είπε')->contains('συγγραφέας'); // true
-```
-
-##### containsAll(array $needles [, boolean $caseSensitive = true ])
-
-Returns true if the string contains all $needles, false otherwise. By
-default the comparison is case-sensitive, but can be made insensitive by
-setting $caseSensitive to false.
-
-```php
-s('foo & bar')->containsAll(['foo', 'bar']); // true
-```
-
-##### containsAny(array $needles [, boolean $caseSensitive = true ])
-
-Returns true if the string contains any $needles, false otherwise. By
-default the comparison is case-sensitive, but can be made insensitive by
-setting $caseSensitive to false.
-
-```php
-s('str contains foo')->containsAny(['foo', 'bar']); // true
-```
-
-##### countSubstr(string $substring [, boolean $caseSensitive = true ])
-
-Returns the number of occurrences of $substring in the given string.
-By default, the comparison is case-sensitive, but can be made insensitive
-by setting $caseSensitive to false.
-
-```php
-s('Ο συγγραφέας είπε')->countSubstr('α'); // 2
-```
-
-##### dasherize()
-
-Returns a lowercase and trimmed string separated by dashes. Dashes are
-inserted before uppercase characters (with the exception of the first
-character of the string), and in place of spaces as well as underscores.
-
-```php
-s('fooBar')->dasherize(); // 'foo-bar'
-```
-
-##### delimit(int $delimiter)
-
-Returns a lowercase and trimmed string separated by the given delimiter.
-Delimiters are inserted before uppercase characters (with the exception
-of the first character of the string), and in place of spaces, dashes,
-and underscores. Alpha delimiters are not converted to lowercase.
-
-```php
-s('fooBar')->delimit('::'); // 'foo::bar'
-```
-
-##### endsWith(string $substring [, boolean $caseSensitive = true ])
-
-Returns true if the string ends with $substring, false otherwise. By
-default, the comparison is case-sensitive, but can be made insensitive by
-setting $caseSensitive to false.
-
-```php
-s('fòôbàř')->endsWith('bàř'); // true
-```
-
-##### endsWithAny(string[] $substrings [, boolean $caseSensitive = true ])
-
-Returns true if the string ends with any of $substrings, false otherwise.
-By default, the comparison is case-sensitive, but can be made insensitive
-by setting $caseSensitive to false.
-
-```php
-s('fòôbàř')->endsWithAny(['bàř', 'baz']); // true
-```
-
-##### ensureLeft(string $substring)
-
-Ensures that the string begins with $substring. If it doesn't, it's prepended.
-
-```php
-s('foobar')->ensureLeft('http://'); // 'http://foobar'
-```
-
-##### ensureRight(string $substring)
-
-Ensures that the string ends with $substring. If it doesn't, it's appended.
-
-```php
-s('foobar')->ensureRight('.com'); // 'foobar.com'
-```
-
-##### first(int $n)
-
-Returns the first $n characters of the string.
-
-```php
-s('fòôbàř')->first(3); // 'fòô'
-```
-
-##### getEncoding()
-
-Returns the encoding used by the Stringy object.
-
-```php
-s('fòôbàř')->getEncoding(); // 'UTF-8'
-```
-
-##### hasLowerCase()
-
-Returns true if the string contains a lower case char, false otherwise.
-
-```php
-s('fòôbàř')->hasLowerCase(); // true
-```
-
-##### hasUpperCase()
-
-Returns true if the string contains an upper case char, false otherwise.
-
-```php
-s('fòôbàř')->hasUpperCase(); // false
-```
-
-##### htmlDecode()
-
-Convert all HTML entities to their applicable characters. An alias of
-html_entity_decode. For a list of flags, refer to
-http://php.net/manual/en/function.html-entity-decode.php
-
-```php
-s('&amp;')->htmlDecode(); // '&'
-```
-
-##### htmlEncode()
-
-Convert all applicable characters to HTML entities. An alias of
-htmlentities. Refer to http://php.net/manual/en/function.htmlentities.php
-for a list of flags.
-
-```php
-s('&')->htmlEncode(); // '&amp;'
-```
-
-##### humanize()
-
-Capitalizes the first word of the string, replaces underscores with
-spaces, and strips '_id'.
-
-```php
-s('author_id')->humanize(); // 'Author'
-```
-
-##### indexOf(string $needle [, $offset = 0 ]);
-
-Returns the index of the first occurrence of $needle in the string,
-and false if not found. Accepts an optional offset from which to begin
-the search. A negative index searches from the end
-
-```php
-s('string')->indexOf('ing'); // 3
-```
-
-##### indexOfLast(string $needle [, $offset = 0 ]);
-
-Returns the index of the last occurrence of $needle in the string,
-and false if not found. Accepts an optional offset from which to begin
-the search. Offsets may be negative to count from the last character
-in the string.
-
-```php
-s('foobarfoo')->indexOfLast('foo'); // 10
-```
-
-##### insert(int $index, string $substring)
-
-Inserts $substring into the string at the $index provided.
-
-```php
-s('fòôbř')->insert('à', 4); // 'fòôbàř'
-```
-
-##### isAlpha()
-
-Returns true if the string contains only alphabetic chars, false otherwise.
-
-```php
-s('丹尼爾')->isAlpha(); // true
-```
-
-##### isAlphanumeric()
-
-Returns true if the string contains only alphabetic and numeric chars, false
-otherwise.
-
-```php
-s('دانيال1')->isAlphanumeric(); // true
-```
-
-##### isBase64()
-
-Returns true if the string is base64 encoded, false otherwise.
-
-```php
-s('Zm9vYmFy')->isBase64(); // true
-```
-
-##### isBlank()
-
-Returns true if the string contains only whitespace chars, false otherwise.
-
-```php
-s("\n\t  \v\f")->isBlank(); // true
-```
-
-##### isHexadecimal()
-
-Returns true if the string contains only hexadecimal chars, false otherwise.
-
-```php
-s('A102F')->isHexadecimal(); // true
-```
-
-##### isJson()
-
-Returns true if the string is JSON, false otherwise. Unlike json_decode
-in PHP 5.x, this method is consistent with PHP 7 and other JSON parsers,
-in that an empty string is not considered valid JSON.
-
-```php
-s('{"foo":"bar"}')->isJson(); // true
-```
-
-##### isLowerCase()
-
-Returns true if the string contains only lower case chars, false otherwise.
-
-```php
-s('fòôbàř')->isLowerCase(); // true
-```
-
-##### isSerialized()
-
-Returns true if the string is serialized, false otherwise.
-
-```php
-s('a:1:{s:3:"foo";s:3:"bar";}')->isSerialized(); // true
-```
-
-##### isUpperCase()
-
-Returns true if the string contains only upper case chars, false otherwise.
-
-```php
-s('FÒÔBÀŘ')->isUpperCase(); // true
-```
-
-##### last(int $n)
-
-Returns the last $n characters of the string.
-
-```php
-s('fòôbàř')->last(3); // 'bàř'
-```
-
-##### length()
-
-Returns the length of the string. An alias for PHP's mb_strlen() function.
-
-```php
-s('fòôbàř')->length(); // 6
-```
-
-##### lines()
-
-Splits on newlines and carriage returns, returning an array of Stringy
-objects corresponding to the lines in the string.
-
-```php
-s("fòô\r\nbàř\n")->lines(); // ['fòô', 'bàř', '']
-```
-
-##### longestCommonPrefix(string $otherStr)
-
-Returns the longest common prefix between the string and $otherStr.
-
-```php
-s('foobar')->longestCommonPrefix('foobaz'); // 'fooba'
-```
-
-##### longestCommonSuffix(string $otherStr)
-
-Returns the longest common suffix between the string and $otherStr.
-
-```php
-s('fòôbàř')->longestCommonSuffix('fòrbàř'); // 'bàř'
-```
-
-##### longestCommonSubstring(string $otherStr)
-
-Returns the longest common substring between the string and $otherStr. In the
-case of ties, it returns that which occurs first.
-
-```php
-s('foobar')->longestCommonSubstring('boofar'); // 'oo'
-```
-
-##### lowerCaseFirst()
-
-Converts the first character of the supplied string to lower case.
-
-```php
-s('Σ foo')->lowerCaseFirst(); // 'σ foo'
-```
-
-##### pad(int $length [, string $padStr = ' ' [, string $padType = 'right' ]])
-
-Pads the string to a given length with $padStr. If length is less than
-or equal to the length of the string, no padding takes places. The default
-string used for padding is a space, and the default type (one of 'left',
-'right', 'both') is 'right'. Throws an InvalidArgumentException if
-$padType isn't one of those 3 values.
-
-```php
-s('fòôbàř')->pad(9, '-/', 'left'); // '-/-fòôbàř'
-```
-
-##### padBoth(int $length [, string $padStr = ' ' ])
-
-Returns a new string of a given length such that both sides of the string
-string are padded. Alias for pad() with a $padType of 'both'.
-
-```php
-s('foo bar')->padBoth(9, ' '); // ' foo bar '
-```
-
-##### padLeft(int $length [, string $padStr = ' ' ])
-
-Returns a new string of a given length such that the beginning of the
-string is padded. Alias for pad() with a $padType of 'left'.
-
-```php
-s('foo bar')->padLeft(9, ' '); // '  foo bar'
-```
-
-##### padRight(int $length [, string $padStr = ' ' ])
-
-Returns a new string of a given length such that the end of the string is
-padded. Alias for pad() with a $padType of 'right'.
-
-```php
-s('foo bar')->padRight(10, '_*'); // 'foo bar_*_'
-```
-
-##### prepend(string $string)
-
-Returns a new string starting with $string.
-
-```php
-s('bàř')->prepend('fòô'); // 'fòôbàř'
-```
-
-##### regexReplace(string $pattern, string $replacement [, string $options = 'msr'])
-
-Replaces all occurrences of $pattern in $str by $replacement. An alias
-for mb_ereg_replace(). Note that the 'i' option with multibyte patterns
-in mb_ereg_replace() requires PHP 5.6+ for correct results. This is due
-to a lack of support in the bundled version of Oniguruma in PHP < 5.6,
-and current versions of HHVM (3.8 and below).
-
-```php
-s('fòô ')->regexReplace('f[òô]+\s', 'bàř'); // 'bàř'
-s('fò')->regexReplace('(ò)', '\\1ô'); // 'fòô'
-```
-
-##### removeLeft(string $substring)
-
-Returns a new string with the prefix $substring removed, if present.
-
-```php
-s('fòôbàř')->removeLeft('fòô'); // 'bàř'
-```
-
-##### removeRight(string $substring)
-
-Returns a new string with the suffix $substring removed, if present.
-
-```php
-s('fòôbàř')->removeRight('bàř'); // 'fòô'
-```
-
-##### repeat(int $multiplier)
-
-Returns a repeated string given a multiplier. An alias for str_repeat.
-
-```php
-s('α')->repeat(3); // 'ααα'
-```
-
-##### replace(string $search, string $replacement)
-
-Replaces all occurrences of $search in $str by $replacement.
-
-```php
-s('fòô bàř fòô bàř')->replace('fòô ', ''); // 'bàř bàř'
-```
-
-##### reverse()
-
-Returns a reversed string. A multibyte version of strrev().
-
-```php
-s('fòôbàř')->reverse(); // 'řàbôòf'
-```
-
-##### safeTruncate(int $length [, string $substring = '' ])
-
-Truncates the string to a given length, while ensuring that it does not
-split words. If $substring is provided, and truncating occurs, the
-string is further truncated so that the substring may be appended without
-exceeding the desired length.
-
-```php
-s('What are your plans today?')->safeTruncate(22, '...');
-// 'What are your plans...'
-```
-
-##### shuffle()
-
-A multibyte str_shuffle() function. It returns a string with its characters in
-random order.
-
-```php
-s('fòôbàř')->shuffle(); // 'àôřbòf'
-```
-
-##### slugify([, string $replacement = '-' [, string $language = 'en']])
-
-Converts the string into an URL slug. This includes replacing non-ASCII
-characters with their closest ASCII equivalents, removing remaining
-non-ASCII and non-alphanumeric characters, and replacing whitespace with
-$replacement. The replacement defaults to a single dash, and the string
-is also converted to lowercase. The language of the source string can
-also be supplied for language-specific transliteration.
-
-```php
-s('Using strings like fòô bàř')->slugify(); // 'using-strings-like-foo-bar'
-```
-
-##### slice(int $start [, int $end ])
-
-Returns the substring beginning at $start, and up to, but not including
-the index specified by $end. If $end is omitted, the function extracts
-the remaining string. If $end is negative, it is computed from the end
-of the string.
-
-```php
-s('fòôbàř')->slice(3, -1); // 'bà'
-```
-
-##### split(string $pattern [, int $limit ])
-
-Splits the string with the provided regular expression, returning an
-array of Stringy objects. An optional integer $limit will truncate the
-results.
-
-```php
-s('foo,bar,baz')->split(',', 2); // ['foo', 'bar']
-```
-
-##### startsWith(string $substring [, boolean $caseSensitive = true ])
-
-Returns true if the string begins with $substring, false otherwise.
-By default, the comparison is case-sensitive, but can be made insensitive
-by setting $caseSensitive to false.
-
-```php
-s('FÒÔbàřbaz')->startsWith('fòôbàř', false); // true
-```
-
-##### startsWithAny(string[] $substrings [, boolean $caseSensitive = true ])
-
-Returns true if the string begins with any of $substrings, false
-otherwise. By default the comparison is case-sensitive, but can be made
-insensitive by setting $caseSensitive to false.
-
-```php
-s('FÒÔbàřbaz')->startsWithAny(['fòô', 'bàř'], false); // true
-```
-
-##### stripWhitespace()
-
-Strip all whitespace characters. This includes tabs and newline
-characters, as well as multibyte whitespace such as the thin space
-and ideographic space.
-
-```php
-s('   Ο     συγγραφέας  ')->stripWhitespace(); // 'Οσυγγραφέας'
-```
-
-##### substr(int $start [, int $length ])
-
-Returns the substring beginning at $start with the specified $length.
-It differs from the mb_substr() function in that providing a $length of
-null will return the rest of the string, rather than an empty string.
-
-```php
-s('fòôbàř')->substr(2, 3); // 'ôbà'
-```
-
-##### surround(string $substring)
-
-Surrounds a string with the given substring.
-
-```php
-s(' ͜ ')->surround('ʘ'); // 'ʘ ͜ ʘ'
-```
-
-##### swapCase()
-
-Returns a case swapped version of the string.
-
-```php
-s('Ντανιλ')->swapCase(); // 'νΤΑΝΙΛ'
-```
-
-##### tidy()
-
-Returns a string with smart quotes, ellipsis characters, and dashes from
-Windows-1252 (commonly used in Word documents) replaced by their ASCII equivalents.
-
-```php
-s('“I see…”')->tidy(); // '"I see..."'
-```
-
-##### titleize([, array $ignore])
-
-Returns a trimmed string with the first letter of each word capitalized.
-Also accepts an array, $ignore, allowing you to list words not to be
-capitalized.
-
-```php
-$ignore = ['at', 'by', 'for', 'in', 'of', 'on', 'out', 'to', 'the'];
-s('i like to watch television')->titleize($ignore);
-// 'I Like to Watch Television'
-```
-
-##### toAscii([, string $language = 'en' [, bool $removeUnsupported = true ]])
-
-Returns an ASCII version of the string. A set of non-ASCII characters are
-replaced with their closest ASCII counterparts, and the rest are removed
-by default. The language or locale of the source string can be supplied
-for language-specific transliteration in any of the following formats:
-en, en_GB, or en-GB. For example, passing "de" results in "äöü" mapping
-to "aeoeue" rather than "aou" as in other languages.
-
-```php
-s('fòôbàř')->toAscii(); // 'foobar'
-s('äöü')->toAscii(); // 'aou'
-s('äöü')->toAscii('de'); // 'aeoeue'
-```
-
-##### toBoolean()
-
-Returns a boolean representation of the given logical string value.
-For example, 'true', '1', 'on' and 'yes' will return true. 'false', '0',
-'off', and 'no' will return false. In all instances, case is ignored.
-For other numeric strings, their sign will determine the return value.
-In addition, blank strings consisting of only whitespace will return
-false. For all other strings, the return value is a result of a
-boolean cast.
-
-```php
-s('OFF')->toBoolean(); // false
-```
-
-##### toLowerCase()
-
-Converts all characters in the string to lowercase. An alias for PHP's
-mb_strtolower().
-
-```php
-s('FÒÔBÀŘ')->toLowerCase(); // 'fòôbàř'
-```
-
-##### toSpaces([, tabLength = 4 ])
-
-Converts each tab in the string to some number of spaces, as defined by
-$tabLength. By default, each tab is converted to 4 consecutive spaces.
-
-```php
-s(' String speech = "Hi"')->toSpaces(); // '    String speech = "Hi"'
-```
-
-##### toTabs([, tabLength = 4 ])
-
-Converts each occurrence of some consecutive number of spaces, as defined
-by $tabLength, to a tab. By default, each 4 consecutive spaces are
-converted to a tab.
-
-```php
-s('    fòô    bàř')->toTabs();
-// '   fòô bàř'
-```
-
-##### toTitleCase()
-
-Converts the first character of each word in the string to uppercase.
-
-```php
-s('fòô bàř')->toTitleCase(); // 'Fòô Bàř'
-```
-
-##### toUpperCase()
-
-Converts all characters in the string to uppercase. An alias for PHP's
-mb_strtoupper().
-
-```php
-s('fòôbàř')->toUpperCase(); // 'FÒÔBÀŘ'
-```
-
-##### trim([, string $chars])
-
-Returns a string with whitespace removed from the start and end of the
-string. Supports the removal of unicode whitespace. Accepts an optional
-string of characters to strip instead of the defaults.
-
-```php
-s('  fòôbàř  ')->trim(); // 'fòôbàř'
-```
-
-##### trimLeft([, string $chars])
-
-Returns a string with whitespace removed from the start of the string.
-Supports the removal of unicode whitespace. Accepts an optional
-string of characters to strip instead of the defaults.
-
-```php
-s('  fòôbàř  ')->trimLeft(); // 'fòôbàř  '
-```
-
-##### trimRight([, string $chars])
-
-Returns a string with whitespace removed from the end of the string.
-Supports the removal of unicode whitespace. Accepts an optional
-string of characters to strip instead of the defaults.
-
-```php
-s('  fòôbàř  ')->trimRight(); // '  fòôbàř'
-```
-
-##### truncate(int $length [, string $substring = '' ])
-
-Truncates the string to a given length. If $substring is provided, and
-truncating occurs, the string is further truncated so that the substring
-may be appended without exceeding the desired length.
-
-```php
-s('What are your plans today?')->truncate(19, '...'); // 'What are your pl...'
-```
-
-##### underscored()
-
-Returns a lowercase and trimmed string separated by underscores.
-Underscores are inserted before uppercase characters (with the exception
-of the first character of the string), and in place of spaces as well as dashes.
-
-```php
-s('TestUCase')->underscored(); // 'test_u_case'
-```
-
-##### upperCamelize()
-
-Returns an UpperCamelCase version of the supplied string. It trims
-surrounding spaces, capitalizes letters following digits, spaces, dashes
-and underscores, and removes spaces, dashes, underscores.
-
-```php
-s('Upper Camel-Case')->upperCamelize(); // 'UpperCamelCase'
-```
-
-##### upperCaseFirst()
-
-Converts the first character of the supplied string to upper case.
-
-```php
-s('σ foo')->upperCaseFirst(); // 'Σ foo'
-```
-
-## Extensions
-
-The following is a list of libraries that extend Stringy:
-
- * [SliceableStringy](https://github.com/danielstjules/SliceableStringy):
-Python-like string slices in PHP
- * [SubStringy](https://github.com/TCB13/SubStringy):
-Advanced substring methods
-
-## Tests
-
-From the project directory, tests can be ran using `phpunit`
-
-## License
-
-Released under the MIT License - see `LICENSE.txt` for details.

+ 0 - 35
vendor/danielstjules/stringy/composer.json

@@ -1,35 +0,0 @@
-{
-    "name": "danielstjules/stringy",
-    "description": "A string manipulation library with multibyte support",
-    "keywords": [
-        "multibyte", "string", "manipulation", "utility", "methods", "utf-8",
-        "helpers", "utils", "utf"
-    ],
-    "homepage": "https://github.com/danielstjules/Stringy",
-    "license": "MIT",
-    "authors": [
-        {
-            "name": "Daniel St. Jules",
-            "email": "danielst.jules@gmail.com",
-            "homepage": "http://www.danielstjules.com"
-        }
-    ],
-    "require": {
-        "php": ">=5.4.0",
-        "symfony/polyfill-mbstring": "~1.1"
-    },
-    "require-dev": {
-        "phpunit/phpunit": "~4.0"
-    },
-    "support": {
-        "issues": "https://github.com/danielstjules/Stringy/issues",
-        "source": "https://github.com/danielstjules/Stringy"
-    },
-    "autoload": {
-        "psr-4": { "Stringy\\": "src/" },
-        "files": ["src/Create.php"]
-    },
-    "autoload-dev": {
-        "classmap": [ "tests" ]
-    }
-}

+ 0 - 19
vendor/danielstjules/stringy/src/Create.php

@@ -1,19 +0,0 @@
-<?php
-
-namespace Stringy;
-
-if (!function_exists('Stringy\create')) {
-    /**
-     * Creates a Stringy object and returns it on success.
-     *
-     * @param  mixed   $str      Value to modify, after being cast to string
-     * @param  string  $encoding The character encoding
-     * @return Stringy A Stringy object
-     * @throws \InvalidArgumentException if an array or object without a
-     *         __toString method is passed as the first argument
-     */
-    function create($str, $encoding = null)
-    {
-        return new Stringy($str, $encoding);
-    }
-}

+ 0 - 161
vendor/danielstjules/stringy/src/StaticStringy.php

@@ -1,161 +0,0 @@
-<?php
-
-namespace Stringy;
-
-use BadMethodCallException;
-use ReflectionClass;
-use ReflectionMethod;
-
-/**
- * Class StaticStringy
- *
- * @method static string append(string $str, string $stringAppend, string $encoding = null)
- * @method static string at(string $str, int $index, string $encoding = null)
- * @method static string between(string $str, string $start, string $end, int $offset = 0, string $encoding = null)
- * @method static string camelize(string $str, string $encoding = null)
- * @method static string chars(string $str, string $encoding = null)
- * @method static string collapseWhitespace(string $str, string $encoding = null)
- * @method static bool contains(string $str, string $needle, bool $caseSensitive = true, string $encoding = null)
- * @method static bool containsAll(string $str, string[] $needle, bool $caseSensitive = true, string $encoding = null)
- * @method static bool containsAny(string $str, string[] $needle, bool $caseSensitive = true, string $encoding = null)
- * @method static int count(string $str, string $encoding = null)
- * @method static int countSubstr(string $str, string $substring, bool $caseSensitive = true, string $encoding = null)
- * @method static string dasherize(string $str, string $encoding = null)
- * @method static string delimit(string $str, string $delimiter, string $encoding = null)
- * @method static bool endsWith(string $str, string $substring, bool $caseSensitive = true, string $encoding = null)
- * @method static bool endsWithAny(string $str, string[] $substrings, bool $caseSensitive = true, string $encoding = null)
- * @method static string ensureLeft(string $str, string $substring, string $encoding = null)
- * @method static string ensureRight(string $str, string $substring, string $encoding = null)
- * @method static string first(string $str, int $n, string $encoding = null)
- * @method static bool hasLowerCase(string $str, string $encoding = null)
- * @method static bool hasUpperCase(string $str, string $encoding = null)
- * @method static string htmlDecode(string $str, int $flags = ENT_COMPAT, string $encoding = null)
- * @method static string htmlEncode(string $str, int $flags = ENT_COMPAT, string $encoding = null)
- * @method static string humanize(string $str, string $encoding = null)
- * @method static int indexOf(string $str, string $needle, int $offset = 0, string $encoding = null)
- * @method static int indexOfLast(string $str, string $needle, int $offset = 0, string $encoding = null)
- * @method static string insert(string $str, string $substring, int $index = 0, string $encoding = null)
- * @method static bool isAlpha(string $str, string $encoding = null)
- * @method static bool isAlphanumeric(string $str, string $encoding = null)
- * @method static bool isBase64(string $str, string $encoding = null)
- * @method static bool isBlank(string $str, string $encoding = null)
- * @method static bool isHexadecimal(string $str, string $encoding = null)
- * @method static bool isJson(string $str, string $encoding = null)
- * @method static bool isLowerCase(string $str, string $encoding = null)
- * @method static bool isSerialized(string $str, string $encoding = null)
- * @method static bool isUpperCase(string $str, string $encoding = null)
- * @method static string last(string $str, string $encoding = null)
- * @method static int length(string $str, string $encoding = null)
- * @method static string[] lines(string $str, string $encoding = null)
- * @method static string longestCommonPrefix(string $str, string $otherStr, string $encoding = null)
- * @method static string longestCommonSuffix(string $str, string $otherStr, string $encoding = null)
- * @method static string longestCommonSubstring(string $str, string $otherStr, string $encoding = null)
- * @method static string lowerCaseFirst(string $str, string $encoding = null)
- * @method static string pad(string $str, int $length, string $padStr = ' ', string $padType = 'right', string $encoding = null)
- * @method static string padBoth(string $str, int $length, string $padStr = ' ', string $encoding = null)
- * @method static string padLeft(string $str, int $length, string $padStr = ' ', string $encoding = null)
- * @method static string padRight(string $str, int $length, string $padStr = ' ', string $encoding = null)
- * @method static string prepend(string $str, string $string, string $encoding = null)
- * @method static string regexReplace(string $str, string $pattern, string $replacement, string $options = 'msr', string $encoding = null)
- * @method static string removeLeft(string $str, string $substring, string $encoding = null)
- * @method static string removeRight(string $str, string $substring, string $encoding = null)
- * @method static string repeat(string $str, int $multiplier, string $encoding = null)
- * @method static string replace(string $str, string $search, string $replacement, string $encoding = null)
- * @method static string reverse(string $str, string $encoding = null)
- * @method static string safeTruncate(string $str, int $length, string $substring = '', string $encoding = null)
- * @method static string shuffle(string $str, string $encoding = null)
- * @method static string slugify(string $str, string $replacement = '-', string $encoding = null)
- * @method static string slice(string $str, int $start, int $end = null, string $encoding = null)
- * @method static string split(string $str, string $pattern, int $limit = null, string $encoding = null)
- * @method static bool startsWith(string $str, string $substring, bool $caseSensitive = true, string $encoding = null)
- * @method static bool startsWithAny(string $str, string[] $substrings, bool $caseSensitive = true, string $encoding = null)
- * @method static string stripWhitespace(string $str, string $encoding = null)
- * @method static string substr(string $str, int $start, int $length = null, string $encoding = null)
- * @method static string surround(string $str, string $substring, string $encoding = null)
- * @method static string swapCase(string $str, string $encoding = null)
- * @method static string tidy(string $str, string $encoding = null)
- * @method static string titleize(string $str, string $encoding = null)
- * @method static string toAscii(string $str, string $language = 'en', bool $removeUnsupported = true, string $encoding = null)
- * @method static bool toBoolean(string $str, string $encoding = null)
- * @method static string toLowerCase(string $str, string $encoding = null)
- * @method static string toSpaces(string $str, int $tabLength = 4, string $encoding = null)
- * @method static string toTabs(string $str, int $tabLength = 4, string $encoding = null)
- * @method static string toTitleCase(string $str, string $encoding = null)
- * @method static string toUpperCase(string $str, string $encoding = null)
- * @method static string trim(string $str, string $chars = null, string $encoding = null)
- * @method static string trimLeft(string $str, string $chars = null, string $encoding = null)
- * @method static string trimRight(string $str, string $chars = null, string $encoding = null)
- * @method static string truncate(string $str, int $length, string $substring = '', string $encoding = null)
- * @method static string underscored(string $str, string $encoding = null)
- * @method static string upperCamelize(string $str, string $encoding = null)
- * @method static string upperCaseFirst(string $str, string $encoding = null)
- */
-class StaticStringy
-{
-    /**
-     * A mapping of method names to the numbers of arguments it accepts. Each
-     * should be two more than the equivalent Stringy method. Necessary as
-     * static methods place the optional $encoding as the last parameter.
-     *
-     * @var string[]
-     */
-    protected static $methodArgs = null;
-
-    /**
-     * Creates an instance of Stringy and invokes the given method with the
-     * rest of the passed arguments. The optional encoding is expected to be
-     * the last argument. For example, the following:
-     * StaticStringy::slice('fòôbàř', 0, 3, 'UTF-8'); translates to
-     * Stringy::create('fòôbàř', 'UTF-8')->slice(0, 3);
-     * The result is not cast, so the return value may be of type Stringy,
-     * integer, boolean, etc.
-     *
-     * @param string  $name
-     * @param mixed[] $arguments
-     *
-     * @return Stringy
-     *
-     * @throws \BadMethodCallException
-     */
-    public static function __callStatic($name, $arguments)
-    {
-        if (!static::$methodArgs) {
-            $stringyClass = new ReflectionClass('Stringy\Stringy');
-            $methods = $stringyClass->getMethods(ReflectionMethod::IS_PUBLIC);
-
-            foreach ($methods as $method) {
-                $params = $method->getNumberOfParameters() + 2;
-                static::$methodArgs[$method->name] = $params;
-            }
-        }
-
-        if (!isset(static::$methodArgs[$name])) {
-            throw new BadMethodCallException($name . ' is not a valid method');
-        }
-
-        $numArgs = count($arguments);
-        $str = ($numArgs) ? $arguments[0] : '';
-
-        if ($numArgs === static::$methodArgs[$name]) {
-            $args = array_slice($arguments, 1, -1);
-            $encoding = $arguments[$numArgs - 1];
-        } else {
-            $args = array_slice($arguments, 1);
-            $encoding = null;
-        }
-
-        $stringy = Stringy::create($str, $encoding);
-
-        $result = call_user_func_array([$stringy, $name], $args);
-
-        $cast = function($val) {
-            if (is_object($val) && $val instanceof Stringy) {
-                return (string) $val;
-            } else {
-                return $val;
-            }
-        };
-
-        return is_array($result) ? array_map($cast, $result) : $cast($result);
-    }
-}

+ 0 - 1986
vendor/danielstjules/stringy/src/Stringy.php

@@ -1,1986 +0,0 @@
-<?php
-
-namespace Stringy;
-
-use ArrayAccess;
-use ArrayIterator;
-use Countable;
-use Exception;
-use InvalidArgumentException;
-use IteratorAggregate;
-use OutOfBoundsException;
-
-class Stringy implements Countable, IteratorAggregate, ArrayAccess
-{
-    /**
-     * An instance's string.
-     *
-     * @var string
-     */
-    protected $str;
-
-    /**
-     * The string's encoding, which should be one of the mbstring module's
-     * supported encodings.
-     *
-     * @var string
-     */
-    protected $encoding;
-
-    /**
-     * Initializes a Stringy object and assigns both str and encoding properties
-     * the supplied values. $str is cast to a string prior to assignment, and if
-     * $encoding is not specified, it defaults to mb_internal_encoding(). Throws
-     * an InvalidArgumentException if the first argument is an array or object
-     * without a __toString method.
-     *
-     * @param  mixed  $str      Value to modify, after being cast to string
-     * @param  string $encoding The character encoding
-     * @throws \InvalidArgumentException if an array or object without a
-     *         __toString method is passed as the first argument
-     */
-    public function __construct($str = '', $encoding = null)
-    {
-        if (is_array($str)) {
-            throw new InvalidArgumentException(
-                'Passed value cannot be an array'
-            );
-        } elseif (is_object($str) && !method_exists($str, '__toString')) {
-            throw new InvalidArgumentException(
-                'Passed object must have a __toString method'
-            );
-        }
-
-        $this->str = (string) $str;
-        $this->encoding = $encoding ?: \mb_internal_encoding();
-    }
-
-    /**
-     * Creates a Stringy object and assigns both str and encoding properties
-     * the supplied values. $str is cast to a string prior to assignment, and if
-     * $encoding is not specified, it defaults to mb_internal_encoding(). It
-     * then returns the initialized object. Throws an InvalidArgumentException
-     * if the first argument is an array or object without a __toString method.
-     *
-     * @param  mixed  $str      Value to modify, after being cast to string
-     * @param  string $encoding The character encoding
-     * @return static A Stringy object
-     * @throws \InvalidArgumentException if an array or object without a
-     *         __toString method is passed as the first argument
-     */
-    public static function create($str = '', $encoding = null)
-    {
-        return new static($str, $encoding);
-    }
-
-    /**
-     * Returns the value in $str.
-     *
-     * @return string The current value of the $str property
-     */
-    public function __toString()
-    {
-        return $this->str;
-    }
-
-    /**
-     * Returns a new string with $string appended.
-     *
-     * @param  string $string The string to append
-     * @return static Object with appended $string
-     */
-    public function append($string)
-    {
-        return static::create($this->str . $string, $this->encoding);
-    }
-
-    /**
-     * Returns the character at $index, with indexes starting at 0.
-     *
-     * @param  int    $index Position of the character
-     * @return static The character at $index
-     */
-    public function at($index)
-    {
-        return $this->substr($index, 1);
-    }
-
-    /**
-     * Returns the substring between $start and $end, if found, or an empty
-     * string. An optional offset may be supplied from which to begin the
-     * search for the start string.
-     *
-     * @param  string $start  Delimiter marking the start of the substring
-     * @param  string $end    Delimiter marking the end of the substring
-     * @param  int    $offset Index from which to begin the search
-     * @return static Object whose $str is a substring between $start and $end
-     */
-    public function between($start, $end, $offset = 0)
-    {
-        $startIndex = $this->indexOf($start, $offset);
-        if ($startIndex === false) {
-            return static::create('', $this->encoding);
-        }
-
-        $substrIndex = $startIndex + \mb_strlen($start, $this->encoding);
-        $endIndex = $this->indexOf($end, $substrIndex);
-        if ($endIndex === false) {
-            return static::create('', $this->encoding);
-        }
-
-        return $this->substr($substrIndex, $endIndex - $substrIndex);
-    }
-
-    /**
-     * Returns a camelCase version of the string. Trims surrounding spaces,
-     * capitalizes letters following digits, spaces, dashes and underscores,
-     * and removes spaces, dashes, as well as underscores.
-     *
-     * @return static Object with $str in camelCase
-     */
-    public function camelize()
-    {
-        $encoding = $this->encoding;
-        $stringy = $this->trim()->lowerCaseFirst();
-        $stringy->str = preg_replace('/^[-_]+/', '', $stringy->str);
-
-        $stringy->str = preg_replace_callback(
-            '/[-_\s]+(.)?/u',
-            function ($match) use ($encoding) {
-                if (isset($match[1])) {
-                    return \mb_strtoupper($match[1], $encoding);
-                }
-
-                return '';
-            },
-            $stringy->str
-        );
-
-        $stringy->str = preg_replace_callback(
-            '/[\d]+(.)?/u',
-            function ($match) use ($encoding) {
-                return \mb_strtoupper($match[0], $encoding);
-            },
-            $stringy->str
-        );
-
-        return $stringy;
-    }
-
-    /**
-     * Returns an array consisting of the characters in the string.
-     *
-     * @return array An array of string chars
-     */
-    public function chars()
-    {
-        $chars = [];
-        for ($i = 0, $l = $this->length(); $i < $l; $i++) {
-            $chars[] = $this->at($i)->str;
-        }
-
-        return $chars;
-    }
-
-    /**
-     * Trims the string and replaces consecutive whitespace characters with a
-     * single space. This includes tabs and newline characters, as well as
-     * multibyte whitespace such as the thin space and ideographic space.
-     *
-     * @return static Object with a trimmed $str and condensed whitespace
-     */
-    public function collapseWhitespace()
-    {
-        return $this->regexReplace('[[:space:]]+', ' ')->trim();
-    }
-
-    /**
-     * Returns true if the string contains $needle, false otherwise. By default
-     * the comparison is case-sensitive, but can be made insensitive by setting
-     * $caseSensitive to false.
-     *
-     * @param  string $needle        Substring to look for
-     * @param  bool   $caseSensitive Whether or not to enforce case-sensitivity
-     * @return bool   Whether or not $str contains $needle
-     */
-    public function contains($needle, $caseSensitive = true)
-    {
-        $encoding = $this->encoding;
-
-        if ($caseSensitive) {
-            return (\mb_strpos($this->str, $needle, 0, $encoding) !== false);
-        }
-
-        return (\mb_stripos($this->str, $needle, 0, $encoding) !== false);
-    }
-
-    /**
-     * Returns true if the string contains all $needles, false otherwise. By
-     * default the comparison is case-sensitive, but can be made insensitive by
-     * setting $caseSensitive to false.
-     *
-     * @param  string[] $needles       Substrings to look for
-     * @param  bool     $caseSensitive Whether or not to enforce case-sensitivity
-     * @return bool     Whether or not $str contains $needle
-     */
-    public function containsAll($needles, $caseSensitive = true)
-    {
-        if (empty($needles)) {
-            return false;
-        }
-
-        foreach ($needles as $needle) {
-            if (!$this->contains($needle, $caseSensitive)) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Returns true if the string contains any $needles, false otherwise. By
-     * default the comparison is case-sensitive, but can be made insensitive by
-     * setting $caseSensitive to false.
-     *
-     * @param  string[] $needles       Substrings to look for
-     * @param  bool     $caseSensitive Whether or not to enforce case-sensitivity
-     * @return bool     Whether or not $str contains $needle
-     */
-    public function containsAny($needles, $caseSensitive = true)
-    {
-        if (empty($needles)) {
-            return false;
-        }
-
-        foreach ($needles as $needle) {
-            if ($this->contains($needle, $caseSensitive)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Returns the length of the string, implementing the countable interface.
-     *
-     * @return int The number of characters in the string, given the encoding
-     */
-    public function count()
-    {
-        return $this->length();
-    }
-
-    /**
-     * Returns the number of occurrences of $substring in the given string.
-     * By default, the comparison is case-sensitive, but can be made insensitive
-     * by setting $caseSensitive to false.
-     *
-     * @param  string $substring     The substring to search for
-     * @param  bool   $caseSensitive Whether or not to enforce case-sensitivity
-     * @return int    The number of $substring occurrences
-     */
-    public function countSubstr($substring, $caseSensitive = true)
-    {
-        if ($caseSensitive) {
-            return \mb_substr_count($this->str, $substring, $this->encoding);
-        }
-
-        $str = \mb_strtoupper($this->str, $this->encoding);
-        $substring = \mb_strtoupper($substring, $this->encoding);
-
-        return \mb_substr_count($str, $substring, $this->encoding);
-    }
-
-    /**
-     * Returns a lowercase and trimmed string separated by dashes. Dashes are
-     * inserted before uppercase characters (with the exception of the first
-     * character of the string), and in place of spaces as well as underscores.
-     *
-     * @return static Object with a dasherized $str
-     */
-    public function dasherize()
-    {
-        return $this->delimit('-');
-    }
-
-    /**
-     * Returns a lowercase and trimmed string separated by the given delimiter.
-     * Delimiters are inserted before uppercase characters (with the exception
-     * of the first character of the string), and in place of spaces, dashes,
-     * and underscores. Alpha delimiters are not converted to lowercase.
-     *
-     * @param  string $delimiter Sequence used to separate parts of the string
-     * @return static Object with a delimited $str
-     */
-    public function delimit($delimiter)
-    {
-        $regexEncoding = $this->regexEncoding();
-        $this->regexEncoding($this->encoding);
-
-        $str = $this->eregReplace('\B([A-Z])', '-\1', $this->trim());
-        $str = \mb_strtolower($str, $this->encoding);
-        $str = $this->eregReplace('[-_\s]+', $delimiter, $str);
-
-        $this->regexEncoding($regexEncoding);
-
-        return static::create($str, $this->encoding);
-    }
-
-    /**
-     * Returns true if the string ends with $substring, false otherwise. By
-     * default, the comparison is case-sensitive, but can be made insensitive
-     * by setting $caseSensitive to false.
-     *
-     * @param  string $substring     The substring to look for
-     * @param  bool   $caseSensitive Whether or not to enforce case-sensitivity
-     * @return bool   Whether or not $str ends with $substring
-     */
-    public function endsWith($substring, $caseSensitive = true)
-    {
-        $substringLength = \mb_strlen($substring, $this->encoding);
-        $strLength = $this->length();
-
-        $endOfStr = \mb_substr($this->str, $strLength - $substringLength,
-            $substringLength, $this->encoding);
-
-        if (!$caseSensitive) {
-            $substring = \mb_strtolower($substring, $this->encoding);
-            $endOfStr = \mb_strtolower($endOfStr, $this->encoding);
-        }
-
-        return (string) $substring === $endOfStr;
-    }
-
-    /**
-     * Returns true if the string ends with any of $substrings, false otherwise.
-     * By default, the comparison is case-sensitive, but can be made insensitive
-     * by setting $caseSensitive to false.
-     *
-     * @param  string[] $substrings    Substrings to look for
-     * @param  bool     $caseSensitive Whether or not to enforce
-     *                                 case-sensitivity
-     * @return bool     Whether or not $str ends with $substring
-     */
-    public function endsWithAny($substrings, $caseSensitive = true)
-    {
-        if (empty($substrings)) {
-            return false;
-        }
-
-        foreach ($substrings as $substring) {
-            if ($this->endsWith($substring, $caseSensitive)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Ensures that the string begins with $substring. If it doesn't, it's
-     * prepended.
-     *
-     * @param  string $substring The substring to add if not present
-     * @return static Object with its $str prefixed by the $substring
-     */
-    public function ensureLeft($substring)
-    {
-        $stringy = static::create($this->str, $this->encoding);
-
-        if (!$stringy->startsWith($substring)) {
-            $stringy->str = $substring . $stringy->str;
-        }
-
-        return $stringy;
-    }
-
-    /**
-     * Ensures that the string ends with $substring. If it doesn't, it's
-     * appended.
-     *
-     * @param  string $substring The substring to add if not present
-     * @return static Object with its $str suffixed by the $substring
-     */
-    public function ensureRight($substring)
-    {
-        $stringy = static::create($this->str, $this->encoding);
-
-        if (!$stringy->endsWith($substring)) {
-            $stringy->str .= $substring;
-        }
-
-        return $stringy;
-    }
-
-    /**
-     * Returns the first $n characters of the string.
-     *
-     * @param  int    $n Number of characters to retrieve from the start
-     * @return static Object with its $str being the first $n chars
-     */
-    public function first($n)
-    {
-        $stringy = static::create($this->str, $this->encoding);
-
-        if ($n < 0) {
-            $stringy->str = '';
-            return $stringy;
-        }
-
-        return $stringy->substr(0, $n);
-    }
-
-    /**
-     * Returns the encoding used by the Stringy object.
-     *
-     * @return string The current value of the $encoding property
-     */
-    public function getEncoding()
-    {
-        return $this->encoding;
-    }
-
-    /**
-     * Returns a new ArrayIterator, thus implementing the IteratorAggregate
-     * interface. The ArrayIterator's constructor is passed an array of chars
-     * in the multibyte string. This enables the use of foreach with instances
-     * of Stringy\Stringy.
-     *
-     * @return \ArrayIterator An iterator for the characters in the string
-     */
-    public function getIterator()
-    {
-        return new ArrayIterator($this->chars());
-    }
-
-    /**
-     * Returns true if the string contains a lower case char, false
-     * otherwise.
-     *
-     * @return bool Whether or not the string contains a lower case character.
-     */
-    public function hasLowerCase()
-    {
-        return $this->matchesPattern('.*[[:lower:]]');
-    }
-
-    /**
-     * Returns true if the string contains an upper case char, false
-     * otherwise.
-     *
-     * @return bool Whether or not the string contains an upper case character.
-     */
-    public function hasUpperCase()
-    {
-        return $this->matchesPattern('.*[[:upper:]]');
-    }
-
-
-    /**
-     * Convert all HTML entities to their applicable characters. An alias of
-     * html_entity_decode. For a list of flags, refer to
-     * http://php.net/manual/en/function.html-entity-decode.php
-     *
-     * @param  int|null $flags Optional flags
-     * @return static   Object with the resulting $str after being html decoded.
-     */
-    public function htmlDecode($flags = ENT_COMPAT)
-    {
-        $str = html_entity_decode($this->str, $flags, $this->encoding);
-
-        return static::create($str, $this->encoding);
-    }
-
-    /**
-     * Convert all applicable characters to HTML entities. An alias of
-     * htmlentities. Refer to http://php.net/manual/en/function.htmlentities.php
-     * for a list of flags.
-     *
-     * @param  int|null $flags Optional flags
-     * @return static   Object with the resulting $str after being html encoded.
-     */
-    public function htmlEncode($flags = ENT_COMPAT)
-    {
-        $str = htmlentities($this->str, $flags, $this->encoding);
-
-        return static::create($str, $this->encoding);
-    }
-
-    /**
-     * Capitalizes the first word of the string, replaces underscores with
-     * spaces, and strips '_id'.
-     *
-     * @return static Object with a humanized $str
-     */
-    public function humanize()
-    {
-        $str = str_replace(['_id', '_'], ['', ' '], $this->str);
-
-        return static::create($str, $this->encoding)->trim()->upperCaseFirst();
-    }
-
-    /**
-     * Returns the index of the first occurrence of $needle in the string,
-     * and false if not found. Accepts an optional offset from which to begin
-     * the search.
-     *
-     * @param  string   $needle Substring to look for
-     * @param  int      $offset Offset from which to search
-     * @return int|bool The occurrence's index if found, otherwise false
-     */
-    public function indexOf($needle, $offset = 0)
-    {
-        return \mb_strpos($this->str, (string) $needle,
-            (int) $offset, $this->encoding);
-    }
-
-    /**
-     * Returns the index of the last occurrence of $needle in the string,
-     * and false if not found. Accepts an optional offset from which to begin
-     * the search. Offsets may be negative to count from the last character
-     * in the string.
-     *
-     * @param  string   $needle Substring to look for
-     * @param  int      $offset Offset from which to search
-     * @return int|bool The last occurrence's index if found, otherwise false
-     */
-    public function indexOfLast($needle, $offset = 0)
-    {
-        return \mb_strrpos($this->str, (string) $needle,
-            (int) $offset, $this->encoding);
-    }
-
-    /**
-     * Inserts $substring into the string at the $index provided.
-     *
-     * @param  string $substring String to be inserted
-     * @param  int    $index     The index at which to insert the substring
-     * @return static Object with the resulting $str after the insertion
-     */
-    public function insert($substring, $index)
-    {
-        $stringy = static::create($this->str, $this->encoding);
-        if ($index > $stringy->length()) {
-            return $stringy;
-        }
-
-        $start = \mb_substr($stringy->str, 0, $index, $stringy->encoding);
-        $end = \mb_substr($stringy->str, $index, $stringy->length(),
-            $stringy->encoding);
-
-        $stringy->str = $start . $substring . $end;
-
-        return $stringy;
-    }
-
-    /**
-     * Returns true if the string contains only alphabetic chars, false
-     * otherwise.
-     *
-     * @return bool Whether or not $str contains only alphabetic chars
-     */
-    public function isAlpha()
-    {
-        return $this->matchesPattern('^[[:alpha:]]*$');
-    }
-
-    /**
-     * Returns true if the string contains only alphabetic and numeric chars,
-     * false otherwise.
-     *
-     * @return bool Whether or not $str contains only alphanumeric chars
-     */
-    public function isAlphanumeric()
-    {
-        return $this->matchesPattern('^[[:alnum:]]*$');
-    }
-
-    /**
-     * Returns true if the string contains only whitespace chars, false
-     * otherwise.
-     *
-     * @return bool Whether or not $str contains only whitespace characters
-     */
-    public function isBlank()
-    {
-        return $this->matchesPattern('^[[:space:]]*$');
-    }
-
-    /**
-     * Returns true if the string contains only hexadecimal chars, false
-     * otherwise.
-     *
-     * @return bool Whether or not $str contains only hexadecimal chars
-     */
-    public function isHexadecimal()
-    {
-        return $this->matchesPattern('^[[:xdigit:]]*$');
-    }
-
-    /**
-     * Returns true if the string is JSON, false otherwise. Unlike json_decode
-     * in PHP 5.x, this method is consistent with PHP 7 and other JSON parsers,
-     * in that an empty string is not considered valid JSON.
-     *
-     * @return bool Whether or not $str is JSON
-     */
-    public function isJson()
-    {
-        if (!$this->length()) {
-            return false;
-        }
-
-        json_decode($this->str);
-
-        return (json_last_error() === JSON_ERROR_NONE);
-    }
-
-    /**
-     * Returns true if the string contains only lower case chars, false
-     * otherwise.
-     *
-     * @return bool Whether or not $str contains only lower case characters
-     */
-    public function isLowerCase()
-    {
-        return $this->matchesPattern('^[[:lower:]]*$');
-    }
-
-    /**
-     * Returns true if the string is serialized, false otherwise.
-     *
-     * @return bool Whether or not $str is serialized
-     */
-    public function isSerialized()
-    {
-        return $this->str === 'b:0;' || @unserialize($this->str) !== false;
-    }
-
-
-    /**
-     * Returns true if the string is base64 encoded, false otherwise.
-     *
-     * @return bool Whether or not $str is base64 encoded
-     */
-    public function isBase64()
-    {
-        return (base64_encode(base64_decode($this->str, true)) === $this->str);
-    }
-
-    /**
-     * Returns true if the string contains only lower case chars, false
-     * otherwise.
-     *
-     * @return bool Whether or not $str contains only lower case characters
-     */
-    public function isUpperCase()
-    {
-        return $this->matchesPattern('^[[:upper:]]*$');
-    }
-
-    /**
-     * Returns the last $n characters of the string.
-     *
-     * @param  int    $n Number of characters to retrieve from the end
-     * @return static Object with its $str being the last $n chars
-     */
-    public function last($n)
-    {
-        $stringy = static::create($this->str, $this->encoding);
-
-        if ($n <= 0) {
-            $stringy->str = '';
-            return $stringy;
-        }
-
-        return $stringy->substr(-$n);
-    }
-
-    /**
-     * Returns the length of the string. An alias for PHP's mb_strlen() function.
-     *
-     * @return int The number of characters in $str given the encoding
-     */
-    public function length()
-    {
-        return \mb_strlen($this->str, $this->encoding);
-    }
-
-    /**
-     * Splits on newlines and carriage returns, returning an array of Stringy
-     * objects corresponding to the lines in the string.
-     *
-     * @return static[] An array of Stringy objects
-     */
-    public function lines()
-    {
-        $array = $this->split('[\r\n]{1,2}', $this->str);
-        for ($i = 0; $i < count($array); $i++) {
-            $array[$i] = static::create($array[$i], $this->encoding);
-        }
-
-        return $array;
-    }
-
-    /**
-     * Returns the longest common prefix between the string and $otherStr.
-     *
-     * @param  string $otherStr Second string for comparison
-     * @return static Object with its $str being the longest common prefix
-     */
-    public function longestCommonPrefix($otherStr)
-    {
-        $encoding = $this->encoding;
-        $maxLength = min($this->length(), \mb_strlen($otherStr, $encoding));
-
-        $longestCommonPrefix = '';
-        for ($i = 0; $i < $maxLength; $i++) {
-            $char = \mb_substr($this->str, $i, 1, $encoding);
-
-            if ($char == \mb_substr($otherStr, $i, 1, $encoding)) {
-                $longestCommonPrefix .= $char;
-            } else {
-                break;
-            }
-        }
-
-        return static::create($longestCommonPrefix, $encoding);
-    }
-
-    /**
-     * Returns the longest common suffix between the string and $otherStr.
-     *
-     * @param  string $otherStr Second string for comparison
-     * @return static Object with its $str being the longest common suffix
-     */
-    public function longestCommonSuffix($otherStr)
-    {
-        $encoding = $this->encoding;
-        $maxLength = min($this->length(), \mb_strlen($otherStr, $encoding));
-
-        $longestCommonSuffix = '';
-        for ($i = 1; $i <= $maxLength; $i++) {
-            $char = \mb_substr($this->str, -$i, 1, $encoding);
-
-            if ($char == \mb_substr($otherStr, -$i, 1, $encoding)) {
-                $longestCommonSuffix = $char . $longestCommonSuffix;
-            } else {
-                break;
-            }
-        }
-
-        return static::create($longestCommonSuffix, $encoding);
-    }
-
-    /**
-     * Returns the longest common substring between the string and $otherStr.
-     * In the case of ties, it returns that which occurs first.
-     *
-     * @param  string $otherStr Second string for comparison
-     * @return static Object with its $str being the longest common substring
-     */
-    public function longestCommonSubstring($otherStr)
-    {
-        // Uses dynamic programming to solve
-        // http://en.wikipedia.org/wiki/Longest_common_substring_problem
-        $encoding = $this->encoding;
-        $stringy = static::create($this->str, $encoding);
-        $strLength = $stringy->length();
-        $otherLength = \mb_strlen($otherStr, $encoding);
-
-        // Return if either string is empty
-        if ($strLength == 0 || $otherLength == 0) {
-            $stringy->str = '';
-            return $stringy;
-        }
-
-        $len = 0;
-        $end = 0;
-        $table = array_fill(0, $strLength + 1,
-            array_fill(0, $otherLength + 1, 0));
-
-        for ($i = 1; $i <= $strLength; $i++) {
-            for ($j = 1; $j <= $otherLength; $j++) {
-                $strChar = \mb_substr($stringy->str, $i - 1, 1, $encoding);
-                $otherChar = \mb_substr($otherStr, $j - 1, 1, $encoding);
-
-                if ($strChar == $otherChar) {
-                    $table[$i][$j] = $table[$i - 1][$j - 1] + 1;
-                    if ($table[$i][$j] > $len) {
-                        $len = $table[$i][$j];
-                        $end = $i;
-                    }
-                } else {
-                    $table[$i][$j] = 0;
-                }
-            }
-        }
-
-        $stringy->str = \mb_substr($stringy->str, $end - $len, $len, $encoding);
-
-        return $stringy;
-    }
-
-    /**
-     * Converts the first character of the string to lower case.
-     *
-     * @return static Object with the first character of $str being lower case
-     */
-    public function lowerCaseFirst()
-    {
-        $first = \mb_substr($this->str, 0, 1, $this->encoding);
-        $rest = \mb_substr($this->str, 1, $this->length() - 1,
-            $this->encoding);
-
-        $str = \mb_strtolower($first, $this->encoding) . $rest;
-
-        return static::create($str, $this->encoding);
-    }
-
-    /**
-     * Returns whether or not a character exists at an index. Offsets may be
-     * negative to count from the last character in the string. Implements
-     * part of the ArrayAccess interface.
-     *
-     * @param  mixed   $offset The index to check
-     * @return boolean Whether or not the index exists
-     */
-    public function offsetExists($offset)
-    {
-        $length = $this->length();
-        $offset = (int) $offset;
-
-        if ($offset >= 0) {
-            return ($length > $offset);
-        }
-
-        return ($length >= abs($offset));
-    }
-
-    /**
-     * Returns the character at the given index. Offsets may be negative to
-     * count from the last character in the string. Implements part of the
-     * ArrayAccess interface, and throws an OutOfBoundsException if the index
-     * does not exist.
-     *
-     * @param  mixed $offset         The index from which to retrieve the char
-     * @return mixed                 The character at the specified index
-     * @throws \OutOfBoundsException If the positive or negative offset does
-     *                               not exist
-     */
-    public function offsetGet($offset)
-    {
-        $offset = (int) $offset;
-        $length = $this->length();
-
-        if (($offset >= 0 && $length <= $offset) || $length < abs($offset)) {
-            throw new OutOfBoundsException('No character exists at the index');
-        }
-
-        return \mb_substr($this->str, $offset, 1, $this->encoding);
-    }
-
-    /**
-     * Implements part of the ArrayAccess interface, but throws an exception
-     * when called. This maintains the immutability of Stringy objects.
-     *
-     * @param  mixed      $offset The index of the character
-     * @param  mixed      $value  Value to set
-     * @throws \Exception When called
-     */
-    public function offsetSet($offset, $value)
-    {
-        // Stringy is immutable, cannot directly set char
-        throw new Exception('Stringy object is immutable, cannot modify char');
-    }
-
-    /**
-     * Implements part of the ArrayAccess interface, but throws an exception
-     * when called. This maintains the immutability of Stringy objects.
-     *
-     * @param  mixed      $offset The index of the character
-     * @throws \Exception When called
-     */
-    public function offsetUnset($offset)
-    {
-        // Don't allow directly modifying the string
-        throw new Exception('Stringy object is immutable, cannot unset char');
-    }
-
-    /**
-     * Pads the string to a given length with $padStr. If length is less than
-     * or equal to the length of the string, no padding takes places. The
-     * default string used for padding is a space, and the default type (one of
-     * 'left', 'right', 'both') is 'right'. Throws an InvalidArgumentException
-     * if $padType isn't one of those 3 values.
-     *
-     * @param  int    $length  Desired string length after padding
-     * @param  string $padStr  String used to pad, defaults to space
-     * @param  string $padType One of 'left', 'right', 'both'
-     * @return static Object with a padded $str
-     * @throws /InvalidArgumentException If $padType isn't one of 'right',
-     *         'left' or 'both'
-     */
-    public function pad($length, $padStr = ' ', $padType = 'right')
-    {
-        if (!in_array($padType, ['left', 'right', 'both'])) {
-            throw new InvalidArgumentException('Pad expects $padType ' .
-                "to be one of 'left', 'right' or 'both'");
-        }
-
-        switch ($padType) {
-            case 'left':
-                return $this->padLeft($length, $padStr);
-            case 'right':
-                return $this->padRight($length, $padStr);
-            default:
-                return $this->padBoth($length, $padStr);
-        }
-    }
-
-    /**
-     * Returns a new string of a given length such that both sides of the
-     * string are padded. Alias for pad() with a $padType of 'both'.
-     *
-     * @param  int    $length Desired string length after padding
-     * @param  string $padStr String used to pad, defaults to space
-     * @return static String with padding applied
-     */
-    public function padBoth($length, $padStr = ' ')
-    {
-        $padding = $length - $this->length();
-
-        return $this->applyPadding(floor($padding / 2), ceil($padding / 2),
-            $padStr);
-    }
-
-    /**
-     * Returns a new string of a given length such that the beginning of the
-     * string is padded. Alias for pad() with a $padType of 'left'.
-     *
-     * @param  int    $length Desired string length after padding
-     * @param  string $padStr String used to pad, defaults to space
-     * @return static String with left padding
-     */
-    public function padLeft($length, $padStr = ' ')
-    {
-        return $this->applyPadding($length - $this->length(), 0, $padStr);
-    }
-
-    /**
-     * Returns a new string of a given length such that the end of the string
-     * is padded. Alias for pad() with a $padType of 'right'.
-     *
-     * @param  int    $length Desired string length after padding
-     * @param  string $padStr String used to pad, defaults to space
-     * @return static String with right padding
-     */
-    public function padRight($length, $padStr = ' ')
-    {
-        return $this->applyPadding(0, $length - $this->length(), $padStr);
-    }
-
-    /**
-     * Returns a new string starting with $string.
-     *
-     * @param  string $string The string to append
-     * @return static Object with appended $string
-     */
-    public function prepend($string)
-    {
-        return static::create($string . $this->str, $this->encoding);
-    }
-
-    /**
-     * Replaces all occurrences of $pattern in $str by $replacement. An alias
-     * for mb_ereg_replace(). Note that the 'i' option with multibyte patterns
-     * in mb_ereg_replace() requires PHP 5.6+ for correct results. This is due
-     * to a lack of support in the bundled version of Oniguruma in PHP < 5.6,
-     * and current versions of HHVM (3.8 and below).
-     *
-     * @param  string $pattern     The regular expression pattern
-     * @param  string $replacement The string to replace with
-     * @param  string $options     Matching conditions to be used
-     * @return static Object with the resulting $str after the replacements
-     */
-    public function regexReplace($pattern, $replacement, $options = 'msr')
-    {
-        $regexEncoding = $this->regexEncoding();
-        $this->regexEncoding($this->encoding);
-
-        $str = $this->eregReplace($pattern, $replacement, $this->str, $options);
-        $this->regexEncoding($regexEncoding);
-
-        return static::create($str, $this->encoding);
-    }
-
-    /**
-     * Returns a new string with the prefix $substring removed, if present.
-     *
-     * @param  string $substring The prefix to remove
-     * @return static Object having a $str without the prefix $substring
-     */
-    public function removeLeft($substring)
-    {
-        $stringy = static::create($this->str, $this->encoding);
-
-        if ($stringy->startsWith($substring)) {
-            $substringLength = \mb_strlen($substring, $stringy->encoding);
-            return $stringy->substr($substringLength);
-        }
-
-        return $stringy;
-    }
-
-    /**
-     * Returns a new string with the suffix $substring removed, if present.
-     *
-     * @param  string $substring The suffix to remove
-     * @return static Object having a $str without the suffix $substring
-     */
-    public function removeRight($substring)
-    {
-        $stringy = static::create($this->str, $this->encoding);
-
-        if ($stringy->endsWith($substring)) {
-            $substringLength = \mb_strlen($substring, $stringy->encoding);
-            return $stringy->substr(0, $stringy->length() - $substringLength);
-        }
-
-        return $stringy;
-    }
-
-    /**
-     * Returns a repeated string given a multiplier. An alias for str_repeat.
-     *
-     * @param  int    $multiplier The number of times to repeat the string
-     * @return static Object with a repeated str
-     */
-    public function repeat($multiplier)
-    {
-        $repeated = str_repeat($this->str, $multiplier);
-
-        return static::create($repeated, $this->encoding);
-    }
-
-    /**
-     * Replaces all occurrences of $search in $str by $replacement.
-     *
-     * @param  string $search      The needle to search for
-     * @param  string $replacement The string to replace with
-     * @return static Object with the resulting $str after the replacements
-     */
-    public function replace($search, $replacement)
-    {
-        return $this->regexReplace(preg_quote($search), $replacement);
-    }
-
-    /**
-     * Returns a reversed string. A multibyte version of strrev().
-     *
-     * @return static Object with a reversed $str
-     */
-    public function reverse()
-    {
-        $strLength = $this->length();
-        $reversed = '';
-
-        // Loop from last index of string to first
-        for ($i = $strLength - 1; $i >= 0; $i--) {
-            $reversed .= \mb_substr($this->str, $i, 1, $this->encoding);
-        }
-
-        return static::create($reversed, $this->encoding);
-    }
-
-    /**
-     * Truncates the string to a given length, while ensuring that it does not
-     * split words. If $substring is provided, and truncating occurs, the
-     * string is further truncated so that the substring may be appended without
-     * exceeding the desired length.
-     *
-     * @param  int    $length    Desired length of the truncated string
-     * @param  string $substring The substring to append if it can fit
-     * @return static Object with the resulting $str after truncating
-     */
-    public function safeTruncate($length, $substring = '')
-    {
-        $stringy = static::create($this->str, $this->encoding);
-        if ($length >= $stringy->length()) {
-            return $stringy;
-        }
-
-        // Need to further trim the string so we can append the substring
-        $encoding = $stringy->encoding;
-        $substringLength = \mb_strlen($substring, $encoding);
-        $length = $length - $substringLength;
-
-        $truncated = \mb_substr($stringy->str, 0, $length, $encoding);
-
-        // If the last word was truncated
-        if (mb_strpos($stringy->str, ' ', $length - 1, $encoding) != $length) {
-            // Find pos of the last occurrence of a space, get up to that
-            $lastPos = \mb_strrpos($truncated, ' ', 0, $encoding);
-            if ($lastPos !== false) {
-                $truncated = \mb_substr($truncated, 0, $lastPos, $encoding);
-            }
-        }
-
-        $stringy->str = $truncated . $substring;
-
-        return $stringy;
-    }
-
-    /*
-     * A multibyte str_shuffle() function. It returns a string with its
-     * characters in random order.
-     *
-     * @return static Object with a shuffled $str
-     */
-    public function shuffle()
-    {
-        $indexes = range(0, $this->length() - 1);
-        shuffle($indexes);
-
-        $shuffledStr = '';
-        foreach ($indexes as $i) {
-            $shuffledStr .= \mb_substr($this->str, $i, 1, $this->encoding);
-        }
-
-        return static::create($shuffledStr, $this->encoding);
-    }
-
-    /**
-     * Converts the string into an URL slug. This includes replacing non-ASCII
-     * characters with their closest ASCII equivalents, removing remaining
-     * non-ASCII and non-alphanumeric characters, and replacing whitespace with
-     * $replacement. The replacement defaults to a single dash, and the string
-     * is also converted to lowercase. The language of the source string can
-     * also be supplied for language-specific transliteration.
-     *
-     * @param  string $replacement The string used to replace whitespace
-     * @param  string $language    Language of the source string
-     * @return static Object whose $str has been converted to an URL slug
-     */
-    public function slugify($replacement = '-', $language = 'en')
-    {
-        $stringy = $this->toAscii($language);
-
-        $stringy->str = str_replace('@', $replacement, $stringy);
-        $quotedReplacement = preg_quote($replacement);
-        $pattern = "/[^a-zA-Z\d\s-_$quotedReplacement]/u";
-        $stringy->str = preg_replace($pattern, '', $stringy);
-
-        return $stringy->toLowerCase()->delimit($replacement)
-                       ->removeLeft($replacement)->removeRight($replacement);
-    }
-
-    /**
-     * Returns true if the string begins with $substring, false otherwise. By
-     * default, the comparison is case-sensitive, but can be made insensitive
-     * by setting $caseSensitive to false.
-     *
-     * @param  string $substring     The substring to look for
-     * @param  bool   $caseSensitive Whether or not to enforce
-     *                               case-sensitivity
-     * @return bool   Whether or not $str starts with $substring
-     */
-    public function startsWith($substring, $caseSensitive = true)
-    {
-        $substringLength = \mb_strlen($substring, $this->encoding);
-        $startOfStr = \mb_substr($this->str, 0, $substringLength,
-            $this->encoding);
-
-        if (!$caseSensitive) {
-            $substring = \mb_strtolower($substring, $this->encoding);
-            $startOfStr = \mb_strtolower($startOfStr, $this->encoding);
-        }
-
-        return (string) $substring === $startOfStr;
-    }
-
-    /**
-     * Returns true if the string begins with any of $substrings, false
-     * otherwise. By default the comparison is case-sensitive, but can be made
-     * insensitive by setting $caseSensitive to false.
-     *
-     * @param  string[] $substrings    Substrings to look for
-     * @param  bool     $caseSensitive Whether or not to enforce
-     *                                 case-sensitivity
-     * @return bool     Whether or not $str starts with $substring
-     */
-    public function startsWithAny($substrings, $caseSensitive = true)
-    {
-        if (empty($substrings)) {
-            return false;
-        }
-
-        foreach ($substrings as $substring) {
-            if ($this->startsWith($substring, $caseSensitive)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Returns the substring beginning at $start, and up to, but not including
-     * the index specified by $end. If $end is omitted, the function extracts
-     * the remaining string. If $end is negative, it is computed from the end
-     * of the string.
-     *
-     * @param  int    $start Initial index from which to begin extraction
-     * @param  int    $end   Optional index at which to end extraction
-     * @return static Object with its $str being the extracted substring
-     */
-    public function slice($start, $end = null)
-    {
-        if ($end === null) {
-            $length = $this->length();
-        } elseif ($end >= 0 && $end <= $start) {
-            return static::create('', $this->encoding);
-        } elseif ($end < 0) {
-            $length = $this->length() + $end - $start;
-        } else {
-            $length = $end - $start;
-        }
-
-        return $this->substr($start, $length);
-    }
-
-    /**
-     * Splits the string with the provided regular expression, returning an
-     * array of Stringy objects. An optional integer $limit will truncate the
-     * results.
-     *
-     * @param  string   $pattern The regex with which to split the string
-     * @param  int      $limit   Optional maximum number of results to return
-     * @return static[] An array of Stringy objects
-     */
-    public function split($pattern, $limit = null)
-    {
-        if ($limit === 0) {
-            return [];
-        }
-
-        // mb_split errors when supplied an empty pattern in < PHP 5.4.13
-        // and HHVM < 3.8
-        if ($pattern === '') {
-            return [static::create($this->str, $this->encoding)];
-        }
-
-        $regexEncoding = $this->regexEncoding();
-        $this->regexEncoding($this->encoding);
-
-        // mb_split returns the remaining unsplit string in the last index when
-        // supplying a limit
-        $limit = ($limit > 0) ? $limit += 1 : -1;
-
-        static $functionExists;
-        if ($functionExists === null) {
-            $functionExists = function_exists('\mb_split');
-        }
-
-        if ($functionExists) {
-            $array = \mb_split($pattern, $this->str, $limit);
-        } else if ($this->supportsEncoding()) {
-            $array = \preg_split("/$pattern/", $this->str, $limit);
-        }
-
-        $this->regexEncoding($regexEncoding);
-
-        if ($limit > 0 && count($array) === $limit) {
-            array_pop($array);
-        }
-
-        for ($i = 0; $i < count($array); $i++) {
-            $array[$i] = static::create($array[$i], $this->encoding);
-        }
-
-        return $array;
-    }
-
-    /**
-     * Strip all whitespace characters. This includes tabs and newline
-     * characters, as well as multibyte whitespace such as the thin space
-     * and ideographic space.
-     *
-     * @return static Object with whitespace stripped
-     */
-    public function stripWhitespace()
-    {
-        return $this->regexReplace('[[:space:]]+', '');
-    }
-
-    /**
-     * Returns the substring beginning at $start with the specified $length.
-     * It differs from the mb_substr() function in that providing a $length of
-     * null will return the rest of the string, rather than an empty string.
-     *
-     * @param  int    $start  Position of the first character to use
-     * @param  int    $length Maximum number of characters used
-     * @return static Object with its $str being the substring
-     */
-    public function substr($start, $length = null)
-    {
-        $length = $length === null ? $this->length() : $length;
-        $str = \mb_substr($this->str, $start, $length, $this->encoding);
-
-        return static::create($str, $this->encoding);
-    }
-
-    /**
-     * Surrounds $str with the given substring.
-     *
-     * @param  string $substring The substring to add to both sides
-     * @return static Object whose $str had the substring both prepended and
-     *                 appended
-     */
-    public function surround($substring)
-    {
-        $str = implode('', [$substring, $this->str, $substring]);
-
-        return static::create($str, $this->encoding);
-    }
-
-    /**
-     * Returns a case swapped version of the string.
-     *
-     * @return static Object whose $str has each character's case swapped
-     */
-    public function swapCase()
-    {
-        $stringy = static::create($this->str, $this->encoding);
-        $encoding = $stringy->encoding;
-
-        $stringy->str = preg_replace_callback(
-            '/[\S]/u',
-            function ($match) use ($encoding) {
-                if ($match[0] == \mb_strtoupper($match[0], $encoding)) {
-                    return \mb_strtolower($match[0], $encoding);
-                }
-
-                return \mb_strtoupper($match[0], $encoding);
-            },
-            $stringy->str
-        );
-
-        return $stringy;
-    }
-
-    /**
-     * Returns a string with smart quotes, ellipsis characters, and dashes from
-     * Windows-1252 (commonly used in Word documents) replaced by their ASCII
-     * equivalents.
-     *
-     * @return static Object whose $str has those characters removed
-     */
-    public function tidy()
-    {
-        $str = preg_replace([
-            '/\x{2026}/u',
-            '/[\x{201C}\x{201D}]/u',
-            '/[\x{2018}\x{2019}]/u',
-            '/[\x{2013}\x{2014}]/u',
-        ], [
-            '...',
-            '"',
-            "'",
-            '-',
-        ], $this->str);
-
-        return static::create($str, $this->encoding);
-    }
-
-    /**
-     * Returns a trimmed string with the first letter of each word capitalized.
-     * Also accepts an array, $ignore, allowing you to list words not to be
-     * capitalized.
-     *
-     * @param  array  $ignore An array of words not to capitalize
-     * @return static Object with a titleized $str
-     */
-    public function titleize($ignore = null)
-    {
-        $stringy = static::create($this->trim(), $this->encoding);
-        $encoding = $this->encoding;
-
-        $stringy->str = preg_replace_callback(
-            '/([\S]+)/u',
-            function ($match) use ($encoding, $ignore) {
-                if ($ignore && in_array($match[0], $ignore)) {
-                    return $match[0];
-                }
-
-                $stringy = new Stringy($match[0], $encoding);
-
-                return (string) $stringy->toLowerCase()->upperCaseFirst();
-            },
-            $stringy->str
-        );
-
-        return $stringy;
-    }
-
-    /**
-     * Returns an ASCII version of the string. A set of non-ASCII characters are
-     * replaced with their closest ASCII counterparts, and the rest are removed
-     * by default. The language or locale of the source string can be supplied
-     * for language-specific transliteration in any of the following formats:
-     * en, en_GB, or en-GB. For example, passing "de" results in "äöü" mapping
-     * to "aeoeue" rather than "aou" as in other languages.
-     *
-     * @param  string $language          Language of the source string
-     * @param  bool   $removeUnsupported Whether or not to remove the
-     *                                    unsupported characters
-     * @return static Object whose $str contains only ASCII characters
-     */
-    public function toAscii($language = 'en', $removeUnsupported = true)
-    {
-        $str = $this->str;
-
-        $langSpecific = $this->langSpecificCharsArray($language);
-        if (!empty($langSpecific)) {
-            $str = str_replace($langSpecific[0], $langSpecific[1], $str);
-        }
-
-        foreach ($this->charsArray() as $key => $value) {
-            $str = str_replace($value, $key, $str);
-        }
-
-        if ($removeUnsupported) {
-            $str = preg_replace('/[^\x20-\x7E]/u', '', $str);
-        }
-
-        return static::create($str, $this->encoding);
-    }
-
-    /**
-     * Returns a boolean representation of the given logical string value.
-     * For example, 'true', '1', 'on' and 'yes' will return true. 'false', '0',
-     * 'off', and 'no' will return false. In all instances, case is ignored.
-     * For other numeric strings, their sign will determine the return value.
-     * In addition, blank strings consisting of only whitespace will return
-     * false. For all other strings, the return value is a result of a
-     * boolean cast.
-     *
-     * @return bool A boolean value for the string
-     */
-    public function toBoolean()
-    {
-        $key = $this->toLowerCase()->str;
-        $map = [
-            'true'  => true,
-            '1'     => true,
-            'on'    => true,
-            'yes'   => true,
-            'false' => false,
-            '0'     => false,
-            'off'   => false,
-            'no'    => false
-        ];
-
-        if (array_key_exists($key, $map)) {
-            return $map[$key];
-        } elseif (is_numeric($this->str)) {
-            return (intval($this->str) > 0);
-        }
-
-        return (bool) $this->regexReplace('[[:space:]]', '')->str;
-    }
-
-    /**
-     * Converts all characters in the string to lowercase. An alias for PHP's
-     * mb_strtolower().
-     *
-     * @return static Object with all characters of $str being lowercase
-     */
-    public function toLowerCase()
-    {
-        $str = \mb_strtolower($this->str, $this->encoding);
-
-        return static::create($str, $this->encoding);
-    }
-
-    /**
-     * Converts each tab in the string to some number of spaces, as defined by
-     * $tabLength. By default, each tab is converted to 4 consecutive spaces.
-     *
-     * @param  int    $tabLength Number of spaces to replace each tab with
-     * @return static Object whose $str has had tabs switched to spaces
-     */
-    public function toSpaces($tabLength = 4)
-    {
-        $spaces = str_repeat(' ', $tabLength);
-        $str = str_replace("\t", $spaces, $this->str);
-
-        return static::create($str, $this->encoding);
-    }
-
-    /**
-     * Converts each occurrence of some consecutive number of spaces, as
-     * defined by $tabLength, to a tab. By default, each 4 consecutive spaces
-     * are converted to a tab.
-     *
-     * @param  int    $tabLength Number of spaces to replace with a tab
-     * @return static Object whose $str has had spaces switched to tabs
-     */
-    public function toTabs($tabLength = 4)
-    {
-        $spaces = str_repeat(' ', $tabLength);
-        $str = str_replace($spaces, "\t", $this->str);
-
-        return static::create($str, $this->encoding);
-    }
-
-    /**
-     * Converts the first character of each word in the string to uppercase.
-     *
-     * @return static Object with all characters of $str being title-cased
-     */
-    public function toTitleCase()
-    {
-        $str = \mb_convert_case($this->str, \MB_CASE_TITLE, $this->encoding);
-
-        return static::create($str, $this->encoding);
-    }
-
-    /**
-     * Converts all characters in the string to uppercase. An alias for PHP's
-     * mb_strtoupper().
-     *
-     * @return static Object with all characters of $str being uppercase
-     */
-    public function toUpperCase()
-    {
-        $str = \mb_strtoupper($this->str, $this->encoding);
-
-        return static::create($str, $this->encoding);
-    }
-
-    /**
-     * Returns a string with whitespace removed from the start and end of the
-     * string. Supports the removal of unicode whitespace. Accepts an optional
-     * string of characters to strip instead of the defaults.
-     *
-     * @param  string $chars Optional string of characters to strip
-     * @return static Object with a trimmed $str
-     */
-    public function trim($chars = null)
-    {
-        $chars = ($chars) ? preg_quote($chars) : '[:space:]';
-
-        return $this->regexReplace("^[$chars]+|[$chars]+\$", '');
-    }
-
-    /**
-     * Returns a string with whitespace removed from the start of the string.
-     * Supports the removal of unicode whitespace. Accepts an optional
-     * string of characters to strip instead of the defaults.
-     *
-     * @param  string $chars Optional string of characters to strip
-     * @return static Object with a trimmed $str
-     */
-    public function trimLeft($chars = null)
-    {
-        $chars = ($chars) ? preg_quote($chars) : '[:space:]';
-
-        return $this->regexReplace("^[$chars]+", '');
-    }
-
-    /**
-     * Returns a string with whitespace removed from the end of the string.
-     * Supports the removal of unicode whitespace. Accepts an optional
-     * string of characters to strip instead of the defaults.
-     *
-     * @param  string $chars Optional string of characters to strip
-     * @return static Object with a trimmed $str
-     */
-    public function trimRight($chars = null)
-    {
-        $chars = ($chars) ? preg_quote($chars) : '[:space:]';
-
-        return $this->regexReplace("[$chars]+\$", '');
-    }
-
-    /**
-     * Truncates the string to a given length. If $substring is provided, and
-     * truncating occurs, the string is further truncated so that the substring
-     * may be appended without exceeding the desired length.
-     *
-     * @param  int    $length    Desired length of the truncated string
-     * @param  string $substring The substring to append if it can fit
-     * @return static Object with the resulting $str after truncating
-     */
-    public function truncate($length, $substring = '')
-    {
-        $stringy = static::create($this->str, $this->encoding);
-        if ($length >= $stringy->length()) {
-            return $stringy;
-        }
-
-        // Need to further trim the string so we can append the substring
-        $substringLength = \mb_strlen($substring, $stringy->encoding);
-        $length = $length - $substringLength;
-
-        $truncated = \mb_substr($stringy->str, 0, $length, $stringy->encoding);
-        $stringy->str = $truncated . $substring;
-
-        return $stringy;
-    }
-
-    /**
-     * Returns a lowercase and trimmed string separated by underscores.
-     * Underscores are inserted before uppercase characters (with the exception
-     * of the first character of the string), and in place of spaces as well as
-     * dashes.
-     *
-     * @return static Object with an underscored $str
-     */
-    public function underscored()
-    {
-        return $this->delimit('_');
-    }
-
-    /**
-     * Returns an UpperCamelCase version of the supplied string. It trims
-     * surrounding spaces, capitalizes letters following digits, spaces, dashes
-     * and underscores, and removes spaces, dashes, underscores.
-     *
-     * @return static Object with $str in UpperCamelCase
-     */
-    public function upperCamelize()
-    {
-        return $this->camelize()->upperCaseFirst();
-    }
-
-    /**
-     * Converts the first character of the supplied string to upper case.
-     *
-     * @return static Object with the first character of $str being upper case
-     */
-    public function upperCaseFirst()
-    {
-        $first = \mb_substr($this->str, 0, 1, $this->encoding);
-        $rest = \mb_substr($this->str, 1, $this->length() - 1,
-            $this->encoding);
-
-        $str = \mb_strtoupper($first, $this->encoding) . $rest;
-
-        return static::create($str, $this->encoding);
-    }
-
-    /**
-     * Returns the replacements for the toAscii() method.
-     *
-     * @return array An array of replacements.
-     */
-    protected function charsArray()
-    {
-        static $charsArray;
-        if (isset($charsArray)) return $charsArray;
-
-        return $charsArray = [
-            '0'     => ['°', '₀', '۰', '0'],
-            '1'     => ['¹', '₁', '۱', '1'],
-            '2'     => ['²', '₂', '۲', '2'],
-            '3'     => ['³', '₃', '۳', '3'],
-            '4'     => ['⁴', '₄', '۴', '٤', '4'],
-            '5'     => ['⁵', '₅', '۵', '٥', '5'],
-            '6'     => ['⁶', '₆', '۶', '٦', '6'],
-            '7'     => ['⁷', '₇', '۷', '7'],
-            '8'     => ['⁸', '₈', '۸', '8'],
-            '9'     => ['⁹', '₉', '۹', '9'],
-            'a'     => ['à', 'á', 'ả', 'ã', 'ạ', 'ă', 'ắ', 'ằ', 'ẳ', 'ẵ',
-                        'ặ', 'â', 'ấ', 'ầ', 'ẩ', 'ẫ', 'ậ', 'ā', 'ą', 'å',
-                        'α', 'ά', 'ἀ', 'ἁ', 'ἂ', 'ἃ', 'ἄ', 'ἅ', 'ἆ', 'ἇ',
-                        'ᾀ', 'ᾁ', 'ᾂ', 'ᾃ', 'ᾄ', 'ᾅ', 'ᾆ', 'ᾇ', 'ὰ', 'ά',
-                        'ᾰ', 'ᾱ', 'ᾲ', 'ᾳ', 'ᾴ', 'ᾶ', 'ᾷ', 'а', 'أ', 'အ',
-                        'ာ', 'ါ', 'ǻ', 'ǎ', 'ª', 'ა', 'अ', 'ا', 'a', 'ä'],
-            'b'     => ['б', 'β', 'ب', 'ဗ', 'ბ', 'b'],
-            'c'     => ['ç', 'ć', 'č', 'ĉ', 'ċ', 'c'],
-            'd'     => ['ď', 'ð', 'đ', 'ƌ', 'ȡ', 'ɖ', 'ɗ', 'ᵭ', 'ᶁ', 'ᶑ',
-                        'д', 'δ', 'د', 'ض', 'ဍ', 'ဒ', 'დ', 'd'],
-            'e'     => ['é', 'è', 'ẻ', 'ẽ', 'ẹ', 'ê', 'ế', 'ề', 'ể', 'ễ',
-                        'ệ', 'ë', 'ē', 'ę', 'ě', 'ĕ', 'ė', 'ε', 'έ', 'ἐ',
-                        'ἑ', 'ἒ', 'ἓ', 'ἔ', 'ἕ', 'ὲ', 'έ', 'е', 'ё', 'э',
-                        'є', 'ə', 'ဧ', 'ေ', 'ဲ', 'ე', 'ए', 'إ', 'ئ', 'e'],
-            'f'     => ['ф', 'φ', 'ف', 'ƒ', 'ფ', 'f'],
-            'g'     => ['ĝ', 'ğ', 'ġ', 'ģ', 'г', 'ґ', 'γ', 'ဂ', 'გ', 'گ',
-                        'g'],
-            'h'     => ['ĥ', 'ħ', 'η', 'ή', 'ح', 'ه', 'ဟ', 'ှ', 'ჰ', 'h'],
-            'i'     => ['í', 'ì', 'ỉ', 'ĩ', 'ị', 'î', 'ï', 'ī', 'ĭ', 'į',
-                        'ı', 'ι', 'ί', 'ϊ', 'ΐ', 'ἰ', 'ἱ', 'ἲ', 'ἳ', 'ἴ',
-                        'ἵ', 'ἶ', 'ἷ', 'ὶ', 'ί', 'ῐ', 'ῑ', 'ῒ', 'ΐ', 'ῖ',
-                        'ῗ', 'і', 'ї', 'и', 'ဣ', 'ိ', 'ီ', 'ည်', 'ǐ', 'ი',
-                        'इ', 'ی', 'i'],
-            'j'     => ['ĵ', 'ј', 'Ј', 'ჯ', 'ج', 'j'],
-            'k'     => ['ķ', 'ĸ', 'к', 'κ', 'Ķ', 'ق', 'ك', 'က', 'კ', 'ქ',
-                        'ک', 'k'],
-            'l'     => ['ł', 'ľ', 'ĺ', 'ļ', 'ŀ', 'л', 'λ', 'ل', 'လ', 'ლ',
-                        'l'],
-            'm'     => ['м', 'μ', 'م', 'မ', 'მ', 'm'],
-            'n'     => ['ñ', 'ń', 'ň', 'ņ', 'ʼn', 'ŋ', 'ν', 'н', 'ن', 'န',
-                        'ნ', 'n'],
-            'o'     => ['ó', 'ò', 'ỏ', 'õ', 'ọ', 'ô', 'ố', 'ồ', 'ổ', 'ỗ',
-                        'ộ', 'ơ', 'ớ', 'ờ', 'ở', 'ỡ', 'ợ', 'ø', 'ō', 'ő',
-                        'ŏ', 'ο', 'ὀ', 'ὁ', 'ὂ', 'ὃ', 'ὄ', 'ὅ', 'ὸ', 'ό',
-                        'о', 'و', 'θ', 'ို', 'ǒ', 'ǿ', 'º', 'ო', 'ओ', 'o',
-                        'ö'],
-            'p'     => ['п', 'π', 'ပ', 'პ', 'پ', 'p'],
-            'q'     => ['ყ', 'q'],
-            'r'     => ['ŕ', 'ř', 'ŗ', 'р', 'ρ', 'ر', 'რ', 'r'],
-            's'     => ['ś', 'š', 'ş', 'с', 'σ', 'ș', 'ς', 'س', 'ص', 'စ',
-                        'ſ', 'ს', 's'],
-            't'     => ['ť', 'ţ', 'т', 'τ', 'ț', 'ت', 'ط', 'ဋ', 'တ', 'ŧ',
-                        'თ', 'ტ', 't'],
-            'u'     => ['ú', 'ù', 'ủ', 'ũ', 'ụ', 'ư', 'ứ', 'ừ', 'ử', 'ữ',
-                        'ự', 'û', 'ū', 'ů', 'ű', 'ŭ', 'ų', 'µ', 'у', 'ဉ',
-                        'ု', 'ူ', 'ǔ', 'ǖ', 'ǘ', 'ǚ', 'ǜ', 'უ', 'उ', 'u',
-                        'ў', 'ü'],
-            'v'     => ['в', 'ვ', 'ϐ', 'v'],
-            'w'     => ['ŵ', 'ω', 'ώ', 'ဝ', 'ွ', 'w'],
-            'x'     => ['χ', 'ξ', 'x'],
-            'y'     => ['ý', 'ỳ', 'ỷ', 'ỹ', 'ỵ', 'ÿ', 'ŷ', 'й', 'ы', 'υ',
-                        'ϋ', 'ύ', 'ΰ', 'ي', 'ယ', 'y'],
-            'z'     => ['ź', 'ž', 'ż', 'з', 'ζ', 'ز', 'ဇ', 'ზ', 'z'],
-            'aa'    => ['ع', 'आ', 'آ'],
-            'ae'    => ['æ', 'ǽ'],
-            'ai'    => ['ऐ'],
-            'ch'    => ['ч', 'ჩ', 'ჭ', 'چ'],
-            'dj'    => ['ђ', 'đ'],
-            'dz'    => ['џ', 'ძ'],
-            'ei'    => ['ऍ'],
-            'gh'    => ['غ', 'ღ'],
-            'ii'    => ['ई'],
-            'ij'    => ['ij'],
-            'kh'    => ['х', 'خ', 'ხ'],
-            'lj'    => ['љ'],
-            'nj'    => ['њ'],
-            'oe'    => ['œ', 'ؤ'],
-            'oi'    => ['ऑ'],
-            'oii'   => ['ऒ'],
-            'ps'    => ['ψ'],
-            'sh'    => ['ш', 'შ', 'ش'],
-            'shch'  => ['щ'],
-            'ss'    => ['ß'],
-            'sx'    => ['ŝ'],
-            'th'    => ['þ', 'ϑ', 'ث', 'ذ', 'ظ'],
-            'ts'    => ['ц', 'ც', 'წ'],
-            'uu'    => ['ऊ'],
-            'ya'    => ['я'],
-            'yu'    => ['ю'],
-            'zh'    => ['ж', 'ჟ', 'ژ'],
-            '(c)'   => ['©'],
-            'A'     => ['Á', 'À', 'Ả', 'Ã', 'Ạ', 'Ă', 'Ắ', 'Ằ', 'Ẳ', 'Ẵ',
-                        'Ặ', 'Â', 'Ấ', 'Ầ', 'Ẩ', 'Ẫ', 'Ậ', 'Å', 'Ā', 'Ą',
-                        'Α', 'Ά', 'Ἀ', 'Ἁ', 'Ἂ', 'Ἃ', 'Ἄ', 'Ἅ', 'Ἆ', 'Ἇ',
-                        'ᾈ', 'ᾉ', 'ᾊ', 'ᾋ', 'ᾌ', 'ᾍ', 'ᾎ', 'ᾏ', 'Ᾰ', 'Ᾱ',
-                        'Ὰ', 'Ά', 'ᾼ', 'А', 'Ǻ', 'Ǎ', 'A', 'Ä'],
-            'B'     => ['Б', 'Β', 'ब', 'B'],
-            'C'     => ['Ç','Ć', 'Č', 'Ĉ', 'Ċ', 'C'],
-            'D'     => ['Ď', 'Ð', 'Đ', 'Ɖ', 'Ɗ', 'Ƌ', 'ᴅ', 'ᴆ', 'Д', 'Δ',
-                        'D'],
-            'E'     => ['É', 'È', 'Ẻ', 'Ẽ', 'Ẹ', 'Ê', 'Ế', 'Ề', 'Ể', 'Ễ',
-                        'Ệ', 'Ë', 'Ē', 'Ę', 'Ě', 'Ĕ', 'Ė', 'Ε', 'Έ', 'Ἐ',
-                        'Ἑ', 'Ἒ', 'Ἓ', 'Ἔ', 'Ἕ', 'Έ', 'Ὲ', 'Е', 'Ё', 'Э',
-                        'Є', 'Ə', 'E'],
-            'F'     => ['Ф', 'Φ', 'F'],
-            'G'     => ['Ğ', 'Ġ', 'Ģ', 'Г', 'Ґ', 'Γ', 'G'],
-            'H'     => ['Η', 'Ή', 'Ħ', 'H'],
-            'I'     => ['Í', 'Ì', 'Ỉ', 'Ĩ', 'Ị', 'Î', 'Ï', 'Ī', 'Ĭ', 'Į',
-                        'İ', 'Ι', 'Ί', 'Ϊ', 'Ἰ', 'Ἱ', 'Ἳ', 'Ἴ', 'Ἵ', 'Ἶ',
-                        'Ἷ', 'Ῐ', 'Ῑ', 'Ὶ', 'Ί', 'И', 'І', 'Ї', 'Ǐ', 'ϒ',
-                        'I'],
-            'J'     => ['J'],
-            'K'     => ['К', 'Κ', 'K'],
-            'L'     => ['Ĺ', 'Ł', 'Л', 'Λ', 'Ļ', 'Ľ', 'Ŀ', 'ल', 'L'],
-            'M'     => ['М', 'Μ', 'M'],
-            'N'     => ['Ń', 'Ñ', 'Ň', 'Ņ', 'Ŋ', 'Н', 'Ν', 'N'],
-            'O'     => ['Ó', 'Ò', 'Ỏ', 'Õ', 'Ọ', 'Ô', 'Ố', 'Ồ', 'Ổ', 'Ỗ',
-                        'Ộ', 'Ơ', 'Ớ', 'Ờ', 'Ở', 'Ỡ', 'Ợ', 'Ø', 'Ō', 'Ő',
-                        'Ŏ', 'Ο', 'Ό', 'Ὀ', 'Ὁ', 'Ὂ', 'Ὃ', 'Ὄ', 'Ὅ', 'Ὸ',
-                        'Ό', 'О', 'Θ', 'Ө', 'Ǒ', 'Ǿ', 'O', 'Ö'],
-            'P'     => ['П', 'Π', 'P'],
-            'Q'     => ['Q'],
-            'R'     => ['Ř', 'Ŕ', 'Р', 'Ρ', 'Ŗ', 'R'],
-            'S'     => ['Ş', 'Ŝ', 'Ș', 'Š', 'Ś', 'С', 'Σ', 'S'],
-            'T'     => ['Ť', 'Ţ', 'Ŧ', 'Ț', 'Т', 'Τ', 'T'],
-            'U'     => ['Ú', 'Ù', 'Ủ', 'Ũ', 'Ụ', 'Ư', 'Ứ', 'Ừ', 'Ử', 'Ữ',
-                        'Ự', 'Û', 'Ū', 'Ů', 'Ű', 'Ŭ', 'Ų', 'У', 'Ǔ', 'Ǖ',
-                        'Ǘ', 'Ǚ', 'Ǜ', 'U', 'Ў', 'Ü'],
-            'V'     => ['В', 'V'],
-            'W'     => ['Ω', 'Ώ', 'Ŵ', 'W'],
-            'X'     => ['Χ', 'Ξ', 'X'],
-            'Y'     => ['Ý', 'Ỳ', 'Ỷ', 'Ỹ', 'Ỵ', 'Ÿ', 'Ῠ', 'Ῡ', 'Ὺ', 'Ύ',
-                        'Ы', 'Й', 'Υ', 'Ϋ', 'Ŷ', 'Y'],
-            'Z'     => ['Ź', 'Ž', 'Ż', 'З', 'Ζ', 'Z'],
-            'AE'    => ['Æ', 'Ǽ'],
-            'Ch'    => ['Ч'],
-            'Dj'    => ['Ђ'],
-            'Dz'    => ['Џ'],
-            'Gx'    => ['Ĝ'],
-            'Hx'    => ['Ĥ'],
-            'Ij'    => ['IJ'],
-            'Jx'    => ['Ĵ'],
-            'Kh'    => ['Х'],
-            'Lj'    => ['Љ'],
-            'Nj'    => ['Њ'],
-            'Oe'    => ['Œ'],
-            'Ps'    => ['Ψ'],
-            'Sh'    => ['Ш'],
-            'Shch'  => ['Щ'],
-            'Ss'    => ['ẞ'],
-            'Th'    => ['Þ'],
-            'Ts'    => ['Ц'],
-            'Ya'    => ['Я'],
-            'Yu'    => ['Ю'],
-            'Zh'    => ['Ж'],
-            ' '     => ["\xC2\xA0", "\xE2\x80\x80", "\xE2\x80\x81",
-                        "\xE2\x80\x82", "\xE2\x80\x83", "\xE2\x80\x84",
-                        "\xE2\x80\x85", "\xE2\x80\x86", "\xE2\x80\x87",
-                        "\xE2\x80\x88", "\xE2\x80\x89", "\xE2\x80\x8A",
-                        "\xE2\x80\xAF", "\xE2\x81\x9F", "\xE3\x80\x80",
-                        "\xEF\xBE\xA0"],
-        ];
-    }
-
-    /**
-     * Returns language-specific replacements for the toAscii() method.
-     * For example, German will map 'ä' to 'ae', while other languages
-     * will simply return 'a'.
-     *
-     * @param  string $language Language of the source string
-     * @return array  An array of replacements.
-     */
-    protected static function langSpecificCharsArray($language = 'en')
-    {
-        $split = preg_split('/[-_]/', $language);
-        $language = strtolower($split[0]);
-
-        static $charsArray = [];
-        if (isset($charsArray[$language])) {
-            return $charsArray[$language];
-        }
-
-        $languageSpecific = [
-            'de' => [
-                ['ä',  'ö',  'ü',  'Ä',  'Ö',  'Ü' ],
-                ['ae', 'oe', 'ue', 'AE', 'OE', 'UE'],
-            ],
-            'bg' => [
-                ['х', 'Х', 'щ', 'Щ', 'ъ', 'Ъ', 'ь', 'Ь'],
-                ['h', 'H', 'sht', 'SHT', 'a', 'А', 'y', 'Y']
-            ]
-        ];
-
-        if (isset($languageSpecific[$language])) {
-            $charsArray[$language] = $languageSpecific[$language];
-        } else {
-            $charsArray[$language] = [];
-        }
-
-        return $charsArray[$language];
-    }
-
-    /**
-     * Adds the specified amount of left and right padding to the given string.
-     * The default character used is a space.
-     *
-     * @param  int    $left   Length of left padding
-     * @param  int    $right  Length of right padding
-     * @param  string $padStr String used to pad
-     * @return static String with padding applied
-     */
-    protected function applyPadding($left = 0, $right = 0, $padStr = ' ')
-    {
-        $stringy = static::create($this->str, $this->encoding);
-        $length = \mb_strlen($padStr, $stringy->encoding);
-
-        $strLength = $stringy->length();
-        $paddedLength = $strLength + $left + $right;
-
-        if (!$length || $paddedLength <= $strLength) {
-            return $stringy;
-        }
-
-        $leftPadding = \mb_substr(str_repeat($padStr, ceil($left / $length)), 0,
-            $left, $stringy->encoding);
-        $rightPadding = \mb_substr(str_repeat($padStr, ceil($right / $length)),
-            0, $right, $stringy->encoding);
-
-        $stringy->str = $leftPadding . $stringy->str . $rightPadding;
-
-        return $stringy;
-    }
-
-    /**
-     * Returns true if $str matches the supplied pattern, false otherwise.
-     *
-     * @param  string $pattern Regex pattern to match against
-     * @return bool   Whether or not $str matches the pattern
-     */
-    protected function matchesPattern($pattern)
-    {
-        $regexEncoding = $this->regexEncoding();
-        $this->regexEncoding($this->encoding);
-
-        $match = \mb_ereg_match($pattern, $this->str);
-        $this->regexEncoding($regexEncoding);
-
-        return $match;
-    }
-
-    /**
-     * Alias for mb_ereg_replace with a fallback to preg_replace if the
-     * mbstring module is not installed.
-     */
-    protected function eregReplace($pattern, $replacement, $string, $option = 'msr')
-    {
-        static $functionExists;
-        if ($functionExists === null) {
-            $functionExists = function_exists('\mb_split');
-        }
-
-        if ($functionExists) {
-            return \mb_ereg_replace($pattern, $replacement, $string, $option);
-        } else if ($this->supportsEncoding()) {
-            $option = str_replace('r', '', $option);
-            return \preg_replace("/$pattern/u$option", $replacement, $string);
-        }
-    }
-
-    /**
-     * Alias for mb_regex_encoding which default to a noop if the mbstring
-     * module is not installed.
-     */
-    protected function regexEncoding()
-    {
-        static $functionExists;
-
-        if ($functionExists === null) {
-            $functionExists = function_exists('\mb_regex_encoding');
-        }
-
-        if ($functionExists) {
-            $args = func_get_args();
-            return call_user_func_array('\mb_regex_encoding', $args);
-        }
-    }
-
-    protected function supportsEncoding()
-    {
-        $supported = ['UTF-8' => true, 'ASCII' => true];
-
-        if (isset($supported[$this->encoding])) {
-            return true;
-        } else {
-            throw new \RuntimeException('Stringy method requires the ' .
-                'mbstring module for encodings other than ASCII and UTF-8. ' .
-                'Encoding used: ' . $this->encoding);
-        }
-    }
-}

+ 4 - 4
vendor/dingo/blueprint/composer.json

@@ -11,14 +11,14 @@
     ],
     ],
     "require": {
     "require": {
         "php": "^7.2.5|^8.0",
         "php": "^7.2.5|^8.0",
-        "illuminate/support": "^7.0|^8.0",
-        "illuminate/filesystem": "^7.0|^8.0",
-        "doctrine/annotations": "~1.2",
+        "illuminate/support": "^7.0|^8.0|^9.0|^10.0",
+        "illuminate/filesystem": "^7.0|^8.0|^9.0|^10.0",
+        "doctrine/annotations": "~1.2 | ^2.0",
         "phpdocumentor/reflection-docblock": "^3.1 || ^4.1 || ^5"
         "phpdocumentor/reflection-docblock": "^3.1 || ^4.1 || ^5"
     },
     },
     "require-dev": {
     "require-dev": {
         "squizlabs/php_codesniffer": "~2.0",
         "squizlabs/php_codesniffer": "~2.0",
-        "phpunit/phpunit": "^6.5|^8.3|^9.0"
+        "phpunit/phpunit": "^6.5|^8.3|^9.0|^10.0"
     },
     },
     "autoload": {
     "autoload": {
         "psr-4": {
         "psr-4": {

+ 6 - 0
vendor/doctrine/annotations/README.md

@@ -1,3 +1,9 @@
+⚠️ PHP 8 introduced
+[attributes](https://www.php.net/manual/en/language.attributes.overview.php),
+which are a native replacement for annotations. As such, this library is
+considered feature complete, and should receive exclusively bugfixes and
+security fixes.
+
 # Doctrine Annotations
 # Doctrine Annotations
 
 
 [![Build Status](https://github.com/doctrine/annotations/workflows/Continuous%20Integration/badge.svg?label=build)](https://github.com/doctrine/persistence/actions)
 [![Build Status](https://github.com/doctrine/annotations/workflows/Continuous%20Integration/badge.svg?label=build)](https://github.com/doctrine/persistence/actions)

+ 8 - 5
vendor/doctrine/annotations/composer.json

@@ -34,17 +34,20 @@
     "require": {
     "require": {
         "php": "^7.1 || ^8.0",
         "php": "^7.1 || ^8.0",
         "ext-tokenizer": "*",
         "ext-tokenizer": "*",
-        "doctrine/lexer": "1.*",
+        "doctrine/lexer": "^1 || ^2",
         "psr/cache": "^1 || ^2 || ^3"
         "psr/cache": "^1 || ^2 || ^3"
     },
     },
     "require-dev": {
     "require-dev": {
         "doctrine/cache": "^1.11 || ^2.0",
         "doctrine/cache": "^1.11 || ^2.0",
-        "doctrine/coding-standard": "^6.0 || ^8.1",
-        "phpstan/phpstan": "^1.4.10 || ^1.8.0",
-        "phpunit/phpunit": "^7.5 || ^8.0 || ^9.1.5",
-        "symfony/cache": "^4.4 || ^5.2",
+        "doctrine/coding-standard": "^9 || ^10",
+        "phpstan/phpstan": "~1.4.10 || ^1.8.0",
+        "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
+        "symfony/cache": "^4.4 || ^5.4 || ^6",
         "vimeo/psalm": "^4.10"
         "vimeo/psalm": "^4.10"
     },
     },
+    "suggest": {
+        "php": "PHP 8.0 or higher comes with attributes, a native replacement for annotations"
+    },
     "autoload": {
     "autoload": {
         "psr-4": {
         "psr-4": {
             "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations"
             "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations"

+ 1 - 1
vendor/doctrine/annotations/docs/en/custom.rst

@@ -69,7 +69,7 @@ When using the ``@NamedArgumentConstructor`` tag, the first argument of the
 constructor is considered as the default one.
 constructor is considered as the default one.
 
 
 
 
-Usage with the ``@NamedArgumentContrustor`` tag
+Usage with the ``@NamedArgumentConstructor`` tag
 
 
 .. code-block:: php
 .. code-block:: php
 
 

+ 9 - 0
vendor/doctrine/annotations/docs/en/index.rst

@@ -1,3 +1,12 @@
+Deprecation notice
+==================
+
+PHP 8 introduced `attributes
+<https://www.php.net/manual/en/language.attributes.overview.php>`_,
+which are a native replacement for annotations. As such, this library is
+considered feature complete, and should receive exclusively bugfixes and
+security fixes.
+
 Introduction
 Introduction
 ============
 ============
 
 

+ 1 - 3
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation.php

@@ -18,9 +18,7 @@ class Annotation
      */
      */
     public $value;
     public $value;
 
 
-    /**
-     * @param array<string, mixed> $data Key-value for properties to be defined in this class.
-     */
+    /** @param array<string, mixed> $data Key-value for properties to be defined in this class. */
     final public function __construct(array $data)
     final public function __construct(array $data)
     {
     {
         foreach ($data as $key => $value) {
         foreach ($data as $key => $value) {

+ 2 - 2
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Enum.php

@@ -34,9 +34,9 @@ final class Enum
     public $literal;
     public $literal;
 
 
     /**
     /**
-     * @throws InvalidArgumentException
-     *
      * @phpstan-param array{literal?: mixed[], value: list<scalar>} $values
      * @phpstan-param array{literal?: mixed[], value: list<scalar>} $values
+     *
+     * @throws InvalidArgumentException
      */
      */
     public function __construct(array $values)
     public function __construct(array $values)
     {
     {

+ 2 - 2
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/IgnoreAnnotation.php

@@ -21,9 +21,9 @@ final class IgnoreAnnotation
     public $names;
     public $names;
 
 
     /**
     /**
-     * @throws RuntimeException
-     *
      * @phpstan-param array{value: string|list<string>} $values
      * @phpstan-param array{value: string|list<string>} $values
+     *
+     * @throws RuntimeException
      */
      */
     public function __construct(array $values)
     public function __construct(array $values)
     {
     {

+ 2 - 2
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Target.php

@@ -56,9 +56,9 @@ final class Target
     public $literal;
     public $literal;
 
 
     /**
     /**
-     * @throws InvalidArgumentException
-     *
      * @phpstan-param array{value?: string|list<string>} $values
      * @phpstan-param array{value?: string|list<string>} $values
+     *
+     * @throws InvalidArgumentException
      */
      */
     public function __construct(array $values)
     public function __construct(array $values)
     {
     {

+ 3 - 8
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationException.php

@@ -133,10 +133,9 @@ class AnnotationException extends Exception
      * @param string $annotationName
      * @param string $annotationName
      * @param string $context
      * @param string $context
      * @param mixed  $given
      * @param mixed  $given
+     * @phpstan-param list<string>        $available
      *
      *
      * @return AnnotationException
      * @return AnnotationException
-     *
-     * @phpstan-param list<string>        $available
      */
      */
     public static function enumeratorError($attributeName, $annotationName, $context, $available, $given)
     public static function enumeratorError($attributeName, $annotationName, $context, $available, $given)
     {
     {
@@ -150,9 +149,7 @@ class AnnotationException extends Exception
         ));
         ));
     }
     }
 
 
-    /**
-     * @return AnnotationException
-     */
+    /** @return AnnotationException */
     public static function optimizerPlusSaveComments()
     public static function optimizerPlusSaveComments()
     {
     {
         return new self(
         return new self(
@@ -160,9 +157,7 @@ class AnnotationException extends Exception
         );
         );
     }
     }
 
 
-    /**
-     * @return AnnotationException
-     */
+    /** @return AnnotationException */
     public static function optimizerPlusLoadComments()
     public static function optimizerPlusLoadComments()
     {
     {
         return new self(
         return new self(

+ 1 - 3
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/CachedReader.php

@@ -38,9 +38,7 @@ final class CachedReader implements Reader
     /** @var int[] */
     /** @var int[] */
     private $loadedFilemtimes = [];
     private $loadedFilemtimes = [];
 
 
-    /**
-     * @param bool $debug
-     */
+    /** @param bool $debug */
     public function __construct(Reader $reader, Cache $cache, $debug = false)
     public function __construct(Reader $reader, Cache $cache, $debug = false)
     {
     {
         $this->delegate = $reader;
         $this->delegate = $reader;

+ 16 - 2
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocLexer.php

@@ -15,6 +15,8 @@ use function substr;
 
 
 /**
 /**
  * Simple lexer for docblock annotations.
  * Simple lexer for docblock annotations.
+ *
+ * @template-extends AbstractLexer<DocLexer::T_*, string>
  */
  */
 final class DocLexer extends AbstractLexer
 final class DocLexer extends AbstractLexer
 {
 {
@@ -39,7 +41,7 @@ final class DocLexer extends AbstractLexer
     public const T_COLON               = 112;
     public const T_COLON               = 112;
     public const T_MINUS               = 113;
     public const T_MINUS               = 113;
 
 
-    /** @var array<string, int> */
+    /** @var array<string, self::T*> */
     protected $noCase = [
     protected $noCase = [
         '@'  => self::T_AT,
         '@'  => self::T_AT,
         ','  => self::T_COMMA,
         ','  => self::T_COMMA,
@@ -53,7 +55,7 @@ final class DocLexer extends AbstractLexer
         '\\' => self::T_NAMESPACE_SEPARATOR,
         '\\' => self::T_NAMESPACE_SEPARATOR,
     ];
     ];
 
 
-    /** @var array<string, int> */
+    /** @var array<string, self::T*> */
     protected $withCase = [
     protected $withCase = [
         'true'  => self::T_TRUE,
         'true'  => self::T_TRUE,
         'false' => self::T_FALSE,
         'false' => self::T_FALSE,
@@ -126,4 +128,16 @@ final class DocLexer extends AbstractLexer
 
 
         return $type;
         return $type;
     }
     }
+
+    /** @return array{value: int|string, type:self::T_*|null, position:int} */
+    public function peek(): ?array
+    {
+        $token = parent::peek();
+
+        if ($token === null) {
+            return null;
+        }
+
+        return (array) $token;
+    }
 }
 }

+ 30 - 11
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php

@@ -357,10 +357,10 @@ final class DocParser
      * @param string $input   The docblock string to parse.
      * @param string $input   The docblock string to parse.
      * @param string $context The parsing context.
      * @param string $context The parsing context.
      *
      *
+     * @phpstan-return list<object> Array of annotations. If no annotations are found, an empty array is returned.
+     *
      * @throws AnnotationException
      * @throws AnnotationException
      * @throws ReflectionException
      * @throws ReflectionException
-     *
-     * @phpstan-return list<object> Array of annotations. If no annotations are found, an empty array is returned.
      */
      */
     public function parse($input, $context = '')
     public function parse($input, $context = '')
     {
     {
@@ -426,9 +426,9 @@ final class DocParser
      * If any of them matches, this method updates the lookahead token; otherwise
      * If any of them matches, this method updates the lookahead token; otherwise
      * a syntax error is raised.
      * a syntax error is raised.
      *
      *
-     * @throws AnnotationException
-     *
      * @phpstan-param list<mixed[]> $tokens
      * @phpstan-param list<mixed[]> $tokens
+     *
+     * @throws AnnotationException
      */
      */
     private function matchAny(array $tokens): bool
     private function matchAny(array $tokens): bool
     {
     {
@@ -613,6 +613,10 @@ final class DocParser
                 $metadata['default_property'] = reset($metadata['properties']);
                 $metadata['default_property'] = reset($metadata['properties']);
             } elseif ($metadata['has_named_argument_constructor']) {
             } elseif ($metadata['has_named_argument_constructor']) {
                 foreach ($constructor->getParameters() as $parameter) {
                 foreach ($constructor->getParameters() as $parameter) {
+                    if ($parameter->isVariadic()) {
+                        break;
+                    }
+
                     $metadata['constructor_args'][$parameter->getName()] = [
                     $metadata['constructor_args'][$parameter->getName()] = [
                         'position' => $parameter->getPosition(),
                         'position' => $parameter->getPosition(),
                         'default' => $parameter->isOptional() ? $parameter->getDefaultValue() : null,
                         'default' => $parameter->isOptional() ? $parameter->getDefaultValue() : null,
@@ -674,10 +678,10 @@ final class DocParser
     /**
     /**
      * Annotations ::= Annotation {[ "*" ]* [Annotation]}*
      * Annotations ::= Annotation {[ "*" ]* [Annotation]}*
      *
      *
+     * @phpstan-return list<object>
+     *
      * @throws AnnotationException
      * @throws AnnotationException
      * @throws ReflectionException
      * @throws ReflectionException
-     *
-     * @phpstan-return list<object>
      */
      */
     private function Annotations(): array
     private function Annotations(): array
     {
     {
@@ -942,6 +946,23 @@ EXCEPTION
 
 
         if (self::$annotationMetadata[$name]['has_named_argument_constructor']) {
         if (self::$annotationMetadata[$name]['has_named_argument_constructor']) {
             if (PHP_VERSION_ID >= 80000) {
             if (PHP_VERSION_ID >= 80000) {
+                foreach ($values as $property => $value) {
+                    if (! isset(self::$annotationMetadata[$name]['constructor_args'][$property])) {
+                        throw AnnotationException::creationError(sprintf(
+                            <<<'EXCEPTION'
+The annotation @%s declared on %s does not have a property named "%s"
+that can be set through its named arguments constructor.
+Available named arguments: %s
+EXCEPTION
+                            ,
+                            $originalName,
+                            $this->context,
+                            $property,
+                            implode(', ', array_keys(self::$annotationMetadata[$name]['constructor_args']))
+                        ));
+                    }
+                }
+
                 return $this->instantiateAnnotiation($originalName, $this->context, $name, $values);
                 return $this->instantiateAnnotiation($originalName, $this->context, $name, $values);
             }
             }
 
 
@@ -1166,9 +1187,7 @@ EXCEPTION
         return $this->getClassConstantPositionInIdentifier($identifier) === strlen($identifier) - strlen('::class');
         return $this->getClassConstantPositionInIdentifier($identifier) === strlen($identifier) - strlen('::class');
     }
     }
 
 
-    /**
-     * @return int|false
-     */
+    /** @return int|false */
     private function getClassConstantPositionInIdentifier(string $identifier)
     private function getClassConstantPositionInIdentifier(string $identifier)
     {
     {
         return stripos($identifier, '::class');
         return stripos($identifier, '::class');
@@ -1357,10 +1376,10 @@ EXCEPTION
      * KeyValuePair ::= Key ("=" | ":") PlainValue | Constant
      * KeyValuePair ::= Key ("=" | ":") PlainValue | Constant
      * Key ::= string | integer | Constant
      * Key ::= string | integer | Constant
      *
      *
+     * @phpstan-return array{mixed, mixed}
+     *
      * @throws AnnotationException
      * @throws AnnotationException
      * @throws ReflectionException
      * @throws ReflectionException
-     *
-     * @phpstan-return array{mixed, mixed}
      */
      */
     private function ArrayEntry(): array
     private function ArrayEntry(): array
     {
     {

+ 1 - 3
vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/TokenParser.php

@@ -46,9 +46,7 @@ class TokenParser
      */
      */
     private $pointer = 0;
     private $pointer = 0;
 
 
-    /**
-     * @param string $contents
-     */
+    /** @param string $contents */
     public function __construct($contents)
     public function __construct($contents)
     {
     {
         $this->tokens = token_get_all($contents);
         $this->tokens = token_get_all($contents);

+ 14 - 14
vendor/doctrine/dbal/README.md

@@ -1,11 +1,11 @@
 # Doctrine DBAL
 # Doctrine DBAL
 
 
-|                 [4.0-dev][4.0]                  |                     [3.3][3.3]                      |
+|                 [4.0-dev][4.0]                  |                     [3.6][3.6]                      |
 |:-----------------------------------------------:|:---------------------------------------------------:|
 |:-----------------------------------------------:|:---------------------------------------------------:|
-|    [![GitHub Actions][GA 4.0 image]][GA 4.0]    |      [![GitHub Actions][GA 3.3 image]][GA 3.3]      |
-| [![AppVeyor][AppVeyor 4.0 image]][AppVeyor 4.0] |   [![AppVeyor][AppVeyor 3.3 image]][AppVeyor 3.3]   |
-| [![Code Coverage][Coverage image]][CodeCov 4.0] | [![Code Coverage][Coverage 3.3 image]][CodeCov 3.3] |
-|                       N/A                       | [![Code Coverage][TypeCov 3.3 image]][TypeCov 3.3]  |
+|    [![GitHub Actions][GA 4.0 image]][GA 4.0]    |      [![GitHub Actions][GA 3.6 image]][GA 3.6]      |
+| [![AppVeyor][AppVeyor 4.0 image]][AppVeyor 4.0] |   [![AppVeyor][AppVeyor 3.6 image]][AppVeyor 3.6]   |
+| [![Code Coverage][Coverage image]][CodeCov 4.0] | [![Code Coverage][Coverage 3.6 image]][CodeCov 3.6] |
+|                       N/A                       | [![Type Coverage][TypeCov 3.6 image]][TypeCov 3.6]  |
 
 
 Powerful ***D***ata***B***ase ***A***bstraction ***L***ayer with many features for database schema introspection and schema management.
 Powerful ***D***ata***B***ase ***A***bstraction ***L***ayer with many features for database schema introspection and schema management.
 
 
@@ -23,12 +23,12 @@ Powerful ***D***ata***B***ase ***A***bstraction ***L***ayer with many features f
   [GA 4.0]: https://github.com/doctrine/dbal/actions?query=workflow%3A%22Continuous+Integration%22+branch%3A4.0.x
   [GA 4.0]: https://github.com/doctrine/dbal/actions?query=workflow%3A%22Continuous+Integration%22+branch%3A4.0.x
   [GA 4.0 image]: https://github.com/doctrine/dbal/workflows/Continuous%20Integration/badge.svg
   [GA 4.0 image]: https://github.com/doctrine/dbal/workflows/Continuous%20Integration/badge.svg
 
 
-  [Coverage 3.3 image]: https://codecov.io/gh/doctrine/dbal/branch/3.3.x/graph/badge.svg
-  [3.3]: https://github.com/doctrine/dbal/tree/3.3.x
-  [CodeCov 3.3]: https://codecov.io/gh/doctrine/dbal/branch/3.3.x
-  [AppVeyor 3.3]: https://ci.appveyor.com/project/doctrine/dbal/branch/3.3.x
-  [AppVeyor 3.3 image]: https://ci.appveyor.com/api/projects/status/i88kitq8qpbm0vie/branch/3.3.x?svg=true
-  [GA 3.3]: https://github.com/doctrine/dbal/actions?query=workflow%3A%22Continuous+Integration%22+branch%3A3.3.x
-  [GA 3.3 image]: https://github.com/doctrine/dbal/workflows/Continuous%20Integration/badge.svg?branch=3.3.x
-  [TypeCov 3.3]: https://shepherd.dev/github/doctrine/dbal
-  [TypeCov 3.3 image]: https://shepherd.dev/github/doctrine/dbal/coverage.svg
+  [Coverage 3.6 image]: https://codecov.io/gh/doctrine/dbal/branch/3.6.x/graph/badge.svg
+  [3.6]: https://github.com/doctrine/dbal/tree/3.6.x
+  [CodeCov 3.6]: https://codecov.io/gh/doctrine/dbal/branch/3.6.x
+  [AppVeyor 3.6]: https://ci.appveyor.com/project/doctrine/dbal/branch/3.6.x
+  [AppVeyor 3.6 image]: https://ci.appveyor.com/api/projects/status/i88kitq8qpbm0vie/branch/3.6.x?svg=true
+  [GA 3.6]: https://github.com/doctrine/dbal/actions?query=workflow%3A%22Continuous+Integration%22+branch%3A3.6.x
+  [GA 3.6 image]: https://github.com/doctrine/dbal/workflows/Continuous%20Integration/badge.svg?branch=3.6.x
+  [TypeCov 3.6]: https://shepherd.dev/github/doctrine/dbal
+  [TypeCov 3.6 image]: https://shepherd.dev/github/doctrine/dbal/coverage.svg

+ 2 - 2
vendor/doctrine/dbal/bin/doctrine-dbal.php

@@ -5,8 +5,8 @@ use Doctrine\DBAL\Tools\Console\ConsoleRunner;
 fwrite(
 fwrite(
     STDERR,
     STDERR,
     '[Warning] The use of this script is discouraged.'
     '[Warning] The use of this script is discouraged.'
-        . ' You find instructions on how to boostrap the console runner in our documentation.'
-        . PHP_EOL
+        . ' You find instructions on how to bootstrap the console runner in our documentation.'
+        . PHP_EOL,
 );
 );
 
 
 echo PHP_EOL . PHP_EOL;
 echo PHP_EOL . PHP_EOL;

+ 13 - 12
vendor/doctrine/dbal/composer.json

@@ -31,25 +31,26 @@
         {"name": "Jonathan Wage", "email": "jonwage@gmail.com"}
         {"name": "Jonathan Wage", "email": "jonwage@gmail.com"}
     ],
     ],
     "require": {
     "require": {
-        "php": "^7.3 || ^8.0",
+        "php": "^7.4 || ^8.0",
         "composer-runtime-api": "^2",
         "composer-runtime-api": "^2",
         "doctrine/cache": "^1.11|^2.0",
         "doctrine/cache": "^1.11|^2.0",
         "doctrine/deprecations": "^0.5.3|^1",
         "doctrine/deprecations": "^0.5.3|^1",
-        "doctrine/event-manager": "^1.0",
+        "doctrine/event-manager": "^1|^2",
         "psr/cache": "^1|^2|^3",
         "psr/cache": "^1|^2|^3",
         "psr/log": "^1|^2|^3"
         "psr/log": "^1|^2|^3"
     },
     },
     "require-dev": {
     "require-dev": {
-        "doctrine/coding-standard": "9.0.0",
-        "jetbrains/phpstorm-stubs": "2022.1",
-        "phpstan/phpstan": "1.7.13",
-        "phpstan/phpstan-strict-rules": "^1.2",
-        "phpunit/phpunit": "9.5.20",
-        "psalm/plugin-phpunit": "0.16.1",
-        "squizlabs/php_codesniffer": "3.7.0",
-        "symfony/cache": "^5.2|^6.0",
-        "symfony/console": "^2.7|^3.0|^4.0|^5.0|^6.0",
-        "vimeo/psalm": "4.23.0"
+        "doctrine/coding-standard": "12.0.0",
+        "fig/log-test": "^1",
+        "jetbrains/phpstorm-stubs": "2022.3",
+        "phpstan/phpstan": "1.10.14",
+        "phpstan/phpstan-strict-rules": "^1.5",
+        "phpunit/phpunit": "9.6.7",
+        "psalm/plugin-phpunit": "0.18.4",
+        "squizlabs/php_codesniffer": "3.7.2",
+        "symfony/cache": "^5.4|^6.0",
+        "symfony/console": "^4.4|^5.4|^6.0",
+        "vimeo/psalm": "4.30.0"
     },
     },
     "suggest": {
     "suggest": {
         "symfony/console": "For helpful console commands such as SQL execution and import of files."
         "symfony/console": "For helpful console commands such as SQL execution and import of files."

+ 37 - 0
vendor/doctrine/dbal/src/ArrayParameterType.php

@@ -0,0 +1,37 @@
+<?php
+
+namespace Doctrine\DBAL;
+
+final class ArrayParameterType
+{
+    /**
+     * Represents an array of ints to be expanded by Doctrine SQL parsing.
+     */
+    public const INTEGER = ParameterType::INTEGER + Connection::ARRAY_PARAM_OFFSET;
+
+    /**
+     * Represents an array of strings to be expanded by Doctrine SQL parsing.
+     */
+    public const STRING = ParameterType::STRING + Connection::ARRAY_PARAM_OFFSET;
+
+    /**
+     * Represents an array of ascii strings to be expanded by Doctrine SQL parsing.
+     */
+    public const ASCII = ParameterType::ASCII + Connection::ARRAY_PARAM_OFFSET;
+
+    /**
+     * @internal
+     *
+     * @psalm-param self::INTEGER|self::STRING|self::ASCII $type
+     *
+     * @psalm-return ParameterType::INTEGER|ParameterType::STRING|ParameterType::ASCII
+     */
+    public static function toElementParameterType(int $type): int
+    {
+        return $type - Connection::ARRAY_PARAM_OFFSET;
+    }
+
+    private function __construct()
+    {
+    }
+}

+ 1 - 3
vendor/doctrine/dbal/src/ArrayParameters/Exception.php

@@ -4,9 +4,7 @@ namespace Doctrine\DBAL\ArrayParameters;
 
 
 use Throwable;
 use Throwable;
 
 
-/**
- * @internal
- */
+/** @internal */
 interface Exception extends Throwable
 interface Exception extends Throwable
 {
 {
 }
 }

+ 2 - 4
vendor/doctrine/dbal/src/ArrayParameters/Exception/MissingNamedParameter.php

@@ -7,15 +7,13 @@ use LogicException;
 
 
 use function sprintf;
 use function sprintf;
 
 
-/**
- * @psalm-immutable
- */
+/** @psalm-immutable */
 class MissingNamedParameter extends LogicException implements Exception
 class MissingNamedParameter extends LogicException implements Exception
 {
 {
     public static function new(string $name): self
     public static function new(string $name): self
     {
     {
         return new self(
         return new self(
-            sprintf('Named parameter "%s" does not have a bound value.', $name)
+            sprintf('Named parameter "%s" does not have a bound value.', $name),
         );
         );
     }
     }
 }
 }

+ 1 - 1
vendor/doctrine/dbal/src/ArrayParameters/Exception/MissingPositionalParameter.php

@@ -17,7 +17,7 @@ class MissingPositionalParameter extends LogicException implements Exception
     public static function new(int $index): self
     public static function new(int $index): self
     {
     {
         return new self(
         return new self(
-            sprintf('Positional parameter at index %d does not have a bound value.', $index)
+            sprintf('Positional parameter at index %d does not have a bound value.', $index),
         );
         );
     }
     }
 }
 }

+ 12 - 21
vendor/doctrine/dbal/src/Cache/ArrayResult.php

@@ -9,23 +9,16 @@ use function array_values;
 use function count;
 use function count;
 use function reset;
 use function reset;
 
 
-/**
- * @internal The class is internal to the caching layer implementation.
- */
+/** @internal The class is internal to the caching layer implementation. */
 final class ArrayResult implements Result
 final class ArrayResult implements Result
 {
 {
     /** @var list<array<string, mixed>> */
     /** @var list<array<string, mixed>> */
-    private $data;
+    private array $data;
 
 
-    /** @var int */
-    private $columnCount = 0;
+    private int $columnCount = 0;
+    private int $num         = 0;
 
 
-    /** @var int */
-    private $num = 0;
-
-    /**
-     * @param list<array<string, mixed>> $data
-     */
+    /** @param list<array<string, mixed>> $data */
     public function __construct(array $data)
     public function __construct(array $data)
     {
     {
         $this->data = $data;
         $this->data = $data;
@@ -37,7 +30,7 @@ final class ArrayResult implements Result
     }
     }
 
 
     /**
     /**
-     * {@inheritdoc}
+     * {@inheritDoc}
      */
      */
     public function fetchNumeric()
     public function fetchNumeric()
     {
     {
@@ -51,7 +44,7 @@ final class ArrayResult implements Result
     }
     }
 
 
     /**
     /**
-     * {@inheritdoc}
+     * {@inheritDoc}
      */
      */
     public function fetchAssociative()
     public function fetchAssociative()
     {
     {
@@ -59,7 +52,7 @@ final class ArrayResult implements Result
     }
     }
 
 
     /**
     /**
-     * {@inheritdoc}
+     * {@inheritDoc}
      */
      */
     public function fetchOne()
     public function fetchOne()
     {
     {
@@ -73,7 +66,7 @@ final class ArrayResult implements Result
     }
     }
 
 
     /**
     /**
-     * {@inheritdoc}
+     * {@inheritDoc}
      */
      */
     public function fetchAllNumeric(): array
     public function fetchAllNumeric(): array
     {
     {
@@ -81,7 +74,7 @@ final class ArrayResult implements Result
     }
     }
 
 
     /**
     /**
-     * {@inheritdoc}
+     * {@inheritDoc}
      */
      */
     public function fetchAllAssociative(): array
     public function fetchAllAssociative(): array
     {
     {
@@ -89,7 +82,7 @@ final class ArrayResult implements Result
     }
     }
 
 
     /**
     /**
-     * {@inheritdoc}
+     * {@inheritDoc}
      */
      */
     public function fetchFirstColumn(): array
     public function fetchFirstColumn(): array
     {
     {
@@ -111,9 +104,7 @@ final class ArrayResult implements Result
         $this->data = [];
         $this->data = [];
     }
     }
 
 
-    /**
-     * @return array<string, mixed>|false
-     */
+    /** @return array<string, mixed>|false */
     private function fetch()
     private function fetch()
     {
     {
         if (! isset($this->data[$this->num])) {
         if (! isset($this->data[$this->num])) {

+ 3 - 9
vendor/doctrine/dbal/src/Cache/CacheException.php

@@ -4,22 +4,16 @@ namespace Doctrine\DBAL\Cache;
 
 
 use Doctrine\DBAL\Exception;
 use Doctrine\DBAL\Exception;
 
 
-/**
- * @psalm-immutable
- */
+/** @psalm-immutable */
 class CacheException extends Exception
 class CacheException extends Exception
 {
 {
-    /**
-     * @return CacheException
-     */
+    /** @return CacheException */
     public static function noCacheKey()
     public static function noCacheKey()
     {
     {
         return new self('No cache key was set.');
         return new self('No cache key was set.');
     }
     }
 
 
-    /**
-     * @return CacheException
-     */
+    /** @return CacheException */
     public static function noResultDriverConfigured()
     public static function noResultDriverConfigured()
     {
     {
         return new self('Trying to cache a query but no result driver is configured.');
         return new self('Trying to cache a query but no result driver is configured.');

+ 8 - 15
vendor/doctrine/dbal/src/Cache/QueryCacheProfile.php

@@ -23,8 +23,7 @@ use function sprintf;
  */
  */
 class QueryCacheProfile
 class QueryCacheProfile
 {
 {
-    /** @var CacheItemPoolInterface|null */
-    private $resultCache;
+    private ?CacheItemPoolInterface $resultCache = null;
 
 
     /** @var int */
     /** @var int */
     private $lifetime;
     private $lifetime;
@@ -50,7 +49,7 @@ class QueryCacheProfile
                 'Passing an instance of %s to %s as $resultCache is deprecated. Pass an instance of %s instead.',
                 'Passing an instance of %s to %s as $resultCache is deprecated. Pass an instance of %s instead.',
                 Cache::class,
                 Cache::class,
                 __METHOD__,
                 __METHOD__,
-                CacheItemPoolInterface::class
+                CacheItemPoolInterface::class,
             );
             );
 
 
             $this->resultCache = CacheAdapter::wrap($resultCache);
             $this->resultCache = CacheAdapter::wrap($resultCache);
@@ -59,7 +58,7 @@ class QueryCacheProfile
                 '$resultCache: Expected either null or an instance of %s or %s, got %s.',
                 '$resultCache: Expected either null or an instance of %s or %s, got %s.',
                 CacheItemPoolInterface::class,
                 CacheItemPoolInterface::class,
                 Cache::class,
                 Cache::class,
-                get_class($resultCache)
+                get_class($resultCache),
             ));
             ));
         }
         }
     }
     }
@@ -80,15 +79,13 @@ class QueryCacheProfile
             'doctrine/dbal',
             'doctrine/dbal',
             'https://github.com/doctrine/dbal/pull/4620',
             'https://github.com/doctrine/dbal/pull/4620',
             '%s is deprecated, call getResultCache() instead.',
             '%s is deprecated, call getResultCache() instead.',
-            __METHOD__
+            __METHOD__,
         );
         );
 
 
         return $this->resultCache !== null ? DoctrineProvider::wrap($this->resultCache) : null;
         return $this->resultCache !== null ? DoctrineProvider::wrap($this->resultCache) : null;
     }
     }
 
 
-    /**
-     * @return int
-     */
+    /** @return int */
     public function getLifetime()
     public function getLifetime()
     {
     {
         return $this->lifetime;
         return $this->lifetime;
@@ -116,7 +113,7 @@ class QueryCacheProfile
      * @param array<int, Type|int|string|null>|array<string, Type|int|string|null> $types
      * @param array<int, Type|int|string|null>|array<string, Type|int|string|null> $types
      * @param array<string, mixed>                                                 $connectionParams
      * @param array<string, mixed>                                                 $connectionParams
      *
      *
-     * @return string[]
+     * @return array{string, string}
      */
      */
     public function generateCacheKeys($sql, $params, $types, array $connectionParams = [])
     public function generateCacheKeys($sql, $params, $types, array $connectionParams = [])
     {
     {
@@ -130,11 +127,7 @@ class QueryCacheProfile
             '&connectionParams=' . hash('sha256', serialize($connectionParams));
             '&connectionParams=' . hash('sha256', serialize($connectionParams));
 
 
         // should the key be automatically generated using the inputs or is the cache key set?
         // should the key be automatically generated using the inputs or is the cache key set?
-        if ($this->cacheKey === null) {
-            $cacheKey = sha1($realCacheKey);
-        } else {
-            $cacheKey = $this->cacheKey;
-        }
+        $cacheKey = $this->cacheKey ?? sha1($realCacheKey);
 
 
         return [$cacheKey, $realCacheKey];
         return [$cacheKey, $realCacheKey];
     }
     }
@@ -155,7 +148,7 @@ class QueryCacheProfile
             'doctrine/dbal',
             'doctrine/dbal',
             'https://github.com/doctrine/dbal/pull/4620',
             'https://github.com/doctrine/dbal/pull/4620',
             '%s is deprecated, call setResultCache() instead.',
             '%s is deprecated, call setResultCache() instead.',
-            __METHOD__
+            __METHOD__,
         );
         );
 
 
         return new QueryCacheProfile($this->lifetime, $this->cacheKey, CacheAdapter::wrap($cache));
         return new QueryCacheProfile($this->lifetime, $this->cacheKey, CacheAdapter::wrap($cache));

+ 64 - 9
vendor/doctrine/dbal/src/Configuration.php

@@ -7,16 +7,19 @@ use Doctrine\Common\Cache\Psr6\CacheAdapter;
 use Doctrine\Common\Cache\Psr6\DoctrineProvider;
 use Doctrine\Common\Cache\Psr6\DoctrineProvider;
 use Doctrine\DBAL\Driver\Middleware;
 use Doctrine\DBAL\Driver\Middleware;
 use Doctrine\DBAL\Logging\SQLLogger;
 use Doctrine\DBAL\Logging\SQLLogger;
+use Doctrine\DBAL\Schema\SchemaManagerFactory;
 use Doctrine\Deprecations\Deprecation;
 use Doctrine\Deprecations\Deprecation;
 use Psr\Cache\CacheItemPoolInterface;
 use Psr\Cache\CacheItemPoolInterface;
 
 
+use function func_num_args;
+
 /**
 /**
  * Configuration container for the Doctrine DBAL.
  * Configuration container for the Doctrine DBAL.
  */
  */
 class Configuration
 class Configuration
 {
 {
     /** @var Middleware[] */
     /** @var Middleware[] */
-    private $middlewares = [];
+    private array $middlewares = [];
 
 
     /**
     /**
      * The SQL logger in use. If null, SQL logging is disabled.
      * The SQL logger in use. If null, SQL logging is disabled.
@@ -27,10 +30,8 @@ class Configuration
 
 
     /**
     /**
      * The cache driver implementation that is used for query result caching.
      * The cache driver implementation that is used for query result caching.
-     *
-     * @var CacheItemPoolInterface|null
      */
      */
-    private $resultCache;
+    private ?CacheItemPoolInterface $resultCache = null;
 
 
     /**
     /**
      * The cache driver implementation that is used for query result caching.
      * The cache driver implementation that is used for query result caching.
@@ -55,19 +56,46 @@ class Configuration
      */
      */
     protected $autoCommit = true;
     protected $autoCommit = true;
 
 
+    private ?SchemaManagerFactory $schemaManagerFactory = null;
+
+    public function __construct()
+    {
+        $this->schemaAssetsFilter = static function (): bool {
+            return true;
+        };
+    }
+
     /**
     /**
      * Sets the SQL logger to use. Defaults to NULL which means SQL logging is disabled.
      * Sets the SQL logger to use. Defaults to NULL which means SQL logging is disabled.
+     *
+     * @deprecated Use {@see setMiddlewares()} and {@see \Doctrine\DBAL\Logging\Middleware} instead.
      */
      */
     public function setSQLLogger(?SQLLogger $logger = null): void
     public function setSQLLogger(?SQLLogger $logger = null): void
     {
     {
+        Deprecation::trigger(
+            'doctrine/dbal',
+            'https://github.com/doctrine/dbal/pull/4967',
+            '%s is deprecated, use setMiddlewares() and Logging\\Middleware instead.',
+            __METHOD__,
+        );
+
         $this->sqlLogger = $logger;
         $this->sqlLogger = $logger;
     }
     }
 
 
     /**
     /**
      * Gets the SQL logger that is used.
      * Gets the SQL logger that is used.
+     *
+     * @deprecated
      */
      */
     public function getSQLLogger(): ?SQLLogger
     public function getSQLLogger(): ?SQLLogger
     {
     {
+        Deprecation::triggerIfCalledFromOutside(
+            'doctrine/dbal',
+            'https://github.com/doctrine/dbal/pull/4967',
+            '%s is deprecated.',
+            __METHOD__,
+        );
+
         return $this->sqlLogger;
         return $this->sqlLogger;
     }
     }
 
 
@@ -90,7 +118,7 @@ class Configuration
             'doctrine/dbal',
             'doctrine/dbal',
             'https://github.com/doctrine/dbal/pull/4620',
             'https://github.com/doctrine/dbal/pull/4620',
             '%s is deprecated, call getResultCache() instead.',
             '%s is deprecated, call getResultCache() instead.',
-            __METHOD__
+            __METHOD__,
         );
         );
 
 
         return $this->resultCacheImpl;
         return $this->resultCacheImpl;
@@ -116,7 +144,7 @@ class Configuration
             'doctrine/dbal',
             'doctrine/dbal',
             'https://github.com/doctrine/dbal/pull/4620',
             'https://github.com/doctrine/dbal/pull/4620',
             '%s is deprecated, call setResultCache() instead.',
             '%s is deprecated, call setResultCache() instead.',
-            __METHOD__
+            __METHOD__,
         );
         );
 
 
         $this->resultCacheImpl = $cacheImpl;
         $this->resultCacheImpl = $cacheImpl;
@@ -128,6 +156,22 @@ class Configuration
      */
      */
     public function setSchemaAssetsFilter(?callable $callable = null): void
     public function setSchemaAssetsFilter(?callable $callable = null): void
     {
     {
+        if (func_num_args() < 1) {
+            Deprecation::trigger(
+                'doctrine/dbal',
+                'https://github.com/doctrine/dbal/pull/5483',
+                'Not passing an argument to %s is deprecated.',
+                __METHOD__,
+            );
+        } elseif ($callable === null) {
+            Deprecation::trigger(
+                'doctrine/dbal',
+                'https://github.com/doctrine/dbal/pull/5483',
+                'Using NULL as a schema asset filter is deprecated.'
+                    . ' Use a callable that always returns true instead.',
+            );
+        }
+
         $this->schemaAssetsFilter = $callable;
         $this->schemaAssetsFilter = $callable;
     }
     }
 
 
@@ -179,11 +223,22 @@ class Configuration
         return $this;
         return $this;
     }
     }
 
 
-    /**
-     * @return Middleware[]
-     */
+    /** @return Middleware[] */
     public function getMiddlewares(): array
     public function getMiddlewares(): array
     {
     {
         return $this->middlewares;
         return $this->middlewares;
     }
     }
+
+    public function getSchemaManagerFactory(): ?SchemaManagerFactory
+    {
+        return $this->schemaManagerFactory;
+    }
+
+    /** @return $this */
+    public function setSchemaManagerFactory(SchemaManagerFactory $schemaManagerFactory): self
+    {
+        $this->schemaManagerFactory = $schemaManagerFactory;
+
+        return $this;
+    }
 }
 }

+ 248 - 127
vendor/doctrine/dbal/src/Connection.php

@@ -21,13 +21,18 @@ use Doctrine\DBAL\Platforms\AbstractPlatform;
 use Doctrine\DBAL\Query\Expression\ExpressionBuilder;
 use Doctrine\DBAL\Query\Expression\ExpressionBuilder;
 use Doctrine\DBAL\Query\QueryBuilder;
 use Doctrine\DBAL\Query\QueryBuilder;
 use Doctrine\DBAL\Schema\AbstractSchemaManager;
 use Doctrine\DBAL\Schema\AbstractSchemaManager;
+use Doctrine\DBAL\Schema\DefaultSchemaManagerFactory;
+use Doctrine\DBAL\Schema\LegacySchemaManagerFactory;
+use Doctrine\DBAL\Schema\SchemaManagerFactory;
 use Doctrine\DBAL\SQL\Parser;
 use Doctrine\DBAL\SQL\Parser;
 use Doctrine\DBAL\Types\Type;
 use Doctrine\DBAL\Types\Type;
 use Doctrine\Deprecations\Deprecation;
 use Doctrine\Deprecations\Deprecation;
 use LogicException;
 use LogicException;
+use SensitiveParameter;
 use Throwable;
 use Throwable;
 use Traversable;
 use Traversable;
 
 
+use function array_key_exists;
 use function assert;
 use function assert;
 use function count;
 use function count;
 use function get_class;
 use function get_class;
@@ -49,35 +54,47 @@ class Connection
 {
 {
     /**
     /**
      * Represents an array of ints to be expanded by Doctrine SQL parsing.
      * Represents an array of ints to be expanded by Doctrine SQL parsing.
+     *
+     * @deprecated Use {@see ArrayParameterType::INTEGER} instead.
      */
      */
-    public const PARAM_INT_ARRAY = ParameterType::INTEGER + self::ARRAY_PARAM_OFFSET;
+    public const PARAM_INT_ARRAY = ArrayParameterType::INTEGER;
 
 
     /**
     /**
      * Represents an array of strings to be expanded by Doctrine SQL parsing.
      * Represents an array of strings to be expanded by Doctrine SQL parsing.
+     *
+     * @deprecated Use {@see ArrayParameterType::STRING} instead.
      */
      */
-    public const PARAM_STR_ARRAY = ParameterType::STRING + self::ARRAY_PARAM_OFFSET;
+    public const PARAM_STR_ARRAY = ArrayParameterType::STRING;
 
 
     /**
     /**
      * Represents an array of ascii strings to be expanded by Doctrine SQL parsing.
      * Represents an array of ascii strings to be expanded by Doctrine SQL parsing.
+     *
+     * @deprecated Use {@see ArrayParameterType::ASCII} instead.
      */
      */
-    public const PARAM_ASCII_STR_ARRAY = ParameterType::ASCII + self::ARRAY_PARAM_OFFSET;
+    public const PARAM_ASCII_STR_ARRAY = ArrayParameterType::ASCII;
 
 
     /**
     /**
      * Offset by which PARAM_* constants are detected as arrays of the param type.
      * Offset by which PARAM_* constants are detected as arrays of the param type.
+     *
+     * @internal Should be used only within the wrapper layer.
      */
      */
     public const ARRAY_PARAM_OFFSET = 100;
     public const ARRAY_PARAM_OFFSET = 100;
 
 
     /**
     /**
      * The wrapped driver connection.
      * The wrapped driver connection.
      *
      *
-     * @var \Doctrine\DBAL\Driver\Connection|null
+     * @var DriverConnection|null
      */
      */
     protected $_conn;
     protected $_conn;
 
 
     /** @var Configuration */
     /** @var Configuration */
     protected $_config;
     protected $_config;
 
 
-    /** @var EventManager */
+    /**
+     * @deprecated
+     *
+     * @var EventManager
+     */
     protected $_eventManager;
     protected $_eventManager;
 
 
     /**
     /**
@@ -89,31 +106,25 @@ class Connection
 
 
     /**
     /**
      * The current auto-commit mode of this connection.
      * The current auto-commit mode of this connection.
-     *
-     * @var bool
      */
      */
-    private $autoCommit = true;
+    private bool $autoCommit = true;
 
 
     /**
     /**
      * The transaction nesting level.
      * The transaction nesting level.
-     *
-     * @var int
      */
      */
-    private $transactionNestingLevel = 0;
+    private int $transactionNestingLevel = 0;
 
 
     /**
     /**
      * The currently active transaction isolation level or NULL before it has been determined.
      * The currently active transaction isolation level or NULL before it has been determined.
      *
      *
-     * @var int|null
+     * @var TransactionIsolationLevel::*|null
      */
      */
     private $transactionIsolationLevel;
     private $transactionIsolationLevel;
 
 
     /**
     /**
      * If nested transactions should use savepoints.
      * If nested transactions should use savepoints.
-     *
-     * @var bool
      */
      */
-    private $nestTransactionsWithSavepoints = false;
+    private bool $nestTransactionsWithSavepoints = false;
 
 
     /**
     /**
      * The parameters used during creation of the Connection instance.
      * The parameters used during creation of the Connection instance.
@@ -121,20 +132,15 @@ class Connection
      * @var array<string,mixed>
      * @var array<string,mixed>
      * @psalm-var Params
      * @psalm-var Params
      */
      */
-    private $params;
+    private array $params;
 
 
     /**
     /**
      * The database platform object used by the connection or NULL before it's initialized.
      * The database platform object used by the connection or NULL before it's initialized.
-     *
-     * @var AbstractPlatform|null
      */
      */
-    private $platform;
-
-    /** @var ExceptionConverter|null */
-    private $exceptionConverter;
+    private ?AbstractPlatform $platform = null;
 
 
-    /** @var Parser|null */
-    private $parser;
+    private ?ExceptionConverter $exceptionConverter = null;
+    private ?Parser $parser                         = null;
 
 
     /**
     /**
      * The schema manager.
      * The schema manager.
@@ -154,10 +160,10 @@ class Connection
 
 
     /**
     /**
      * Flag that indicates whether the current transaction is marked for rollback only.
      * Flag that indicates whether the current transaction is marked for rollback only.
-     *
-     * @var bool
      */
      */
-    private $isRollbackOnly = false;
+    private bool $isRollbackOnly = false;
+
+    private SchemaManagerFactory $schemaManagerFactory;
 
 
     /**
     /**
      * Initializes a new instance of the Connection class.
      * Initializes a new instance of the Connection class.
@@ -169,11 +175,11 @@ class Connection
      * @param Configuration|null  $config       The configuration, optional.
      * @param Configuration|null  $config       The configuration, optional.
      * @param EventManager|null   $eventManager The event manager, optional.
      * @param EventManager|null   $eventManager The event manager, optional.
      * @psalm-param Params $params
      * @psalm-param Params $params
-     * @phpstan-param array<string,mixed> $params
      *
      *
      * @throws Exception
      * @throws Exception
      */
      */
     public function __construct(
     public function __construct(
+        #[SensitiveParameter]
         array $params,
         array $params,
         Driver $driver,
         Driver $driver,
         ?Configuration $config = null,
         ?Configuration $config = null,
@@ -183,13 +189,8 @@ class Connection
         $this->params  = $params;
         $this->params  = $params;
 
 
         // Create default config and event manager if none given
         // Create default config and event manager if none given
-        if ($config === null) {
-            $config = new Configuration();
-        }
-
-        if ($eventManager === null) {
-            $eventManager = new EventManager();
-        }
+        $config       ??= new Configuration();
+        $eventManager ??= new EventManager();
 
 
         $this->_config       = $config;
         $this->_config       = $config;
         $this->_eventManager = $eventManager;
         $this->_eventManager = $eventManager;
@@ -199,6 +200,13 @@ class Connection
                 throw Exception::invalidPlatformType($params['platform']);
                 throw Exception::invalidPlatformType($params['platform']);
             }
             }
 
 
+            Deprecation::trigger(
+                'doctrine/dbal',
+                'https://github.com/doctrine/dbal/pull/5699',
+                'The "platform" connection parameter is deprecated.'
+                    . ' Use a driver middleware that would instantiate the platform instead.',
+            );
+
             $this->platform = $params['platform'];
             $this->platform = $params['platform'];
             $this->platform->setEventManager($this->_eventManager);
             $this->platform->setEventManager($this->_eventManager);
         }
         }
@@ -206,6 +214,21 @@ class Connection
         $this->_expr = $this->createExpressionBuilder();
         $this->_expr = $this->createExpressionBuilder();
 
 
         $this->autoCommit = $config->getAutoCommit();
         $this->autoCommit = $config->getAutoCommit();
+
+        $schemaManagerFactory = $config->getSchemaManagerFactory();
+        if ($schemaManagerFactory === null) {
+            Deprecation::trigger(
+                'doctrine/dbal',
+                'https://github.com/doctrine/dbal/issues/5812',
+                'Not configuring a schema manager factory is deprecated.'
+                    . ' Use %s which is going to be the default in DBAL 4.',
+                DefaultSchemaManagerFactory::class,
+            );
+
+            $schemaManagerFactory = new LegacySchemaManagerFactory();
+        }
+
+        $this->schemaManagerFactory = $schemaManagerFactory;
     }
     }
 
 
     /**
     /**
@@ -264,10 +287,19 @@ class Connection
     /**
     /**
      * Gets the EventManager used by the Connection.
      * Gets the EventManager used by the Connection.
      *
      *
+     * @deprecated
+     *
      * @return EventManager
      * @return EventManager
      */
      */
     public function getEventManager()
     public function getEventManager()
     {
     {
+        Deprecation::triggerIfCalledFromOutside(
+            'doctrine/dbal',
+            'https://github.com/doctrine/dbal/issues/5784',
+            '%s is deprecated.',
+            __METHOD__,
+        );
+
         return $this->_eventManager;
         return $this->_eventManager;
     }
     }
 
 
@@ -309,7 +341,7 @@ class Connection
             'doctrine/dbal',
             'doctrine/dbal',
             'https://github.com/doctrine/dbal/issues/4515',
             'https://github.com/doctrine/dbal/issues/4515',
             'Connection::getExpressionBuilder() is deprecated,'
             'Connection::getExpressionBuilder() is deprecated,'
-                . ' use Connection::createExpressionBuilder() instead.'
+                . ' use Connection::createExpressionBuilder() instead.',
         );
         );
 
 
         return $this->_expr;
         return $this->_expr;
@@ -324,13 +356,15 @@ class Connection
      *              the connection is already open.
      *              the connection is already open.
      *
      *
      * @throws Exception
      * @throws Exception
+     *
+     * @psalm-assert !null $this->_conn
      */
      */
     public function connect()
     public function connect()
     {
     {
         Deprecation::triggerIfCalledFromOutside(
         Deprecation::triggerIfCalledFromOutside(
             'doctrine/dbal',
             'doctrine/dbal',
             'https://github.com/doctrine/dbal/issues/4966',
             'https://github.com/doctrine/dbal/issues/4966',
-            'Public access to Connection::connect() is deprecated.'
+            'Public access to Connection::connect() is deprecated.',
         );
         );
 
 
         if ($this->_conn !== null) {
         if ($this->_conn !== null) {
@@ -348,6 +382,13 @@ class Connection
         }
         }
 
 
         if ($this->_eventManager->hasListeners(Events::postConnect)) {
         if ($this->_eventManager->hasListeners(Events::postConnect)) {
+            Deprecation::trigger(
+                'doctrine/dbal',
+                'https://github.com/doctrine/dbal/issues/5784',
+                'Subscribing to %s events is deprecated. Implement a middleware instead.',
+                Events::postConnect,
+            );
+
             $eventArgs = new Event\ConnectionEventArgs($this);
             $eventArgs = new Event\ConnectionEventArgs($this);
             $this->_eventManager->dispatchEvent(Events::postConnect, $eventArgs);
             $this->_eventManager->dispatchEvent(Events::postConnect, $eventArgs);
         }
         }
@@ -399,6 +440,10 @@ class Connection
             return $this->params['serverVersion'];
             return $this->params['serverVersion'];
         }
         }
 
 
+        if (isset($this->params['primary']) && isset($this->params['primary']['serverVersion'])) {
+            return $this->params['primary']['serverVersion'];
+        }
+
         // If not connected, we need to connect now to determine the platform version.
         // If not connected, we need to connect now to determine the platform version.
         if ($this->_conn === null) {
         if ($this->_conn === null) {
             try {
             try {
@@ -408,6 +453,15 @@ class Connection
                     throw $originalException;
                     throw $originalException;
                 }
                 }
 
 
+                Deprecation::trigger(
+                    'doctrine/dbal',
+                    'https://github.com/doctrine/dbal/pull/5707',
+                    'Relying on a fallback connection used to determine the database platform while connecting'
+                        . ' to a non-existing database is deprecated. Either use an existing database name in'
+                        . ' connection parameters or omit the database name if the platform'
+                        . ' and the server configuration allow that.',
+                );
+
                 // The database to connect to might not yet exist.
                 // The database to connect to might not yet exist.
                 // Retry detection without database name connection parameter.
                 // Retry detection without database name connection parameter.
                 $params = $this->params;
                 $params = $this->params;
@@ -458,9 +512,9 @@ class Connection
 
 
         Deprecation::trigger(
         Deprecation::trigger(
             'doctrine/dbal',
             'doctrine/dbal',
-            'https://github.com/doctrine/dbal/pulls/4750',
+            'https://github.com/doctrine/dbal/pull/4750',
             'Not implementing the ServerInfoAwareConnection interface in %s is deprecated',
             'Not implementing the ServerInfoAwareConnection interface in %s is deprecated',
-            get_class($connection)
+            get_class($connection),
         );
         );
 
 
         // Unable to detect platform version.
         // Unable to detect platform version.
@@ -641,7 +695,7 @@ class Connection
         return $this->executeStatement(
         return $this->executeStatement(
             'DELETE FROM ' . $table . ' WHERE ' . implode(' AND ', $conditions),
             'DELETE FROM ' . $table . ' WHERE ' . implode(' AND ', $conditions),
             $values,
             $values,
-            is_string(key($types)) ? $this->extractTypeValues($columns, $types) : $types
+            is_string(key($types)) ? $this->extractTypeValues($columns, $types) : $types,
         );
         );
     }
     }
 
 
@@ -659,7 +713,7 @@ class Connection
     /**
     /**
      * Sets the transaction isolation level.
      * Sets the transaction isolation level.
      *
      *
-     * @param int $level The level to set.
+     * @param TransactionIsolationLevel::* $level The level to set.
      *
      *
      * @return int|string
      * @return int|string
      *
      *
@@ -675,17 +729,13 @@ class Connection
     /**
     /**
      * Gets the currently active transaction isolation level.
      * Gets the currently active transaction isolation level.
      *
      *
-     * @return int The current transaction isolation level.
+     * @return TransactionIsolationLevel::* The current transaction isolation level.
      *
      *
      * @throws Exception
      * @throws Exception
      */
      */
     public function getTransactionIsolation()
     public function getTransactionIsolation()
     {
     {
-        if ($this->transactionIsolationLevel === null) {
-            $this->transactionIsolationLevel = $this->getDatabasePlatform()->getDefaultTransactionIsolationLevel();
-        }
-
-        return $this->transactionIsolationLevel;
+        return $this->transactionIsolationLevel ??= $this->getDatabasePlatform()->getDefaultTransactionIsolationLevel();
     }
     }
 
 
     /**
     /**
@@ -757,7 +807,7 @@ class Connection
             'INSERT INTO ' . $table . ' (' . implode(', ', $columns) . ')' .
             'INSERT INTO ' . $table . ' (' . implode(', ', $columns) . ')' .
             ' VALUES (' . implode(', ', $set) . ')',
             ' VALUES (' . implode(', ', $set) . ')',
             $values,
             $values,
-            is_string(key($types)) ? $this->extractTypeValues($columns, $types) : $types
+            is_string(key($types)) ? $this->extractTypeValues($columns, $types) : $types,
         );
         );
     }
     }
 
 
@@ -1005,7 +1055,7 @@ class Connection
     }
     }
 
 
     /**
     /**
-     * Executes an, optionally parametrized, SQL query.
+     * Executes an, optionally parameterized, SQL query.
      *
      *
      * If the query is parametrized, a prepared statement is used.
      * If the query is parametrized, a prepared statement is used.
      * If an SQLLogger is configured, the execution is logged.
      * If an SQLLogger is configured, the execution is logged.
@@ -1040,12 +1090,10 @@ class Connection
                 }
                 }
 
 
                 $stmt = $connection->prepare($sql);
                 $stmt = $connection->prepare($sql);
-                if (count($types) > 0) {
-                    $this->_bindTypedValues($stmt, $params, $types);
-                    $result = $stmt->execute();
-                } else {
-                    $result = $stmt->execute($params);
-                }
+
+                $this->bindParameters($stmt, $params, $types);
+
+                $result = $stmt->execute();
             } else {
             } else {
                 $result = $connection->query($sql);
                 $result = $connection->query($sql);
             }
             }
@@ -1079,7 +1127,7 @@ class Connection
         }
         }
 
 
         $connectionParams = $this->params;
         $connectionParams = $this->params;
-        unset($connectionParams['platform']);
+        unset($connectionParams['platform'], $connectionParams['password'], $connectionParams['url']);
 
 
         [$cacheKey, $realKey] = $qcp->generateCacheKeys($sql, $params, $types, $connectionParams);
         [$cacheKey, $realKey] = $qcp->generateCacheKeys($sql, $params, $types, $connectionParams);
 
 
@@ -1147,15 +1195,10 @@ class Connection
 
 
                 $stmt = $connection->prepare($sql);
                 $stmt = $connection->prepare($sql);
 
 
-                if (count($types) > 0) {
-                    $this->_bindTypedValues($stmt, $params, $types);
-
-                    $result = $stmt->execute();
-                } else {
-                    $result = $stmt->execute($params);
-                }
+                $this->bindParameters($stmt, $params, $types);
 
 
-                return $result->rowCount();
+                return $stmt->execute()
+                    ->rowCount();
             }
             }
 
 
             return $connection->exec($sql);
             return $connection->exec($sql);
@@ -1198,7 +1241,7 @@ class Connection
             Deprecation::trigger(
             Deprecation::trigger(
                 'doctrine/dbal',
                 'doctrine/dbal',
                 'https://github.com/doctrine/dbal/issues/4687',
                 'https://github.com/doctrine/dbal/issues/4687',
-                'The usage of Connection::lastInsertId() with a sequence name is deprecated.'
+                'The usage of Connection::lastInsertId() with a sequence name is deprecated.',
             );
             );
         }
         }
 
 
@@ -1217,11 +1260,13 @@ class Connection
      * If an exception occurs during execution of the function or transaction commit,
      * If an exception occurs during execution of the function or transaction commit,
      * the transaction is rolled back and the exception re-thrown.
      * the transaction is rolled back and the exception re-thrown.
      *
      *
-     * @param Closure $func The function to execute transactionally.
+     * @param Closure(self):T $func The function to execute transactionally.
      *
      *
-     * @return mixed The value returned by $func
+     * @return T The value returned by $func
      *
      *
      * @throws Throwable
      * @throws Throwable
+     *
+     * @template T
      */
      */
     public function transactional(Closure $func)
     public function transactional(Closure $func)
     {
     {
@@ -1249,6 +1294,18 @@ class Connection
      */
      */
     public function setNestTransactionsWithSavepoints($nestTransactionsWithSavepoints)
     public function setNestTransactionsWithSavepoints($nestTransactionsWithSavepoints)
     {
     {
+        if (! $nestTransactionsWithSavepoints) {
+            Deprecation::trigger(
+                'doctrine/dbal',
+                'https://github.com/doctrine/dbal/pull/5383',
+                <<<'DEPRECATION'
+                Nesting transactions without enabling savepoints is deprecated.
+                Call %s::setNestTransactionsWithSavepoints(true) to enable savepoints.
+                DEPRECATION,
+                self::class,
+            );
+        }
+
         if ($this->transactionNestingLevel > 0) {
         if ($this->transactionNestingLevel > 0) {
             throw ConnectionException::mayNotAlterNestedTransactionWithSavepointsInTransaction();
             throw ConnectionException::mayNotAlterNestedTransactionWithSavepointsInTransaction();
         }
         }
@@ -1312,9 +1369,30 @@ class Connection
             if ($logger !== null) {
             if ($logger !== null) {
                 $logger->stopQuery();
                 $logger->stopQuery();
             }
             }
+        } else {
+            Deprecation::trigger(
+                'doctrine/dbal',
+                'https://github.com/doctrine/dbal/pull/5383',
+                <<<'DEPRECATION'
+                Nesting transactions without enabling savepoints is deprecated.
+                Call %s::setNestTransactionsWithSavepoints(true) to enable savepoints.
+                DEPRECATION,
+                self::class,
+            );
         }
         }
 
 
-        $this->getEventManager()->dispatchEvent(Events::onTransactionBegin, new TransactionBeginEventArgs($this));
+        $eventManager = $this->getEventManager();
+
+        if ($eventManager->hasListeners(Events::onTransactionBegin)) {
+            Deprecation::trigger(
+                'doctrine/dbal',
+                'https://github.com/doctrine/dbal/issues/5784',
+                'Subscribing to %s events is deprecated.',
+                Events::onTransactionBegin,
+            );
+
+            $eventManager->dispatchEvent(Events::onTransactionBegin, new TransactionBeginEventArgs($this));
+        }
 
 
         return true;
         return true;
     }
     }
@@ -1338,32 +1416,26 @@ class Connection
 
 
         $connection = $this->getWrappedConnection();
         $connection = $this->getWrappedConnection();
 
 
-        $logger = $this->_config->getSQLLogger();
-
         if ($this->transactionNestingLevel === 1) {
         if ($this->transactionNestingLevel === 1) {
-            if ($logger !== null) {
-                $logger->startQuery('"COMMIT"');
-            }
-
-            $result = $connection->commit();
-
-            if ($logger !== null) {
-                $logger->stopQuery();
-            }
+            $result = $this->doCommit($connection);
         } elseif ($this->nestTransactionsWithSavepoints) {
         } elseif ($this->nestTransactionsWithSavepoints) {
-            if ($logger !== null) {
-                $logger->startQuery('"RELEASE SAVEPOINT"');
-            }
-
             $this->releaseSavepoint($this->_getNestedTransactionSavePointName());
             $this->releaseSavepoint($this->_getNestedTransactionSavePointName());
-            if ($logger !== null) {
-                $logger->stopQuery();
-            }
         }
         }
 
 
         --$this->transactionNestingLevel;
         --$this->transactionNestingLevel;
 
 
-        $this->getEventManager()->dispatchEvent(Events::onTransactionCommit, new TransactionCommitEventArgs($this));
+        $eventManager = $this->getEventManager();
+
+        if ($eventManager->hasListeners(Events::onTransactionCommit)) {
+            Deprecation::trigger(
+                'doctrine/dbal',
+                'https://github.com/doctrine/dbal/issues/5784',
+                'Subscribing to %s events is deprecated.',
+                Events::onTransactionCommit,
+            );
+
+            $eventManager->dispatchEvent(Events::onTransactionCommit, new TransactionCommitEventArgs($this));
+        }
 
 
         if ($this->autoCommit !== false || $this->transactionNestingLevel !== 0) {
         if ($this->autoCommit !== false || $this->transactionNestingLevel !== 0) {
             return $result;
             return $result;
@@ -1374,6 +1446,28 @@ class Connection
         return $result;
         return $result;
     }
     }
 
 
+    /**
+     * @return bool
+     *
+     * @throws DriverException
+     */
+    private function doCommit(DriverConnection $connection)
+    {
+        $logger = $this->_config->getSQLLogger();
+
+        if ($logger !== null) {
+            $logger->startQuery('"COMMIT"');
+        }
+
+        $result = $connection->commit();
+
+        if ($logger !== null) {
+            $logger->stopQuery();
+        }
+
+        return $result;
+    }
+
     /**
     /**
      * Commits all current nesting transactions.
      * Commits all current nesting transactions.
      *
      *
@@ -1441,7 +1535,18 @@ class Connection
             --$this->transactionNestingLevel;
             --$this->transactionNestingLevel;
         }
         }
 
 
-        $this->getEventManager()->dispatchEvent(Events::onTransactionRollBack, new TransactionRollBackEventArgs($this));
+        $eventManager = $this->getEventManager();
+
+        if ($eventManager->hasListeners(Events::onTransactionRollBack)) {
+            Deprecation::trigger(
+                'doctrine/dbal',
+                'https://github.com/doctrine/dbal/issues/5784',
+                'Subscribing to %s events is deprecated.',
+                Events::onTransactionRollBack,
+            );
+
+            $eventManager->dispatchEvent(Events::onTransactionRollBack, new TransactionRollBackEventArgs($this));
+        }
 
 
         return true;
         return true;
     }
     }
@@ -1477,6 +1582,8 @@ class Connection
      */
      */
     public function releaseSavepoint($savepoint)
     public function releaseSavepoint($savepoint)
     {
     {
+        $logger = $this->_config->getSQLLogger();
+
         $platform = $this->getDatabasePlatform();
         $platform = $this->getDatabasePlatform();
 
 
         if (! $platform->supportsSavepoints()) {
         if (! $platform->supportsSavepoints()) {
@@ -1484,10 +1591,24 @@ class Connection
         }
         }
 
 
         if (! $platform->supportsReleaseSavepoints()) {
         if (! $platform->supportsReleaseSavepoints()) {
+            if ($logger !== null) {
+                $logger->stopQuery();
+            }
+
             return;
             return;
         }
         }
 
 
+        if ($logger !== null) {
+            $logger->startQuery('"RELEASE SAVEPOINT"');
+        }
+
         $this->executeStatement($platform->releaseSavePoint($savepoint));
         $this->executeStatement($platform->releaseSavePoint($savepoint));
+
+        if ($logger === null) {
+            return;
+        }
+
+        $logger->stopQuery();
     }
     }
 
 
     /**
     /**
@@ -1525,28 +1646,23 @@ class Connection
             'doctrine/dbal',
             'doctrine/dbal',
             'https://github.com/doctrine/dbal/issues/4966',
             'https://github.com/doctrine/dbal/issues/4966',
             'Connection::getWrappedConnection() is deprecated.'
             'Connection::getWrappedConnection() is deprecated.'
-                . ' Use Connection::getNativeConnection() to access the native connection.'
+                . ' Use Connection::getNativeConnection() to access the native connection.',
         );
         );
 
 
         $this->connect();
         $this->connect();
 
 
-        assert($this->_conn !== null);
-
         return $this->_conn;
         return $this->_conn;
     }
     }
 
 
-    /**
-     * @return resource|object
-     */
+    /** @return resource|object */
     public function getNativeConnection()
     public function getNativeConnection()
     {
     {
         $this->connect();
         $this->connect();
 
 
-        assert($this->_conn !== null);
         if (! method_exists($this->_conn, 'getNativeConnection')) {
         if (! method_exists($this->_conn, 'getNativeConnection')) {
             throw new LogicException(sprintf(
             throw new LogicException(sprintf(
                 'The driver connection %s does not support accessing the native connection.',
                 'The driver connection %s does not support accessing the native connection.',
-                get_class($this->_conn)
+                get_class($this->_conn),
             ));
             ));
         }
         }
 
 
@@ -1561,10 +1677,7 @@ class Connection
      */
      */
     public function createSchemaManager(): AbstractSchemaManager
     public function createSchemaManager(): AbstractSchemaManager
     {
     {
-        return $this->_driver->getSchemaManager(
-            $this,
-            $this->getDatabasePlatform()
-        );
+        return $this->schemaManagerFactory->createSchemaManager($this);
     }
     }
 
 
     /**
     /**
@@ -1582,14 +1695,10 @@ class Connection
         Deprecation::triggerIfCalledFromOutside(
         Deprecation::triggerIfCalledFromOutside(
             'doctrine/dbal',
             'doctrine/dbal',
             'https://github.com/doctrine/dbal/issues/4515',
             'https://github.com/doctrine/dbal/issues/4515',
-            'Connection::getSchemaManager() is deprecated, use Connection::createSchemaManager() instead.'
+            'Connection::getSchemaManager() is deprecated, use Connection::createSchemaManager() instead.',
         );
         );
 
 
-        if ($this->_schemaManager === null) {
-            $this->_schemaManager = $this->createSchemaManager();
-        }
-
-        return $this->_schemaManager;
+        return $this->_schemaManager ??= $this->createSchemaManager();
     }
     }
 
 
     /**
     /**
@@ -1667,7 +1776,7 @@ class Connection
      *
      *
      * @throws Exception
      * @throws Exception
      */
      */
-    private function _bindTypedValues(DriverStatement $stmt, array $params, array $types): void
+    private function bindParameters(DriverStatement $stmt, array $params, array $types): void
     {
     {
         // Check whether parameters are positional or named. Mixing is not allowed.
         // Check whether parameters are positional or named. Mixing is not allowed.
         if (is_int(key($params))) {
         if (is_int(key($params))) {
@@ -1677,11 +1786,21 @@ class Connection
                 if (isset($types[$key])) {
                 if (isset($types[$key])) {
                     $type                  = $types[$key];
                     $type                  = $types[$key];
                     [$value, $bindingType] = $this->getBindingInfo($value, $type);
                     [$value, $bindingType] = $this->getBindingInfo($value, $type);
-                    $stmt->bindValue($bindIndex, $value, $bindingType);
                 } else {
                 } else {
-                    $stmt->bindValue($bindIndex, $value);
+                    if (array_key_exists($key, $types)) {
+                        Deprecation::trigger(
+                            'doctrine/dbal',
+                            'https://github.com/doctrine/dbal/pull/5550',
+                            'Using NULL as prepared statement parameter type is deprecated.'
+                                . 'Omit or use Parameter::STRING instead',
+                        );
+                    }
+
+                    $bindingType = ParameterType::STRING;
                 }
                 }
 
 
+                $stmt->bindValue($bindIndex, $value, $bindingType);
+
                 ++$bindIndex;
                 ++$bindIndex;
             }
             }
         } else {
         } else {
@@ -1690,10 +1809,20 @@ class Connection
                 if (isset($types[$name])) {
                 if (isset($types[$name])) {
                     $type                  = $types[$name];
                     $type                  = $types[$name];
                     [$value, $bindingType] = $this->getBindingInfo($value, $type);
                     [$value, $bindingType] = $this->getBindingInfo($value, $type);
-                    $stmt->bindValue($name, $value, $bindingType);
                 } else {
                 } else {
-                    $stmt->bindValue($name, $value);
+                    if (array_key_exists($name, $types)) {
+                        Deprecation::trigger(
+                            'doctrine/dbal',
+                            'https://github.com/doctrine/dbal/pull/5550',
+                            'Using NULL as prepared statement parameter type is deprecated.'
+                                . 'Omit or use Parameter::STRING instead',
+                        );
+                    }
+
+                    $bindingType = ParameterType::STRING;
                 }
                 }
+
+                $stmt->bindValue($name, $value, $bindingType);
             }
             }
         }
         }
     }
     }
@@ -1749,9 +1878,7 @@ class Connection
         return $this->handleDriverException($e, new Query($sql, $params, $types));
         return $this->handleDriverException($e, new Query($sql, $params, $types));
     }
     }
 
 
-    /**
-     * @internal
-     */
+    /** @internal */
     final public function convertException(Driver\Exception $e): DriverException
     final public function convertException(Driver\Exception $e): DriverException
     {
     {
         return $this->handleDriverException($e, null);
         return $this->handleDriverException($e, null);
@@ -1765,11 +1892,8 @@ class Connection
      */
      */
     private function expandArrayParameters(string $sql, array $params, array $types): array
     private function expandArrayParameters(string $sql, array $params, array $types): array
     {
     {
-        if ($this->parser === null) {
-            $this->parser = $this->getDatabasePlatform()->createSQLParser();
-        }
-
-        $visitor = new ExpandArrayParameters($params, $types);
+        $this->parser ??= $this->getDatabasePlatform()->createSQLParser();
+        $visitor        = new ExpandArrayParameters($params, $types);
 
 
         $this->parser->parse($sql, $visitor);
         $this->parser->parse($sql, $visitor);
 
 
@@ -1792,9 +1916,9 @@ class Connection
 
 
         foreach ($types as $type) {
         foreach ($types as $type) {
             if (
             if (
-                $type === self::PARAM_INT_ARRAY
-                || $type === self::PARAM_STR_ARRAY
-                || $type === self::PARAM_ASCII_STR_ARRAY
+                $type === ArrayParameterType::INTEGER
+                || $type === ArrayParameterType::STRING
+                || $type === ArrayParameterType::ASCII
             ) {
             ) {
                 return true;
                 return true;
             }
             }
@@ -1807,11 +1931,8 @@ class Connection
         Driver\Exception $driverException,
         Driver\Exception $driverException,
         ?Query $query
         ?Query $query
     ): DriverException {
     ): DriverException {
-        if ($this->exceptionConverter === null) {
-            $this->exceptionConverter = $this->_driver->getExceptionConverter();
-        }
-
-        $exception = $this->exceptionConverter->convert($driverException, $query);
+        $this->exceptionConverter ??= $this->_driver->getExceptionConverter();
+        $exception                  = $this->exceptionConverter->convert($driverException, $query);
 
 
         if ($exception instanceof ConnectionLost) {
         if ($exception instanceof ConnectionLost) {
             $this->close();
             $this->close();

+ 5 - 15
vendor/doctrine/dbal/src/ConnectionException.php

@@ -2,38 +2,28 @@
 
 
 namespace Doctrine\DBAL;
 namespace Doctrine\DBAL;
 
 
-/**
- * @psalm-immutable
- */
+/** @psalm-immutable */
 class ConnectionException extends Exception
 class ConnectionException extends Exception
 {
 {
-    /**
-     * @return ConnectionException
-     */
+    /** @return ConnectionException */
     public static function commitFailedRollbackOnly()
     public static function commitFailedRollbackOnly()
     {
     {
         return new self('Transaction commit failed because the transaction has been marked for rollback only.');
         return new self('Transaction commit failed because the transaction has been marked for rollback only.');
     }
     }
 
 
-    /**
-     * @return ConnectionException
-     */
+    /** @return ConnectionException */
     public static function noActiveTransaction()
     public static function noActiveTransaction()
     {
     {
         return new self('There is no active transaction.');
         return new self('There is no active transaction.');
     }
     }
 
 
-    /**
-     * @return ConnectionException
-     */
+    /** @return ConnectionException */
     public static function savepointsNotSupported()
     public static function savepointsNotSupported()
     {
     {
         return new self('Savepoints are not supported by this driver.');
         return new self('Savepoints are not supported by this driver.');
     }
     }
 
 
-    /**
-     * @return ConnectionException
-     */
+    /** @return ConnectionException */
     public static function mayNotAlterNestedTransactionWithSavepointsInTransaction()
     public static function mayNotAlterNestedTransactionWithSavepointsInTransaction()
     {
     {
         return new self('May not alter the nested transaction with savepoints behavior while a transaction is open.');
         return new self('May not alter the nested transaction with savepoints behavior while a transaction is open.');

+ 15 - 4
vendor/doctrine/dbal/src/Connections/PrimaryReadReplicaConnection.php

@@ -13,7 +13,9 @@ use Doctrine\DBAL\Event\ConnectionEventArgs;
 use Doctrine\DBAL\Events;
 use Doctrine\DBAL\Events;
 use Doctrine\DBAL\Exception;
 use Doctrine\DBAL\Exception;
 use Doctrine\DBAL\Statement;
 use Doctrine\DBAL\Statement;
+use Doctrine\Deprecations\Deprecation;
 use InvalidArgumentException;
 use InvalidArgumentException;
+use SensitiveParameter;
 
 
 use function array_rand;
 use function array_rand;
 use function count;
 use function count;
@@ -97,7 +99,6 @@ class PrimaryReadReplicaConnection extends Connection
      *
      *
      * @param array<string,mixed> $params
      * @param array<string,mixed> $params
      * @psalm-param Params $params
      * @psalm-param Params $params
-     * @phpstan-param array<string,mixed> $params
      *
      *
      * @throws Exception
      * @throws Exception
      * @throws InvalidArgumentException
      * @throws InvalidArgumentException
@@ -147,7 +148,7 @@ class PrimaryReadReplicaConnection extends Connection
         if ($connectionName !== null) {
         if ($connectionName !== null) {
             throw new InvalidArgumentException(
             throw new InvalidArgumentException(
                 'Passing a connection name as first argument is not supported anymore.'
                 'Passing a connection name as first argument is not supported anymore.'
-                    . ' Use ensureConnectedToPrimary()/ensureConnectedToReplica() instead.'
+                    . ' Use ensureConnectedToPrimary()/ensureConnectedToReplica() instead.',
             );
             );
         }
         }
 
 
@@ -199,6 +200,13 @@ class PrimaryReadReplicaConnection extends Connection
         }
         }
 
 
         if ($this->_eventManager->hasListeners(Events::postConnect)) {
         if ($this->_eventManager->hasListeners(Events::postConnect)) {
+            Deprecation::trigger(
+                'doctrine/dbal',
+                'https://github.com/doctrine/dbal/issues/5784',
+                'Subscribing to %s events is deprecated. Implement a middleware instead.',
+                Events::postConnect,
+            );
+
             $eventArgs = new ConnectionEventArgs($this);
             $eventArgs = new ConnectionEventArgs($this);
             $this->_eventManager->dispatchEvent(Events::postConnect, $eventArgs);
             $this->_eventManager->dispatchEvent(Events::postConnect, $eventArgs);
         }
         }
@@ -256,8 +264,11 @@ class PrimaryReadReplicaConnection extends Connection
      *
      *
      * @return mixed
      * @return mixed
      */
      */
-    protected function chooseConnectionConfiguration($connectionName, $params)
-    {
+    protected function chooseConnectionConfiguration(
+        $connectionName,
+        #[SensitiveParameter]
+        $params
+    ) {
         if ($connectionName === 'primary') {
         if ($connectionName === 'primary') {
             return $params['primary'];
             return $params['primary'];
         }
         }

+ 11 - 2
vendor/doctrine/dbal/src/Driver.php

@@ -7,23 +7,30 @@ use Doctrine\DBAL\Driver\Connection as DriverConnection;
 use Doctrine\DBAL\Driver\Exception;
 use Doctrine\DBAL\Driver\Exception;
 use Doctrine\DBAL\Platforms\AbstractPlatform;
 use Doctrine\DBAL\Platforms\AbstractPlatform;
 use Doctrine\DBAL\Schema\AbstractSchemaManager;
 use Doctrine\DBAL\Schema\AbstractSchemaManager;
+use SensitiveParameter;
 
 
 /**
 /**
  * Driver interface.
  * Driver interface.
  * Interface that all DBAL drivers must implement.
  * Interface that all DBAL drivers must implement.
+ *
+ * @psalm-import-type Params from DriverManager
  */
  */
 interface Driver
 interface Driver
 {
 {
     /**
     /**
      * Attempts to create a connection with the database.
      * Attempts to create a connection with the database.
      *
      *
-     * @param mixed[] $params All connection parameters.
+     * @param array<string, mixed> $params All connection parameters.
+     * @psalm-param Params $params All connection parameters.
      *
      *
      * @return DriverConnection The database connection.
      * @return DriverConnection The database connection.
      *
      *
      * @throws Exception
      * @throws Exception
      */
      */
-    public function connect(array $params);
+    public function connect(
+        #[SensitiveParameter]
+        array $params
+    );
 
 
     /**
     /**
      * Gets the DatabasePlatform instance that provides all the metadata about
      * Gets the DatabasePlatform instance that provides all the metadata about
@@ -37,6 +44,8 @@ interface Driver
      * Gets the SchemaManager that can be used to inspect and change the underlying
      * Gets the SchemaManager that can be used to inspect and change the underlying
      * database schema of the platform this driver connects to.
      * database schema of the platform this driver connects to.
      *
      *
+     * @deprecated Use {@link AbstractPlatform::createSchemaManager()} instead.
+     *
      * @return AbstractSchemaManager
      * @return AbstractSchemaManager
      */
      */
     public function getSchemaManager(Connection $conn, AbstractPlatform $platform);
     public function getSchemaManager(Connection $conn, AbstractPlatform $platform);

+ 1 - 3
vendor/doctrine/dbal/src/Driver/API/MySQL/ExceptionConverter.php

@@ -22,9 +22,7 @@ use Doctrine\DBAL\Exception\TableNotFoundException;
 use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
 use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
 use Doctrine\DBAL\Query;
 use Doctrine\DBAL\Query;
 
 
-/**
- * @internal
- */
+/** @internal */
 final class ExceptionConverter implements ExceptionConverterInterface
 final class ExceptionConverter implements ExceptionConverterInterface
 {
 {
     /**
     /**

+ 2 - 6
vendor/doctrine/dbal/src/Driver/API/OCI/ExceptionConverter.php

@@ -20,14 +20,10 @@ use Doctrine\DBAL\Exception\TableNotFoundException;
 use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
 use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
 use Doctrine\DBAL\Query;
 use Doctrine\DBAL\Query;
 
 
-/**
- * @internal
- */
+/** @internal */
 final class ExceptionConverter implements ExceptionConverterInterface
 final class ExceptionConverter implements ExceptionConverterInterface
 {
 {
-    /**
-     * @link http://www.dba-oracle.com/t_error_code_list.htm
-     */
+    /** @link http://www.dba-oracle.com/t_error_code_list.htm */
     public function convert(Exception $exception, ?Query $query): DriverException
     public function convert(Exception $exception, ?Query $query): DriverException
     {
     {
         switch ($exception->getCode()) {
         switch ($exception->getCode()) {

+ 3 - 7
vendor/doctrine/dbal/src/Driver/API/PostgreSQL/ExceptionConverter.php

@@ -23,14 +23,10 @@ use Doctrine\DBAL\Query;
 
 
 use function strpos;
 use function strpos;
 
 
-/**
- * @internal
- */
+/** @internal */
 final class ExceptionConverter implements ExceptionConverterInterface
 final class ExceptionConverter implements ExceptionConverterInterface
 {
 {
-    /**
-     * @link http://www.postgresql.org/docs/9.4/static/errcodes-appendix.html
-     */
+    /** @link http://www.postgresql.org/docs/9.4/static/errcodes-appendix.html */
     public function convert(Exception $exception, ?Query $query): DriverException
     public function convert(Exception $exception, ?Query $query): DriverException
     {
     {
         switch ($exception->getSQLState()) {
         switch ($exception->getSQLState()) {
@@ -81,7 +77,7 @@ final class ExceptionConverter implements ExceptionConverterInterface
                 return new ConnectionException($exception, $query);
                 return new ConnectionException($exception, $query);
         }
         }
 
 
-        // Prior to fixing https://bugs.php.net/bug.php?id=64705 (PHP 7.3.22 and PHP 7.4.10),
+        // Prior to fixing https://bugs.php.net/bug.php?id=64705 (PHP 7.4.10),
         // in some cases (mainly connection errors) the PDO exception wouldn't provide a SQLSTATE via its code.
         // in some cases (mainly connection errors) the PDO exception wouldn't provide a SQLSTATE via its code.
         // We have to match against the SQLSTATE in the error message in these cases.
         // We have to match against the SQLSTATE in the error message in these cases.
         if ($exception->getCode() === 7 && strpos($exception->getMessage(), 'SQLSTATE[08006]') !== false) {
         if ($exception->getCode() === 7 && strpos($exception->getMessage(), 'SQLSTATE[08006]') !== false) {

+ 7 - 6
vendor/doctrine/dbal/src/Driver/API/SQLite/ExceptionConverter.php

@@ -8,6 +8,7 @@ use Doctrine\DBAL\Driver\API\ExceptionConverter as ExceptionConverterInterface;
 use Doctrine\DBAL\Driver\Exception;
 use Doctrine\DBAL\Driver\Exception;
 use Doctrine\DBAL\Exception\ConnectionException;
 use Doctrine\DBAL\Exception\ConnectionException;
 use Doctrine\DBAL\Exception\DriverException;
 use Doctrine\DBAL\Exception\DriverException;
+use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
 use Doctrine\DBAL\Exception\InvalidFieldNameException;
 use Doctrine\DBAL\Exception\InvalidFieldNameException;
 use Doctrine\DBAL\Exception\LockWaitTimeoutException;
 use Doctrine\DBAL\Exception\LockWaitTimeoutException;
 use Doctrine\DBAL\Exception\NonUniqueFieldNameException;
 use Doctrine\DBAL\Exception\NonUniqueFieldNameException;
@@ -21,14 +22,10 @@ use Doctrine\DBAL\Query;
 
 
 use function strpos;
 use function strpos;
 
 
-/**
- * @internal
- */
+/** @internal */
 final class ExceptionConverter implements ExceptionConverterInterface
 final class ExceptionConverter implements ExceptionConverterInterface
 {
 {
-    /**
-     * @link http://www.sqlite.org/c3ref/c_abort.html
-     */
+    /** @link http://www.sqlite.org/c3ref/c_abort.html */
     public function convert(Exception $exception, ?Query $query): DriverException
     public function convert(Exception $exception, ?Query $query): DriverException
     {
     {
         if (strpos($exception->getMessage(), 'database is locked') !== false) {
         if (strpos($exception->getMessage(), 'database is locked') !== false) {
@@ -79,6 +76,10 @@ final class ExceptionConverter implements ExceptionConverterInterface
             return new ConnectionException($exception, $query);
             return new ConnectionException($exception, $query);
         }
         }
 
 
+        if (strpos($exception->getMessage(), 'FOREIGN KEY constraint failed') !== false) {
+            return new ForeignKeyConstraintViolationException($exception, $query);
+        }
+
         return new DriverException($exception, $query);
         return new DriverException($exception, $query);
     }
     }
 }
 }

+ 32 - 0
vendor/doctrine/dbal/src/Driver/API/SQLite/UserDefinedFunctions.php

@@ -2,6 +2,11 @@
 
 
 namespace Doctrine\DBAL\Driver\API\SQLite;
 namespace Doctrine\DBAL\Driver\API\SQLite;
 
 
+use Doctrine\DBAL\Platforms\AbstractPlatform;
+use Doctrine\DBAL\Platforms\SqlitePlatform;
+use Doctrine\Deprecations\Deprecation;
+
+use function array_merge;
 use function strpos;
 use function strpos;
 
 
 /**
 /**
@@ -11,6 +16,25 @@ use function strpos;
  */
  */
 final class UserDefinedFunctions
 final class UserDefinedFunctions
 {
 {
+    private const DEFAULT_FUNCTIONS = [
+        'sqrt' => ['callback' => [SqlitePlatform::class, 'udfSqrt'], 'numArgs' => 1],
+        'mod'  => ['callback' => [SqlitePlatform::class, 'udfMod'], 'numArgs' => 2],
+        'locate'  => ['callback' => [SqlitePlatform::class, 'udfLocate'], 'numArgs' => -1],
+    ];
+
+    /**
+     * @param callable(string, callable, int): bool                  $callback
+     * @param array<string, array{callback: callable, numArgs: int}> $additionalFunctions
+     */
+    public static function register(callable $callback, array $additionalFunctions = []): void
+    {
+        $userDefinedFunctions = array_merge(self::DEFAULT_FUNCTIONS, $additionalFunctions);
+
+        foreach ($userDefinedFunctions as $function => $data) {
+            $callback($function, $data['callback'], $data['numArgs']);
+        }
+    }
+
     /**
     /**
      * User-defined function that implements MOD().
      * User-defined function that implements MOD().
      *
      *
@@ -31,6 +55,14 @@ final class UserDefinedFunctions
      */
      */
     public static function locate($str, $substr, $offset = 0): int
     public static function locate($str, $substr, $offset = 0): int
     {
     {
+        Deprecation::trigger(
+            'doctrine/dbal',
+            'https://github.com/doctrine/dbal/pull/5749',
+            'Relying on DBAL\'s emulated LOCATE() function is deprecated. '
+                . 'Use INSTR() or %s::getLocateExpression() instead.',
+            AbstractPlatform::class,
+        );
+
         // SQL's LOCATE function works on 1-based positions, while PHP's strpos works on 0-based positions.
         // SQL's LOCATE function works on 1-based positions, while PHP's strpos works on 0-based positions.
         // So we have to make them compatible if an offset is given.
         // So we have to make them compatible if an offset is given.
         if ($offset > 0) {
         if ($offset > 0) {

+ 12 - 2
vendor/doctrine/dbal/src/Driver/AbstractDB2Driver.php

@@ -9,6 +9,7 @@ use Doctrine\DBAL\Driver\API\IBMDB2\ExceptionConverter;
 use Doctrine\DBAL\Platforms\AbstractPlatform;
 use Doctrine\DBAL\Platforms\AbstractPlatform;
 use Doctrine\DBAL\Platforms\DB2Platform;
 use Doctrine\DBAL\Platforms\DB2Platform;
 use Doctrine\DBAL\Schema\DB2SchemaManager;
 use Doctrine\DBAL\Schema\DB2SchemaManager;
+use Doctrine\Deprecations\Deprecation;
 
 
 use function assert;
 use function assert;
 
 
@@ -18,7 +19,7 @@ use function assert;
 abstract class AbstractDB2Driver implements Driver
 abstract class AbstractDB2Driver implements Driver
 {
 {
     /**
     /**
-     * {@inheritdoc}
+     * {@inheritDoc}
      */
      */
     public function getDatabasePlatform()
     public function getDatabasePlatform()
     {
     {
@@ -26,10 +27,19 @@ abstract class AbstractDB2Driver implements Driver
     }
     }
 
 
     /**
     /**
-     * {@inheritdoc}
+     * {@inheritDoc}
+     *
+     * @deprecated Use {@link DB2Platform::createSchemaManager()} instead.
      */
      */
     public function getSchemaManager(Connection $conn, AbstractPlatform $platform)
     public function getSchemaManager(Connection $conn, AbstractPlatform $platform)
     {
     {
+        Deprecation::triggerIfCalledFromOutside(
+            'doctrine/dbal',
+            'https://github.com/doctrine/dbal/pull/5458',
+            'AbstractDB2Driver::getSchemaManager() is deprecated.'
+                . ' Use DB2Platform::createSchemaManager() instead.',
+        );
+
         assert($platform instanceof DB2Platform);
         assert($platform instanceof DB2Platform);
 
 
         return new DB2SchemaManager($conn, $platform);
         return new DB2SchemaManager($conn, $platform);

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