diff --git a/app/admin/controller/Config.php b/app/admin/controller/Config.php index 8cd216e4..a6081720 100644 --- a/app/admin/controller/Config.php +++ b/app/admin/controller/Config.php @@ -3,6 +3,8 @@ namespace app\admin\controller; use app\admin\service\ConfigService; +use app\utility\MongoConnection; +use think\facade\Cache; use think\facade\Filesystem; use app\model\ConfigModel; @@ -90,4 +92,81 @@ class Config extends AdminBaseController $returnData = (new ConfigService())->editSmsTemplate($this->request->param()); return json($returnData); } + + // 获取行情数据列表 + public function quoteList() + { + $params = $this->request->param(); + if (!isset($params['page']) || !isset($params['page_size'])) { + return json([ + 'code' => 400, + 'message' => '缺少参数', + 'data' => [] + ]); + } + + // 分页计算 + $page = $params['page']; + $pageSize = $params['page_size']; + $options = [ + 'skip' => ($page - 1) * $pageSize, + 'limit' => $pageSize, + 'sort' => ['_id' => -1], // 按创建时间倒序 + ]; + + // 构造查询条件 + $filter = []; + if (!empty($params['name'])) { + // 使用正则表达式进行模糊匹配(i 表示不区分大小写) + $filter['Name'] = [ + '$regex' => $params['name'], + '$options' => 'i' + ]; + } + + // 查询数据 + $client = MongoConnection::getClient(); + $collection = $client->selectCollection('bourse', 'stockListBak'); + $cursor = $collection->find($filter, $options); + $results = iterator_to_array($cursor); // 将 BSON 文档转换为数组 + $total = $collection->countDocuments($filter); + + + $list = []; + foreach ($results as $item) { + $arr = (array)$item; + $list[] = $arr; + } + + + return json([ + 'code' => 400, + 'message' => '缺少参数', + 'data' => [ + 'total' => $total, + 'page' => $page, + 'pageSize' => $pageSize, + 'list' => $list, + ] + ]); + } + + // 行情数据置顶 + public function quoteTopData() + { + $params = $this->request->param(); + if (empty($params['id'])) { + return json([ + 'code' => 400, + 'message' => '缺少参数', + 'data' => [] + ]); + } + $res = Cache::store('redis')->lPush(MongoConnection::QUOTE_TOP_DATA_LIST_KEY, trim($params['id'])); + return json([ + 'code' => 0, + 'message' => 'ok', + 'data' => [$res] + ]); + } } \ No newline at end of file diff --git a/app/admin/controller/Test.php b/app/admin/controller/Test.php index 80eb6e27..5c58398f 100644 --- a/app/admin/controller/Test.php +++ b/app/admin/controller/Test.php @@ -1,10 +1,9 @@ $appNumber ]]); } + + public function testMongo() + { + $client = MongoConnection::getClient(); + $collection = $client->selectCollection('bourse', 'stockListBak'); + + // 分页计算 + $page = 1; + $pageSize = 10; + $options = [ + 'skip' => ($page - 1) * $pageSize, + 'limit' => $pageSize, + 'sort' => ['_id' => -1], // 按创建时间倒序 + ]; + + // 构造查询条件 + $filter = []; + $filterName = 'xxx'; + if (!empty($filterName)) { + // 使用正则表达式进行模糊匹配(i 表示不区分大小写) + $filter['Name'] = [ + '$regex' => 'POP', + '$options' => 'i' // i = ignore case + ]; + } + + // 查询数据 + $cursor = $collection->find($filter, $options); + $total = $collection->countDocuments($filter); + + // 将 BSON 文档转换为数组 + $results = iterator_to_array($cursor); + + $data = []; + foreach ($results as $item) { + $arr = (array)$item; + $data[] = $arr; + if ($arr['Name'] == "POPULAR FOUNDATIONS LIMITED") { + $oidArr = (array)$arr['_id']; + echo "oid===".$oidArr['oid']; + // 将目标缓存到redis队列中 + $res = Cache::store('redis')->lPush('STOCK_MARKET_TOP_DATA', $oidArr['oid']); + echo "cache res=="; + var_dump($res); + echo PHP_EOL; + } + } + + return json( [ + 'total' => $total, + 'page' => $page, + 'pageSize' => $pageSize, + 'data' => $data + ]); + } } \ No newline at end of file diff --git a/app/admin/route/app.php b/app/admin/route/app.php index 590ab5a7..a26de921 100644 --- a/app/admin/route/app.php +++ b/app/admin/route/app.php @@ -12,7 +12,7 @@ $header = [ // 需要登陆的接口 使用中间件校验 请求路径 XwkjlLbDcG/test //Route::get('/test', 'Test/index'); -Route::post('/test', 'Test/index'); +Route::post('/test', 'Test/testMongo'); Route::post('/test_upload', 'Upload/uploadVideo'); Route::post('test_api', 'Index/dailyUserRegistration'); Route::group('/', function () { @@ -28,6 +28,10 @@ Route::group('/', function () { Route::post('config/sms_template_list', 'Config/smsTemplateList'); //获取短信模板列表 Route::post('config/edit_sms_template', 'Config/editSmsTemplate'); //编辑短信模板 + // 行情数据列表 + Route::post('config/quote_list', 'Config/quoteList'); // 获取行情数据列表 + Route::post('config/quote_top_data', 'Config/quoteTopData'); // 置顶某条行情数据(这里是将其加入缓存,由go服务那边去过滤处理) + // 消息推送 Route::post('notice/popup', 'Notice/popUp'); // 弹窗推送消息 Route::post('notice/push_message', 'Notice/pushMessage'); // 使用Pusher推送系统级消息 diff --git a/app/utility/MongoConnection.php b/app/utility/MongoConnection.php new file mode 100644 index 00000000..1d174cc8 --- /dev/null +++ b/app/utility/MongoConnection.php @@ -0,0 +1,23 @@ + 200, // 设置连接池最大连接数 + 'minPoolSize' => 10, // 设置连接池最小连接数(可选) + 'serverSelectionTimeoutMS' => 5000, // 超时设置(防止请求挂死) 单位是毫秒 + ]); + } + + return self::$client; + } +} \ No newline at end of file diff --git a/composer.json b/composer.json index 161d06e1..414ef0c2 100644 --- a/composer.json +++ b/composer.json @@ -37,7 +37,9 @@ "ext-json": "*", "aws/aws-sdk-php": "^3.337", "workerman/gatewayclient": "^3.1", - "pusher/pusher-push-notifications": "^2.0" + "pusher/pusher-push-notifications": "^2.0", + "mongodb/mongodb": "^1.21", + "ext-mongodb": "*" }, "require-dev": { "symfony/var-dumper": "^4.2", diff --git a/composer.lock b/composer.lock index c2c3a5d6..5019354c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "060b4e88568c2f7d16da36058884c54d", + "content-hash": "ce65030475f43004bd1110c2ef9dadce", "packages": [ { "name": "adbario/php-dot-notation", @@ -1924,6 +1924,88 @@ }, "time": "2024-11-14T23:14:52+00:00" }, + { + "name": "mongodb/mongodb", + "version": "1.21.1", + "source": { + "type": "git", + "url": "https://github.com/mongodb/mongo-php-library.git", + "reference": "37bc8df3a67ddf8380704a5ba5dbd00e92ec1f6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mongodb/mongo-php-library/zipball/37bc8df3a67ddf8380704a5ba5dbd00e92ec1f6a", + "reference": "37bc8df3a67ddf8380704a5ba5dbd00e92ec1f6a", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "composer-runtime-api": "^2.0", + "ext-mongodb": "^1.21.0", + "php": "^8.1", + "psr/log": "^1.1.4|^2|^3" + }, + "replace": { + "mongodb/builder": "*" + }, + "require-dev": { + "doctrine/coding-standard": "^12.0", + "phpunit/phpunit": "^10.5.35", + "rector/rector": "^1.2", + "squizlabs/php_codesniffer": "^3.7", + "vimeo/psalm": "6.5.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "MongoDB\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Andreas Braun", + "email": "andreas.braun@mongodb.com" + }, + { + "name": "Jeremy Mikola", + "email": "jmikola@gmail.com" + }, + { + "name": "Jérôme Tamarelle", + "email": "jerome.tamarelle@mongodb.com" + } + ], + "description": "MongoDB driver library", + "homepage": "https://jira.mongodb.org/browse/PHPLIB", + "keywords": [ + "database", + "driver", + "mongodb", + "persistence" + ], + "support": { + "issues": "https://github.com/mongodb/mongo-php-library/issues", + "source": "https://github.com/mongodb/mongo-php-library/tree/1.21.1" + }, + "time": "2025-02-28T17:24:20+00:00" + }, { "name": "mtdowling/jmespath.php", "version": "2.7.0", diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php index 79ce8fb1..a0eaf2b5 100644 --- a/vendor/composer/autoload_files.php +++ b/vendor/composer/autoload_files.php @@ -21,6 +21,7 @@ return array( 'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php', '66453932bc1be9fb2f910a27947d11b6' => $vendorDir . '/alibabacloud/client/src/Functions.php', '8a9dc1de0ca7e01f3e08231539562f61' => $vendorDir . '/aws/aws-sdk-php/src/functions.php', + '3a37ebac017bc098e9a86b35401e7a68' => $vendorDir . '/mongodb/mongodb/src/functions.php', '667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php', 'cc56288302d9df745d97c934d6a6e5f0' => $vendorDir . '/topthink/think-queue/src/common.php', ); diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php index abe5e774..5b6b0c2e 100644 --- a/vendor/composer/autoload_psr4.php +++ b/vendor/composer/autoload_psr4.php @@ -35,6 +35,7 @@ return array( 'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'), 'PhpOffice\\PhpSpreadsheet\\' => array($vendorDir . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet'), 'PHPMailer\\PHPMailer\\' => array($vendorDir . '/phpmailer/phpmailer/src'), + 'MongoDB\\' => array($vendorDir . '/mongodb/mongodb/src'), 'MaxMind\\WebService\\' => array($vendorDir . '/maxmind/web-service-common/src/WebService'), 'MaxMind\\Exception\\' => array($vendorDir . '/maxmind/web-service-common/src/Exception'), 'MaxMind\\Db\\' => array($vendorDir . '/maxmind-db/reader/src/MaxMind/Db'), diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 704dde43..ddd32ad8 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -22,6 +22,7 @@ class ComposerStaticInitdd94061c596fec45ed08426e6d417237 'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php', '66453932bc1be9fb2f910a27947d11b6' => __DIR__ . '/..' . '/alibabacloud/client/src/Functions.php', '8a9dc1de0ca7e01f3e08231539562f61' => __DIR__ . '/..' . '/aws/aws-sdk-php/src/functions.php', + '3a37ebac017bc098e9a86b35401e7a68' => __DIR__ . '/..' . '/mongodb/mongodb/src/functions.php', '667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php', 'cc56288302d9df745d97c934d6a6e5f0' => __DIR__ . '/..' . '/topthink/think-queue/src/common.php', ); @@ -85,6 +86,7 @@ class ComposerStaticInitdd94061c596fec45ed08426e6d417237 ), 'M' => array ( + 'MongoDB\\' => 8, 'MaxMind\\WebService\\' => 19, 'MaxMind\\Exception\\' => 18, 'MaxMind\\Db\\' => 11, @@ -254,6 +256,10 @@ class ComposerStaticInitdd94061c596fec45ed08426e6d417237 array ( 0 => __DIR__ . '/..' . '/phpmailer/phpmailer/src', ), + 'MongoDB\\' => + array ( + 0 => __DIR__ . '/..' . '/mongodb/mongodb/src', + ), 'MaxMind\\WebService\\' => array ( 0 => __DIR__ . '/..' . '/maxmind/web-service-common/src/WebService', diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 068d2c99..7a94440c 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -1927,6 +1927,91 @@ }, "install-path": "../maxmind/web-service-common" }, + { + "name": "mongodb/mongodb", + "version": "1.21.1", + "version_normalized": "1.21.1.0", + "source": { + "type": "git", + "url": "https://github.com/mongodb/mongo-php-library.git", + "reference": "37bc8df3a67ddf8380704a5ba5dbd00e92ec1f6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mongodb/mongo-php-library/zipball/37bc8df3a67ddf8380704a5ba5dbd00e92ec1f6a", + "reference": "37bc8df3a67ddf8380704a5ba5dbd00e92ec1f6a", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "composer-runtime-api": "^2.0", + "ext-mongodb": "^1.21.0", + "php": "^8.1", + "psr/log": "^1.1.4|^2|^3" + }, + "replace": { + "mongodb/builder": "*" + }, + "require-dev": { + "doctrine/coding-standard": "^12.0", + "phpunit/phpunit": "^10.5.35", + "rector/rector": "^1.2", + "squizlabs/php_codesniffer": "^3.7", + "vimeo/psalm": "6.5.*" + }, + "time": "2025-02-28T17:24:20+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "MongoDB\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Andreas Braun", + "email": "andreas.braun@mongodb.com" + }, + { + "name": "Jeremy Mikola", + "email": "jmikola@gmail.com" + }, + { + "name": "Jérôme Tamarelle", + "email": "jerome.tamarelle@mongodb.com" + } + ], + "description": "MongoDB driver library", + "homepage": "https://jira.mongodb.org/browse/PHPLIB", + "keywords": [ + "database", + "driver", + "mongodb", + "persistence" + ], + "support": { + "issues": "https://github.com/mongodb/mongo-php-library/issues", + "source": "https://github.com/mongodb/mongo-php-library/tree/1.21.1" + }, + "install-path": "../mongodb/mongodb" + }, { "name": "mtdowling/jmespath.php", "version": "2.7.0", diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 63162fcf..b880bed6 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -3,7 +3,7 @@ 'name' => 'topthink/think', 'pretty_version' => 'dev-master', 'version' => 'dev-master', - 'reference' => '1192d0618a9dbdb678eb70e99b050efbe932cbcf', + 'reference' => 'ba177235a471c2287f0d0ca76391e63ae146cc1f', 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -235,6 +235,21 @@ 'aliases' => array(), 'dev_requirement' => false, ), + 'mongodb/builder' => array( + 'dev_requirement' => false, + 'replaced' => array( + 0 => '*', + ), + ), + 'mongodb/mongodb' => array( + 'pretty_version' => '1.21.1', + 'version' => '1.21.1.0', + 'reference' => '37bc8df3a67ddf8380704a5ba5dbd00e92ec1f6a', + 'type' => 'library', + 'install_path' => __DIR__ . '/../mongodb/mongodb', + 'aliases' => array(), + 'dev_requirement' => false, + ), 'mtdowling/jmespath.php' => array( 'pretty_version' => '2.7.0', 'version' => '2.7.0.0', @@ -538,7 +553,7 @@ 'topthink/think' => array( 'pretty_version' => 'dev-master', 'version' => 'dev-master', - 'reference' => '1192d0618a9dbdb678eb70e99b050efbe932cbcf', + 'reference' => 'ba177235a471c2287f0d0ca76391e63ae146cc1f', 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), diff --git a/vendor/mongodb/mongodb/LICENSE b/vendor/mongodb/mongodb/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/vendor/mongodb/mongodb/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/mongodb/mongodb/composer.json b/vendor/mongodb/mongodb/composer.json new file mode 100644 index 00000000..0d1438f0 --- /dev/null +++ b/vendor/mongodb/mongodb/composer.json @@ -0,0 +1,65 @@ +{ + "name": "mongodb/mongodb", + "description": "MongoDB driver library", + "keywords": ["database", "driver", "mongodb", "persistence"], + "homepage": "https://jira.mongodb.org/browse/PHPLIB", + "license": "Apache-2.0", + "authors": [ + { "name": "Andreas Braun", "email": "andreas.braun@mongodb.com" }, + { "name": "Jeremy Mikola", "email": "jmikola@gmail.com" }, + { "name": "Jérôme Tamarelle", "email": "jerome.tamarelle@mongodb.com" } + ], + "require": { + "php": "^8.1", + "ext-mongodb": "^1.21.0", + "composer-runtime-api": "^2.0", + "psr/log": "^1.1.4|^2|^3" + }, + "require-dev": { + "doctrine/coding-standard": "^12.0", + "phpunit/phpunit": "^10.5.35", + "rector/rector": "^1.2", + "squizlabs/php_codesniffer": "^3.7", + "vimeo/psalm": "6.5.*" + }, + "replace": { + "mongodb/builder": "*" + }, + "autoload": { + "psr-4": { "MongoDB\\": "src/" }, + "files": [ "src/functions.php" ] + }, + "autoload-dev": { + "psr-4": { + "MongoDB\\Tests\\": "tests/" + } + }, + "scripts": { + "pre-install-cmd": "git submodule update --init", + "pre-update-cmd": "git submodule update --init", + "bench": "cd benchmark && composer update && vendor/bin/phpbench run --report=aggregate", + "checks": [ + "@check:cs", + "@check:psalm", + "@check:rector" + ], + "check:cs": "phpcs", + "check:psalm": "psalm", + "check:rector": "rector --ansi --dry-run", + "fix:cs": "phpcbf", + "fix:psalm:baseline": "psalm --set-baseline=psalm-baseline.xml", + "fix:rector": "rector process --ansi", + "test": "phpunit" + }, + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "config": { + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true + }, + "sort-packages": true + } +} diff --git a/vendor/mongodb/mongodb/sbom.json b/vendor/mongodb/mongodb/sbom.json new file mode 100644 index 00000000..4dce69b3 --- /dev/null +++ b/vendor/mongodb/mongodb/sbom.json @@ -0,0 +1,85 @@ +{ + "$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.5", + "serialNumber": "urn:uuid:dc42a43b-4ace-4c42-9a6e-0b9e28fdd100", + "version": 1, + "metadata": { + "timestamp": "2024-05-08T09:51:01Z", + "tools": [ + { + "name": "composer", + "version": "2.7.6" + }, + { + "vendor": "cyclonedx", + "name": "cyclonedx-php-composer", + "version": "v5.2.0", + "externalReferences": [ + { + "type": "distribution", + "url": "https://api.github.com/repos/CycloneDX/cyclonedx-php-composer/zipball/f3a3cdc1a9e34bf1d5748e4279a24569cbf31fed", + "comment": "dist reference: f3a3cdc1a9e34bf1d5748e4279a24569cbf31fed" + }, + { + "type": "vcs", + "url": "https://github.com/CycloneDX/cyclonedx-php-composer.git", + "comment": "source reference: f3a3cdc1a9e34bf1d5748e4279a24569cbf31fed" + }, + { + "type": "website", + "url": "https://github.com/CycloneDX/cyclonedx-php-composer/#readme", + "comment": "as detected from Composer manifest 'homepage'" + }, + { + "type": "issue-tracker", + "url": "https://github.com/CycloneDX/cyclonedx-php-composer/issues", + "comment": "as detected from Composer manifest 'support.issues'" + }, + { + "type": "vcs", + "url": "https://github.com/CycloneDX/cyclonedx-php-composer/", + "comment": "as detected from Composer manifest 'support.source'" + } + ] + }, + { + "vendor": "cyclonedx", + "name": "cyclonedx-library", + "version": "v3.3.1", + "externalReferences": [ + { + "type": "distribution", + "url": "https://api.github.com/repos/CycloneDX/cyclonedx-php-library/zipball/cad0f92b36c85f36b3d3c11ff96002af5f20cd10", + "comment": "dist reference: cad0f92b36c85f36b3d3c11ff96002af5f20cd10" + }, + { + "type": "vcs", + "url": "https://github.com/CycloneDX/cyclonedx-php-library.git", + "comment": "source reference: cad0f92b36c85f36b3d3c11ff96002af5f20cd10" + }, + { + "type": "website", + "url": "https://github.com/CycloneDX/cyclonedx-php-library/#readme", + "comment": "as detected from Composer manifest 'homepage'" + }, + { + "type": "documentation", + "url": "https://cyclonedx-php-library.readthedocs.io", + "comment": "as detected from Composer manifest 'support.docs'" + }, + { + "type": "issue-tracker", + "url": "https://github.com/CycloneDX/cyclonedx-php-library/issues", + "comment": "as detected from Composer manifest 'support.issues'" + }, + { + "type": "vcs", + "url": "https://github.com/CycloneDX/cyclonedx-php-library/", + "comment": "as detected from Composer manifest 'support.source'" + } + ] + } + ] + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Accumulator.php b/vendor/mongodb/mongodb/src/Builder/Accumulator.php new file mode 100644 index 00000000..75d460bd --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Accumulator.php @@ -0,0 +1,44 @@ +|stdClass $operator Window operator to use in the $setWindowFields stage. + * @param Optional|array{string|int,string|int} $documents A window where the lower and upper boundaries are specified relative to the position of the current document read from the collection. + * @param Optional|array{string|numeric,string|numeric} $range Arguments passed to the init function. + * @param Optional|non-empty-string $unit Specifies the units for time range window boundaries. If omitted, default numeric range window boundaries are used. + */ + public static function outputWindow( + Document|Serializable|WindowInterface|stdClass|array $operator, + Optional|array $documents = Optional::Undefined, + Optional|array $range = Optional::Undefined, + Optional|TimeUnit|string $unit = Optional::Undefined, + ): OutputWindow { + return new OutputWindow($operator, $documents, $range, $unit); + } + + private function __construct() + { + // This class cannot be instantiated + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Accumulator/AccumulatorAccumulator.php b/vendor/mongodb/mongodb/src/Builder/Accumulator/AccumulatorAccumulator.php new file mode 100644 index 00000000..f26e5f7d --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Accumulator/AccumulatorAccumulator.php @@ -0,0 +1,127 @@ + 'init', + 'accumulate' => 'accumulate', + 'accumulateArgs' => 'accumulateArgs', + 'merge' => 'merge', + 'lang' => 'lang', + 'initArgs' => 'initArgs', + 'finalize' => 'finalize', + ]; + + /** @var Javascript|string $init Function used to initialize the state. The init function receives its arguments from the initArgs array expression. You can specify the function definition as either BSON type Code or String. */ + public readonly Javascript|string $init; + + /** @var Javascript|string $accumulate Function used to accumulate documents. The accumulate function receives its arguments from the current state and accumulateArgs array expression. The result of the accumulate function becomes the new state. You can specify the function definition as either BSON type Code or String. */ + public readonly Javascript|string $accumulate; + + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $accumulateArgs Arguments passed to the accumulate function. You can use accumulateArgs to specify what field value(s) to pass to the accumulate function. */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $accumulateArgs; + + /** @var Javascript|string $merge Function used to merge two internal states. merge must be either a String or Code BSON type. merge returns the combined result of the two merged states. For information on when the merge function is called, see Merge Two States with $merge. */ + public readonly Javascript|string $merge; + + /** @var string $lang The language used in the $accumulator code. */ + public readonly string $lang; + + /** @var Optional|BSONArray|PackedArray|ResolvesToArray|array|string $initArgs Arguments passed to the init function. */ + public readonly Optional|PackedArray|ResolvesToArray|BSONArray|array|string $initArgs; + + /** @var Optional|Javascript|string $finalize Function used to update the result of the accumulation. */ + public readonly Optional|Javascript|string $finalize; + + /** + * @param Javascript|string $init Function used to initialize the state. The init function receives its arguments from the initArgs array expression. You can specify the function definition as either BSON type Code or String. + * @param Javascript|string $accumulate Function used to accumulate documents. The accumulate function receives its arguments from the current state and accumulateArgs array expression. The result of the accumulate function becomes the new state. You can specify the function definition as either BSON type Code or String. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $accumulateArgs Arguments passed to the accumulate function. You can use accumulateArgs to specify what field value(s) to pass to the accumulate function. + * @param Javascript|string $merge Function used to merge two internal states. merge must be either a String or Code BSON type. merge returns the combined result of the two merged states. For information on when the merge function is called, see Merge Two States with $merge. + * @param string $lang The language used in the $accumulator code. + * @param Optional|BSONArray|PackedArray|ResolvesToArray|array|string $initArgs Arguments passed to the init function. + * @param Optional|Javascript|string $finalize Function used to update the result of the accumulation. + */ + public function __construct( + Javascript|string $init, + Javascript|string $accumulate, + PackedArray|ResolvesToArray|BSONArray|array|string $accumulateArgs, + Javascript|string $merge, + string $lang, + Optional|PackedArray|ResolvesToArray|BSONArray|array|string $initArgs = Optional::Undefined, + Optional|Javascript|string $finalize = Optional::Undefined, + ) { + if (is_string($init)) { + $init = new Javascript($init); + } + + $this->init = $init; + if (is_string($accumulate)) { + $accumulate = new Javascript($accumulate); + } + + $this->accumulate = $accumulate; + if (is_string($accumulateArgs) && ! str_starts_with($accumulateArgs, '$')) { + throw new InvalidArgumentException('Argument $accumulateArgs can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + if (is_array($accumulateArgs) && ! array_is_list($accumulateArgs)) { + throw new InvalidArgumentException('Expected $accumulateArgs argument to be a list, got an associative array.'); + } + + $this->accumulateArgs = $accumulateArgs; + if (is_string($merge)) { + $merge = new Javascript($merge); + } + + $this->merge = $merge; + $this->lang = $lang; + if (is_string($initArgs) && ! str_starts_with($initArgs, '$')) { + throw new InvalidArgumentException('Argument $initArgs can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + if (is_array($initArgs) && ! array_is_list($initArgs)) { + throw new InvalidArgumentException('Expected $initArgs argument to be a list, got an associative array.'); + } + + $this->initArgs = $initArgs; + if (is_string($finalize)) { + $finalize = new Javascript($finalize); + } + + $this->finalize = $finalize; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Accumulator/AddToSetAccumulator.php b/vendor/mongodb/mongodb/src/Builder/Accumulator/AddToSetAccumulator.php new file mode 100644 index 00000000..7e29eed6 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Accumulator/AddToSetAccumulator.php @@ -0,0 +1,44 @@ + 'expression']; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ) { + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Accumulator/AvgAccumulator.php b/vendor/mongodb/mongodb/src/Builder/Accumulator/AvgAccumulator.php new file mode 100644 index 00000000..afbb1747 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Accumulator/AvgAccumulator.php @@ -0,0 +1,50 @@ + 'expression']; + + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression + */ + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) + { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Accumulator/BottomAccumulator.php b/vendor/mongodb/mongodb/src/Builder/Accumulator/BottomAccumulator.php new file mode 100644 index 00000000..8d4dd417 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Accumulator/BottomAccumulator.php @@ -0,0 +1,52 @@ + 'sortBy', 'output' => 'output']; + + /** @var Document|Serializable|array|stdClass $sortBy Specifies the order of results, with syntax similar to $sort. */ + public readonly Document|Serializable|stdClass|array $sortBy; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $output Represents the output for each element in the group and can be any expression. */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $output; + + /** + * @param Document|Serializable|array|stdClass $sortBy Specifies the order of results, with syntax similar to $sort. + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $output Represents the output for each element in the group and can be any expression. + */ + public function __construct( + Document|Serializable|stdClass|array $sortBy, + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $output, + ) { + $this->sortBy = $sortBy; + $this->output = $output; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Accumulator/BottomNAccumulator.php b/vendor/mongodb/mongodb/src/Builder/Accumulator/BottomNAccumulator.php new file mode 100644 index 00000000..95f0d755 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Accumulator/BottomNAccumulator.php @@ -0,0 +1,68 @@ + 'n', 'sortBy' => 'sortBy', 'output' => 'output']; + + /** @var ResolvesToInt|int|string $n Limits the number of results per group and has to be a positive integral expression that is either a constant or depends on the _id value for $group. */ + public readonly ResolvesToInt|int|string $n; + + /** @var Document|Serializable|array|stdClass $sortBy Specifies the order of results, with syntax similar to $sort. */ + public readonly Document|Serializable|stdClass|array $sortBy; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $output Represents the output for each element in the group and can be any expression. */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $output; + + /** + * @param ResolvesToInt|int|string $n Limits the number of results per group and has to be a positive integral expression that is either a constant or depends on the _id value for $group. + * @param Document|Serializable|array|stdClass $sortBy Specifies the order of results, with syntax similar to $sort. + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $output Represents the output for each element in the group and can be any expression. + */ + public function __construct( + ResolvesToInt|int|string $n, + Document|Serializable|stdClass|array $sortBy, + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $output, + ) { + if (is_string($n) && ! str_starts_with($n, '$')) { + throw new InvalidArgumentException('Argument $n can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->n = $n; + $this->sortBy = $sortBy; + $this->output = $output; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Accumulator/CountAccumulator.php b/vendor/mongodb/mongodb/src/Builder/Accumulator/CountAccumulator.php new file mode 100644 index 00000000..933d86c6 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Accumulator/CountAccumulator.php @@ -0,0 +1,32 @@ + 'expression1', 'expression2' => 'expression2']; + + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression1 */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression1; + + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression2 */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression2; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression1 + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression2 + */ + public function __construct( + Decimal128|Int64|ResolvesToNumber|float|int|string $expression1, + Decimal128|Int64|ResolvesToNumber|float|int|string $expression2, + ) { + if (is_string($expression1) && ! str_starts_with($expression1, '$')) { + throw new InvalidArgumentException('Argument $expression1 can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->expression1 = $expression1; + if (is_string($expression2) && ! str_starts_with($expression2, '$')) { + throw new InvalidArgumentException('Argument $expression2 can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->expression2 = $expression2; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Accumulator/CovarianceSampAccumulator.php b/vendor/mongodb/mongodb/src/Builder/Accumulator/CovarianceSampAccumulator.php new file mode 100644 index 00000000..eacd6631 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Accumulator/CovarianceSampAccumulator.php @@ -0,0 +1,60 @@ + 'expression1', 'expression2' => 'expression2']; + + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression1 */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression1; + + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression2 */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression2; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression1 + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression2 + */ + public function __construct( + Decimal128|Int64|ResolvesToNumber|float|int|string $expression1, + Decimal128|Int64|ResolvesToNumber|float|int|string $expression2, + ) { + if (is_string($expression1) && ! str_starts_with($expression1, '$')) { + throw new InvalidArgumentException('Argument $expression1 can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->expression1 = $expression1; + if (is_string($expression2) && ! str_starts_with($expression2, '$')) { + throw new InvalidArgumentException('Argument $expression2 can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->expression2 = $expression2; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Accumulator/DenseRankAccumulator.php b/vendor/mongodb/mongodb/src/Builder/Accumulator/DenseRankAccumulator.php new file mode 100644 index 00000000..c5bc4bee --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Accumulator/DenseRankAccumulator.php @@ -0,0 +1,30 @@ + 'input', 'unit' => 'unit']; + + /** @var DateTimeInterface|Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int|string $input */ + public readonly DateTimeInterface|Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int|string $input; + + /** + * @var Optional|ResolvesToString|TimeUnit|string $unit A string that specifies the time unit. Use one of these strings: "week", "day","hour", "minute", "second", "millisecond". + * If the sortBy field is not a date, you must omit a unit. If you specify a unit, you must specify a date in the sortBy field. + */ + public readonly Optional|ResolvesToString|TimeUnit|string $unit; + + /** + * @param DateTimeInterface|Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int|string $input + * @param Optional|ResolvesToString|TimeUnit|string $unit A string that specifies the time unit. Use one of these strings: "week", "day","hour", "minute", "second", "millisecond". + * If the sortBy field is not a date, you must omit a unit. If you specify a unit, you must specify a date in the sortBy field. + */ + public function __construct( + DateTimeInterface|Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int|string $input, + Optional|ResolvesToString|TimeUnit|string $unit = Optional::Undefined, + ) { + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->input = $input; + $this->unit = $unit; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Accumulator/DocumentNumberAccumulator.php b/vendor/mongodb/mongodb/src/Builder/Accumulator/DocumentNumberAccumulator.php new file mode 100644 index 00000000..a44f6347 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Accumulator/DocumentNumberAccumulator.php @@ -0,0 +1,30 @@ + 'input', 'N' => 'N', 'alpha' => 'alpha']; + + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $input */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $input; + + /** + * @var Optional|int $N An integer that specifies the number of historical documents that have a significant mathematical weight in the exponential moving average calculation, with the most recent documents contributing the most weight. + * You must specify either N or alpha. You cannot specify both. + * The N value is used in this formula to calculate the current result based on the expression value from the current document being read and the previous result of the calculation: + */ + public readonly Optional|int $N; + + /** + * @var Optional|Int64|float|int $alpha A double that specifies the exponential decay value to use in the exponential moving average calculation. A higher alpha value assigns a lower mathematical significance to previous results from the calculation. + * You must specify either N or alpha. You cannot specify both. + */ + public readonly Optional|Int64|float|int $alpha; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $input + * @param Optional|int $N An integer that specifies the number of historical documents that have a significant mathematical weight in the exponential moving average calculation, with the most recent documents contributing the most weight. + * You must specify either N or alpha. You cannot specify both. + * The N value is used in this formula to calculate the current result based on the expression value from the current document being read and the previous result of the calculation: + * @param Optional|Int64|float|int $alpha A double that specifies the exponential decay value to use in the exponential moving average calculation. A higher alpha value assigns a lower mathematical significance to previous results from the calculation. + * You must specify either N or alpha. You cannot specify both. + */ + public function __construct( + Decimal128|Int64|ResolvesToNumber|float|int|string $input, + Optional|int $N = Optional::Undefined, + Optional|Int64|float|int $alpha = Optional::Undefined, + ) { + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->input = $input; + $this->N = $N; + $this->alpha = $alpha; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Accumulator/FactoryTrait.php b/vendor/mongodb/mongodb/src/Builder/Accumulator/FactoryTrait.php new file mode 100644 index 00000000..9e925754 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Accumulator/FactoryTrait.php @@ -0,0 +1,554 @@ + 'expression']; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ) { + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Accumulator/FirstNAccumulator.php b/vendor/mongodb/mongodb/src/Builder/Accumulator/FirstNAccumulator.php new file mode 100644 index 00000000..03d412fd --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Accumulator/FirstNAccumulator.php @@ -0,0 +1,60 @@ + 'input', 'n' => 'n']; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $input An expression that resolves to the array from which to return n elements. */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $input; + + /** @var ResolvesToInt|int|string $n A positive integral expression that is either a constant or depends on the _id value for $group. */ + public readonly ResolvesToInt|int|string $n; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $input An expression that resolves to the array from which to return n elements. + * @param ResolvesToInt|int|string $n A positive integral expression that is either a constant or depends on the _id value for $group. + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $input, + ResolvesToInt|int|string $n, + ) { + $this->input = $input; + if (is_string($n) && ! str_starts_with($n, '$')) { + throw new InvalidArgumentException('Argument $n can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->n = $n; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Accumulator/IntegralAccumulator.php b/vendor/mongodb/mongodb/src/Builder/Accumulator/IntegralAccumulator.php new file mode 100644 index 00000000..3abe3ff9 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Accumulator/IntegralAccumulator.php @@ -0,0 +1,66 @@ + 'input', 'unit' => 'unit']; + + /** @var DateTimeInterface|Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int|string $input */ + public readonly DateTimeInterface|Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int|string $input; + + /** + * @var Optional|ResolvesToString|TimeUnit|string $unit A string that specifies the time unit. Use one of these strings: "week", "day","hour", "minute", "second", "millisecond". + * If the sortBy field is not a date, you must omit a unit. If you specify a unit, you must specify a date in the sortBy field. + */ + public readonly Optional|ResolvesToString|TimeUnit|string $unit; + + /** + * @param DateTimeInterface|Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int|string $input + * @param Optional|ResolvesToString|TimeUnit|string $unit A string that specifies the time unit. Use one of these strings: "week", "day","hour", "minute", "second", "millisecond". + * If the sortBy field is not a date, you must omit a unit. If you specify a unit, you must specify a date in the sortBy field. + */ + public function __construct( + DateTimeInterface|Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int|string $input, + Optional|ResolvesToString|TimeUnit|string $unit = Optional::Undefined, + ) { + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->input = $input; + $this->unit = $unit; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Accumulator/LastAccumulator.php b/vendor/mongodb/mongodb/src/Builder/Accumulator/LastAccumulator.php new file mode 100644 index 00000000..5d7635d6 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Accumulator/LastAccumulator.php @@ -0,0 +1,44 @@ + 'expression']; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ) { + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Accumulator/LastNAccumulator.php b/vendor/mongodb/mongodb/src/Builder/Accumulator/LastNAccumulator.php new file mode 100644 index 00000000..45a2a0f9 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Accumulator/LastNAccumulator.php @@ -0,0 +1,69 @@ + 'input', 'n' => 'n']; + + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return n elements. */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $input; + + /** @var ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $firstN returns. */ + public readonly ResolvesToInt|int|string $n; + + /** + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return n elements. + * @param ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $firstN returns. + */ + public function __construct( + PackedArray|ResolvesToArray|BSONArray|array|string $input, + ResolvesToInt|int|string $n, + ) { + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + if (is_array($input) && ! array_is_list($input)) { + throw new InvalidArgumentException('Expected $input argument to be a list, got an associative array.'); + } + + $this->input = $input; + if (is_string($n) && ! str_starts_with($n, '$')) { + throw new InvalidArgumentException('Argument $n can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->n = $n; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Accumulator/LinearFillAccumulator.php b/vendor/mongodb/mongodb/src/Builder/Accumulator/LinearFillAccumulator.php new file mode 100644 index 00000000..19126adb --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Accumulator/LinearFillAccumulator.php @@ -0,0 +1,50 @@ + 'expression']; + + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression + */ + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) + { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Accumulator/LocfAccumulator.php b/vendor/mongodb/mongodb/src/Builder/Accumulator/LocfAccumulator.php new file mode 100644 index 00000000..effb6e46 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Accumulator/LocfAccumulator.php @@ -0,0 +1,44 @@ + 'expression']; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ) { + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Accumulator/MaxAccumulator.php b/vendor/mongodb/mongodb/src/Builder/Accumulator/MaxAccumulator.php new file mode 100644 index 00000000..7870591d --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Accumulator/MaxAccumulator.php @@ -0,0 +1,44 @@ + 'expression']; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ) { + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Accumulator/MaxNAccumulator.php b/vendor/mongodb/mongodb/src/Builder/Accumulator/MaxNAccumulator.php new file mode 100644 index 00000000..eafbfbcf --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Accumulator/MaxNAccumulator.php @@ -0,0 +1,67 @@ + 'input', 'n' => 'n']; + + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return the maximal n elements. */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $input; + + /** @var ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $maxN returns. */ + public readonly ResolvesToInt|int|string $n; + + /** + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return the maximal n elements. + * @param ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $maxN returns. + */ + public function __construct( + PackedArray|ResolvesToArray|BSONArray|array|string $input, + ResolvesToInt|int|string $n, + ) { + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + if (is_array($input) && ! array_is_list($input)) { + throw new InvalidArgumentException('Expected $input argument to be a list, got an associative array.'); + } + + $this->input = $input; + if (is_string($n) && ! str_starts_with($n, '$')) { + throw new InvalidArgumentException('Argument $n can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->n = $n; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Accumulator/MedianAccumulator.php b/vendor/mongodb/mongodb/src/Builder/Accumulator/MedianAccumulator.php new file mode 100644 index 00000000..cfdd05e8 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Accumulator/MedianAccumulator.php @@ -0,0 +1,59 @@ + 'input', 'method' => 'method']; + + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $input $median calculates the 50th percentile value of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $median calculation ignores it. */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $input; + + /** @var string $method The method that mongod uses to calculate the 50th percentile value. The method must be 'approximate'. */ + public readonly string $method; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $input $median calculates the 50th percentile value of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $median calculation ignores it. + * @param string $method The method that mongod uses to calculate the 50th percentile value. The method must be 'approximate'. + */ + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $input, string $method) + { + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->input = $input; + $this->method = $method; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Accumulator/MergeObjectsAccumulator.php b/vendor/mongodb/mongodb/src/Builder/Accumulator/MergeObjectsAccumulator.php new file mode 100644 index 00000000..0a567b77 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Accumulator/MergeObjectsAccumulator.php @@ -0,0 +1,49 @@ + 'document']; + + /** @var Document|ResolvesToObject|Serializable|array|stdClass|string $document Any valid expression that resolves to a document. */ + public readonly Document|Serializable|ResolvesToObject|stdClass|array|string $document; + + /** + * @param Document|ResolvesToObject|Serializable|array|stdClass|string $document Any valid expression that resolves to a document. + */ + public function __construct(Document|Serializable|ResolvesToObject|stdClass|array|string $document) + { + if (is_string($document) && ! str_starts_with($document, '$')) { + throw new InvalidArgumentException('Argument $document can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->document = $document; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Accumulator/MinAccumulator.php b/vendor/mongodb/mongodb/src/Builder/Accumulator/MinAccumulator.php new file mode 100644 index 00000000..3b8f5a05 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Accumulator/MinAccumulator.php @@ -0,0 +1,44 @@ + 'expression']; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ) { + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Accumulator/MinNAccumulator.php b/vendor/mongodb/mongodb/src/Builder/Accumulator/MinNAccumulator.php new file mode 100644 index 00000000..2d5eeab7 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Accumulator/MinNAccumulator.php @@ -0,0 +1,67 @@ + 'input', 'n' => 'n']; + + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return the maximal n elements. */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $input; + + /** @var ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $maxN returns. */ + public readonly ResolvesToInt|int|string $n; + + /** + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return the maximal n elements. + * @param ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $maxN returns. + */ + public function __construct( + PackedArray|ResolvesToArray|BSONArray|array|string $input, + ResolvesToInt|int|string $n, + ) { + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + if (is_array($input) && ! array_is_list($input)) { + throw new InvalidArgumentException('Expected $input argument to be a list, got an associative array.'); + } + + $this->input = $input; + if (is_string($n) && ! str_starts_with($n, '$')) { + throw new InvalidArgumentException('Argument $n can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->n = $n; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Accumulator/PercentileAccumulator.php b/vendor/mongodb/mongodb/src/Builder/Accumulator/PercentileAccumulator.php new file mode 100644 index 00000000..030f13aa --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Accumulator/PercentileAccumulator.php @@ -0,0 +1,87 @@ + 'input', 'p' => 'p', 'method' => 'method']; + + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $input $percentile calculates the percentile values of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $percentile calculation ignores it. */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $input; + + /** + * @var BSONArray|PackedArray|ResolvesToArray|array|string $p $percentile calculates a percentile value for each element in p. The elements represent percentages and must evaluate to numeric values in the range 0.0 to 1.0, inclusive. + * $percentile returns results in the same order as the elements in p. + */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $p; + + /** @var string $method The method that mongod uses to calculate the percentile value. The method must be 'approximate'. */ + public readonly string $method; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $input $percentile calculates the percentile values of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $percentile calculation ignores it. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $p $percentile calculates a percentile value for each element in p. The elements represent percentages and must evaluate to numeric values in the range 0.0 to 1.0, inclusive. + * $percentile returns results in the same order as the elements in p. + * @param string $method The method that mongod uses to calculate the percentile value. The method must be 'approximate'. + */ + public function __construct( + Decimal128|Int64|ResolvesToNumber|float|int|string $input, + PackedArray|ResolvesToArray|BSONArray|array|string $p, + string $method, + ) { + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->input = $input; + if (is_string($p) && ! str_starts_with($p, '$')) { + throw new InvalidArgumentException('Argument $p can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + if (is_array($p) && ! array_is_list($p)) { + throw new InvalidArgumentException('Expected $p argument to be a list, got an associative array.'); + } + + $this->p = $p; + $this->method = $method; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Accumulator/PushAccumulator.php b/vendor/mongodb/mongodb/src/Builder/Accumulator/PushAccumulator.php new file mode 100644 index 00000000..85576e0c --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Accumulator/PushAccumulator.php @@ -0,0 +1,44 @@ + 'expression']; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ) { + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Accumulator/RankAccumulator.php b/vendor/mongodb/mongodb/src/Builder/Accumulator/RankAccumulator.php new file mode 100644 index 00000000..ddf2f665 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Accumulator/RankAccumulator.php @@ -0,0 +1,30 @@ + 'output', 'by' => 'by', 'default' => 'default']; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $output Specifies an expression to evaluate and return in the output. */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $output; + + /** + * @var int $by Specifies an integer with a numeric document position relative to the current document in the output. + * For example: + * 1 specifies the document position after the current document. + * -1 specifies the document position before the current document. + * -2 specifies the document position that is two positions before the current document. + */ + public readonly int $by; + + /** + * @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $default Specifies an optional default expression to evaluate if the document position is outside of the implicit $setWindowFields stage window. The implicit window contains all the documents in the partition. + * The default expression must evaluate to a constant value. + * If you do not specify a default expression, $shift returns null for documents whose positions are outside of the implicit $setWindowFields stage window. + */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $default; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $output Specifies an expression to evaluate and return in the output. + * @param int $by Specifies an integer with a numeric document position relative to the current document in the output. + * For example: + * 1 specifies the document position after the current document. + * -1 specifies the document position before the current document. + * -2 specifies the document position that is two positions before the current document. + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $default Specifies an optional default expression to evaluate if the document position is outside of the implicit $setWindowFields stage window. The implicit window contains all the documents in the partition. + * The default expression must evaluate to a constant value. + * If you do not specify a default expression, $shift returns null for documents whose positions are outside of the implicit $setWindowFields stage window. + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $output, + int $by, + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $default, + ) { + $this->output = $output; + $this->by = $by; + $this->default = $default; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Accumulator/StdDevPopAccumulator.php b/vendor/mongodb/mongodb/src/Builder/Accumulator/StdDevPopAccumulator.php new file mode 100644 index 00000000..dd234dab --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Accumulator/StdDevPopAccumulator.php @@ -0,0 +1,51 @@ + 'expression']; + + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression + */ + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) + { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Accumulator/StdDevSampAccumulator.php b/vendor/mongodb/mongodb/src/Builder/Accumulator/StdDevSampAccumulator.php new file mode 100644 index 00000000..897e0856 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Accumulator/StdDevSampAccumulator.php @@ -0,0 +1,51 @@ + 'expression']; + + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression + */ + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) + { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Accumulator/SumAccumulator.php b/vendor/mongodb/mongodb/src/Builder/Accumulator/SumAccumulator.php new file mode 100644 index 00000000..fa8cdb64 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Accumulator/SumAccumulator.php @@ -0,0 +1,50 @@ + 'expression']; + + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression + */ + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) + { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Accumulator/TopAccumulator.php b/vendor/mongodb/mongodb/src/Builder/Accumulator/TopAccumulator.php new file mode 100644 index 00000000..d7fb258f --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Accumulator/TopAccumulator.php @@ -0,0 +1,53 @@ + 'sortBy', 'output' => 'output']; + + /** @var Document|Serializable|array|stdClass $sortBy Specifies the order of results, with syntax similar to $sort. */ + public readonly Document|Serializable|stdClass|array $sortBy; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $output Represents the output for each element in the group and can be any expression. */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $output; + + /** + * @param Document|Serializable|array|stdClass $sortBy Specifies the order of results, with syntax similar to $sort. + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $output Represents the output for each element in the group and can be any expression. + */ + public function __construct( + Document|Serializable|stdClass|array $sortBy, + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $output, + ) { + $this->sortBy = $sortBy; + $this->output = $output; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Accumulator/TopNAccumulator.php b/vendor/mongodb/mongodb/src/Builder/Accumulator/TopNAccumulator.php new file mode 100644 index 00000000..45087d5e --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Accumulator/TopNAccumulator.php @@ -0,0 +1,68 @@ + 'n', 'sortBy' => 'sortBy', 'output' => 'output']; + + /** @var ResolvesToInt|int|string $n limits the number of results per group and has to be a positive integral expression that is either a constant or depends on the _id value for $group. */ + public readonly ResolvesToInt|int|string $n; + + /** @var Document|Serializable|array|stdClass $sortBy Specifies the order of results, with syntax similar to $sort. */ + public readonly Document|Serializable|stdClass|array $sortBy; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $output Represents the output for each element in the group and can be any expression. */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $output; + + /** + * @param ResolvesToInt|int|string $n limits the number of results per group and has to be a positive integral expression that is either a constant or depends on the _id value for $group. + * @param Document|Serializable|array|stdClass $sortBy Specifies the order of results, with syntax similar to $sort. + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $output Represents the output for each element in the group and can be any expression. + */ + public function __construct( + ResolvesToInt|int|string $n, + Document|Serializable|stdClass|array $sortBy, + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $output, + ) { + if (is_string($n) && ! str_starts_with($n, '$')) { + throw new InvalidArgumentException('Argument $n can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->n = $n; + $this->sortBy = $sortBy; + $this->output = $output; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/BuilderEncoder.php b/vendor/mongodb/mongodb/src/Builder/BuilderEncoder.php new file mode 100644 index 00000000..833409b0 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/BuilderEncoder.php @@ -0,0 +1,109 @@ + */ +final class BuilderEncoder implements Encoder +{ + /** @template-use EncodeIfSupported */ + use EncodeIfSupported; + + /** @var array */ + private array $encoders; + + /** @var array */ + private array $cachedEncoders = []; + + /** @param array $encoders */ + public function __construct(array $encoders = []) + { + $self = WeakReference::create($this); + + $this->encoders = $encoders + [ + Pipeline::class => new PipelineEncoder($self), + Variable::class => new VariableEncoder(), + DictionaryInterface::class => new DictionaryEncoder(), + FieldPathInterface::class => new FieldPathEncoder(), + CombinedFieldQuery::class => new CombinedFieldQueryEncoder($self), + QueryObject::class => new QueryEncoder($self), + OutputWindow::class => new OutputWindowEncoder($self), + OperatorInterface::class => new OperatorEncoder($self), + DateTimeInterface::class => new DateTimeEncoder(), + ]; + } + + /** @psalm-assert-if-true object $value */ + public function canEncode(mixed $value): bool + { + if (! is_object($value)) { + return false; + } + + return (bool) $this->getEncoderFor($value)?->canEncode($value); + } + + public function encode(mixed $value): Type|stdClass|array|string|int + { + $encoder = $this->getEncoderFor($value); + + if (! $encoder?->canEncode($value)) { + throw UnsupportedValueException::invalidEncodableValue($value); + } + + return $encoder->encode($value); + } + + private function getEncoderFor(object $value): Encoder|null + { + $valueClass = $value::class; + if (array_key_exists($valueClass, $this->cachedEncoders)) { + return $this->cachedEncoders[$valueClass]; + } + + // First attempt: match class name exactly + if (isset($this->encoders[$valueClass])) { + return $this->cachedEncoders[$valueClass] = $this->encoders[$valueClass]; + } + + // Second attempt: catch child classes + foreach ($this->encoders as $className => $encoder) { + if ($value instanceof $className) { + return $this->cachedEncoders[$valueClass] = $encoder; + } + } + + return $this->cachedEncoders[$valueClass] = null; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Encoder/CombinedFieldQueryEncoder.php b/vendor/mongodb/mongodb/src/Builder/Encoder/CombinedFieldQueryEncoder.php new file mode 100644 index 00000000..11875790 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Encoder/CombinedFieldQueryEncoder.php @@ -0,0 +1,57 @@ + + * @internal + */ +final class CombinedFieldQueryEncoder implements Encoder +{ + /** @template-use EncodeIfSupported */ + use EncodeIfSupported; + use RecursiveEncode; + + public function canEncode(mixed $value): bool + { + return $value instanceof CombinedFieldQuery; + } + + public function encode(mixed $value): stdClass + { + if (! $this->canEncode($value)) { + throw UnsupportedValueException::invalidEncodableValue($value); + } + + $result = new stdClass(); + foreach ($value->fieldQueries as $filter) { + $filter = $this->recursiveEncode($filter); + if (is_object($filter)) { + $filter = get_object_vars($filter); + } elseif (! is_array($filter)) { + throw new LogicException(sprintf('Query filters must an array or an object. Got "%s"', get_debug_type($filter))); + } + + foreach ($filter as $key => $filterValue) { + $result->{$key} = $filterValue; + } + } + + return $result; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Encoder/DateTimeEncoder.php b/vendor/mongodb/mongodb/src/Builder/Encoder/DateTimeEncoder.php new file mode 100644 index 00000000..6926bd81 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Encoder/DateTimeEncoder.php @@ -0,0 +1,36 @@ + + * @internal + */ +final class DateTimeEncoder implements Encoder +{ + /** @template-use EncodeIfSupported */ + use EncodeIfSupported; + + /** @psalm-assert-if-true DateTimeInterface $value */ + public function canEncode(mixed $value): bool + { + return $value instanceof DateTimeInterface; + } + + public function encode(mixed $value): UTCDateTime + { + if (! $this->canEncode($value)) { + throw UnsupportedValueException::invalidEncodableValue($value); + } + + return new UTCDateTime($value); + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Encoder/DictionaryEncoder.php b/vendor/mongodb/mongodb/src/Builder/Encoder/DictionaryEncoder.php new file mode 100644 index 00000000..dc89cff1 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Encoder/DictionaryEncoder.php @@ -0,0 +1,35 @@ + + * @internal + */ +final class DictionaryEncoder implements Encoder +{ + /** @template-use EncodeIfSupported */ + use EncodeIfSupported; + + public function canEncode(mixed $value): bool + { + return $value instanceof DictionaryInterface; + } + + public function encode(mixed $value): string|int|array|stdClass + { + if (! $this->canEncode($value)) { + throw UnsupportedValueException::invalidEncodableValue($value); + } + + return $value->getValue(); + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Encoder/FieldPathEncoder.php b/vendor/mongodb/mongodb/src/Builder/Encoder/FieldPathEncoder.php new file mode 100644 index 00000000..3766f9a0 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Encoder/FieldPathEncoder.php @@ -0,0 +1,34 @@ + + * @internal + */ +final class FieldPathEncoder implements Encoder +{ + /** @template-use EncodeIfSupported */ + use EncodeIfSupported; + + public function canEncode(mixed $value): bool + { + return $value instanceof FieldPathInterface; + } + + public function encode(mixed $value): string + { + if (! $this->canEncode($value)) { + throw UnsupportedValueException::invalidEncodableValue($value); + } + + return '$' . $value->name; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Encoder/OperatorEncoder.php b/vendor/mongodb/mongodb/src/Builder/Encoder/OperatorEncoder.php new file mode 100644 index 00000000..8f81edfa --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Encoder/OperatorEncoder.php @@ -0,0 +1,126 @@ + + * @internal + */ +final class OperatorEncoder implements Encoder +{ + /** @template-use EncodeIfSupported */ + use EncodeIfSupported; + use RecursiveEncode; + + public function canEncode(mixed $value): bool + { + return $value instanceof OperatorInterface; + } + + public function encode(mixed $value): stdClass + { + if (! $this->canEncode($value)) { + throw UnsupportedValueException::invalidEncodableValue($value); + } + + return match ($value::ENCODE) { + Encode::Single => $this->encodeAsSingle($value), + Encode::Array => $this->encodeAsArray($value), + Encode::Object => $this->encodeAsObject($value), + default => throw new LogicException(sprintf('Class "%s" does not have a valid ENCODE constant.', $value::class)), + }; + } + + /** + * Encode the value as an array of properties, in the order they are defined in the class. + */ + private function encodeAsArray(OperatorInterface $value): stdClass + { + $result = []; + foreach ($value::PROPERTIES as $prop => $name) { + $val = $value->$prop; + // Skip optional arguments. For example, the $slice expression operator has an optional argument + // in the middle of the array. + if ($val === Optional::Undefined) { + continue; + } + + $result[] = $this->recursiveEncode($val); + } + + return $this->wrap($value, $result); + } + + /** + * Encode the value as an object with properties. Property names are + * mapped by the PROPERTIES constant. + */ + private function encodeAsObject(OperatorInterface $value): stdClass + { + $result = new stdClass(); + foreach ($value::PROPERTIES as $prop => $name) { + $val = $value->$prop; + + // Skip optional arguments. If they have a default value, it is resolved by the server. + if ($val === Optional::Undefined) { + continue; + } + + // The name is null for arguments with "mergeObject: true" in the YAML file, + // the value properties are merged into the parent object. + if ($name === null) { + $val = $this->recursiveEncode($val); + foreach ($val as $k => $v) { + $result->{$k} = $v; + } + } else { + $result->{$name} = $this->recursiveEncode($val); + } + } + + if ($value::NAME === null) { + return $result; + } + + return $this->wrap($value, $result); + } + + /** + * Get the unique property of the operator as value + */ + private function encodeAsSingle(OperatorInterface $value): stdClass + { + foreach ($value::PROPERTIES as $prop => $name) { + $result = $this->recursiveEncode($value->$prop); + + return $this->wrap($value, $result); + } + + throw new LogicException(sprintf('Class "%s" does not have a single property.', $value::class)); + } + + private function wrap(OperatorInterface $value, mixed $result): stdClass + { + assert(is_string($value::NAME)); + + $object = new stdClass(); + $object->{$value::NAME} = $result; + + return $object; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Encoder/OutputWindowEncoder.php b/vendor/mongodb/mongodb/src/Builder/Encoder/OutputWindowEncoder.php new file mode 100644 index 00000000..4e435a98 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Encoder/OutputWindowEncoder.php @@ -0,0 +1,65 @@ + + * @internal + */ +final class OutputWindowEncoder implements Encoder +{ + /** @template-use EncodeIfSupported */ + use EncodeIfSupported; + use RecursiveEncode; + + public function canEncode(mixed $value): bool + { + return $value instanceof OutputWindow; + } + + public function encode(mixed $value): stdClass + { + if (! $this->canEncode($value)) { + throw UnsupportedValueException::invalidEncodableValue($value); + } + + $result = $this->recursiveEncode($value->operator); + + // Transform the result into an stdClass if a document is provided + if (! $value->operator instanceof WindowInterface) { + if (! is_first_key_operator($result)) { + $firstKey = array_key_first((array) $result); + + throw new LogicException(sprintf('Expected OutputWindow::$operator to be an operator. Got "%s"', $firstKey ?? 'null')); + } + + $result = (object) $result; + } + + if (! $result instanceof stdClass) { + throw new LogicException(sprintf('Expected OutputWindow::$operator to be an stdClass, array or WindowInterface. Got "%s"', get_debug_type($result))); + } + + if ($value->window !== Optional::Undefined) { + $result->window = $this->recursiveEncode($value->window); + } + + return $result; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Encoder/PipelineEncoder.php b/vendor/mongodb/mongodb/src/Builder/Encoder/PipelineEncoder.php new file mode 100644 index 00000000..c4c0829c --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Encoder/PipelineEncoder.php @@ -0,0 +1,42 @@ +, Pipeline> + * @internal + */ +final class PipelineEncoder implements Encoder +{ + /** @template-use EncodeIfSupported, Pipeline> */ + use EncodeIfSupported; + use RecursiveEncode; + + /** @psalm-assert-if-true Pipeline $value */ + public function canEncode(mixed $value): bool + { + return $value instanceof Pipeline; + } + + /** @return list */ + public function encode(mixed $value): array + { + if (! $this->canEncode($value)) { + throw UnsupportedValueException::invalidEncodableValue($value); + } + + $encoded = []; + foreach ($value->getIterator() as $stage) { + $encoded[] = $this->recursiveEncode($stage); + } + + return $encoded; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Encoder/QueryEncoder.php b/vendor/mongodb/mongodb/src/Builder/Encoder/QueryEncoder.php new file mode 100644 index 00000000..19f21897 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Encoder/QueryEncoder.php @@ -0,0 +1,62 @@ + + * @internal + */ +final class QueryEncoder implements Encoder +{ + /** @template-use EncodeIfSupported */ + use EncodeIfSupported; + use RecursiveEncode; + + public function canEncode(mixed $value): bool + { + return $value instanceof QueryObject; + } + + public function encode(mixed $value): stdClass + { + if (! $this->canEncode($value)) { + throw UnsupportedValueException::invalidEncodableValue($value); + } + + $result = new stdClass(); + foreach ($value->queries as $key => $value) { + if ($value instanceof QueryInterface) { + // The sub-objects is merged into the main object, replacing duplicate keys + foreach (get_object_vars($this->recursiveEncode($value)) as $subKey => $subValue) { + if (property_exists($result, $subKey)) { + throw new LogicException(sprintf('Duplicate key "%s" in query object', $subKey)); + } + + $result->{$subKey} = $subValue; + } + } else { + if (property_exists($result, (string) $key)) { + throw new LogicException(sprintf('Duplicate key "%s" in query object', $key)); + } + + $result->{$key} = $this->recursiveEncode($value); + } + } + + return $result; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Encoder/RecursiveEncode.php b/vendor/mongodb/mongodb/src/Builder/Encoder/RecursiveEncode.php new file mode 100644 index 00000000..e83af8a2 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Encoder/RecursiveEncode.php @@ -0,0 +1,59 @@ + $encoder */ + final public function __construct(private readonly WeakReference $encoder) + { + } + + /** + * Nested arrays and objects must be encoded recursively. + * + * @psalm-template T + * @psalm-param T $value + * + * @psalm-return (T is stdClass ? stdClass : (T is array ? array : mixed)) + * + * @template T + */ + private function recursiveEncode(mixed $value): mixed + { + if (is_array($value)) { + foreach ($value as $key => $val) { + $value[$key] = $this->recursiveEncode($val); + } + + return $value; + } + + if ($value instanceof stdClass) { + foreach (get_object_vars($value) as $key => $val) { + $value->{$key} = $this->recursiveEncode($val); + } + + return $value; + } + + /** + * If the BuilderEncoder instance is removed from the memory, the + * instances of the classes using this trait will be removed as well. + * Therefore, the weak reference will never return null. + * + * @psalm-suppress PossiblyNullReference + */ + return $this->encoder->get()->encodeIfSupported($value); + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Encoder/VariableEncoder.php b/vendor/mongodb/mongodb/src/Builder/Encoder/VariableEncoder.php new file mode 100644 index 00000000..05197797 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Encoder/VariableEncoder.php @@ -0,0 +1,35 @@ + + * @internal + */ +final class VariableEncoder implements Encoder +{ + /** @template-use EncodeIfSupported */ + use EncodeIfSupported; + + public function canEncode(mixed $value): bool + { + return $value instanceof Variable; + } + + public function encode(mixed $value): string + { + if (! $this->canEncode($value)) { + throw UnsupportedValueException::invalidEncodableValue($value); + } + + // TODO: needs method because interfaces can't have properties + return '$$' . $value->name; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression.php b/vendor/mongodb/mongodb/src/Builder/Expression.php new file mode 100644 index 00000000..9e477914 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression.php @@ -0,0 +1,21 @@ + 'value']; + + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $value */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $value; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $value + */ + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $value) + { + if (is_string($value) && ! str_starts_with($value, '$')) { + throw new InvalidArgumentException('Argument $value can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->value = $value; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/AcosOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/AcosOperator.php new file mode 100644 index 00000000..4b5017ec --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/AcosOperator.php @@ -0,0 +1,52 @@ + 'expression']; + + /** + * @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression $acos takes any valid expression that resolves to a number between -1 and 1, e.g. -1 <= value <= 1. + * $acos returns values in radians. Use $radiansToDegrees operator to convert the output value from radians to degrees. + * By default $acos returns values as a double. $acos can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. + */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $acos takes any valid expression that resolves to a number between -1 and 1, e.g. -1 <= value <= 1. + * $acos returns values in radians. Use $radiansToDegrees operator to convert the output value from radians to degrees. + * By default $acos returns values as a double. $acos can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. + */ + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) + { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/AcoshOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/AcoshOperator.php new file mode 100644 index 00000000..1da69026 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/AcoshOperator.php @@ -0,0 +1,52 @@ + 'expression']; + + /** + * @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression $acosh takes any valid expression that resolves to a number between 1 and +Infinity, e.g. 1 <= value <= +Infinity. + * $acosh returns values in radians. Use $radiansToDegrees operator to convert the output value from radians to degrees. + * By default $acosh returns values as a double. $acosh can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. + */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $acosh takes any valid expression that resolves to a number between 1 and +Infinity, e.g. 1 <= value <= +Infinity. + * $acosh returns values in radians. Use $radiansToDegrees operator to convert the output value from radians to degrees. + * By default $acosh returns values as a double. $acosh can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. + */ + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) + { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/AddOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/AddOperator.php new file mode 100644 index 00000000..9eb139f3 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/AddOperator.php @@ -0,0 +1,53 @@ + 'expression']; + + /** @var list $expression The arguments can be any valid expression as long as they resolve to either all numbers or to numbers and a date. */ + public readonly array $expression; + + /** + * @param DateTimeInterface|Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int|string ...$expression The arguments can be any valid expression as long as they resolve to either all numbers or to numbers and a date. + * @no-named-arguments + */ + public function __construct( + DateTimeInterface|Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int|string ...$expression, + ) { + if (\count($expression) < 1) { + throw new InvalidArgumentException(\sprintf('Expected at least %d values for $expression, got %d.', 1, \count($expression))); + } + + if (! array_is_list($expression)) { + throw new InvalidArgumentException('Expected $expression arguments to be a list (array), named arguments are not supported'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/AllElementsTrueOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/AllElementsTrueOperator.php new file mode 100644 index 00000000..282de6df --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/AllElementsTrueOperator.php @@ -0,0 +1,52 @@ + 'expression']; + + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $expression */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $expression; + + /** + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression + */ + public function __construct(PackedArray|ResolvesToArray|BSONArray|array|string $expression) + { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + if (is_array($expression) && ! array_is_list($expression)) { + throw new InvalidArgumentException('Expected $expression argument to be a list, got an associative array.'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/AndOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/AndOperator.php new file mode 100644 index 00000000..5e912167 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/AndOperator.php @@ -0,0 +1,55 @@ + 'expression']; + + /** @var list $expression */ + public readonly array $expression; + + /** + * @param DateTimeInterface|Decimal128|ExpressionInterface|Int64|ResolvesToBool|ResolvesToNull|ResolvesToNumber|ResolvesToString|Type|array|bool|float|int|null|stdClass|string ...$expression + * @no-named-arguments + */ + public function __construct( + DateTimeInterface|Decimal128|Int64|Type|ResolvesToBool|ResolvesToNull|ResolvesToNumber|ResolvesToString|ExpressionInterface|stdClass|array|bool|float|int|null|string ...$expression, + ) { + if (\count($expression) < 1) { + throw new InvalidArgumentException(\sprintf('Expected at least %d values for $expression, got %d.', 1, \count($expression))); + } + + if (! array_is_list($expression)) { + throw new InvalidArgumentException('Expected $expression arguments to be a list (array), named arguments are not supported'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/AnyElementTrueOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/AnyElementTrueOperator.php new file mode 100644 index 00000000..c3566ca9 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/AnyElementTrueOperator.php @@ -0,0 +1,52 @@ + 'expression']; + + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $expression */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $expression; + + /** + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression + */ + public function __construct(PackedArray|ResolvesToArray|BSONArray|array|string $expression) + { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + if (is_array($expression) && ! array_is_list($expression)) { + throw new InvalidArgumentException('Expected $expression argument to be a list, got an associative array.'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/ArrayElemAtOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/ArrayElemAtOperator.php new file mode 100644 index 00000000..9cbca3cf --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/ArrayElemAtOperator.php @@ -0,0 +1,63 @@ + 'array', 'idx' => 'idx']; + + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $array */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $array; + + /** @var ResolvesToInt|int|string $idx */ + public readonly ResolvesToInt|int|string $idx; + + /** + * @param BSONArray|PackedArray|ResolvesToArray|array|string $array + * @param ResolvesToInt|int|string $idx + */ + public function __construct( + PackedArray|ResolvesToArray|BSONArray|array|string $array, + ResolvesToInt|int|string $idx, + ) { + if (is_string($array) && ! str_starts_with($array, '$')) { + throw new InvalidArgumentException('Argument $array can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + if (is_array($array) && ! array_is_list($array)) { + throw new InvalidArgumentException('Expected $array argument to be a list, got an associative array.'); + } + + $this->array = $array; + if (is_string($idx) && ! str_starts_with($idx, '$')) { + throw new InvalidArgumentException('Argument $idx can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->idx = $idx; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/ArrayFieldPath.php b/vendor/mongodb/mongodb/src/Builder/Expression/ArrayFieldPath.php new file mode 100644 index 00000000..f475beb1 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/ArrayFieldPath.php @@ -0,0 +1,29 @@ +name = $name; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/ArrayToObjectOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/ArrayToObjectOperator.php new file mode 100644 index 00000000..3a881363 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/ArrayToObjectOperator.php @@ -0,0 +1,52 @@ + 'array']; + + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $array */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $array; + + /** + * @param BSONArray|PackedArray|ResolvesToArray|array|string $array + */ + public function __construct(PackedArray|ResolvesToArray|BSONArray|array|string $array) + { + if (is_string($array) && ! str_starts_with($array, '$')) { + throw new InvalidArgumentException('Argument $array can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + if (is_array($array) && ! array_is_list($array)) { + throw new InvalidArgumentException('Expected $array argument to be a list, got an associative array.'); + } + + $this->array = $array; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/AsinOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/AsinOperator.php new file mode 100644 index 00000000..d814f6cf --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/AsinOperator.php @@ -0,0 +1,52 @@ + 'expression']; + + /** + * @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression $asin takes any valid expression that resolves to a number between -1 and 1, e.g. -1 <= value <= 1. + * $asin returns values in radians. Use $radiansToDegrees operator to convert the output value from radians to degrees. + * By default $asin returns values as a double. $asin can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. + */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $asin takes any valid expression that resolves to a number between -1 and 1, e.g. -1 <= value <= 1. + * $asin returns values in radians. Use $radiansToDegrees operator to convert the output value from radians to degrees. + * By default $asin returns values as a double. $asin can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. + */ + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) + { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/AsinhOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/AsinhOperator.php new file mode 100644 index 00000000..edc2f206 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/AsinhOperator.php @@ -0,0 +1,52 @@ + 'expression']; + + /** + * @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression $asinh takes any valid expression that resolves to a number. + * $asinh returns values in radians. Use $radiansToDegrees operator to convert the output value from radians to degrees. + * By default $asinh returns values as a double. $asinh can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. + */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $asinh takes any valid expression that resolves to a number. + * $asinh returns values in radians. Use $radiansToDegrees operator to convert the output value from radians to degrees. + * By default $asinh returns values as a double. $asinh can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. + */ + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) + { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/Atan2Operator.php b/vendor/mongodb/mongodb/src/Builder/Expression/Atan2Operator.php new file mode 100644 index 00000000..f0af1fc9 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/Atan2Operator.php @@ -0,0 +1,63 @@ + 'y', 'x' => 'x']; + + /** + * @var Decimal128|Int64|ResolvesToNumber|float|int|string $y $atan2 takes any valid expression that resolves to a number. + * $atan2 returns values in radians. Use $radiansToDegrees operator to convert the output value from radians to degrees. + * By default $atan returns values as a double. $atan2 can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. + */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $y; + + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $x */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $x; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $y $atan2 takes any valid expression that resolves to a number. + * $atan2 returns values in radians. Use $radiansToDegrees operator to convert the output value from radians to degrees. + * By default $atan returns values as a double. $atan2 can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $x + */ + public function __construct( + Decimal128|Int64|ResolvesToNumber|float|int|string $y, + Decimal128|Int64|ResolvesToNumber|float|int|string $x, + ) { + if (is_string($y) && ! str_starts_with($y, '$')) { + throw new InvalidArgumentException('Argument $y can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->y = $y; + if (is_string($x) && ! str_starts_with($x, '$')) { + throw new InvalidArgumentException('Argument $x can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->x = $x; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/AtanOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/AtanOperator.php new file mode 100644 index 00000000..938a9b00 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/AtanOperator.php @@ -0,0 +1,52 @@ + 'expression']; + + /** + * @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression $atan takes any valid expression that resolves to a number. + * $atan returns values in radians. Use $radiansToDegrees operator to convert the output value from radians to degrees. + * By default $atan returns values as a double. $atan can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. + */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $atan takes any valid expression that resolves to a number. + * $atan returns values in radians. Use $radiansToDegrees operator to convert the output value from radians to degrees. + * By default $atan returns values as a double. $atan can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. + */ + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) + { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/AtanhOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/AtanhOperator.php new file mode 100644 index 00000000..fde1dae1 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/AtanhOperator.php @@ -0,0 +1,52 @@ + 'expression']; + + /** + * @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression $atanh takes any valid expression that resolves to a number between -1 and 1, e.g. -1 <= value <= 1. + * $atanh returns values in radians. Use $radiansToDegrees operator to convert the output value from radians to degrees. + * By default $atanh returns values as a double. $atanh can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. + */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $atanh takes any valid expression that resolves to a number between -1 and 1, e.g. -1 <= value <= 1. + * $atanh returns values in radians. Use $radiansToDegrees operator to convert the output value from radians to degrees. + * By default $atanh returns values as a double. $atanh can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. + */ + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) + { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/AvgOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/AvgOperator.php new file mode 100644 index 00000000..52be761a --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/AvgOperator.php @@ -0,0 +1,51 @@ + 'expression']; + + /** @var list $expression */ + public readonly array $expression; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string ...$expression + * @no-named-arguments + */ + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string ...$expression) + { + if (\count($expression) < 1) { + throw new InvalidArgumentException(\sprintf('Expected at least %d values for $expression, got %d.', 1, \count($expression))); + } + + if (! array_is_list($expression)) { + throw new InvalidArgumentException('Expected $expression arguments to be a list (array), named arguments are not supported'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/BinDataFieldPath.php b/vendor/mongodb/mongodb/src/Builder/Expression/BinDataFieldPath.php new file mode 100644 index 00000000..77c2d39e --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/BinDataFieldPath.php @@ -0,0 +1,29 @@ +name = $name; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/BinarySizeOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/BinarySizeOperator.php new file mode 100644 index 00000000..792da66b --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/BinarySizeOperator.php @@ -0,0 +1,37 @@ + 'expression']; + + /** @var Binary|ResolvesToBinData|ResolvesToNull|ResolvesToString|null|string $expression */ + public readonly Binary|ResolvesToBinData|ResolvesToNull|ResolvesToString|null|string $expression; + + /** + * @param Binary|ResolvesToBinData|ResolvesToNull|ResolvesToString|null|string $expression + */ + public function __construct(Binary|ResolvesToBinData|ResolvesToNull|ResolvesToString|null|string $expression) + { + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/BitAndOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/BitAndOperator.php new file mode 100644 index 00000000..eb6fffac --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/BitAndOperator.php @@ -0,0 +1,50 @@ + 'expression']; + + /** @var list $expression */ + public readonly array $expression; + + /** + * @param Int64|ResolvesToInt|ResolvesToLong|int|string ...$expression + * @no-named-arguments + */ + public function __construct(Int64|ResolvesToInt|ResolvesToLong|int|string ...$expression) + { + if (\count($expression) < 1) { + throw new InvalidArgumentException(\sprintf('Expected at least %d values for $expression, got %d.', 1, \count($expression))); + } + + if (! array_is_list($expression)) { + throw new InvalidArgumentException('Expected $expression arguments to be a list (array), named arguments are not supported'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/BitNotOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/BitNotOperator.php new file mode 100644 index 00000000..adac4fc6 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/BitNotOperator.php @@ -0,0 +1,46 @@ + 'expression']; + + /** @var Int64|ResolvesToInt|ResolvesToLong|int|string $expression */ + public readonly Int64|ResolvesToInt|ResolvesToLong|int|string $expression; + + /** + * @param Int64|ResolvesToInt|ResolvesToLong|int|string $expression + */ + public function __construct(Int64|ResolvesToInt|ResolvesToLong|int|string $expression) + { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/BitOrOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/BitOrOperator.php new file mode 100644 index 00000000..bc68838e --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/BitOrOperator.php @@ -0,0 +1,50 @@ + 'expression']; + + /** @var list $expression */ + public readonly array $expression; + + /** + * @param Int64|ResolvesToInt|ResolvesToLong|int|string ...$expression + * @no-named-arguments + */ + public function __construct(Int64|ResolvesToInt|ResolvesToLong|int|string ...$expression) + { + if (\count($expression) < 1) { + throw new InvalidArgumentException(\sprintf('Expected at least %d values for $expression, got %d.', 1, \count($expression))); + } + + if (! array_is_list($expression)) { + throw new InvalidArgumentException('Expected $expression arguments to be a list (array), named arguments are not supported'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/BitXorOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/BitXorOperator.php new file mode 100644 index 00000000..adbf5eb2 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/BitXorOperator.php @@ -0,0 +1,50 @@ + 'expression']; + + /** @var list $expression */ + public readonly array $expression; + + /** + * @param Int64|ResolvesToInt|ResolvesToLong|int|string ...$expression + * @no-named-arguments + */ + public function __construct(Int64|ResolvesToInt|ResolvesToLong|int|string ...$expression) + { + if (\count($expression) < 1) { + throw new InvalidArgumentException(\sprintf('Expected at least %d values for $expression, got %d.', 1, \count($expression))); + } + + if (! array_is_list($expression)) { + throw new InvalidArgumentException('Expected $expression arguments to be a list (array), named arguments are not supported'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/BoolFieldPath.php b/vendor/mongodb/mongodb/src/Builder/Expression/BoolFieldPath.php new file mode 100644 index 00000000..1dff80de --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/BoolFieldPath.php @@ -0,0 +1,29 @@ +name = $name; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/BsonSizeOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/BsonSizeOperator.php new file mode 100644 index 00000000..37626d0d --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/BsonSizeOperator.php @@ -0,0 +1,48 @@ + 'object']; + + /** @var Document|ResolvesToNull|ResolvesToObject|Serializable|array|null|stdClass|string $object */ + public readonly Document|Serializable|ResolvesToNull|ResolvesToObject|stdClass|array|null|string $object; + + /** + * @param Document|ResolvesToNull|ResolvesToObject|Serializable|array|null|stdClass|string $object + */ + public function __construct( + Document|Serializable|ResolvesToNull|ResolvesToObject|stdClass|array|null|string $object, + ) { + if (is_string($object) && ! str_starts_with($object, '$')) { + throw new InvalidArgumentException('Argument $object can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->object = $object; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/CaseOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/CaseOperator.php new file mode 100644 index 00000000..686d27ec --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/CaseOperator.php @@ -0,0 +1,56 @@ + 'case', 'then' => 'then']; + + /** @var ResolvesToBool|bool|string $case Can be any valid expression that resolves to a boolean. If the result is not a boolean, it is coerced to a boolean value. More information about how MongoDB evaluates expressions as either true or false can be found here. */ + public readonly ResolvesToBool|bool|string $case; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $then Can be any valid expression. */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $then; + + /** + * @param ResolvesToBool|bool|string $case Can be any valid expression that resolves to a boolean. If the result is not a boolean, it is coerced to a boolean value. More information about how MongoDB evaluates expressions as either true or false can be found here. + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $then Can be any valid expression. + */ + public function __construct( + ResolvesToBool|bool|string $case, + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $then, + ) { + if (is_string($case) && ! str_starts_with($case, '$')) { + throw new InvalidArgumentException('Argument $case can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->case = $case; + $this->then = $then; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/CeilOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/CeilOperator.php new file mode 100644 index 00000000..9f318c45 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/CeilOperator.php @@ -0,0 +1,46 @@ + 'expression']; + + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression If the argument resolves to a value of null or refers to a field that is missing, $ceil returns null. If the argument resolves to NaN, $ceil returns NaN. */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression If the argument resolves to a value of null or refers to a field that is missing, $ceil returns null. If the argument resolves to NaN, $ceil returns NaN. + */ + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) + { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/CmpOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/CmpOperator.php new file mode 100644 index 00000000..7e090f24 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/CmpOperator.php @@ -0,0 +1,47 @@ + 'expression1', 'expression2' => 'expression2']; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression1 */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression1; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression2 */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression2; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression1 + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression2 + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression1, + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression2, + ) { + $this->expression1 = $expression1; + $this->expression2 = $expression2; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/ConcatArraysOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/ConcatArraysOperator.php new file mode 100644 index 00000000..12f86208 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/ConcatArraysOperator.php @@ -0,0 +1,50 @@ + 'array']; + + /** @var list $array */ + public readonly array $array; + + /** + * @param BSONArray|PackedArray|ResolvesToArray|array|string ...$array + * @no-named-arguments + */ + public function __construct(PackedArray|ResolvesToArray|BSONArray|array|string ...$array) + { + if (\count($array) < 1) { + throw new InvalidArgumentException(\sprintf('Expected at least %d values for $array, got %d.', 1, \count($array))); + } + + if (! array_is_list($array)) { + throw new InvalidArgumentException('Expected $array arguments to be a list (array), named arguments are not supported'); + } + + $this->array = $array; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/ConcatOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/ConcatOperator.php new file mode 100644 index 00000000..c8497be0 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/ConcatOperator.php @@ -0,0 +1,48 @@ + 'expression']; + + /** @var list $expression */ + public readonly array $expression; + + /** + * @param ResolvesToString|string ...$expression + * @no-named-arguments + */ + public function __construct(ResolvesToString|string ...$expression) + { + if (\count($expression) < 1) { + throw new InvalidArgumentException(\sprintf('Expected at least %d values for $expression, got %d.', 1, \count($expression))); + } + + if (! array_is_list($expression)) { + throw new InvalidArgumentException('Expected $expression arguments to be a list (array), named arguments are not supported'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/CondOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/CondOperator.php new file mode 100644 index 00000000..ba34c910 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/CondOperator.php @@ -0,0 +1,61 @@ + 'if', 'then' => 'then', 'else' => 'else']; + + /** @var ResolvesToBool|bool|string $if */ + public readonly ResolvesToBool|bool|string $if; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $then */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $then; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $else */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $else; + + /** + * @param ResolvesToBool|bool|string $if + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $then + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $else + */ + public function __construct( + ResolvesToBool|bool|string $if, + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $then, + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $else, + ) { + if (is_string($if) && ! str_starts_with($if, '$')) { + throw new InvalidArgumentException('Argument $if can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->if = $if; + $this->then = $then; + $this->else = $else; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/ConvertOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/ConvertOperator.php new file mode 100644 index 00000000..3a8d3764 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/ConvertOperator.php @@ -0,0 +1,69 @@ + 'input', 'to' => 'to', 'onError' => 'onError', 'onNull' => 'onNull']; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $input */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $input; + + /** @var ResolvesToInt|ResolvesToString|int|string $to */ + public readonly ResolvesToInt|ResolvesToString|int|string $to; + + /** + * @var Optional|DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $onError The value to return on encountering an error during conversion, including unsupported type conversions. The arguments can be any valid expression. + * If unspecified, the operation throws an error upon encountering an error and stops. + */ + public readonly Optional|DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $onError; + + /** + * @var Optional|DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $onNull The value to return if the input is null or missing. The arguments can be any valid expression. + * If unspecified, $convert returns null if the input is null or missing. + */ + public readonly Optional|DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $onNull; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $input + * @param ResolvesToInt|ResolvesToString|int|string $to + * @param Optional|DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $onError The value to return on encountering an error during conversion, including unsupported type conversions. The arguments can be any valid expression. + * If unspecified, the operation throws an error upon encountering an error and stops. + * @param Optional|DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $onNull The value to return if the input is null or missing. The arguments can be any valid expression. + * If unspecified, $convert returns null if the input is null or missing. + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $input, + ResolvesToInt|ResolvesToString|int|string $to, + Optional|DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $onError = Optional::Undefined, + Optional|DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $onNull = Optional::Undefined, + ) { + $this->input = $input; + $this->to = $to; + $this->onError = $onError; + $this->onNull = $onNull; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/CosOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/CosOperator.php new file mode 100644 index 00000000..fdc5fe5f --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/CosOperator.php @@ -0,0 +1,50 @@ + 'expression']; + + /** + * @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression $cos takes any valid expression that resolves to a number. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the result to radians. + * By default $cos returns values as a double. $cos can also return values as a 128-bit decimal as long as the resolves to a 128-bit decimal value. + */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $cos takes any valid expression that resolves to a number. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the result to radians. + * By default $cos returns values as a double. $cos can also return values as a 128-bit decimal as long as the resolves to a 128-bit decimal value. + */ + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) + { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/CoshOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/CoshOperator.php new file mode 100644 index 00000000..3133153a --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/CoshOperator.php @@ -0,0 +1,50 @@ + 'expression']; + + /** + * @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression $cosh takes any valid expression that resolves to a number, measured in radians. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the value to radians. + * By default $cosh returns values as a double. $cosh can also return values as a 128-bit decimal if the resolves to a 128-bit decimal value. + */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $cosh takes any valid expression that resolves to a number, measured in radians. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the value to radians. + * By default $cosh returns values as a double. $cosh can also return values as a 128-bit decimal if the resolves to a 128-bit decimal value. + */ + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) + { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/DateAddOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/DateAddOperator.php new file mode 100644 index 00000000..333cfca1 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/DateAddOperator.php @@ -0,0 +1,74 @@ + 'startDate', 'unit' => 'unit', 'amount' => 'amount', 'timezone' => 'timezone']; + + /** @var DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $startDate The beginning date, in UTC, for the addition operation. The startDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $startDate; + + /** @var ResolvesToString|TimeUnit|string $unit The unit used to measure the amount of time added to the startDate. */ + public readonly ResolvesToString|TimeUnit|string $unit; + + /** @var Int64|ResolvesToInt|ResolvesToLong|int|string $amount */ + public readonly Int64|ResolvesToInt|ResolvesToLong|int|string $amount; + + /** @var Optional|ResolvesToString|string $timezone The timezone to carry out the operation. $timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ + public readonly Optional|ResolvesToString|string $timezone; + + /** + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $startDate The beginning date, in UTC, for the addition operation. The startDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ResolvesToString|TimeUnit|string $unit The unit used to measure the amount of time added to the startDate. + * @param Int64|ResolvesToInt|ResolvesToLong|int|string $amount + * @param Optional|ResolvesToString|string $timezone The timezone to carry out the operation. $timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + */ + public function __construct( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $startDate, + ResolvesToString|TimeUnit|string $unit, + Int64|ResolvesToInt|ResolvesToLong|int|string $amount, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + ) { + if (is_string($startDate) && ! str_starts_with($startDate, '$')) { + throw new InvalidArgumentException('Argument $startDate can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->startDate = $startDate; + $this->unit = $unit; + if (is_string($amount) && ! str_starts_with($amount, '$')) { + throw new InvalidArgumentException('Argument $amount can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->amount = $amount; + $this->timezone = $timezone; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/DateDiffOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/DateDiffOperator.php new file mode 100644 index 00000000..8c4f5e5b --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/DateDiffOperator.php @@ -0,0 +1,86 @@ + 'startDate', + 'endDate' => 'endDate', + 'unit' => 'unit', + 'timezone' => 'timezone', + 'startOfWeek' => 'startOfWeek', + ]; + + /** @var DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $startDate The start of the time period. The startDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $startDate; + + /** @var DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $endDate The end of the time period. The endDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $endDate; + + /** @var ResolvesToString|TimeUnit|string $unit The time measurement unit between the startDate and endDate */ + public readonly ResolvesToString|TimeUnit|string $unit; + + /** @var Optional|ResolvesToString|string $timezone The timezone to carry out the operation. $timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ + public readonly Optional|ResolvesToString|string $timezone; + + /** @var Optional|ResolvesToString|string $startOfWeek Used when the unit is equal to week. Defaults to Sunday. The startOfWeek parameter is an expression that resolves to a case insensitive string */ + public readonly Optional|ResolvesToString|string $startOfWeek; + + /** + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $startDate The start of the time period. The startDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $endDate The end of the time period. The endDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ResolvesToString|TimeUnit|string $unit The time measurement unit between the startDate and endDate + * @param Optional|ResolvesToString|string $timezone The timezone to carry out the operation. $timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + * @param Optional|ResolvesToString|string $startOfWeek Used when the unit is equal to week. Defaults to Sunday. The startOfWeek parameter is an expression that resolves to a case insensitive string + */ + public function __construct( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $startDate, + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $endDate, + ResolvesToString|TimeUnit|string $unit, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + Optional|ResolvesToString|string $startOfWeek = Optional::Undefined, + ) { + if (is_string($startDate) && ! str_starts_with($startDate, '$')) { + throw new InvalidArgumentException('Argument $startDate can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->startDate = $startDate; + if (is_string($endDate) && ! str_starts_with($endDate, '$')) { + throw new InvalidArgumentException('Argument $endDate can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->endDate = $endDate; + $this->unit = $unit; + $this->timezone = $timezone; + $this->startOfWeek = $startOfWeek; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/DateFieldPath.php b/vendor/mongodb/mongodb/src/Builder/Expression/DateFieldPath.php new file mode 100644 index 00000000..d3298853 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/DateFieldPath.php @@ -0,0 +1,29 @@ +name = $name; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/DateFromPartsOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/DateFromPartsOperator.php new file mode 100644 index 00000000..c2d32c29 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/DateFromPartsOperator.php @@ -0,0 +1,157 @@ + 'year', + 'isoWeekYear' => 'isoWeekYear', + 'month' => 'month', + 'isoWeek' => 'isoWeek', + 'day' => 'day', + 'isoDayOfWeek' => 'isoDayOfWeek', + 'hour' => 'hour', + 'minute' => 'minute', + 'second' => 'second', + 'millisecond' => 'millisecond', + 'timezone' => 'timezone', + ]; + + /** @var Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $year Calendar year. Can be any expression that evaluates to a number. */ + public readonly Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $year; + + /** @var Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoWeekYear ISO Week Date Year. Can be any expression that evaluates to a number. */ + public readonly Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoWeekYear; + + /** @var Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $month Month. Defaults to 1. */ + public readonly Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $month; + + /** @var Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoWeek Week of year. Defaults to 1. */ + public readonly Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoWeek; + + /** @var Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $day Day of month. Defaults to 1. */ + public readonly Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $day; + + /** @var Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoDayOfWeek Day of week (Monday 1 - Sunday 7). Defaults to 1. */ + public readonly Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoDayOfWeek; + + /** @var Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $hour Hour. Defaults to 0. */ + public readonly Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $hour; + + /** @var Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $minute Minute. Defaults to 0. */ + public readonly Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $minute; + + /** @var Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $second Second. Defaults to 0. */ + public readonly Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $second; + + /** @var Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $millisecond Millisecond. Defaults to 0. */ + public readonly Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $millisecond; + + /** @var Optional|ResolvesToString|string $timezone The timezone to carry out the operation. $timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ + public readonly Optional|ResolvesToString|string $timezone; + + /** + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $year Calendar year. Can be any expression that evaluates to a number. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoWeekYear ISO Week Date Year. Can be any expression that evaluates to a number. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $month Month. Defaults to 1. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoWeek Week of year. Defaults to 1. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $day Day of month. Defaults to 1. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoDayOfWeek Day of week (Monday 1 - Sunday 7). Defaults to 1. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $hour Hour. Defaults to 0. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $minute Minute. Defaults to 0. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $second Second. Defaults to 0. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $millisecond Millisecond. Defaults to 0. + * @param Optional|ResolvesToString|string $timezone The timezone to carry out the operation. $timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + */ + public function __construct( + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $year = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoWeekYear = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $month = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoWeek = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $day = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoDayOfWeek = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $hour = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $minute = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $second = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $millisecond = Optional::Undefined, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + ) { + if (is_string($year) && ! str_starts_with($year, '$')) { + throw new InvalidArgumentException('Argument $year can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->year = $year; + if (is_string($isoWeekYear) && ! str_starts_with($isoWeekYear, '$')) { + throw new InvalidArgumentException('Argument $isoWeekYear can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->isoWeekYear = $isoWeekYear; + if (is_string($month) && ! str_starts_with($month, '$')) { + throw new InvalidArgumentException('Argument $month can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->month = $month; + if (is_string($isoWeek) && ! str_starts_with($isoWeek, '$')) { + throw new InvalidArgumentException('Argument $isoWeek can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->isoWeek = $isoWeek; + if (is_string($day) && ! str_starts_with($day, '$')) { + throw new InvalidArgumentException('Argument $day can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->day = $day; + if (is_string($isoDayOfWeek) && ! str_starts_with($isoDayOfWeek, '$')) { + throw new InvalidArgumentException('Argument $isoDayOfWeek can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->isoDayOfWeek = $isoDayOfWeek; + if (is_string($hour) && ! str_starts_with($hour, '$')) { + throw new InvalidArgumentException('Argument $hour can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->hour = $hour; + if (is_string($minute) && ! str_starts_with($minute, '$')) { + throw new InvalidArgumentException('Argument $minute can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->minute = $minute; + if (is_string($second) && ! str_starts_with($second, '$')) { + throw new InvalidArgumentException('Argument $second can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->second = $second; + if (is_string($millisecond) && ! str_starts_with($millisecond, '$')) { + throw new InvalidArgumentException('Argument $millisecond can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->millisecond = $millisecond; + $this->timezone = $timezone; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/DateFromStringOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/DateFromStringOperator.php new file mode 100644 index 00000000..ad796df9 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/DateFromStringOperator.php @@ -0,0 +1,85 @@ + 'dateString', + 'format' => 'format', + 'timezone' => 'timezone', + 'onError' => 'onError', + 'onNull' => 'onNull', + ]; + + /** @var ResolvesToString|string $dateString The date/time string to convert to a date object. */ + public readonly ResolvesToString|string $dateString; + + /** + * @var Optional|ResolvesToString|string $format The date format specification of the dateString. The format can be any expression that evaluates to a string literal, containing 0 or more format specifiers. + * If unspecified, $dateFromString uses "%Y-%m-%dT%H:%M:%S.%LZ" as the default format but accepts a variety of formats and attempts to parse the dateString if possible. + */ + public readonly Optional|ResolvesToString|string $format; + + /** @var Optional|ResolvesToString|string $timezone The time zone to use to format the date. */ + public readonly Optional|ResolvesToString|string $timezone; + + /** + * @var Optional|DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $onError If $dateFromString encounters an error while parsing the given dateString, it outputs the result value of the provided onError expression. This result value can be of any type. + * If you do not specify onError, $dateFromString throws an error if it cannot parse dateString. + */ + public readonly Optional|DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $onError; + + /** + * @var Optional|DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $onNull If the dateString provided to $dateFromString is null or missing, it outputs the result value of the provided onNull expression. This result value can be of any type. + * If you do not specify onNull and dateString is null or missing, then $dateFromString outputs null. + */ + public readonly Optional|DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $onNull; + + /** + * @param ResolvesToString|string $dateString The date/time string to convert to a date object. + * @param Optional|ResolvesToString|string $format The date format specification of the dateString. The format can be any expression that evaluates to a string literal, containing 0 or more format specifiers. + * If unspecified, $dateFromString uses "%Y-%m-%dT%H:%M:%S.%LZ" as the default format but accepts a variety of formats and attempts to parse the dateString if possible. + * @param Optional|ResolvesToString|string $timezone The time zone to use to format the date. + * @param Optional|DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $onError If $dateFromString encounters an error while parsing the given dateString, it outputs the result value of the provided onError expression. This result value can be of any type. + * If you do not specify onError, $dateFromString throws an error if it cannot parse dateString. + * @param Optional|DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $onNull If the dateString provided to $dateFromString is null or missing, it outputs the result value of the provided onNull expression. This result value can be of any type. + * If you do not specify onNull and dateString is null or missing, then $dateFromString outputs null. + */ + public function __construct( + ResolvesToString|string $dateString, + Optional|ResolvesToString|string $format = Optional::Undefined, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + Optional|DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $onError = Optional::Undefined, + Optional|DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $onNull = Optional::Undefined, + ) { + $this->dateString = $dateString; + $this->format = $format; + $this->timezone = $timezone; + $this->onError = $onError; + $this->onNull = $onNull; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/DateSubtractOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/DateSubtractOperator.php new file mode 100644 index 00000000..91c79087 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/DateSubtractOperator.php @@ -0,0 +1,74 @@ + 'startDate', 'unit' => 'unit', 'amount' => 'amount', 'timezone' => 'timezone']; + + /** @var DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $startDate The beginning date, in UTC, for the addition operation. The startDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $startDate; + + /** @var ResolvesToString|TimeUnit|string $unit The unit used to measure the amount of time added to the startDate. */ + public readonly ResolvesToString|TimeUnit|string $unit; + + /** @var Int64|ResolvesToInt|ResolvesToLong|int|string $amount */ + public readonly Int64|ResolvesToInt|ResolvesToLong|int|string $amount; + + /** @var Optional|ResolvesToString|string $timezone The timezone to carry out the operation. $timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ + public readonly Optional|ResolvesToString|string $timezone; + + /** + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $startDate The beginning date, in UTC, for the addition operation. The startDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ResolvesToString|TimeUnit|string $unit The unit used to measure the amount of time added to the startDate. + * @param Int64|ResolvesToInt|ResolvesToLong|int|string $amount + * @param Optional|ResolvesToString|string $timezone The timezone to carry out the operation. $timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + */ + public function __construct( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $startDate, + ResolvesToString|TimeUnit|string $unit, + Int64|ResolvesToInt|ResolvesToLong|int|string $amount, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + ) { + if (is_string($startDate) && ! str_starts_with($startDate, '$')) { + throw new InvalidArgumentException('Argument $startDate can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->startDate = $startDate; + $this->unit = $unit; + if (is_string($amount) && ! str_starts_with($amount, '$')) { + throw new InvalidArgumentException('Argument $amount can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->amount = $amount; + $this->timezone = $timezone; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/DateToPartsOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/DateToPartsOperator.php new file mode 100644 index 00000000..8e23c751 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/DateToPartsOperator.php @@ -0,0 +1,62 @@ + 'date', 'timezone' => 'timezone', 'iso8601' => 'iso8601']; + + /** @var DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The input date for which to return parts. date can be any expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date; + + /** @var Optional|ResolvesToString|string $timezone The timezone to carry out the operation. $timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ + public readonly Optional|ResolvesToString|string $timezone; + + /** @var Optional|bool $iso8601 If set to true, modifies the output document to use ISO week date fields. Defaults to false. */ + public readonly Optional|bool $iso8601; + + /** + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The input date for which to return parts. date can be any expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param Optional|ResolvesToString|string $timezone The timezone to carry out the operation. $timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + * @param Optional|bool $iso8601 If set to true, modifies the output document to use ISO week date fields. Defaults to false. + */ + public function __construct( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + Optional|bool $iso8601 = Optional::Undefined, + ) { + if (is_string($date) && ! str_starts_with($date, '$')) { + throw new InvalidArgumentException('Argument $date can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->date = $date; + $this->timezone = $timezone; + $this->iso8601 = $iso8601; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/DateToStringOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/DateToStringOperator.php new file mode 100644 index 00000000..703ac643 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/DateToStringOperator.php @@ -0,0 +1,79 @@ + 'date', 'format' => 'format', 'timezone' => 'timezone', 'onNull' => 'onNull']; + + /** @var DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to convert to string. Must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date; + + /** + * @var Optional|ResolvesToString|string $format The date format specification of the dateString. The format can be any expression that evaluates to a string literal, containing 0 or more format specifiers. + * If unspecified, $dateFromString uses "%Y-%m-%dT%H:%M:%S.%LZ" as the default format but accepts a variety of formats and attempts to parse the dateString if possible. + */ + public readonly Optional|ResolvesToString|string $format; + + /** @var Optional|ResolvesToString|string $timezone The time zone to use to format the date. */ + public readonly Optional|ResolvesToString|string $timezone; + + /** + * @var Optional|DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $onNull The value to return if the date is null or missing. + * If unspecified, $dateToString returns null if the date is null or missing. + */ + public readonly Optional|DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $onNull; + + /** + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to convert to string. Must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param Optional|ResolvesToString|string $format The date format specification of the dateString. The format can be any expression that evaluates to a string literal, containing 0 or more format specifiers. + * If unspecified, $dateFromString uses "%Y-%m-%dT%H:%M:%S.%LZ" as the default format but accepts a variety of formats and attempts to parse the dateString if possible. + * @param Optional|ResolvesToString|string $timezone The time zone to use to format the date. + * @param Optional|DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $onNull The value to return if the date is null or missing. + * If unspecified, $dateToString returns null if the date is null or missing. + */ + public function __construct( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, + Optional|ResolvesToString|string $format = Optional::Undefined, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + Optional|DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $onNull = Optional::Undefined, + ) { + if (is_string($date) && ! str_starts_with($date, '$')) { + throw new InvalidArgumentException('Argument $date can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->date = $date; + $this->format = $format; + $this->timezone = $timezone; + $this->onNull = $onNull; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/DateTruncOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/DateTruncOperator.php new file mode 100644 index 00000000..af550491 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/DateTruncOperator.php @@ -0,0 +1,100 @@ + 'date', + 'unit' => 'unit', + 'binSize' => 'binSize', + 'timezone' => 'timezone', + 'startOfWeek' => 'startOfWeek', + ]; + + /** @var DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to truncate, specified in UTC. The date can be any expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date; + + /** + * @var ResolvesToString|TimeUnit|string $unit The unit of time, specified as an expression that must resolve to one of these strings: year, quarter, week, month, day, hour, minute, second. + * Together, binSize and unit specify the time period used in the $dateTrunc calculation. + */ + public readonly ResolvesToString|TimeUnit|string $unit; + + /** + * @var Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $binSize The numeric time value, specified as an expression that must resolve to a positive non-zero number. Defaults to 1. + * Together, binSize and unit specify the time period used in the $dateTrunc calculation. + */ + public readonly Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $binSize; + + /** @var Optional|ResolvesToString|string $timezone The timezone to carry out the operation. $timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ + public readonly Optional|ResolvesToString|string $timezone; + + /** + * @var Optional|string $startOfWeek The start of the week. Used when + * unit is week. Defaults to Sunday. + */ + public readonly Optional|string $startOfWeek; + + /** + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to truncate, specified in UTC. The date can be any expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ResolvesToString|TimeUnit|string $unit The unit of time, specified as an expression that must resolve to one of these strings: year, quarter, week, month, day, hour, minute, second. + * Together, binSize and unit specify the time period used in the $dateTrunc calculation. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $binSize The numeric time value, specified as an expression that must resolve to a positive non-zero number. Defaults to 1. + * Together, binSize and unit specify the time period used in the $dateTrunc calculation. + * @param Optional|ResolvesToString|string $timezone The timezone to carry out the operation. $timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + * @param Optional|string $startOfWeek The start of the week. Used when + * unit is week. Defaults to Sunday. + */ + public function __construct( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, + ResolvesToString|TimeUnit|string $unit, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $binSize = Optional::Undefined, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + Optional|string $startOfWeek = Optional::Undefined, + ) { + if (is_string($date) && ! str_starts_with($date, '$')) { + throw new InvalidArgumentException('Argument $date can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->date = $date; + $this->unit = $unit; + if (is_string($binSize) && ! str_starts_with($binSize, '$')) { + throw new InvalidArgumentException('Argument $binSize can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->binSize = $binSize; + $this->timezone = $timezone; + $this->startOfWeek = $startOfWeek; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/DayOfMonthOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/DayOfMonthOperator.php new file mode 100644 index 00000000..ce3df4a8 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/DayOfMonthOperator.php @@ -0,0 +1,56 @@ + 'date', 'timezone' => 'timezone']; + + /** @var DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date; + + /** @var Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ + public readonly Optional|ResolvesToString|string $timezone; + + /** + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + */ + public function __construct( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + ) { + if (is_string($date) && ! str_starts_with($date, '$')) { + throw new InvalidArgumentException('Argument $date can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->date = $date; + $this->timezone = $timezone; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/DayOfWeekOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/DayOfWeekOperator.php new file mode 100644 index 00000000..db07c7a2 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/DayOfWeekOperator.php @@ -0,0 +1,56 @@ + 'date', 'timezone' => 'timezone']; + + /** @var DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date; + + /** @var Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ + public readonly Optional|ResolvesToString|string $timezone; + + /** + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + */ + public function __construct( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + ) { + if (is_string($date) && ! str_starts_with($date, '$')) { + throw new InvalidArgumentException('Argument $date can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->date = $date; + $this->timezone = $timezone; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/DayOfYearOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/DayOfYearOperator.php new file mode 100644 index 00000000..530fc619 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/DayOfYearOperator.php @@ -0,0 +1,56 @@ + 'date', 'timezone' => 'timezone']; + + /** @var DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date; + + /** @var Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ + public readonly Optional|ResolvesToString|string $timezone; + + /** + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + */ + public function __construct( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + ) { + if (is_string($date) && ! str_starts_with($date, '$')) { + throw new InvalidArgumentException('Argument $date can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->date = $date; + $this->timezone = $timezone; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/DecimalFieldPath.php b/vendor/mongodb/mongodb/src/Builder/Expression/DecimalFieldPath.php new file mode 100644 index 00000000..2a913667 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/DecimalFieldPath.php @@ -0,0 +1,29 @@ +name = $name; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/DegreesToRadiansOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/DegreesToRadiansOperator.php new file mode 100644 index 00000000..45482c73 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/DegreesToRadiansOperator.php @@ -0,0 +1,50 @@ + 'expression']; + + /** + * @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression $degreesToRadians takes any valid expression that resolves to a number. + * By default $degreesToRadians returns values as a double. $degreesToRadians can also return values as a 128-bit decimal as long as the resolves to a 128-bit decimal value. + */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $degreesToRadians takes any valid expression that resolves to a number. + * By default $degreesToRadians returns values as a double. $degreesToRadians can also return values as a 128-bit decimal as long as the resolves to a 128-bit decimal value. + */ + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) + { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/DivideOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/DivideOperator.php new file mode 100644 index 00000000..55ba88b2 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/DivideOperator.php @@ -0,0 +1,57 @@ + 'dividend', 'divisor' => 'divisor']; + + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $dividend The first argument is the dividend, and the second argument is the divisor; i.e. the first argument is divided by the second argument. */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $dividend; + + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $divisor */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $divisor; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $dividend The first argument is the dividend, and the second argument is the divisor; i.e. the first argument is divided by the second argument. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $divisor + */ + public function __construct( + Decimal128|Int64|ResolvesToNumber|float|int|string $dividend, + Decimal128|Int64|ResolvesToNumber|float|int|string $divisor, + ) { + if (is_string($dividend) && ! str_starts_with($dividend, '$')) { + throw new InvalidArgumentException('Argument $dividend can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->dividend = $dividend; + if (is_string($divisor) && ! str_starts_with($divisor, '$')) { + throw new InvalidArgumentException('Argument $divisor can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->divisor = $divisor; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/DoubleFieldPath.php b/vendor/mongodb/mongodb/src/Builder/Expression/DoubleFieldPath.php new file mode 100644 index 00000000..2af25b87 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/DoubleFieldPath.php @@ -0,0 +1,29 @@ +name = $name; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/EqOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/EqOperator.php new file mode 100644 index 00000000..5db6ed26 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/EqOperator.php @@ -0,0 +1,47 @@ + 'expression1', 'expression2' => 'expression2']; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression1 */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression1; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression2 */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression2; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression1 + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression2 + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression1, + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression2, + ) { + $this->expression1 = $expression1; + $this->expression2 = $expression2; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/ExpOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/ExpOperator.php new file mode 100644 index 00000000..5aab19c1 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/ExpOperator.php @@ -0,0 +1,46 @@ + 'exponent']; + + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $exponent */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $exponent; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $exponent + */ + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $exponent) + { + if (is_string($exponent) && ! str_starts_with($exponent, '$')) { + throw new InvalidArgumentException('Argument $exponent can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->exponent = $exponent; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/ExpressionFactoryTrait.php b/vendor/mongodb/mongodb/src/Builder/Expression/ExpressionFactoryTrait.php new file mode 100644 index 00000000..3f5f0433 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/ExpressionFactoryTrait.php @@ -0,0 +1,105 @@ + resolves to a 128-bit decimal value. + */ + public static function cos(Decimal128|Int64|ResolvesToNumber|float|int|string $expression): CosOperator + { + return new CosOperator($expression); + } + + /** + * Returns the hyperbolic cosine of a value that is measured in radians. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/cosh/ + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $cosh takes any valid expression that resolves to a number, measured in radians. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the value to radians. + * By default $cosh returns values as a double. $cosh can also return values as a 128-bit decimal if the resolves to a 128-bit decimal value. + */ + public static function cosh(Decimal128|Int64|ResolvesToNumber|float|int|string $expression): CoshOperator + { + return new CoshOperator($expression); + } + + /** + * Adds a number of time units to a date object. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/dateAdd/ + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $startDate The beginning date, in UTC, for the addition operation. The startDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ResolvesToString|TimeUnit|string $unit The unit used to measure the amount of time added to the startDate. + * @param Int64|ResolvesToInt|ResolvesToLong|int|string $amount + * @param Optional|ResolvesToString|string $timezone The timezone to carry out the operation. $timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + */ + public static function dateAdd( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $startDate, + ResolvesToString|TimeUnit|string $unit, + Int64|ResolvesToInt|ResolvesToLong|int|string $amount, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + ): DateAddOperator { + return new DateAddOperator($startDate, $unit, $amount, $timezone); + } + + /** + * Returns the difference between two dates. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/dateDiff/ + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $startDate The start of the time period. The startDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $endDate The end of the time period. The endDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ResolvesToString|TimeUnit|string $unit The time measurement unit between the startDate and endDate + * @param Optional|ResolvesToString|string $timezone The timezone to carry out the operation. $timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + * @param Optional|ResolvesToString|string $startOfWeek Used when the unit is equal to week. Defaults to Sunday. The startOfWeek parameter is an expression that resolves to a case insensitive string + */ + public static function dateDiff( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $startDate, + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $endDate, + ResolvesToString|TimeUnit|string $unit, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + Optional|ResolvesToString|string $startOfWeek = Optional::Undefined, + ): DateDiffOperator { + return new DateDiffOperator($startDate, $endDate, $unit, $timezone, $startOfWeek); + } + + /** + * Constructs a BSON Date object given the date's constituent parts. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/dateFromParts/ + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $year Calendar year. Can be any expression that evaluates to a number. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoWeekYear ISO Week Date Year. Can be any expression that evaluates to a number. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $month Month. Defaults to 1. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoWeek Week of year. Defaults to 1. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $day Day of month. Defaults to 1. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoDayOfWeek Day of week (Monday 1 - Sunday 7). Defaults to 1. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $hour Hour. Defaults to 0. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $minute Minute. Defaults to 0. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $second Second. Defaults to 0. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $millisecond Millisecond. Defaults to 0. + * @param Optional|ResolvesToString|string $timezone The timezone to carry out the operation. $timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + */ + public static function dateFromParts( + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $year = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoWeekYear = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $month = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoWeek = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $day = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoDayOfWeek = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $hour = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $minute = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $second = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $millisecond = Optional::Undefined, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + ): DateFromPartsOperator { + return new DateFromPartsOperator($year, $isoWeekYear, $month, $isoWeek, $day, $isoDayOfWeek, $hour, $minute, $second, $millisecond, $timezone); + } + + /** + * Converts a date/time string to a date object. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/dateFromString/ + * @param ResolvesToString|string $dateString The date/time string to convert to a date object. + * @param Optional|ResolvesToString|string $format The date format specification of the dateString. The format can be any expression that evaluates to a string literal, containing 0 or more format specifiers. + * If unspecified, $dateFromString uses "%Y-%m-%dT%H:%M:%S.%LZ" as the default format but accepts a variety of formats and attempts to parse the dateString if possible. + * @param Optional|ResolvesToString|string $timezone The time zone to use to format the date. + * @param Optional|DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $onError If $dateFromString encounters an error while parsing the given dateString, it outputs the result value of the provided onError expression. This result value can be of any type. + * If you do not specify onError, $dateFromString throws an error if it cannot parse dateString. + * @param Optional|DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $onNull If the dateString provided to $dateFromString is null or missing, it outputs the result value of the provided onNull expression. This result value can be of any type. + * If you do not specify onNull and dateString is null or missing, then $dateFromString outputs null. + */ + public static function dateFromString( + ResolvesToString|string $dateString, + Optional|ResolvesToString|string $format = Optional::Undefined, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + Optional|DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $onError = Optional::Undefined, + Optional|DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $onNull = Optional::Undefined, + ): DateFromStringOperator { + return new DateFromStringOperator($dateString, $format, $timezone, $onError, $onNull); + } + + /** + * Subtracts a number of time units from a date object. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/dateSubtract/ + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $startDate The beginning date, in UTC, for the addition operation. The startDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ResolvesToString|TimeUnit|string $unit The unit used to measure the amount of time added to the startDate. + * @param Int64|ResolvesToInt|ResolvesToLong|int|string $amount + * @param Optional|ResolvesToString|string $timezone The timezone to carry out the operation. $timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + */ + public static function dateSubtract( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $startDate, + ResolvesToString|TimeUnit|string $unit, + Int64|ResolvesToInt|ResolvesToLong|int|string $amount, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + ): DateSubtractOperator { + return new DateSubtractOperator($startDate, $unit, $amount, $timezone); + } + + /** + * Returns a document containing the constituent parts of a date. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/dateToParts/ + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The input date for which to return parts. date can be any expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param Optional|ResolvesToString|string $timezone The timezone to carry out the operation. $timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + * @param Optional|bool $iso8601 If set to true, modifies the output document to use ISO week date fields. Defaults to false. + */ + public static function dateToParts( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + Optional|bool $iso8601 = Optional::Undefined, + ): DateToPartsOperator { + return new DateToPartsOperator($date, $timezone, $iso8601); + } + + /** + * Returns the date as a formatted string. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/dateToString/ + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to convert to string. Must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param Optional|ResolvesToString|string $format The date format specification of the dateString. The format can be any expression that evaluates to a string literal, containing 0 or more format specifiers. + * If unspecified, $dateFromString uses "%Y-%m-%dT%H:%M:%S.%LZ" as the default format but accepts a variety of formats and attempts to parse the dateString if possible. + * @param Optional|ResolvesToString|string $timezone The time zone to use to format the date. + * @param Optional|DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $onNull The value to return if the date is null or missing. + * If unspecified, $dateToString returns null if the date is null or missing. + */ + public static function dateToString( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, + Optional|ResolvesToString|string $format = Optional::Undefined, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + Optional|DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $onNull = Optional::Undefined, + ): DateToStringOperator { + return new DateToStringOperator($date, $format, $timezone, $onNull); + } + + /** + * Truncates a date. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/dateTrunc/ + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to truncate, specified in UTC. The date can be any expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ResolvesToString|TimeUnit|string $unit The unit of time, specified as an expression that must resolve to one of these strings: year, quarter, week, month, day, hour, minute, second. + * Together, binSize and unit specify the time period used in the $dateTrunc calculation. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $binSize The numeric time value, specified as an expression that must resolve to a positive non-zero number. Defaults to 1. + * Together, binSize and unit specify the time period used in the $dateTrunc calculation. + * @param Optional|ResolvesToString|string $timezone The timezone to carry out the operation. $timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + * @param Optional|string $startOfWeek The start of the week. Used when + * unit is week. Defaults to Sunday. + */ + public static function dateTrunc( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, + ResolvesToString|TimeUnit|string $unit, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $binSize = Optional::Undefined, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + Optional|string $startOfWeek = Optional::Undefined, + ): DateTruncOperator { + return new DateTruncOperator($date, $unit, $binSize, $timezone, $startOfWeek); + } + + /** + * Returns the day of the month for a date as a number between 1 and 31. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/dayOfMonth/ + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + */ + public static function dayOfMonth( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + ): DayOfMonthOperator { + return new DayOfMonthOperator($date, $timezone); + } + + /** + * Returns the day of the week for a date as a number between 1 (Sunday) and 7 (Saturday). + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/dayOfWeek/ + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + */ + public static function dayOfWeek( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + ): DayOfWeekOperator { + return new DayOfWeekOperator($date, $timezone); + } + + /** + * Returns the day of the year for a date as a number between 1 and 366 (leap year). + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/dayOfYear/ + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + */ + public static function dayOfYear( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + ): DayOfYearOperator { + return new DayOfYearOperator($date, $timezone); + } + + /** + * Converts a value from degrees to radians. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/degreesToRadians/ + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $degreesToRadians takes any valid expression that resolves to a number. + * By default $degreesToRadians returns values as a double. $degreesToRadians can also return values as a 128-bit decimal as long as the resolves to a 128-bit decimal value. + */ + public static function degreesToRadians( + Decimal128|Int64|ResolvesToNumber|float|int|string $expression, + ): DegreesToRadiansOperator { + return new DegreesToRadiansOperator($expression); + } + + /** + * Returns the result of dividing the first number by the second. Accepts two argument expressions. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/divide/ + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $dividend The first argument is the dividend, and the second argument is the divisor; i.e. the first argument is divided by the second argument. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $divisor + */ + public static function divide( + Decimal128|Int64|ResolvesToNumber|float|int|string $dividend, + Decimal128|Int64|ResolvesToNumber|float|int|string $divisor, + ): DivideOperator { + return new DivideOperator($dividend, $divisor); + } + + /** + * Returns true if the values are equivalent. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/eq/ + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression1 + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression2 + */ + public static function eq( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression1, + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression2, + ): EqOperator { + return new EqOperator($expression1, $expression2); + } + + /** + * Raises e to the specified exponent. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/exp/ + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $exponent + */ + public static function exp(Decimal128|Int64|ResolvesToNumber|float|int|string $exponent): ExpOperator + { + return new ExpOperator($exponent); + } + + /** + * Selects a subset of the array to return an array with only the elements that match the filter condition. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/filter/ + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input + * @param ResolvesToBool|bool|string $cond An expression that resolves to a boolean value used to determine if an element should be included in the output array. The expression references each element of the input array individually with the variable name specified in as. + * @param Optional|string $as A name for the variable that represents each individual element of the input array. If no name is specified, the variable name defaults to this. + * @param Optional|ResolvesToInt|int|string $limit A number expression that restricts the number of matching array elements that $filter returns. You cannot specify a limit less than 1. The matching array elements are returned in the order they appear in the input array. + * If the specified limit is greater than the number of matching array elements, $filter returns all matching array elements. If the limit is null, $filter returns all matching array elements. + */ + public static function filter( + PackedArray|ResolvesToArray|BSONArray|array|string $input, + ResolvesToBool|bool|string $cond, + Optional|string $as = Optional::Undefined, + Optional|ResolvesToInt|int|string $limit = Optional::Undefined, + ): FilterOperator { + return new FilterOperator($input, $cond, $as, $limit); + } + + /** + * Returns the result of an expression for the first document in an array. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/first/ + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression + */ + public static function first(PackedArray|ResolvesToArray|BSONArray|array|string $expression): FirstOperator + { + return new FirstOperator($expression); + } + + /** + * Returns a specified number of elements from the beginning of an array. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/firstN-array-element/ + * @param ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $firstN returns. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return n elements. + */ + public static function firstN( + ResolvesToInt|int|string $n, + PackedArray|ResolvesToArray|BSONArray|array|string $input, + ): FirstNOperator { + return new FirstNOperator($n, $input); + } + + /** + * Returns the largest integer less than or equal to the specified number. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/floor/ + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression + */ + public static function floor(Decimal128|Int64|ResolvesToNumber|float|int|string $expression): FloorOperator + { + return new FloorOperator($expression); + } + + /** + * Defines a custom function. + * New in MongoDB 4.4. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/function/ + * @param Javascript|string $body The function definition. You can specify the function definition as either BSON\JavaScript or string. + * function(arg1, arg2, ...) { ... } + * @param BSONArray|PackedArray|array $args Arguments passed to the function body. If the body function does not take an argument, you can specify an empty array [ ]. + * @param string $lang + */ + public static function function( + Javascript|string $body, + PackedArray|BSONArray|array $args = [], + string $lang = 'js', + ): FunctionOperator { + return new FunctionOperator($body, $args, $lang); + } + + /** + * Returns the value of a specified field from a document. You can use $getField to retrieve the value of fields with names that contain periods (.) or start with dollar signs ($). + * New in MongoDB 5.0. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/getField/ + * @param ResolvesToString|string $field Field in the input object for which you want to return a value. field can be any valid expression that resolves to a string constant. + * If field begins with a dollar sign ($), place the field name inside of a $literal expression to return its value. + * @param Optional|DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $input Default: $$CURRENT + * A valid expression that contains the field for which you want to return a value. input must resolve to an object, missing, null, or undefined. If omitted, defaults to the document currently being processed in the pipeline ($$CURRENT). + */ + public static function getField( + ResolvesToString|string $field, + Optional|DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $input = Optional::Undefined, + ): GetFieldOperator { + return new GetFieldOperator($field, $input); + } + + /** + * Returns true if the first value is greater than the second. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/gt/ + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression1 + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression2 + */ + public static function gt( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression1, + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression2, + ): GtOperator { + return new GtOperator($expression1, $expression2); + } + + /** + * Returns true if the first value is greater than or equal to the second. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/gte/ + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression1 + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression2 + */ + public static function gte( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression1, + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression2, + ): GteOperator { + return new GteOperator($expression1, $expression2); + } + + /** + * Returns the hour for a date as a number between 0 and 23. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/hour/ + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + */ + public static function hour( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + ): HourOperator { + return new HourOperator($date, $timezone); + } + + /** + * Returns either the non-null result of the first expression or the result of the second expression if the first expression results in a null result. Null result encompasses instances of undefined values or missing fields. Accepts two expressions as arguments. The result of the second expression can be null. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/ifNull/ + * @no-named-arguments + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string ...$expression + */ + public static function ifNull( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string ...$expression, + ): IfNullOperator { + return new IfNullOperator(...$expression); + } + + /** + * Returns a boolean indicating whether a specified value is in an array. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/in/ + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression Any valid expression expression. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $array Any valid expression that resolves to an array. + */ + public static function in( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + PackedArray|ResolvesToArray|BSONArray|array|string $array, + ): InOperator { + return new InOperator($expression, $array); + } + + /** + * Searches an array for an occurrence of a specified value and returns the array index of the first occurrence. Array indexes start at zero. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/indexOfArray/ + * @param BSONArray|PackedArray|ResolvesToArray|array|string $array Can be any valid expression as long as it resolves to an array. + * If the array expression resolves to a value of null or refers to a field that is missing, $indexOfArray returns null. + * If the array expression does not resolve to an array or null nor refers to a missing field, $indexOfArray returns an error. + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $search + * @param Optional|ResolvesToInt|int|string $start An integer, or a number that can be represented as integers (such as 2.0), that specifies the starting index position for the search. Can be any valid expression that resolves to a non-negative integral number. + * If unspecified, the starting index position for the search is the beginning of the string. + * @param Optional|ResolvesToInt|int|string $end An integer, or a number that can be represented as integers (such as 2.0), that specifies the ending index position for the search. Can be any valid expression that resolves to a non-negative integral number. If you specify a index value, you should also specify a index value; otherwise, $indexOfArray uses the value as the index value instead of the value. + * If unspecified, the ending index position for the search is the end of the string. + */ + public static function indexOfArray( + PackedArray|ResolvesToArray|BSONArray|array|string $array, + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $search, + Optional|ResolvesToInt|int|string $start = Optional::Undefined, + Optional|ResolvesToInt|int|string $end = Optional::Undefined, + ): IndexOfArrayOperator { + return new IndexOfArrayOperator($array, $search, $start, $end); + } + + /** + * Searches a string for an occurrence of a substring and returns the UTF-8 byte index of the first occurrence. If the substring is not found, returns -1. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/indexOfBytes/ + * @param ResolvesToString|string $string Can be any valid expression as long as it resolves to a string. + * If the string expression resolves to a value of null or refers to a field that is missing, $indexOfBytes returns null. + * If the string expression does not resolve to a string or null nor refers to a missing field, $indexOfBytes returns an error. + * @param ResolvesToString|string $substring Can be any valid expression as long as it resolves to a string. + * @param Optional|ResolvesToInt|int|string $start An integer, or a number that can be represented as integers (such as 2.0), that specifies the starting index position for the search. Can be any valid expression that resolves to a non-negative integral number. + * If unspecified, the starting index position for the search is the beginning of the string. + * @param Optional|ResolvesToInt|int|string $end An integer, or a number that can be represented as integers (such as 2.0), that specifies the ending index position for the search. Can be any valid expression that resolves to a non-negative integral number. If you specify a index value, you should also specify a index value; otherwise, $indexOfArray uses the value as the index value instead of the value. + * If unspecified, the ending index position for the search is the end of the string. + */ + public static function indexOfBytes( + ResolvesToString|string $string, + ResolvesToString|string $substring, + Optional|ResolvesToInt|int|string $start = Optional::Undefined, + Optional|ResolvesToInt|int|string $end = Optional::Undefined, + ): IndexOfBytesOperator { + return new IndexOfBytesOperator($string, $substring, $start, $end); + } + + /** + * Searches a string for an occurrence of a substring and returns the UTF-8 code point index of the first occurrence. If the substring is not found, returns -1 + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/indexOfCP/ + * @param ResolvesToString|string $string Can be any valid expression as long as it resolves to a string. + * If the string expression resolves to a value of null or refers to a field that is missing, $indexOfCP returns null. + * If the string expression does not resolve to a string or null nor refers to a missing field, $indexOfCP returns an error. + * @param ResolvesToString|string $substring Can be any valid expression as long as it resolves to a string. + * @param Optional|ResolvesToInt|int|string $start An integer, or a number that can be represented as integers (such as 2.0), that specifies the starting index position for the search. Can be any valid expression that resolves to a non-negative integral number. + * If unspecified, the starting index position for the search is the beginning of the string. + * @param Optional|ResolvesToInt|int|string $end An integer, or a number that can be represented as integers (such as 2.0), that specifies the ending index position for the search. Can be any valid expression that resolves to a non-negative integral number. If you specify a index value, you should also specify a index value; otherwise, $indexOfArray uses the value as the index value instead of the value. + * If unspecified, the ending index position for the search is the end of the string. + */ + public static function indexOfCP( + ResolvesToString|string $string, + ResolvesToString|string $substring, + Optional|ResolvesToInt|int|string $start = Optional::Undefined, + Optional|ResolvesToInt|int|string $end = Optional::Undefined, + ): IndexOfCPOperator { + return new IndexOfCPOperator($string, $substring, $start, $end); + } + + /** + * Determines if the operand is an array. Returns a boolean. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/isArray/ + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public static function isArray( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ): IsArrayOperator { + return new IsArrayOperator($expression); + } + + /** + * Returns boolean true if the specified expression resolves to an integer, decimal, double, or long. + * Returns boolean false if the expression resolves to any other BSON type, null, or a missing field. + * New in MongoDB 4.4. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/isNumber/ + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public static function isNumber( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ): IsNumberOperator { + return new IsNumberOperator($expression); + } + + /** + * Returns the weekday number in ISO 8601 format, ranging from 1 (for Monday) to 7 (for Sunday). + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/isoDayOfWeek/ + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + */ + public static function isoDayOfWeek( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + ): IsoDayOfWeekOperator { + return new IsoDayOfWeekOperator($date, $timezone); + } + + /** + * Returns the week number in ISO 8601 format, ranging from 1 to 53. Week numbers start at 1 with the week (Monday through Sunday) that contains the year's first Thursday. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/isoWeek/ + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + */ + public static function isoWeek( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + ): IsoWeekOperator { + return new IsoWeekOperator($date, $timezone); + } + + /** + * Returns the year number in ISO 8601 format. The year starts with the Monday of week 1 (ISO 8601) and ends with the Sunday of the last week (ISO 8601). + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/isoWeekYear/ + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + */ + public static function isoWeekYear( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + ): IsoWeekYearOperator { + return new IsoWeekYearOperator($date, $timezone); + } + + /** + * Returns the result of an expression for the last document in an array. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/last/ + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression + */ + public static function last(PackedArray|ResolvesToArray|BSONArray|array|string $expression): LastOperator + { + return new LastOperator($expression); + } + + /** + * Returns a specified number of elements from the end of an array. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/lastN-array-element/ + * @param ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $firstN returns. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return n elements. + */ + public static function lastN( + ResolvesToInt|int|string $n, + PackedArray|ResolvesToArray|BSONArray|array|string $input, + ): LastNOperator { + return new LastNOperator($n, $input); + } + + /** + * Defines variables for use within the scope of a subexpression and returns the result of the subexpression. Accepts named parameters. + * Accepts any number of argument expressions. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/let/ + * @param Document|Serializable|array|stdClass $vars Assignment block for the variables accessible in the in expression. To assign a variable, specify a string for the variable name and assign a valid expression for the value. + * The variable assignments have no meaning outside the in expression, not even within the vars block itself. + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $in The expression to evaluate. + */ + public static function let( + Document|Serializable|stdClass|array $vars, + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $in, + ): LetOperator { + return new LetOperator($vars, $in); + } + + /** + * Return a value without parsing. Use for values that the aggregation pipeline may interpret as an expression. For example, use a $literal expression to a string that starts with a dollar sign ($) to avoid parsing as a field path. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/literal/ + * @param DateTimeInterface|Type|array|bool|float|int|null|stdClass|string $value If the value is an expression, $literal does not evaluate the expression but instead returns the unparsed expression. + */ + public static function literal( + DateTimeInterface|Type|stdClass|array|bool|float|int|null|string $value, + ): LiteralOperator { + return new LiteralOperator($value); + } + + /** + * Calculates the natural log of a number. + * $ln is equivalent to $log: [ , Math.E ] expression, where Math.E is a JavaScript representation for Euler's number e. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/ln/ + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $number Any valid expression as long as it resolves to a non-negative number. For more information on expressions, see Expressions. + */ + public static function ln(Decimal128|Int64|ResolvesToNumber|float|int|string $number): LnOperator + { + return new LnOperator($number); + } + + /** + * Calculates the log of a number in the specified base. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/log/ + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $number Any valid expression as long as it resolves to a non-negative number. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $base Any valid expression as long as it resolves to a positive number greater than 1. + */ + public static function log( + Decimal128|Int64|ResolvesToNumber|float|int|string $number, + Decimal128|Int64|ResolvesToNumber|float|int|string $base, + ): LogOperator { + return new LogOperator($number, $base); + } + + /** + * Calculates the log base 10 of a number. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/log10/ + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $number Any valid expression as long as it resolves to a non-negative number. + */ + public static function log10(Decimal128|Int64|ResolvesToNumber|float|int|string $number): Log10Operator + { + return new Log10Operator($number); + } + + /** + * Returns true if the first value is less than the second. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/lt/ + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression1 + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression2 + */ + public static function lt( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression1, + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression2, + ): LtOperator { + return new LtOperator($expression1, $expression2); + } + + /** + * Returns true if the first value is less than or equal to the second. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/lte/ + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression1 + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression2 + */ + public static function lte( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression1, + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression2, + ): LteOperator { + return new LteOperator($expression1, $expression2); + } + + /** + * Removes whitespace or the specified characters from the beginning of a string. + * New in MongoDB 4.0. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/ltrim/ + * @param ResolvesToString|string $input The string to trim. The argument can be any valid expression that resolves to a string. + * @param Optional|ResolvesToString|string $chars The character(s) to trim from the beginning of the input. + * The argument can be any valid expression that resolves to a string. The $ltrim operator breaks down the string into individual UTF code point to trim from input. + * If unspecified, $ltrim removes whitespace characters, including the null character. + */ + public static function ltrim( + ResolvesToString|string $input, + Optional|ResolvesToString|string $chars = Optional::Undefined, + ): LtrimOperator { + return new LtrimOperator($input, $chars); + } + + /** + * Applies a subexpression to each element of an array and returns the array of resulting values in order. Accepts named parameters. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/map/ + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to an array. + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $in An expression that is applied to each element of the input array. The expression references each element individually with the variable name specified in as. + * @param Optional|ResolvesToString|string $as A name for the variable that represents each individual element of the input array. If no name is specified, the variable name defaults to this. + */ + public static function map( + PackedArray|ResolvesToArray|BSONArray|array|string $input, + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $in, + Optional|ResolvesToString|string $as = Optional::Undefined, + ): MapOperator { + return new MapOperator($input, $in, $as); + } + + /** + * Returns the maximum value that results from applying an expression to each document. + * Changed in MongoDB 5.0: Available in the $setWindowFields stage. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/max/ + * @no-named-arguments + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string ...$expression + */ + public static function max( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string ...$expression, + ): MaxOperator { + return new MaxOperator(...$expression); + } + + /** + * Returns the n largest values in an array. Distinct from the $maxN accumulator. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/maxN-array-element/ + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return the maximal n elements. + * @param ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $maxN returns. + */ + public static function maxN( + PackedArray|ResolvesToArray|BSONArray|array|string $input, + ResolvesToInt|int|string $n, + ): MaxNOperator { + return new MaxNOperator($input, $n); + } + + /** + * Returns an approximation of the median, the 50th percentile, as a scalar value. + * New in MongoDB 7.0. + * This operator is available as an accumulator in these stages: + * $group + * $setWindowFields + * It is also available as an aggregation expression. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/median/ + * @param BSONArray|Decimal128|Int64|PackedArray|ResolvesToNumber|array|float|int|string $input $median calculates the 50th percentile value of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $median calculation ignores it. + * @param string $method The method that mongod uses to calculate the 50th percentile value. The method must be 'approximate'. + */ + public static function median( + Decimal128|Int64|PackedArray|ResolvesToNumber|BSONArray|array|float|int|string $input, + string $method, + ): MedianOperator { + return new MedianOperator($input, $method); + } + + /** + * Combines multiple documents into a single document. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/mergeObjects/ + * @no-named-arguments + * @param Document|ResolvesToObject|Serializable|array|stdClass|string ...$document Any valid expression that resolves to a document. + */ + public static function mergeObjects( + Document|Serializable|ResolvesToObject|stdClass|array|string ...$document, + ): MergeObjectsOperator { + return new MergeObjectsOperator(...$document); + } + + /** + * Access available per-document metadata related to the aggregation operation. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/meta/ + * @param string $keyword + */ + public static function meta(string $keyword): MetaOperator + { + return new MetaOperator($keyword); + } + + /** + * Returns the milliseconds of a date as a number between 0 and 999. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/millisecond/ + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + */ + public static function millisecond( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + ): MillisecondOperator { + return new MillisecondOperator($date, $timezone); + } + + /** + * Returns the minimum value that results from applying an expression to each document. + * Changed in MongoDB 5.0: Available in the $setWindowFields stage. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/min/ + * @no-named-arguments + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string ...$expression + */ + public static function min( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string ...$expression, + ): MinOperator { + return new MinOperator(...$expression); + } + + /** + * Returns the n smallest values in an array. Distinct from the $minN accumulator. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/minN-array-element/ + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return the maximal n elements. + * @param ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $maxN returns. + */ + public static function minN( + PackedArray|ResolvesToArray|BSONArray|array|string $input, + ResolvesToInt|int|string $n, + ): MinNOperator { + return new MinNOperator($input, $n); + } + + /** + * Returns the minute for a date as a number between 0 and 59. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/minute/ + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + */ + public static function minute( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + ): MinuteOperator { + return new MinuteOperator($date, $timezone); + } + + /** + * Returns the remainder of the first number divided by the second. Accepts two argument expressions. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/mod/ + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $dividend The first argument is the dividend, and the second argument is the divisor; i.e. first argument is divided by the second argument. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $divisor + */ + public static function mod( + Decimal128|Int64|ResolvesToNumber|float|int|string $dividend, + Decimal128|Int64|ResolvesToNumber|float|int|string $divisor, + ): ModOperator { + return new ModOperator($dividend, $divisor); + } + + /** + * Returns the month for a date as a number between 1 (January) and 12 (December). + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/month/ + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + */ + public static function month( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + ): MonthOperator { + return new MonthOperator($date, $timezone); + } + + /** + * Multiplies numbers to return the product. Accepts any number of argument expressions. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/multiply/ + * @no-named-arguments + * @param Decimal128|Int64|ResolvesToNumber|float|int|string ...$expression The arguments can be any valid expression as long as they resolve to numbers. + * Starting in MongoDB 6.1 you can optimize the $multiply operation. To improve performance, group references at the end of the argument list. + */ + public static function multiply( + Decimal128|Int64|ResolvesToNumber|float|int|string ...$expression, + ): MultiplyOperator { + return new MultiplyOperator(...$expression); + } + + /** + * Returns true if the values are not equivalent. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/ne/ + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression1 + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression2 + */ + public static function ne( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression1, + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression2, + ): NeOperator { + return new NeOperator($expression1, $expression2); + } + + /** + * Returns the boolean value that is the opposite of its argument expression. Accepts a single argument expression. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/not/ + * @param DateTimeInterface|ExpressionInterface|ResolvesToBool|Type|array|bool|float|int|null|stdClass|string $expression + */ + public static function not( + DateTimeInterface|Type|ResolvesToBool|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ): NotOperator { + return new NotOperator($expression); + } + + /** + * Converts a document to an array of documents representing key-value pairs. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/objectToArray/ + * @param Document|ResolvesToObject|Serializable|array|stdClass|string $object Any valid expression as long as it resolves to a document object. $objectToArray applies to the top-level fields of its argument. If the argument is a document that itself contains embedded document fields, the $objectToArray does not recursively apply to the embedded document fields. + */ + public static function objectToArray( + Document|Serializable|ResolvesToObject|stdClass|array|string $object, + ): ObjectToArrayOperator { + return new ObjectToArrayOperator($object); + } + + /** + * Returns true when any of its expressions evaluates to true. Accepts any number of argument expressions. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/or/ + * @no-named-arguments + * @param DateTimeInterface|ExpressionInterface|ResolvesToBool|Type|array|bool|float|int|null|stdClass|string ...$expression + */ + public static function or( + DateTimeInterface|Type|ResolvesToBool|ExpressionInterface|stdClass|array|bool|float|int|null|string ...$expression, + ): OrOperator { + return new OrOperator(...$expression); + } + + /** + * Returns an array of scalar values that correspond to specified percentile values. + * New in MongoDB 7.0. + * + * This operator is available as an accumulator in these stages: + * $group + * + * $setWindowFields + * + * It is also available as an aggregation expression. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/percentile/ + * @param BSONArray|Decimal128|Int64|PackedArray|ResolvesToNumber|array|float|int|string $input $percentile calculates the percentile values of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $percentile calculation ignores it. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $p $percentile calculates a percentile value for each element in p. The elements represent percentages and must evaluate to numeric values in the range 0.0 to 1.0, inclusive. + * $percentile returns results in the same order as the elements in p. + * @param string $method The method that mongod uses to calculate the percentile value. The method must be 'approximate'. + */ + public static function percentile( + Decimal128|Int64|PackedArray|ResolvesToNumber|BSONArray|array|float|int|string $input, + PackedArray|ResolvesToArray|BSONArray|array|string $p, + string $method, + ): PercentileOperator { + return new PercentileOperator($input, $p, $method); + } + + /** + * Raises a number to the specified exponent. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/pow/ + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $number + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $exponent + */ + public static function pow( + Decimal128|Int64|ResolvesToNumber|float|int|string $number, + Decimal128|Int64|ResolvesToNumber|float|int|string $exponent, + ): PowOperator { + return new PowOperator($number, $exponent); + } + + /** + * Converts a value from radians to degrees. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/radiansToDegrees/ + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression + */ + public static function radiansToDegrees( + Decimal128|Int64|ResolvesToNumber|float|int|string $expression, + ): RadiansToDegreesOperator { + return new RadiansToDegreesOperator($expression); + } + + /** + * Returns a random float between 0 and 1 + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/rand/ + */ + public static function rand(): RandOperator + { + return new RandOperator(); + } + + /** + * Outputs an array containing a sequence of integers according to user-defined inputs. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/range/ + * @param ResolvesToInt|int|string $start An integer that specifies the start of the sequence. Can be any valid expression that resolves to an integer. + * @param ResolvesToInt|int|string $end An integer that specifies the exclusive upper limit of the sequence. Can be any valid expression that resolves to an integer. + * @param Optional|ResolvesToInt|int|string $step An integer that specifies the increment value. Can be any valid expression that resolves to a non-zero integer. Defaults to 1. + */ + public static function range( + ResolvesToInt|int|string $start, + ResolvesToInt|int|string $end, + Optional|ResolvesToInt|int|string $step = Optional::Undefined, + ): RangeOperator { + return new RangeOperator($start, $end, $step); + } + + /** + * Applies an expression to each element in an array and combines them into a single value. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/reduce/ + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input Can be any valid expression that resolves to an array. + * If the argument resolves to a value of null or refers to a missing field, $reduce returns null. + * If the argument does not resolve to an array or null nor refers to a missing field, $reduce returns an error. + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $initialValue The initial cumulative value set before in is applied to the first element of the input array. + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $in A valid expression that $reduce applies to each element in the input array in left-to-right order. Wrap the input value with $reverseArray to yield the equivalent of applying the combining expression from right-to-left. + * During evaluation of the in expression, two variables will be available: + * - value is the variable that represents the cumulative value of the expression. + * - this is the variable that refers to the element being processed. + */ + public static function reduce( + PackedArray|ResolvesToArray|BSONArray|array|string $input, + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $initialValue, + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $in, + ): ReduceOperator { + return new ReduceOperator($input, $initialValue, $in); + } + + /** + * Applies a regular expression (regex) to a string and returns information on the first matched substring. + * New in MongoDB 4.2. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/regexFind/ + * @param ResolvesToString|string $input The string on which you wish to apply the regex pattern. Can be a string or any valid expression that resolves to a string. + * @param Regex|ResolvesToString|string $regex The regex pattern to apply. Can be any valid expression that resolves to either a string or regex pattern //. When using the regex //, you can also specify the regex options i and m (but not the s or x options) + * @param Optional|string $options + */ + public static function regexFind( + ResolvesToString|string $input, + Regex|ResolvesToString|string $regex, + Optional|string $options = Optional::Undefined, + ): RegexFindOperator { + return new RegexFindOperator($input, $regex, $options); + } + + /** + * Applies a regular expression (regex) to a string and returns information on the all matched substrings. + * New in MongoDB 4.2. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/regexFindAll/ + * @param ResolvesToString|string $input The string on which you wish to apply the regex pattern. Can be a string or any valid expression that resolves to a string. + * @param Regex|ResolvesToString|string $regex The regex pattern to apply. Can be any valid expression that resolves to either a string or regex pattern //. When using the regex //, you can also specify the regex options i and m (but not the s or x options) + * @param Optional|string $options + */ + public static function regexFindAll( + ResolvesToString|string $input, + Regex|ResolvesToString|string $regex, + Optional|string $options = Optional::Undefined, + ): RegexFindAllOperator { + return new RegexFindAllOperator($input, $regex, $options); + } + + /** + * Applies a regular expression (regex) to a string and returns a boolean that indicates if a match is found or not. + * New in MongoDB 4.2. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/regexMatch/ + * @param ResolvesToString|string $input The string on which you wish to apply the regex pattern. Can be a string or any valid expression that resolves to a string. + * @param Regex|ResolvesToString|string $regex The regex pattern to apply. Can be any valid expression that resolves to either a string or regex pattern //. When using the regex //, you can also specify the regex options i and m (but not the s or x options) + * @param Optional|string $options + */ + public static function regexMatch( + ResolvesToString|string $input, + Regex|ResolvesToString|string $regex, + Optional|string $options = Optional::Undefined, + ): RegexMatchOperator { + return new RegexMatchOperator($input, $regex, $options); + } + + /** + * Replaces all instances of a search string in an input string with a replacement string. + * $replaceAll is both case-sensitive and diacritic-sensitive, and ignores any collation present on a collection. + * New in MongoDB 4.4. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/replaceAll/ + * @param ResolvesToNull|ResolvesToString|null|string $input The string on which you wish to apply the find. Can be any valid expression that resolves to a string or a null. If input refers to a field that is missing, $replaceAll returns null. + * @param ResolvesToNull|ResolvesToString|null|string $find The string to search for within the given input. Can be any valid expression that resolves to a string or a null. If find refers to a field that is missing, $replaceAll returns null. + * @param ResolvesToNull|ResolvesToString|null|string $replacement The string to use to replace all matched instances of find in input. Can be any valid expression that resolves to a string or a null. + */ + public static function replaceAll( + ResolvesToNull|ResolvesToString|null|string $input, + ResolvesToNull|ResolvesToString|null|string $find, + ResolvesToNull|ResolvesToString|null|string $replacement, + ): ReplaceAllOperator { + return new ReplaceAllOperator($input, $find, $replacement); + } + + /** + * Replaces the first instance of a matched string in a given input. + * New in MongoDB 4.4. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/replaceOne/ + * @param ResolvesToNull|ResolvesToString|null|string $input The string on which you wish to apply the find. Can be any valid expression that resolves to a string or a null. If input refers to a field that is missing, $replaceAll returns null. + * @param ResolvesToNull|ResolvesToString|null|string $find The string to search for within the given input. Can be any valid expression that resolves to a string or a null. If find refers to a field that is missing, $replaceAll returns null. + * @param ResolvesToNull|ResolvesToString|null|string $replacement The string to use to replace all matched instances of find in input. Can be any valid expression that resolves to a string or a null. + */ + public static function replaceOne( + ResolvesToNull|ResolvesToString|null|string $input, + ResolvesToNull|ResolvesToString|null|string $find, + ResolvesToNull|ResolvesToString|null|string $replacement, + ): ReplaceOneOperator { + return new ReplaceOneOperator($input, $find, $replacement); + } + + /** + * Returns an array with the elements in reverse order. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/reverseArray/ + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression The argument can be any valid expression as long as it resolves to an array. + */ + public static function reverseArray( + PackedArray|ResolvesToArray|BSONArray|array|string $expression, + ): ReverseArrayOperator { + return new ReverseArrayOperator($expression); + } + + /** + * Rounds a number to a whole integer or to a specified decimal place. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/round/ + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $number Can be any valid expression that resolves to a number. Specifically, the expression must resolve to an integer, double, decimal, or long. + * $round returns an error if the expression resolves to a non-numeric data type. + * @param Optional|ResolvesToInt|int|string $place Can be any valid expression that resolves to an integer between -20 and 100, exclusive. + */ + public static function round( + Decimal128|Int64|ResolvesToNumber|float|int|string $number, + Optional|ResolvesToInt|int|string $place = Optional::Undefined, + ): RoundOperator { + return new RoundOperator($number, $place); + } + + /** + * Removes whitespace characters, including null, or the specified characters from the end of a string. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/rtrim/ + * @param ResolvesToString|string $input The string to trim. The argument can be any valid expression that resolves to a string. + * @param Optional|ResolvesToString|string $chars The character(s) to trim from the beginning of the input. + * The argument can be any valid expression that resolves to a string. The $ltrim operator breaks down the string into individual UTF code point to trim from input. + * If unspecified, $ltrim removes whitespace characters, including the null character. + */ + public static function rtrim( + ResolvesToString|string $input, + Optional|ResolvesToString|string $chars = Optional::Undefined, + ): RtrimOperator { + return new RtrimOperator($input, $chars); + } + + /** + * Returns the seconds for a date as a number between 0 and 60 (leap seconds). + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/second/ + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + */ + public static function second( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + ): SecondOperator { + return new SecondOperator($date, $timezone); + } + + /** + * Returns a set with elements that appear in the first set but not in the second set; i.e. performs a relative complement of the second set relative to the first. Accepts exactly two argument expressions. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/setDifference/ + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression1 The arguments can be any valid expression as long as they each resolve to an array. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression2 The arguments can be any valid expression as long as they each resolve to an array. + */ + public static function setDifference( + PackedArray|ResolvesToArray|BSONArray|array|string $expression1, + PackedArray|ResolvesToArray|BSONArray|array|string $expression2, + ): SetDifferenceOperator { + return new SetDifferenceOperator($expression1, $expression2); + } + + /** + * Returns true if the input sets have the same distinct elements. Accepts two or more argument expressions. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/setEquals/ + * @no-named-arguments + * @param BSONArray|PackedArray|ResolvesToArray|array|string ...$expression + */ + public static function setEquals( + PackedArray|ResolvesToArray|BSONArray|array|string ...$expression, + ): SetEqualsOperator { + return new SetEqualsOperator(...$expression); + } + + /** + * Adds, updates, or removes a specified field in a document. You can use $setField to add, update, or remove fields with names that contain periods (.) or start with dollar signs ($). + * New in MongoDB 5.0. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/setField/ + * @param ResolvesToString|string $field Field in the input object that you want to add, update, or remove. field can be any valid expression that resolves to a string constant. + * @param Document|ResolvesToObject|Serializable|array|stdClass|string $input Document that contains the field that you want to add or update. input must resolve to an object, missing, null, or undefined. + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $value The value that you want to assign to field. value can be any valid expression. + * Set to $$REMOVE to remove field from the input document. + */ + public static function setField( + ResolvesToString|string $field, + Document|Serializable|ResolvesToObject|stdClass|array|string $input, + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $value, + ): SetFieldOperator { + return new SetFieldOperator($field, $input, $value); + } + + /** + * Returns a set with elements that appear in all of the input sets. Accepts any number of argument expressions. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/setIntersection/ + * @no-named-arguments + * @param BSONArray|PackedArray|ResolvesToArray|array|string ...$expression + */ + public static function setIntersection( + PackedArray|ResolvesToArray|BSONArray|array|string ...$expression, + ): SetIntersectionOperator { + return new SetIntersectionOperator(...$expression); + } + + /** + * Returns true if all elements of the first set appear in the second set, including when the first set equals the second set; i.e. not a strict subset. Accepts exactly two argument expressions. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/setIsSubset/ + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression1 + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression2 + */ + public static function setIsSubset( + PackedArray|ResolvesToArray|BSONArray|array|string $expression1, + PackedArray|ResolvesToArray|BSONArray|array|string $expression2, + ): SetIsSubsetOperator { + return new SetIsSubsetOperator($expression1, $expression2); + } + + /** + * Returns a set with elements that appear in any of the input sets. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/setUnion/ + * @no-named-arguments + * @param BSONArray|PackedArray|ResolvesToArray|array|string ...$expression + */ + public static function setUnion( + PackedArray|ResolvesToArray|BSONArray|array|string ...$expression, + ): SetUnionOperator { + return new SetUnionOperator(...$expression); + } + + /** + * Returns the sine of a value that is measured in radians. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/sin/ + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $sin takes any valid expression that resolves to a number. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the result to radians. + * By default $sin returns values as a double. $sin can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. + */ + public static function sin(Decimal128|Int64|ResolvesToNumber|float|int|string $expression): SinOperator + { + return new SinOperator($expression); + } + + /** + * Returns the hyperbolic sine of a value that is measured in radians. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/sinh/ + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $sinh takes any valid expression that resolves to a number, measured in radians. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the value to radians. + * By default $sinh returns values as a double. $sinh can also return values as a 128-bit decimal if the expression resolves to a 128-bit decimal value. + */ + public static function sinh(Decimal128|Int64|ResolvesToNumber|float|int|string $expression): SinhOperator + { + return new SinhOperator($expression); + } + + /** + * Returns the number of elements in the array. Accepts a single expression as argument. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/size/ + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression The argument for $size can be any expression as long as it resolves to an array. + */ + public static function size(PackedArray|ResolvesToArray|BSONArray|array|string $expression): SizeOperator + { + return new SizeOperator($expression); + } + + /** + * Returns a subset of an array. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/slice/ + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression Any valid expression as long as it resolves to an array. + * @param ResolvesToInt|int|string $n Any valid expression as long as it resolves to an integer. If position is specified, n must resolve to a positive integer. + * If positive, $slice returns up to the first n elements in the array. If the position is specified, $slice returns the first n elements starting from the position. + * If negative, $slice returns up to the last n elements in the array. n cannot resolve to a negative number if is specified. + * @param Optional|ResolvesToInt|int|string $position Any valid expression as long as it resolves to an integer. + * If positive, $slice determines the starting position from the start of the array. If position is greater than the number of elements, the $slice returns an empty array. + * If negative, $slice determines the starting position from the end of the array. If the absolute value of the is greater than the number of elements, the starting position is the start of the array. + */ + public static function slice( + PackedArray|ResolvesToArray|BSONArray|array|string $expression, + ResolvesToInt|int|string $n, + Optional|ResolvesToInt|int|string $position = Optional::Undefined, + ): SliceOperator { + return new SliceOperator($expression, $n, $position); + } + + /** + * Sorts the elements of an array. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/sortArray/ + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input The array to be sorted. + * The result is null if the expression: is missing, evaluates to null, or evaluates to undefined + * If the expression evaluates to any other non-array value, the document returns an error. + * @param Document|Serializable|Sort|array|int|stdClass $sortBy The document specifies a sort ordering. + */ + public static function sortArray( + PackedArray|ResolvesToArray|BSONArray|array|string $input, + Document|Serializable|Sort|stdClass|array|int $sortBy, + ): SortArrayOperator { + return new SortArrayOperator($input, $sortBy); + } + + /** + * Splits a string into substrings based on a delimiter. Returns an array of substrings. If the delimiter is not found within the string, returns an array containing the original string. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/split/ + * @param ResolvesToString|string $string The string to be split. string expression can be any valid expression as long as it resolves to a string. + * @param ResolvesToString|string $delimiter The delimiter to use when splitting the string expression. delimiter can be any valid expression as long as it resolves to a string. + */ + public static function split(ResolvesToString|string $string, ResolvesToString|string $delimiter): SplitOperator + { + return new SplitOperator($string, $delimiter); + } + + /** + * Calculates the square root. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/sqrt/ + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $number The argument can be any valid expression as long as it resolves to a non-negative number. + */ + public static function sqrt(Decimal128|Int64|ResolvesToNumber|float|int|string $number): SqrtOperator + { + return new SqrtOperator($number); + } + + /** + * Calculates the population standard deviation of the input values. Use if the values encompass the entire population of data you want to represent and do not wish to generalize about a larger population. $stdDevPop ignores non-numeric values. + * If the values represent only a sample of a population of data from which to generalize about the population, use $stdDevSamp instead. + * Changed in MongoDB 5.0: Available in the $setWindowFields stage. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/stdDevPop/ + * @no-named-arguments + * @param Decimal128|Int64|ResolvesToNumber|float|int|string ...$expression + */ + public static function stdDevPop( + Decimal128|Int64|ResolvesToNumber|float|int|string ...$expression, + ): StdDevPopOperator { + return new StdDevPopOperator(...$expression); + } + + /** + * Calculates the sample standard deviation of the input values. Use if the values encompass a sample of a population of data from which to generalize about the population. $stdDevSamp ignores non-numeric values. + * If the values represent the entire population of data or you do not wish to generalize about a larger population, use $stdDevPop instead. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/stdDevSamp/ + * @no-named-arguments + * @param Decimal128|Int64|ResolvesToNumber|float|int|string ...$expression + */ + public static function stdDevSamp( + Decimal128|Int64|ResolvesToNumber|float|int|string ...$expression, + ): StdDevSampOperator { + return new StdDevSampOperator(...$expression); + } + + /** + * Performs case-insensitive string comparison and returns: 0 if two strings are equivalent, 1 if the first string is greater than the second, and -1 if the first string is less than the second. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/strcasecmp/ + * @param ResolvesToString|string $expression1 + * @param ResolvesToString|string $expression2 + */ + public static function strcasecmp( + ResolvesToString|string $expression1, + ResolvesToString|string $expression2, + ): StrcasecmpOperator { + return new StrcasecmpOperator($expression1, $expression2); + } + + /** + * Returns the number of UTF-8 encoded bytes in a string. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/strLenBytes/ + * @param ResolvesToString|string $expression + */ + public static function strLenBytes(ResolvesToString|string $expression): StrLenBytesOperator + { + return new StrLenBytesOperator($expression); + } + + /** + * Returns the number of UTF-8 code points in a string. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/strLenCP/ + * @param ResolvesToString|string $expression + */ + public static function strLenCP(ResolvesToString|string $expression): StrLenCPOperator + { + return new StrLenCPOperator($expression); + } + + /** + * Deprecated. Use $substrBytes or $substrCP. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/substr/ + * @param ResolvesToString|string $string + * @param ResolvesToInt|int|string $start If start is a negative number, $substr returns an empty string "". + * @param ResolvesToInt|int|string $length If length is a negative number, $substr returns a substring that starts at the specified index and includes the rest of the string. + */ + public static function substr( + ResolvesToString|string $string, + ResolvesToInt|int|string $start, + ResolvesToInt|int|string $length, + ): SubstrOperator { + return new SubstrOperator($string, $start, $length); + } + + /** + * Returns the substring of a string. Starts with the character at the specified UTF-8 byte index (zero-based) in the string and continues for the specified number of bytes. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/substrBytes/ + * @param ResolvesToString|string $string + * @param ResolvesToInt|int|string $start If start is a negative number, $substr returns an empty string "". + * @param ResolvesToInt|int|string $length If length is a negative number, $substr returns a substring that starts at the specified index and includes the rest of the string. + */ + public static function substrBytes( + ResolvesToString|string $string, + ResolvesToInt|int|string $start, + ResolvesToInt|int|string $length, + ): SubstrBytesOperator { + return new SubstrBytesOperator($string, $start, $length); + } + + /** + * Returns the substring of a string. Starts with the character at the specified UTF-8 code point (CP) index (zero-based) in the string and continues for the number of code points specified. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/substrCP/ + * @param ResolvesToString|string $string + * @param ResolvesToInt|int|string $start If start is a negative number, $substr returns an empty string "". + * @param ResolvesToInt|int|string $length If length is a negative number, $substr returns a substring that starts at the specified index and includes the rest of the string. + */ + public static function substrCP( + ResolvesToString|string $string, + ResolvesToInt|int|string $start, + ResolvesToInt|int|string $length, + ): SubstrCPOperator { + return new SubstrCPOperator($string, $start, $length); + } + + /** + * Returns the result of subtracting the second value from the first. If the two values are numbers, return the difference. If the two values are dates, return the difference in milliseconds. If the two values are a date and a number in milliseconds, return the resulting date. Accepts two argument expressions. If the two values are a date and a number, specify the date argument first as it is not meaningful to subtract a date from a number. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/subtract/ + * @param DateTimeInterface|Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int|string $expression1 + * @param DateTimeInterface|Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int|string $expression2 + */ + public static function subtract( + DateTimeInterface|Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int|string $expression1, + DateTimeInterface|Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int|string $expression2, + ): SubtractOperator { + return new SubtractOperator($expression1, $expression2); + } + + /** + * Returns a sum of numerical values. Ignores non-numeric values. + * Changed in MongoDB 5.0: Available in the $setWindowFields stage. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum/ + * @no-named-arguments + * @param BSONArray|Decimal128|Int64|PackedArray|ResolvesToArray|ResolvesToNumber|array|float|int|string ...$expression + */ + public static function sum( + Decimal128|Int64|PackedArray|ResolvesToArray|ResolvesToNumber|BSONArray|array|float|int|string ...$expression, + ): SumOperator { + return new SumOperator(...$expression); + } + + /** + * Evaluates a series of case expressions. When it finds an expression which evaluates to true, $switch executes a specified expression and breaks out of the control flow. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/switch/ + * @param BSONArray|PackedArray|array $branches An array of control branch documents. Each branch is a document with the following fields: + * - case Can be any valid expression that resolves to a boolean. If the result is not a boolean, it is coerced to a boolean value. More information about how MongoDB evaluates expressions as either true or false can be found here. + * - then Can be any valid expression. + * The branches array must contain at least one branch document. + * @param Optional|DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $default The path to take if no branch case expression evaluates to true. + * Although optional, if default is unspecified and no branch case evaluates to true, $switch returns an error. + */ + public static function switch( + PackedArray|BSONArray|array $branches, + Optional|DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $default = Optional::Undefined, + ): SwitchOperator { + return new SwitchOperator($branches, $default); + } + + /** + * Returns the tangent of a value that is measured in radians. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/tan/ + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $tan takes any valid expression that resolves to a number. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the result to radians. + * By default $tan returns values as a double. $tan can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. + */ + public static function tan(Decimal128|Int64|ResolvesToNumber|float|int|string $expression): TanOperator + { + return new TanOperator($expression); + } + + /** + * Returns the hyperbolic tangent of a value that is measured in radians. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/tanh/ + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $tanh takes any valid expression that resolves to a number, measured in radians. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the value to radians. + * By default $tanh returns values as a double. $tanh can also return values as a 128-bit decimal if the expression resolves to a 128-bit decimal value. + */ + public static function tanh(Decimal128|Int64|ResolvesToNumber|float|int|string $expression): TanhOperator + { + return new TanhOperator($expression); + } + + /** + * Converts value to a boolean. + * New in MongoDB 4.0. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/toBool/ + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public static function toBool( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ): ToBoolOperator { + return new ToBoolOperator($expression); + } + + /** + * Converts value to a Date. + * New in MongoDB 4.0. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/toDate/ + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public static function toDate( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ): ToDateOperator { + return new ToDateOperator($expression); + } + + /** + * Converts value to a Decimal128. + * New in MongoDB 4.0. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/toDecimal/ + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public static function toDecimal( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ): ToDecimalOperator { + return new ToDecimalOperator($expression); + } + + /** + * Converts value to a double. + * New in MongoDB 4.0. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/toDouble/ + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public static function toDouble( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ): ToDoubleOperator { + return new ToDoubleOperator($expression); + } + + /** + * Computes and returns the hash value of the input expression using the same hash function that MongoDB uses to create a hashed index. A hash function maps a key or string to a fixed-size numeric value. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/toHashedIndexKey/ + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $value key or string to hash + */ + public static function toHashedIndexKey( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $value, + ): ToHashedIndexKeyOperator { + return new ToHashedIndexKeyOperator($value); + } + + /** + * Converts value to an integer. + * New in MongoDB 4.0. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/toInt/ + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public static function toInt( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ): ToIntOperator { + return new ToIntOperator($expression); + } + + /** + * Converts value to a long. + * New in MongoDB 4.0. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/toLong/ + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public static function toLong( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ): ToLongOperator { + return new ToLongOperator($expression); + } + + /** + * Converts a string to lowercase. Accepts a single argument expression. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/toLower/ + * @param ResolvesToString|string $expression + */ + public static function toLower(ResolvesToString|string $expression): ToLowerOperator + { + return new ToLowerOperator($expression); + } + + /** + * Converts value to an ObjectId. + * New in MongoDB 4.0. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/toObjectId/ + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public static function toObjectId( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ): ToObjectIdOperator { + return new ToObjectIdOperator($expression); + } + + /** + * Converts value to a string. + * New in MongoDB 4.0. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/toString/ + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public static function toString( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ): ToStringOperator { + return new ToStringOperator($expression); + } + + /** + * Converts a string to uppercase. Accepts a single argument expression. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/toUpper/ + * @param ResolvesToString|string $expression + */ + public static function toUpper(ResolvesToString|string $expression): ToUpperOperator + { + return new ToUpperOperator($expression); + } + + /** + * Removes whitespace or the specified characters from the beginning and end of a string. + * New in MongoDB 4.0. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/trim/ + * @param ResolvesToString|string $input The string to trim. The argument can be any valid expression that resolves to a string. + * @param Optional|ResolvesToString|string $chars The character(s) to trim from the beginning of the input. + * The argument can be any valid expression that resolves to a string. The $ltrim operator breaks down the string into individual UTF code point to trim from input. + * If unspecified, $ltrim removes whitespace characters, including the null character. + */ + public static function trim( + ResolvesToString|string $input, + Optional|ResolvesToString|string $chars = Optional::Undefined, + ): TrimOperator { + return new TrimOperator($input, $chars); + } + + /** + * Truncates a number to a whole integer or to a specified decimal place. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/trunc/ + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $number Can be any valid expression that resolves to a number. Specifically, the expression must resolve to an integer, double, decimal, or long. + * $trunc returns an error if the expression resolves to a non-numeric data type. + * @param Optional|ResolvesToInt|int|string $place Can be any valid expression that resolves to an integer between -20 and 100, exclusive. e.g. -20 < place < 100. Defaults to 0. + */ + public static function trunc( + Decimal128|Int64|ResolvesToNumber|float|int|string $number, + Optional|ResolvesToInt|int|string $place = Optional::Undefined, + ): TruncOperator { + return new TruncOperator($number, $place); + } + + /** + * Returns the incrementing ordinal from a timestamp as a long. + * New in MongoDB 5.1. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/tsIncrement/ + * @param ResolvesToTimestamp|Timestamp|int|string $expression + */ + public static function tsIncrement(Timestamp|ResolvesToTimestamp|int|string $expression): TsIncrementOperator + { + return new TsIncrementOperator($expression); + } + + /** + * Returns the seconds from a timestamp as a long. + * New in MongoDB 5.1. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/tsSecond/ + * @param ResolvesToTimestamp|Timestamp|int|string $expression + */ + public static function tsSecond(Timestamp|ResolvesToTimestamp|int|string $expression): TsSecondOperator + { + return new TsSecondOperator($expression); + } + + /** + * Return the BSON data type of the field. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/type/ + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public static function type( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ): TypeOperator { + return new TypeOperator($expression); + } + + /** + * You can use $unsetField to remove fields with names that contain periods (.) or that start with dollar signs ($). + * $unsetField is an alias for $setField using $$REMOVE to remove fields. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/unsetField/ + * @param ResolvesToString|string $field Field in the input object that you want to add, update, or remove. field can be any valid expression that resolves to a string constant. + * @param Document|ResolvesToObject|Serializable|array|stdClass|string $input Document that contains the field that you want to add or update. input must resolve to an object, missing, null, or undefined. + */ + public static function unsetField( + ResolvesToString|string $field, + Document|Serializable|ResolvesToObject|stdClass|array|string $input, + ): UnsetFieldOperator { + return new UnsetFieldOperator($field, $input); + } + + /** + * Returns the week number for a date as a number between 0 (the partial week that precedes the first Sunday of the year) and 53 (leap year). + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/week/ + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + */ + public static function week( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + ): WeekOperator { + return new WeekOperator($date, $timezone); + } + + /** + * Returns the year for a date as a number (e.g. 2014). + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/year/ + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + */ + public static function year( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + ): YearOperator { + return new YearOperator($date, $timezone); + } + + /** + * Merge two arrays together. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/zip/ + * @param BSONArray|PackedArray|ResolvesToArray|array|string $inputs An array of expressions that resolve to arrays. The elements of these input arrays combine to form the arrays of the output array. + * If any of the inputs arrays resolves to a value of null or refers to a missing field, $zip returns null. + * If any of the inputs arrays does not resolve to an array or null nor refers to a missing field, $zip returns an error. + * @param Optional|bool $useLongestLength A boolean which specifies whether the length of the longest array determines the number of arrays in the output array. + * The default value is false: the shortest array length determines the number of arrays in the output array. + * @param Optional|BSONArray|PackedArray|array $defaults An array of default element values to use if the input arrays have different lengths. You must specify useLongestLength: true along with this field, or else $zip will return an error. + * If useLongestLength: true but defaults is empty or not specified, $zip uses null as the default value. + * If specifying a non-empty defaults, you must specify a default for each input array or else $zip will return an error. + */ + public static function zip( + PackedArray|ResolvesToArray|BSONArray|array|string $inputs, + Optional|bool $useLongestLength = Optional::Undefined, + Optional|PackedArray|BSONArray|array $defaults = Optional::Undefined, + ): ZipOperator { + return new ZipOperator($inputs, $useLongestLength, $defaults); + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/FieldPath.php b/vendor/mongodb/mongodb/src/Builder/Expression/FieldPath.php new file mode 100644 index 00000000..4563994b --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/FieldPath.php @@ -0,0 +1,29 @@ +name = $name; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/FilterOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/FilterOperator.php new file mode 100644 index 00000000..b2f2df99 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/FilterOperator.php @@ -0,0 +1,84 @@ + 'input', 'cond' => 'cond', 'as' => 'as', 'limit' => 'limit']; + + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $input */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $input; + + /** @var ResolvesToBool|bool|string $cond An expression that resolves to a boolean value used to determine if an element should be included in the output array. The expression references each element of the input array individually with the variable name specified in as. */ + public readonly ResolvesToBool|bool|string $cond; + + /** @var Optional|string $as A name for the variable that represents each individual element of the input array. If no name is specified, the variable name defaults to this. */ + public readonly Optional|string $as; + + /** + * @var Optional|ResolvesToInt|int|string $limit A number expression that restricts the number of matching array elements that $filter returns. You cannot specify a limit less than 1. The matching array elements are returned in the order they appear in the input array. + * If the specified limit is greater than the number of matching array elements, $filter returns all matching array elements. If the limit is null, $filter returns all matching array elements. + */ + public readonly Optional|ResolvesToInt|int|string $limit; + + /** + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input + * @param ResolvesToBool|bool|string $cond An expression that resolves to a boolean value used to determine if an element should be included in the output array. The expression references each element of the input array individually with the variable name specified in as. + * @param Optional|string $as A name for the variable that represents each individual element of the input array. If no name is specified, the variable name defaults to this. + * @param Optional|ResolvesToInt|int|string $limit A number expression that restricts the number of matching array elements that $filter returns. You cannot specify a limit less than 1. The matching array elements are returned in the order they appear in the input array. + * If the specified limit is greater than the number of matching array elements, $filter returns all matching array elements. If the limit is null, $filter returns all matching array elements. + */ + public function __construct( + PackedArray|ResolvesToArray|BSONArray|array|string $input, + ResolvesToBool|bool|string $cond, + Optional|string $as = Optional::Undefined, + Optional|ResolvesToInt|int|string $limit = Optional::Undefined, + ) { + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + if (is_array($input) && ! array_is_list($input)) { + throw new InvalidArgumentException('Expected $input argument to be a list, got an associative array.'); + } + + $this->input = $input; + if (is_string($cond) && ! str_starts_with($cond, '$')) { + throw new InvalidArgumentException('Argument $cond can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->cond = $cond; + $this->as = $as; + if (is_string($limit) && ! str_starts_with($limit, '$')) { + throw new InvalidArgumentException('Argument $limit can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->limit = $limit; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/FirstNOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/FirstNOperator.php new file mode 100644 index 00000000..9051441d --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/FirstNOperator.php @@ -0,0 +1,63 @@ + 'n', 'input' => 'input']; + + /** @var ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $firstN returns. */ + public readonly ResolvesToInt|int|string $n; + + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return n elements. */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $input; + + /** + * @param ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $firstN returns. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return n elements. + */ + public function __construct( + ResolvesToInt|int|string $n, + PackedArray|ResolvesToArray|BSONArray|array|string $input, + ) { + if (is_string($n) && ! str_starts_with($n, '$')) { + throw new InvalidArgumentException('Argument $n can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->n = $n; + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + if (is_array($input) && ! array_is_list($input)) { + throw new InvalidArgumentException('Expected $input argument to be a list, got an associative array.'); + } + + $this->input = $input; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/FirstOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/FirstOperator.php new file mode 100644 index 00000000..d967bf7d --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/FirstOperator.php @@ -0,0 +1,52 @@ + 'expression']; + + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $expression */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $expression; + + /** + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression + */ + public function __construct(PackedArray|ResolvesToArray|BSONArray|array|string $expression) + { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + if (is_array($expression) && ! array_is_list($expression)) { + throw new InvalidArgumentException('Expected $expression argument to be a list, got an associative array.'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/FloorOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/FloorOperator.php new file mode 100644 index 00000000..b81d5e05 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/FloorOperator.php @@ -0,0 +1,46 @@ + 'expression']; + + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression + */ + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) + { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/FunctionOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/FunctionOperator.php new file mode 100644 index 00000000..516729e3 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/FunctionOperator.php @@ -0,0 +1,67 @@ + 'body', 'args' => 'args', 'lang' => 'lang']; + + /** + * @var Javascript|string $body The function definition. You can specify the function definition as either BSON\JavaScript or string. + * function(arg1, arg2, ...) { ... } + */ + public readonly Javascript|string $body; + + /** @var BSONArray|PackedArray|array $args Arguments passed to the function body. If the body function does not take an argument, you can specify an empty array [ ]. */ + public readonly PackedArray|BSONArray|array $args; + + /** @var string $lang */ + public readonly string $lang; + + /** + * @param Javascript|string $body The function definition. You can specify the function definition as either BSON\JavaScript or string. + * function(arg1, arg2, ...) { ... } + * @param BSONArray|PackedArray|array $args Arguments passed to the function body. If the body function does not take an argument, you can specify an empty array [ ]. + * @param string $lang + */ + public function __construct(Javascript|string $body, PackedArray|BSONArray|array $args = [], string $lang = 'js') + { + if (is_string($body)) { + $body = new Javascript($body); + } + + $this->body = $body; + if (is_array($args) && ! array_is_list($args)) { + throw new InvalidArgumentException('Expected $args argument to be a list, got an associative array.'); + } + + $this->args = $args; + $this->lang = $lang; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/GetFieldOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/GetFieldOperator.php new file mode 100644 index 00000000..faf2272e --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/GetFieldOperator.php @@ -0,0 +1,57 @@ + 'field', 'input' => 'input']; + + /** + * @var ResolvesToString|string $field Field in the input object for which you want to return a value. field can be any valid expression that resolves to a string constant. + * If field begins with a dollar sign ($), place the field name inside of a $literal expression to return its value. + */ + public readonly ResolvesToString|string $field; + + /** + * @var Optional|DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $input Default: $$CURRENT + * A valid expression that contains the field for which you want to return a value. input must resolve to an object, missing, null, or undefined. If omitted, defaults to the document currently being processed in the pipeline ($$CURRENT). + */ + public readonly Optional|DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $input; + + /** + * @param ResolvesToString|string $field Field in the input object for which you want to return a value. field can be any valid expression that resolves to a string constant. + * If field begins with a dollar sign ($), place the field name inside of a $literal expression to return its value. + * @param Optional|DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $input Default: $$CURRENT + * A valid expression that contains the field for which you want to return a value. input must resolve to an object, missing, null, or undefined. If omitted, defaults to the document currently being processed in the pipeline ($$CURRENT). + */ + public function __construct( + ResolvesToString|string $field, + Optional|DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $input = Optional::Undefined, + ) { + $this->field = $field; + $this->input = $input; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/GtOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/GtOperator.php new file mode 100644 index 00000000..9d92a714 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/GtOperator.php @@ -0,0 +1,47 @@ + 'expression1', 'expression2' => 'expression2']; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression1 */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression1; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression2 */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression2; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression1 + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression2 + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression1, + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression2, + ) { + $this->expression1 = $expression1; + $this->expression2 = $expression2; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/GteOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/GteOperator.php new file mode 100644 index 00000000..4a6708ca --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/GteOperator.php @@ -0,0 +1,47 @@ + 'expression1', 'expression2' => 'expression2']; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression1 */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression1; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression2 */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression2; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression1 + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression2 + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression1, + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression2, + ) { + $this->expression1 = $expression1; + $this->expression2 = $expression2; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/HourOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/HourOperator.php new file mode 100644 index 00000000..ffbd5ac4 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/HourOperator.php @@ -0,0 +1,56 @@ + 'date', 'timezone' => 'timezone']; + + /** @var DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date; + + /** @var Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ + public readonly Optional|ResolvesToString|string $timezone; + + /** + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + */ + public function __construct( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + ) { + if (is_string($date) && ! str_starts_with($date, '$')) { + throw new InvalidArgumentException('Argument $date can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->date = $date; + $this->timezone = $timezone; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/IfNullOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/IfNullOperator.php new file mode 100644 index 00000000..878944cd --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/IfNullOperator.php @@ -0,0 +1,53 @@ + 'expression']; + + /** @var list $expression */ + public readonly array $expression; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string ...$expression + * @no-named-arguments + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string ...$expression, + ) { + if (\count($expression) < 1) { + throw new InvalidArgumentException(\sprintf('Expected at least %d values for $expression, got %d.', 1, \count($expression))); + } + + if (! array_is_list($expression)) { + throw new InvalidArgumentException('Expected $expression arguments to be a list (array), named arguments are not supported'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/InOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/InOperator.php new file mode 100644 index 00000000..5c4d408f --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/InOperator.php @@ -0,0 +1,63 @@ + 'expression', 'array' => 'array']; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression Any valid expression expression. */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression; + + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $array Any valid expression that resolves to an array. */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $array; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression Any valid expression expression. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $array Any valid expression that resolves to an array. + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + PackedArray|ResolvesToArray|BSONArray|array|string $array, + ) { + $this->expression = $expression; + if (is_string($array) && ! str_starts_with($array, '$')) { + throw new InvalidArgumentException('Argument $array can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + if (is_array($array) && ! array_is_list($array)) { + throw new InvalidArgumentException('Expected $array argument to be a list, got an associative array.'); + } + + $this->array = $array; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/IndexOfArrayOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/IndexOfArrayOperator.php new file mode 100644 index 00000000..34c68db4 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/IndexOfArrayOperator.php @@ -0,0 +1,98 @@ + 'array', 'search' => 'search', 'start' => 'start', 'end' => 'end']; + + /** + * @var BSONArray|PackedArray|ResolvesToArray|array|string $array Can be any valid expression as long as it resolves to an array. + * If the array expression resolves to a value of null or refers to a field that is missing, $indexOfArray returns null. + * If the array expression does not resolve to an array or null nor refers to a missing field, $indexOfArray returns an error. + */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $array; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $search */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $search; + + /** + * @var Optional|ResolvesToInt|int|string $start An integer, or a number that can be represented as integers (such as 2.0), that specifies the starting index position for the search. Can be any valid expression that resolves to a non-negative integral number. + * If unspecified, the starting index position for the search is the beginning of the string. + */ + public readonly Optional|ResolvesToInt|int|string $start; + + /** + * @var Optional|ResolvesToInt|int|string $end An integer, or a number that can be represented as integers (such as 2.0), that specifies the ending index position for the search. Can be any valid expression that resolves to a non-negative integral number. If you specify a index value, you should also specify a index value; otherwise, $indexOfArray uses the value as the index value instead of the value. + * If unspecified, the ending index position for the search is the end of the string. + */ + public readonly Optional|ResolvesToInt|int|string $end; + + /** + * @param BSONArray|PackedArray|ResolvesToArray|array|string $array Can be any valid expression as long as it resolves to an array. + * If the array expression resolves to a value of null or refers to a field that is missing, $indexOfArray returns null. + * If the array expression does not resolve to an array or null nor refers to a missing field, $indexOfArray returns an error. + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $search + * @param Optional|ResolvesToInt|int|string $start An integer, or a number that can be represented as integers (such as 2.0), that specifies the starting index position for the search. Can be any valid expression that resolves to a non-negative integral number. + * If unspecified, the starting index position for the search is the beginning of the string. + * @param Optional|ResolvesToInt|int|string $end An integer, or a number that can be represented as integers (such as 2.0), that specifies the ending index position for the search. Can be any valid expression that resolves to a non-negative integral number. If you specify a index value, you should also specify a index value; otherwise, $indexOfArray uses the value as the index value instead of the value. + * If unspecified, the ending index position for the search is the end of the string. + */ + public function __construct( + PackedArray|ResolvesToArray|BSONArray|array|string $array, + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $search, + Optional|ResolvesToInt|int|string $start = Optional::Undefined, + Optional|ResolvesToInt|int|string $end = Optional::Undefined, + ) { + if (is_string($array) && ! str_starts_with($array, '$')) { + throw new InvalidArgumentException('Argument $array can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + if (is_array($array) && ! array_is_list($array)) { + throw new InvalidArgumentException('Expected $array argument to be a list, got an associative array.'); + } + + $this->array = $array; + $this->search = $search; + if (is_string($start) && ! str_starts_with($start, '$')) { + throw new InvalidArgumentException('Argument $start can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->start = $start; + if (is_string($end) && ! str_starts_with($end, '$')) { + throw new InvalidArgumentException('Argument $end can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->end = $end; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/IndexOfBytesOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/IndexOfBytesOperator.php new file mode 100644 index 00000000..e2f2a1ca --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/IndexOfBytesOperator.php @@ -0,0 +1,82 @@ + 'string', 'substring' => 'substring', 'start' => 'start', 'end' => 'end']; + + /** + * @var ResolvesToString|string $string Can be any valid expression as long as it resolves to a string. + * If the string expression resolves to a value of null or refers to a field that is missing, $indexOfBytes returns null. + * If the string expression does not resolve to a string or null nor refers to a missing field, $indexOfBytes returns an error. + */ + public readonly ResolvesToString|string $string; + + /** @var ResolvesToString|string $substring Can be any valid expression as long as it resolves to a string. */ + public readonly ResolvesToString|string $substring; + + /** + * @var Optional|ResolvesToInt|int|string $start An integer, or a number that can be represented as integers (such as 2.0), that specifies the starting index position for the search. Can be any valid expression that resolves to a non-negative integral number. + * If unspecified, the starting index position for the search is the beginning of the string. + */ + public readonly Optional|ResolvesToInt|int|string $start; + + /** + * @var Optional|ResolvesToInt|int|string $end An integer, or a number that can be represented as integers (such as 2.0), that specifies the ending index position for the search. Can be any valid expression that resolves to a non-negative integral number. If you specify a index value, you should also specify a index value; otherwise, $indexOfArray uses the value as the index value instead of the value. + * If unspecified, the ending index position for the search is the end of the string. + */ + public readonly Optional|ResolvesToInt|int|string $end; + + /** + * @param ResolvesToString|string $string Can be any valid expression as long as it resolves to a string. + * If the string expression resolves to a value of null or refers to a field that is missing, $indexOfBytes returns null. + * If the string expression does not resolve to a string or null nor refers to a missing field, $indexOfBytes returns an error. + * @param ResolvesToString|string $substring Can be any valid expression as long as it resolves to a string. + * @param Optional|ResolvesToInt|int|string $start An integer, or a number that can be represented as integers (such as 2.0), that specifies the starting index position for the search. Can be any valid expression that resolves to a non-negative integral number. + * If unspecified, the starting index position for the search is the beginning of the string. + * @param Optional|ResolvesToInt|int|string $end An integer, or a number that can be represented as integers (such as 2.0), that specifies the ending index position for the search. Can be any valid expression that resolves to a non-negative integral number. If you specify a index value, you should also specify a index value; otherwise, $indexOfArray uses the value as the index value instead of the value. + * If unspecified, the ending index position for the search is the end of the string. + */ + public function __construct( + ResolvesToString|string $string, + ResolvesToString|string $substring, + Optional|ResolvesToInt|int|string $start = Optional::Undefined, + Optional|ResolvesToInt|int|string $end = Optional::Undefined, + ) { + $this->string = $string; + $this->substring = $substring; + if (is_string($start) && ! str_starts_with($start, '$')) { + throw new InvalidArgumentException('Argument $start can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->start = $start; + if (is_string($end) && ! str_starts_with($end, '$')) { + throw new InvalidArgumentException('Argument $end can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->end = $end; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/IndexOfCPOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/IndexOfCPOperator.php new file mode 100644 index 00000000..67b0c33e --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/IndexOfCPOperator.php @@ -0,0 +1,82 @@ + 'string', 'substring' => 'substring', 'start' => 'start', 'end' => 'end']; + + /** + * @var ResolvesToString|string $string Can be any valid expression as long as it resolves to a string. + * If the string expression resolves to a value of null or refers to a field that is missing, $indexOfCP returns null. + * If the string expression does not resolve to a string or null nor refers to a missing field, $indexOfCP returns an error. + */ + public readonly ResolvesToString|string $string; + + /** @var ResolvesToString|string $substring Can be any valid expression as long as it resolves to a string. */ + public readonly ResolvesToString|string $substring; + + /** + * @var Optional|ResolvesToInt|int|string $start An integer, or a number that can be represented as integers (such as 2.0), that specifies the starting index position for the search. Can be any valid expression that resolves to a non-negative integral number. + * If unspecified, the starting index position for the search is the beginning of the string. + */ + public readonly Optional|ResolvesToInt|int|string $start; + + /** + * @var Optional|ResolvesToInt|int|string $end An integer, or a number that can be represented as integers (such as 2.0), that specifies the ending index position for the search. Can be any valid expression that resolves to a non-negative integral number. If you specify a index value, you should also specify a index value; otherwise, $indexOfArray uses the value as the index value instead of the value. + * If unspecified, the ending index position for the search is the end of the string. + */ + public readonly Optional|ResolvesToInt|int|string $end; + + /** + * @param ResolvesToString|string $string Can be any valid expression as long as it resolves to a string. + * If the string expression resolves to a value of null or refers to a field that is missing, $indexOfCP returns null. + * If the string expression does not resolve to a string or null nor refers to a missing field, $indexOfCP returns an error. + * @param ResolvesToString|string $substring Can be any valid expression as long as it resolves to a string. + * @param Optional|ResolvesToInt|int|string $start An integer, or a number that can be represented as integers (such as 2.0), that specifies the starting index position for the search. Can be any valid expression that resolves to a non-negative integral number. + * If unspecified, the starting index position for the search is the beginning of the string. + * @param Optional|ResolvesToInt|int|string $end An integer, or a number that can be represented as integers (such as 2.0), that specifies the ending index position for the search. Can be any valid expression that resolves to a non-negative integral number. If you specify a index value, you should also specify a index value; otherwise, $indexOfArray uses the value as the index value instead of the value. + * If unspecified, the ending index position for the search is the end of the string. + */ + public function __construct( + ResolvesToString|string $string, + ResolvesToString|string $substring, + Optional|ResolvesToInt|int|string $start = Optional::Undefined, + Optional|ResolvesToInt|int|string $end = Optional::Undefined, + ) { + $this->string = $string; + $this->substring = $substring; + if (is_string($start) && ! str_starts_with($start, '$')) { + throw new InvalidArgumentException('Argument $start can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->start = $start; + if (is_string($end) && ! str_starts_with($end, '$')) { + throw new InvalidArgumentException('Argument $end can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->end = $end; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/IntFieldPath.php b/vendor/mongodb/mongodb/src/Builder/Expression/IntFieldPath.php new file mode 100644 index 00000000..dc9baeec --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/IntFieldPath.php @@ -0,0 +1,29 @@ +name = $name; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/IsArrayOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/IsArrayOperator.php new file mode 100644 index 00000000..136fc42b --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/IsArrayOperator.php @@ -0,0 +1,41 @@ + 'expression']; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ) { + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/IsNumberOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/IsNumberOperator.php new file mode 100644 index 00000000..96034de4 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/IsNumberOperator.php @@ -0,0 +1,43 @@ + 'expression']; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ) { + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/IsoDayOfWeekOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/IsoDayOfWeekOperator.php new file mode 100644 index 00000000..46261538 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/IsoDayOfWeekOperator.php @@ -0,0 +1,56 @@ + 'date', 'timezone' => 'timezone']; + + /** @var DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date; + + /** @var Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ + public readonly Optional|ResolvesToString|string $timezone; + + /** + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + */ + public function __construct( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + ) { + if (is_string($date) && ! str_starts_with($date, '$')) { + throw new InvalidArgumentException('Argument $date can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->date = $date; + $this->timezone = $timezone; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/IsoWeekOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/IsoWeekOperator.php new file mode 100644 index 00000000..e59d66dc --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/IsoWeekOperator.php @@ -0,0 +1,56 @@ + 'date', 'timezone' => 'timezone']; + + /** @var DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date; + + /** @var Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ + public readonly Optional|ResolvesToString|string $timezone; + + /** + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + */ + public function __construct( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + ) { + if (is_string($date) && ! str_starts_with($date, '$')) { + throw new InvalidArgumentException('Argument $date can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->date = $date; + $this->timezone = $timezone; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/IsoWeekYearOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/IsoWeekYearOperator.php new file mode 100644 index 00000000..2fe1440e --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/IsoWeekYearOperator.php @@ -0,0 +1,56 @@ + 'date', 'timezone' => 'timezone']; + + /** @var DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date; + + /** @var Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ + public readonly Optional|ResolvesToString|string $timezone; + + /** + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + */ + public function __construct( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + ) { + if (is_string($date) && ! str_starts_with($date, '$')) { + throw new InvalidArgumentException('Argument $date can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->date = $date; + $this->timezone = $timezone; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/JavascriptFieldPath.php b/vendor/mongodb/mongodb/src/Builder/Expression/JavascriptFieldPath.php new file mode 100644 index 00000000..e371ab7a --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/JavascriptFieldPath.php @@ -0,0 +1,29 @@ +name = $name; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/LastNOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/LastNOperator.php new file mode 100644 index 00000000..be714cd9 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/LastNOperator.php @@ -0,0 +1,63 @@ + 'n', 'input' => 'input']; + + /** @var ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $firstN returns. */ + public readonly ResolvesToInt|int|string $n; + + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return n elements. */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $input; + + /** + * @param ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $firstN returns. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return n elements. + */ + public function __construct( + ResolvesToInt|int|string $n, + PackedArray|ResolvesToArray|BSONArray|array|string $input, + ) { + if (is_string($n) && ! str_starts_with($n, '$')) { + throw new InvalidArgumentException('Argument $n can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->n = $n; + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + if (is_array($input) && ! array_is_list($input)) { + throw new InvalidArgumentException('Expected $input argument to be a list, got an associative array.'); + } + + $this->input = $input; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/LastOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/LastOperator.php new file mode 100644 index 00000000..68043d7d --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/LastOperator.php @@ -0,0 +1,52 @@ + 'expression']; + + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $expression */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $expression; + + /** + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression + */ + public function __construct(PackedArray|ResolvesToArray|BSONArray|array|string $expression) + { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + if (is_array($expression) && ! array_is_list($expression)) { + throw new InvalidArgumentException('Expected $expression argument to be a list, got an associative array.'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/LetOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/LetOperator.php new file mode 100644 index 00000000..e3dfdf80 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/LetOperator.php @@ -0,0 +1,54 @@ + 'vars', 'in' => 'in']; + + /** + * @var Document|Serializable|array|stdClass $vars Assignment block for the variables accessible in the in expression. To assign a variable, specify a string for the variable name and assign a valid expression for the value. + * The variable assignments have no meaning outside the in expression, not even within the vars block itself. + */ + public readonly Document|Serializable|stdClass|array $vars; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $in The expression to evaluate. */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $in; + + /** + * @param Document|Serializable|array|stdClass $vars Assignment block for the variables accessible in the in expression. To assign a variable, specify a string for the variable name and assign a valid expression for the value. + * The variable assignments have no meaning outside the in expression, not even within the vars block itself. + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $in The expression to evaluate. + */ + public function __construct( + Document|Serializable|stdClass|array $vars, + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $in, + ) { + $this->vars = $vars; + $this->in = $in; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/LiteralOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/LiteralOperator.php new file mode 100644 index 00000000..fe65495d --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/LiteralOperator.php @@ -0,0 +1,39 @@ + 'value']; + + /** @var DateTimeInterface|Type|array|bool|float|int|null|stdClass|string $value If the value is an expression, $literal does not evaluate the expression but instead returns the unparsed expression. */ + public readonly DateTimeInterface|Type|stdClass|array|bool|float|int|null|string $value; + + /** + * @param DateTimeInterface|Type|array|bool|float|int|null|stdClass|string $value If the value is an expression, $literal does not evaluate the expression but instead returns the unparsed expression. + */ + public function __construct(DateTimeInterface|Type|stdClass|array|bool|float|int|null|string $value) + { + $this->value = $value; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/LnOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/LnOperator.php new file mode 100644 index 00000000..1848fbec --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/LnOperator.php @@ -0,0 +1,47 @@ +, Math.E ] expression, where Math.E is a JavaScript representation for Euler's number e. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/ln/ + * @internal + */ +final class LnOperator implements ResolvesToDouble, OperatorInterface +{ + public const ENCODE = Encode::Single; + public const NAME = '$ln'; + public const PROPERTIES = ['number' => 'number']; + + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $number Any valid expression as long as it resolves to a non-negative number. For more information on expressions, see Expressions. */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $number; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $number Any valid expression as long as it resolves to a non-negative number. For more information on expressions, see Expressions. + */ + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $number) + { + if (is_string($number) && ! str_starts_with($number, '$')) { + throw new InvalidArgumentException('Argument $number can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->number = $number; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/Log10Operator.php b/vendor/mongodb/mongodb/src/Builder/Expression/Log10Operator.php new file mode 100644 index 00000000..24ea9824 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/Log10Operator.php @@ -0,0 +1,46 @@ + 'number']; + + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $number Any valid expression as long as it resolves to a non-negative number. */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $number; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $number Any valid expression as long as it resolves to a non-negative number. + */ + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $number) + { + if (is_string($number) && ! str_starts_with($number, '$')) { + throw new InvalidArgumentException('Argument $number can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->number = $number; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/LogOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/LogOperator.php new file mode 100644 index 00000000..b61fa3be --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/LogOperator.php @@ -0,0 +1,57 @@ + 'number', 'base' => 'base']; + + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $number Any valid expression as long as it resolves to a non-negative number. */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $number; + + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $base Any valid expression as long as it resolves to a positive number greater than 1. */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $base; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $number Any valid expression as long as it resolves to a non-negative number. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $base Any valid expression as long as it resolves to a positive number greater than 1. + */ + public function __construct( + Decimal128|Int64|ResolvesToNumber|float|int|string $number, + Decimal128|Int64|ResolvesToNumber|float|int|string $base, + ) { + if (is_string($number) && ! str_starts_with($number, '$')) { + throw new InvalidArgumentException('Argument $number can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->number = $number; + if (is_string($base) && ! str_starts_with($base, '$')) { + throw new InvalidArgumentException('Argument $base can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->base = $base; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/LongFieldPath.php b/vendor/mongodb/mongodb/src/Builder/Expression/LongFieldPath.php new file mode 100644 index 00000000..7d18c015 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/LongFieldPath.php @@ -0,0 +1,29 @@ +name = $name; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/LtOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/LtOperator.php new file mode 100644 index 00000000..b29d33ef --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/LtOperator.php @@ -0,0 +1,47 @@ + 'expression1', 'expression2' => 'expression2']; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression1 */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression1; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression2 */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression2; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression1 + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression2 + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression1, + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression2, + ) { + $this->expression1 = $expression1; + $this->expression2 = $expression2; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/LteOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/LteOperator.php new file mode 100644 index 00000000..2bd7ab4f --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/LteOperator.php @@ -0,0 +1,47 @@ + 'expression1', 'expression2' => 'expression2']; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression1 */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression1; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression2 */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression2; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression1 + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression2 + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression1, + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression2, + ) { + $this->expression1 = $expression1; + $this->expression2 = $expression2; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/LtrimOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/LtrimOperator.php new file mode 100644 index 00000000..0dd94eaa --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/LtrimOperator.php @@ -0,0 +1,51 @@ + 'input', 'chars' => 'chars']; + + /** @var ResolvesToString|string $input The string to trim. The argument can be any valid expression that resolves to a string. */ + public readonly ResolvesToString|string $input; + + /** + * @var Optional|ResolvesToString|string $chars The character(s) to trim from the beginning of the input. + * The argument can be any valid expression that resolves to a string. The $ltrim operator breaks down the string into individual UTF code point to trim from input. + * If unspecified, $ltrim removes whitespace characters, including the null character. + */ + public readonly Optional|ResolvesToString|string $chars; + + /** + * @param ResolvesToString|string $input The string to trim. The argument can be any valid expression that resolves to a string. + * @param Optional|ResolvesToString|string $chars The character(s) to trim from the beginning of the input. + * The argument can be any valid expression that resolves to a string. The $ltrim operator breaks down the string into individual UTF code point to trim from input. + * If unspecified, $ltrim removes whitespace characters, including the null character. + */ + public function __construct( + ResolvesToString|string $input, + Optional|ResolvesToString|string $chars = Optional::Undefined, + ) { + $this->input = $input; + $this->chars = $chars; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/MapOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/MapOperator.php new file mode 100644 index 00000000..a965e69c --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/MapOperator.php @@ -0,0 +1,70 @@ + 'input', 'in' => 'in', 'as' => 'as']; + + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to an array. */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $input; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $in An expression that is applied to each element of the input array. The expression references each element individually with the variable name specified in as. */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $in; + + /** @var Optional|ResolvesToString|string $as A name for the variable that represents each individual element of the input array. If no name is specified, the variable name defaults to this. */ + public readonly Optional|ResolvesToString|string $as; + + /** + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to an array. + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $in An expression that is applied to each element of the input array. The expression references each element individually with the variable name specified in as. + * @param Optional|ResolvesToString|string $as A name for the variable that represents each individual element of the input array. If no name is specified, the variable name defaults to this. + */ + public function __construct( + PackedArray|ResolvesToArray|BSONArray|array|string $input, + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $in, + Optional|ResolvesToString|string $as = Optional::Undefined, + ) { + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + if (is_array($input) && ! array_is_list($input)) { + throw new InvalidArgumentException('Expected $input argument to be a list, got an associative array.'); + } + + $this->input = $input; + $this->in = $in; + $this->as = $as; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/MaxNOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/MaxNOperator.php new file mode 100644 index 00000000..b0da2c04 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/MaxNOperator.php @@ -0,0 +1,63 @@ + 'input', 'n' => 'n']; + + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return the maximal n elements. */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $input; + + /** @var ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $maxN returns. */ + public readonly ResolvesToInt|int|string $n; + + /** + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return the maximal n elements. + * @param ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $maxN returns. + */ + public function __construct( + PackedArray|ResolvesToArray|BSONArray|array|string $input, + ResolvesToInt|int|string $n, + ) { + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + if (is_array($input) && ! array_is_list($input)) { + throw new InvalidArgumentException('Expected $input argument to be a list, got an associative array.'); + } + + $this->input = $input; + if (is_string($n) && ! str_starts_with($n, '$')) { + throw new InvalidArgumentException('Argument $n can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->n = $n; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/MaxOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/MaxOperator.php new file mode 100644 index 00000000..acac1c5d --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/MaxOperator.php @@ -0,0 +1,54 @@ + 'expression']; + + /** @var list $expression */ + public readonly array $expression; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string ...$expression + * @no-named-arguments + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string ...$expression, + ) { + if (\count($expression) < 1) { + throw new InvalidArgumentException(\sprintf('Expected at least %d values for $expression, got %d.', 1, \count($expression))); + } + + if (! array_is_list($expression)) { + throw new InvalidArgumentException('Expected $expression arguments to be a list (array), named arguments are not supported'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/MedianOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/MedianOperator.php new file mode 100644 index 00000000..ec9afbdc --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/MedianOperator.php @@ -0,0 +1,66 @@ + 'input', 'method' => 'method']; + + /** @var BSONArray|Decimal128|Int64|PackedArray|ResolvesToNumber|array|float|int|string $input $median calculates the 50th percentile value of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $median calculation ignores it. */ + public readonly Decimal128|Int64|PackedArray|ResolvesToNumber|BSONArray|array|float|int|string $input; + + /** @var string $method The method that mongod uses to calculate the 50th percentile value. The method must be 'approximate'. */ + public readonly string $method; + + /** + * @param BSONArray|Decimal128|Int64|PackedArray|ResolvesToNumber|array|float|int|string $input $median calculates the 50th percentile value of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $median calculation ignores it. + * @param string $method The method that mongod uses to calculate the 50th percentile value. The method must be 'approximate'. + */ + public function __construct( + Decimal128|Int64|PackedArray|ResolvesToNumber|BSONArray|array|float|int|string $input, + string $method, + ) { + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + if (is_array($input) && ! array_is_list($input)) { + throw new InvalidArgumentException('Expected $input argument to be a list, got an associative array.'); + } + + $this->input = $input; + $this->method = $method; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/MergeObjectsOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/MergeObjectsOperator.php new file mode 100644 index 00000000..e17e1ae1 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/MergeObjectsOperator.php @@ -0,0 +1,51 @@ + 'document']; + + /** @var list $document Any valid expression that resolves to a document. */ + public readonly array $document; + + /** + * @param Document|ResolvesToObject|Serializable|array|stdClass|string ...$document Any valid expression that resolves to a document. + * @no-named-arguments + */ + public function __construct(Document|Serializable|ResolvesToObject|stdClass|array|string ...$document) + { + if (\count($document) < 1) { + throw new InvalidArgumentException(\sprintf('Expected at least %d values for $document, got %d.', 1, \count($document))); + } + + if (! array_is_list($document)) { + throw new InvalidArgumentException('Expected $document arguments to be a list (array), named arguments are not supported'); + } + + $this->document = $document; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/MetaOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/MetaOperator.php new file mode 100644 index 00000000..ec1fd63e --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/MetaOperator.php @@ -0,0 +1,36 @@ + 'keyword']; + + /** @var string $keyword */ + public readonly string $keyword; + + /** + * @param string $keyword + */ + public function __construct(string $keyword) + { + $this->keyword = $keyword; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/MillisecondOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/MillisecondOperator.php new file mode 100644 index 00000000..91dc5917 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/MillisecondOperator.php @@ -0,0 +1,56 @@ + 'date', 'timezone' => 'timezone']; + + /** @var DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date; + + /** @var Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ + public readonly Optional|ResolvesToString|string $timezone; + + /** + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + */ + public function __construct( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + ) { + if (is_string($date) && ! str_starts_with($date, '$')) { + throw new InvalidArgumentException('Argument $date can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->date = $date; + $this->timezone = $timezone; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/MinNOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/MinNOperator.php new file mode 100644 index 00000000..50b22e1f --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/MinNOperator.php @@ -0,0 +1,63 @@ + 'input', 'n' => 'n']; + + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return the maximal n elements. */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $input; + + /** @var ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $maxN returns. */ + public readonly ResolvesToInt|int|string $n; + + /** + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return the maximal n elements. + * @param ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $maxN returns. + */ + public function __construct( + PackedArray|ResolvesToArray|BSONArray|array|string $input, + ResolvesToInt|int|string $n, + ) { + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + if (is_array($input) && ! array_is_list($input)) { + throw new InvalidArgumentException('Expected $input argument to be a list, got an associative array.'); + } + + $this->input = $input; + if (is_string($n) && ! str_starts_with($n, '$')) { + throw new InvalidArgumentException('Argument $n can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->n = $n; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/MinOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/MinOperator.php new file mode 100644 index 00000000..28b707d4 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/MinOperator.php @@ -0,0 +1,54 @@ + 'expression']; + + /** @var list $expression */ + public readonly array $expression; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string ...$expression + * @no-named-arguments + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string ...$expression, + ) { + if (\count($expression) < 1) { + throw new InvalidArgumentException(\sprintf('Expected at least %d values for $expression, got %d.', 1, \count($expression))); + } + + if (! array_is_list($expression)) { + throw new InvalidArgumentException('Expected $expression arguments to be a list (array), named arguments are not supported'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/MinuteOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/MinuteOperator.php new file mode 100644 index 00000000..ff86f885 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/MinuteOperator.php @@ -0,0 +1,56 @@ + 'date', 'timezone' => 'timezone']; + + /** @var DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date; + + /** @var Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ + public readonly Optional|ResolvesToString|string $timezone; + + /** + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + */ + public function __construct( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + ) { + if (is_string($date) && ! str_starts_with($date, '$')) { + throw new InvalidArgumentException('Argument $date can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->date = $date; + $this->timezone = $timezone; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/ModOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/ModOperator.php new file mode 100644 index 00000000..0e7a44df --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/ModOperator.php @@ -0,0 +1,57 @@ + 'dividend', 'divisor' => 'divisor']; + + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $dividend The first argument is the dividend, and the second argument is the divisor; i.e. first argument is divided by the second argument. */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $dividend; + + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $divisor */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $divisor; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $dividend The first argument is the dividend, and the second argument is the divisor; i.e. first argument is divided by the second argument. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $divisor + */ + public function __construct( + Decimal128|Int64|ResolvesToNumber|float|int|string $dividend, + Decimal128|Int64|ResolvesToNumber|float|int|string $divisor, + ) { + if (is_string($dividend) && ! str_starts_with($dividend, '$')) { + throw new InvalidArgumentException('Argument $dividend can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->dividend = $dividend; + if (is_string($divisor) && ! str_starts_with($divisor, '$')) { + throw new InvalidArgumentException('Argument $divisor can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->divisor = $divisor; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/MonthOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/MonthOperator.php new file mode 100644 index 00000000..7fd6e176 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/MonthOperator.php @@ -0,0 +1,56 @@ + 'date', 'timezone' => 'timezone']; + + /** @var DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date; + + /** @var Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ + public readonly Optional|ResolvesToString|string $timezone; + + /** + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + */ + public function __construct( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + ) { + if (is_string($date) && ! str_starts_with($date, '$')) { + throw new InvalidArgumentException('Argument $date can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->date = $date; + $this->timezone = $timezone; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/MultiplyOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/MultiplyOperator.php new file mode 100644 index 00000000..31d781ad --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/MultiplyOperator.php @@ -0,0 +1,54 @@ + 'expression']; + + /** + * @var list $expression The arguments can be any valid expression as long as they resolve to numbers. + * Starting in MongoDB 6.1 you can optimize the $multiply operation. To improve performance, group references at the end of the argument list. + */ + public readonly array $expression; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string ...$expression The arguments can be any valid expression as long as they resolve to numbers. + * Starting in MongoDB 6.1 you can optimize the $multiply operation. To improve performance, group references at the end of the argument list. + * @no-named-arguments + */ + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string ...$expression) + { + if (\count($expression) < 1) { + throw new InvalidArgumentException(\sprintf('Expected at least %d values for $expression, got %d.', 1, \count($expression))); + } + + if (! array_is_list($expression)) { + throw new InvalidArgumentException('Expected $expression arguments to be a list (array), named arguments are not supported'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/NeOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/NeOperator.php new file mode 100644 index 00000000..b9d60c6e --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/NeOperator.php @@ -0,0 +1,47 @@ + 'expression1', 'expression2' => 'expression2']; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression1 */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression1; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression2 */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression2; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression1 + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression2 + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression1, + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression2, + ) { + $this->expression1 = $expression1; + $this->expression2 = $expression2; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/NotOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/NotOperator.php new file mode 100644 index 00000000..21289896 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/NotOperator.php @@ -0,0 +1,41 @@ + 'expression']; + + /** @var DateTimeInterface|ExpressionInterface|ResolvesToBool|Type|array|bool|float|int|null|stdClass|string $expression */ + public readonly DateTimeInterface|Type|ResolvesToBool|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression; + + /** + * @param DateTimeInterface|ExpressionInterface|ResolvesToBool|Type|array|bool|float|int|null|stdClass|string $expression + */ + public function __construct( + DateTimeInterface|Type|ResolvesToBool|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ) { + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/NullFieldPath.php b/vendor/mongodb/mongodb/src/Builder/Expression/NullFieldPath.php new file mode 100644 index 00000000..63bf171d --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/NullFieldPath.php @@ -0,0 +1,29 @@ +name = $name; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/NumberFieldPath.php b/vendor/mongodb/mongodb/src/Builder/Expression/NumberFieldPath.php new file mode 100644 index 00000000..d8ab23a2 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/NumberFieldPath.php @@ -0,0 +1,29 @@ +name = $name; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/ObjectFieldPath.php b/vendor/mongodb/mongodb/src/Builder/Expression/ObjectFieldPath.php new file mode 100644 index 00000000..08298983 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/ObjectFieldPath.php @@ -0,0 +1,29 @@ +name = $name; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/ObjectIdFieldPath.php b/vendor/mongodb/mongodb/src/Builder/Expression/ObjectIdFieldPath.php new file mode 100644 index 00000000..4428c1a3 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/ObjectIdFieldPath.php @@ -0,0 +1,29 @@ +name = $name; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/ObjectToArrayOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/ObjectToArrayOperator.php new file mode 100644 index 00000000..c8a26097 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/ObjectToArrayOperator.php @@ -0,0 +1,47 @@ + 'object']; + + /** @var Document|ResolvesToObject|Serializable|array|stdClass|string $object Any valid expression as long as it resolves to a document object. $objectToArray applies to the top-level fields of its argument. If the argument is a document that itself contains embedded document fields, the $objectToArray does not recursively apply to the embedded document fields. */ + public readonly Document|Serializable|ResolvesToObject|stdClass|array|string $object; + + /** + * @param Document|ResolvesToObject|Serializable|array|stdClass|string $object Any valid expression as long as it resolves to a document object. $objectToArray applies to the top-level fields of its argument. If the argument is a document that itself contains embedded document fields, the $objectToArray does not recursively apply to the embedded document fields. + */ + public function __construct(Document|Serializable|ResolvesToObject|stdClass|array|string $object) + { + if (is_string($object) && ! str_starts_with($object, '$')) { + throw new InvalidArgumentException('Argument $object can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->object = $object; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/OrOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/OrOperator.php new file mode 100644 index 00000000..4289c2b7 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/OrOperator.php @@ -0,0 +1,53 @@ + 'expression']; + + /** @var list $expression */ + public readonly array $expression; + + /** + * @param DateTimeInterface|ExpressionInterface|ResolvesToBool|Type|array|bool|float|int|null|stdClass|string ...$expression + * @no-named-arguments + */ + public function __construct( + DateTimeInterface|Type|ResolvesToBool|ExpressionInterface|stdClass|array|bool|float|int|null|string ...$expression, + ) { + if (\count($expression) < 1) { + throw new InvalidArgumentException(\sprintf('Expected at least %d values for $expression, got %d.', 1, \count($expression))); + } + + if (! array_is_list($expression)) { + throw new InvalidArgumentException('Expected $expression arguments to be a list (array), named arguments are not supported'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/PercentileOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/PercentileOperator.php new file mode 100644 index 00000000..c30775ca --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/PercentileOperator.php @@ -0,0 +1,87 @@ + 'input', 'p' => 'p', 'method' => 'method']; + + /** @var BSONArray|Decimal128|Int64|PackedArray|ResolvesToNumber|array|float|int|string $input $percentile calculates the percentile values of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $percentile calculation ignores it. */ + public readonly Decimal128|Int64|PackedArray|ResolvesToNumber|BSONArray|array|float|int|string $input; + + /** + * @var BSONArray|PackedArray|ResolvesToArray|array|string $p $percentile calculates a percentile value for each element in p. The elements represent percentages and must evaluate to numeric values in the range 0.0 to 1.0, inclusive. + * $percentile returns results in the same order as the elements in p. + */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $p; + + /** @var string $method The method that mongod uses to calculate the percentile value. The method must be 'approximate'. */ + public readonly string $method; + + /** + * @param BSONArray|Decimal128|Int64|PackedArray|ResolvesToNumber|array|float|int|string $input $percentile calculates the percentile values of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $percentile calculation ignores it. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $p $percentile calculates a percentile value for each element in p. The elements represent percentages and must evaluate to numeric values in the range 0.0 to 1.0, inclusive. + * $percentile returns results in the same order as the elements in p. + * @param string $method The method that mongod uses to calculate the percentile value. The method must be 'approximate'. + */ + public function __construct( + Decimal128|Int64|PackedArray|ResolvesToNumber|BSONArray|array|float|int|string $input, + PackedArray|ResolvesToArray|BSONArray|array|string $p, + string $method, + ) { + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + if (is_array($input) && ! array_is_list($input)) { + throw new InvalidArgumentException('Expected $input argument to be a list, got an associative array.'); + } + + $this->input = $input; + if (is_string($p) && ! str_starts_with($p, '$')) { + throw new InvalidArgumentException('Argument $p can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + if (is_array($p) && ! array_is_list($p)) { + throw new InvalidArgumentException('Expected $p argument to be a list, got an associative array.'); + } + + $this->p = $p; + $this->method = $method; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/PowOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/PowOperator.php new file mode 100644 index 00000000..bf132280 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/PowOperator.php @@ -0,0 +1,57 @@ + 'number', 'exponent' => 'exponent']; + + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $number */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $number; + + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $exponent */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $exponent; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $number + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $exponent + */ + public function __construct( + Decimal128|Int64|ResolvesToNumber|float|int|string $number, + Decimal128|Int64|ResolvesToNumber|float|int|string $exponent, + ) { + if (is_string($number) && ! str_starts_with($number, '$')) { + throw new InvalidArgumentException('Argument $number can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->number = $number; + if (is_string($exponent) && ! str_starts_with($exponent, '$')) { + throw new InvalidArgumentException('Argument $exponent can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->exponent = $exponent; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/RadiansToDegreesOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/RadiansToDegreesOperator.php new file mode 100644 index 00000000..c8e4d529 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/RadiansToDegreesOperator.php @@ -0,0 +1,46 @@ + 'expression']; + + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression + */ + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) + { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/RandOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/RandOperator.php new file mode 100644 index 00000000..26da2763 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/RandOperator.php @@ -0,0 +1,28 @@ + 'start', 'end' => 'end', 'step' => 'step']; + + /** @var ResolvesToInt|int|string $start An integer that specifies the start of the sequence. Can be any valid expression that resolves to an integer. */ + public readonly ResolvesToInt|int|string $start; + + /** @var ResolvesToInt|int|string $end An integer that specifies the exclusive upper limit of the sequence. Can be any valid expression that resolves to an integer. */ + public readonly ResolvesToInt|int|string $end; + + /** @var Optional|ResolvesToInt|int|string $step An integer that specifies the increment value. Can be any valid expression that resolves to a non-zero integer. Defaults to 1. */ + public readonly Optional|ResolvesToInt|int|string $step; + + /** + * @param ResolvesToInt|int|string $start An integer that specifies the start of the sequence. Can be any valid expression that resolves to an integer. + * @param ResolvesToInt|int|string $end An integer that specifies the exclusive upper limit of the sequence. Can be any valid expression that resolves to an integer. + * @param Optional|ResolvesToInt|int|string $step An integer that specifies the increment value. Can be any valid expression that resolves to a non-zero integer. Defaults to 1. + */ + public function __construct( + ResolvesToInt|int|string $start, + ResolvesToInt|int|string $end, + Optional|ResolvesToInt|int|string $step = Optional::Undefined, + ) { + if (is_string($start) && ! str_starts_with($start, '$')) { + throw new InvalidArgumentException('Argument $start can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->start = $start; + if (is_string($end) && ! str_starts_with($end, '$')) { + throw new InvalidArgumentException('Argument $end can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->end = $end; + if (is_string($step) && ! str_starts_with($step, '$')) { + throw new InvalidArgumentException('Argument $step can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->step = $step; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/ReduceOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/ReduceOperator.php new file mode 100644 index 00000000..d285a453 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/ReduceOperator.php @@ -0,0 +1,83 @@ + 'input', 'initialValue' => 'initialValue', 'in' => 'in']; + + /** + * @var BSONArray|PackedArray|ResolvesToArray|array|string $input Can be any valid expression that resolves to an array. + * If the argument resolves to a value of null or refers to a missing field, $reduce returns null. + * If the argument does not resolve to an array or null nor refers to a missing field, $reduce returns an error. + */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $input; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $initialValue The initial cumulative value set before in is applied to the first element of the input array. */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $initialValue; + + /** + * @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $in A valid expression that $reduce applies to each element in the input array in left-to-right order. Wrap the input value with $reverseArray to yield the equivalent of applying the combining expression from right-to-left. + * During evaluation of the in expression, two variables will be available: + * - value is the variable that represents the cumulative value of the expression. + * - this is the variable that refers to the element being processed. + */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $in; + + /** + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input Can be any valid expression that resolves to an array. + * If the argument resolves to a value of null or refers to a missing field, $reduce returns null. + * If the argument does not resolve to an array or null nor refers to a missing field, $reduce returns an error. + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $initialValue The initial cumulative value set before in is applied to the first element of the input array. + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $in A valid expression that $reduce applies to each element in the input array in left-to-right order. Wrap the input value with $reverseArray to yield the equivalent of applying the combining expression from right-to-left. + * During evaluation of the in expression, two variables will be available: + * - value is the variable that represents the cumulative value of the expression. + * - this is the variable that refers to the element being processed. + */ + public function __construct( + PackedArray|ResolvesToArray|BSONArray|array|string $input, + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $initialValue, + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $in, + ) { + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + if (is_array($input) && ! array_is_list($input)) { + throw new InvalidArgumentException('Expected $input argument to be a list, got an associative array.'); + } + + $this->input = $input; + $this->initialValue = $initialValue; + $this->in = $in; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/RegexFieldPath.php b/vendor/mongodb/mongodb/src/Builder/Expression/RegexFieldPath.php new file mode 100644 index 00000000..14950bee --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/RegexFieldPath.php @@ -0,0 +1,29 @@ +name = $name; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/RegexFindAllOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/RegexFindAllOperator.php new file mode 100644 index 00000000..e6e36a9f --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/RegexFindAllOperator.php @@ -0,0 +1,52 @@ + 'input', 'regex' => 'regex', 'options' => 'options']; + + /** @var ResolvesToString|string $input The string on which you wish to apply the regex pattern. Can be a string or any valid expression that resolves to a string. */ + public readonly ResolvesToString|string $input; + + /** @var Regex|ResolvesToString|string $regex The regex pattern to apply. Can be any valid expression that resolves to either a string or regex pattern //. When using the regex //, you can also specify the regex options i and m (but not the s or x options) */ + public readonly Regex|ResolvesToString|string $regex; + + /** @var Optional|string $options */ + public readonly Optional|string $options; + + /** + * @param ResolvesToString|string $input The string on which you wish to apply the regex pattern. Can be a string or any valid expression that resolves to a string. + * @param Regex|ResolvesToString|string $regex The regex pattern to apply. Can be any valid expression that resolves to either a string or regex pattern //. When using the regex //, you can also specify the regex options i and m (but not the s or x options) + * @param Optional|string $options + */ + public function __construct( + ResolvesToString|string $input, + Regex|ResolvesToString|string $regex, + Optional|string $options = Optional::Undefined, + ) { + $this->input = $input; + $this->regex = $regex; + $this->options = $options; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/RegexFindOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/RegexFindOperator.php new file mode 100644 index 00000000..81f713f3 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/RegexFindOperator.php @@ -0,0 +1,52 @@ + 'input', 'regex' => 'regex', 'options' => 'options']; + + /** @var ResolvesToString|string $input The string on which you wish to apply the regex pattern. Can be a string or any valid expression that resolves to a string. */ + public readonly ResolvesToString|string $input; + + /** @var Regex|ResolvesToString|string $regex The regex pattern to apply. Can be any valid expression that resolves to either a string or regex pattern //. When using the regex //, you can also specify the regex options i and m (but not the s or x options) */ + public readonly Regex|ResolvesToString|string $regex; + + /** @var Optional|string $options */ + public readonly Optional|string $options; + + /** + * @param ResolvesToString|string $input The string on which you wish to apply the regex pattern. Can be a string or any valid expression that resolves to a string. + * @param Regex|ResolvesToString|string $regex The regex pattern to apply. Can be any valid expression that resolves to either a string or regex pattern //. When using the regex //, you can also specify the regex options i and m (but not the s or x options) + * @param Optional|string $options + */ + public function __construct( + ResolvesToString|string $input, + Regex|ResolvesToString|string $regex, + Optional|string $options = Optional::Undefined, + ) { + $this->input = $input; + $this->regex = $regex; + $this->options = $options; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/RegexMatchOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/RegexMatchOperator.php new file mode 100644 index 00000000..50fbb176 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/RegexMatchOperator.php @@ -0,0 +1,52 @@ + 'input', 'regex' => 'regex', 'options' => 'options']; + + /** @var ResolvesToString|string $input The string on which you wish to apply the regex pattern. Can be a string or any valid expression that resolves to a string. */ + public readonly ResolvesToString|string $input; + + /** @var Regex|ResolvesToString|string $regex The regex pattern to apply. Can be any valid expression that resolves to either a string or regex pattern //. When using the regex //, you can also specify the regex options i and m (but not the s or x options) */ + public readonly Regex|ResolvesToString|string $regex; + + /** @var Optional|string $options */ + public readonly Optional|string $options; + + /** + * @param ResolvesToString|string $input The string on which you wish to apply the regex pattern. Can be a string or any valid expression that resolves to a string. + * @param Regex|ResolvesToString|string $regex The regex pattern to apply. Can be any valid expression that resolves to either a string or regex pattern //. When using the regex //, you can also specify the regex options i and m (but not the s or x options) + * @param Optional|string $options + */ + public function __construct( + ResolvesToString|string $input, + Regex|ResolvesToString|string $regex, + Optional|string $options = Optional::Undefined, + ) { + $this->input = $input; + $this->regex = $regex; + $this->options = $options; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/ReplaceAllOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/ReplaceAllOperator.php new file mode 100644 index 00000000..14cfb17e --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/ReplaceAllOperator.php @@ -0,0 +1,51 @@ + 'input', 'find' => 'find', 'replacement' => 'replacement']; + + /** @var ResolvesToNull|ResolvesToString|null|string $input The string on which you wish to apply the find. Can be any valid expression that resolves to a string or a null. If input refers to a field that is missing, $replaceAll returns null. */ + public readonly ResolvesToNull|ResolvesToString|null|string $input; + + /** @var ResolvesToNull|ResolvesToString|null|string $find The string to search for within the given input. Can be any valid expression that resolves to a string or a null. If find refers to a field that is missing, $replaceAll returns null. */ + public readonly ResolvesToNull|ResolvesToString|null|string $find; + + /** @var ResolvesToNull|ResolvesToString|null|string $replacement The string to use to replace all matched instances of find in input. Can be any valid expression that resolves to a string or a null. */ + public readonly ResolvesToNull|ResolvesToString|null|string $replacement; + + /** + * @param ResolvesToNull|ResolvesToString|null|string $input The string on which you wish to apply the find. Can be any valid expression that resolves to a string or a null. If input refers to a field that is missing, $replaceAll returns null. + * @param ResolvesToNull|ResolvesToString|null|string $find The string to search for within the given input. Can be any valid expression that resolves to a string or a null. If find refers to a field that is missing, $replaceAll returns null. + * @param ResolvesToNull|ResolvesToString|null|string $replacement The string to use to replace all matched instances of find in input. Can be any valid expression that resolves to a string or a null. + */ + public function __construct( + ResolvesToNull|ResolvesToString|null|string $input, + ResolvesToNull|ResolvesToString|null|string $find, + ResolvesToNull|ResolvesToString|null|string $replacement, + ) { + $this->input = $input; + $this->find = $find; + $this->replacement = $replacement; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/ReplaceOneOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/ReplaceOneOperator.php new file mode 100644 index 00000000..0237aacc --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/ReplaceOneOperator.php @@ -0,0 +1,50 @@ + 'input', 'find' => 'find', 'replacement' => 'replacement']; + + /** @var ResolvesToNull|ResolvesToString|null|string $input The string on which you wish to apply the find. Can be any valid expression that resolves to a string or a null. If input refers to a field that is missing, $replaceAll returns null. */ + public readonly ResolvesToNull|ResolvesToString|null|string $input; + + /** @var ResolvesToNull|ResolvesToString|null|string $find The string to search for within the given input. Can be any valid expression that resolves to a string or a null. If find refers to a field that is missing, $replaceAll returns null. */ + public readonly ResolvesToNull|ResolvesToString|null|string $find; + + /** @var ResolvesToNull|ResolvesToString|null|string $replacement The string to use to replace all matched instances of find in input. Can be any valid expression that resolves to a string or a null. */ + public readonly ResolvesToNull|ResolvesToString|null|string $replacement; + + /** + * @param ResolvesToNull|ResolvesToString|null|string $input The string on which you wish to apply the find. Can be any valid expression that resolves to a string or a null. If input refers to a field that is missing, $replaceAll returns null. + * @param ResolvesToNull|ResolvesToString|null|string $find The string to search for within the given input. Can be any valid expression that resolves to a string or a null. If find refers to a field that is missing, $replaceAll returns null. + * @param ResolvesToNull|ResolvesToString|null|string $replacement The string to use to replace all matched instances of find in input. Can be any valid expression that resolves to a string or a null. + */ + public function __construct( + ResolvesToNull|ResolvesToString|null|string $input, + ResolvesToNull|ResolvesToString|null|string $find, + ResolvesToNull|ResolvesToString|null|string $replacement, + ) { + $this->input = $input; + $this->find = $find; + $this->replacement = $replacement; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/ResolvesToAny.php b/vendor/mongodb/mongodb/src/Builder/Expression/ResolvesToAny.php new file mode 100644 index 00000000..66556488 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/ResolvesToAny.php @@ -0,0 +1,13 @@ + 'expression']; + + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $expression The argument can be any valid expression as long as it resolves to an array. */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $expression; + + /** + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression The argument can be any valid expression as long as it resolves to an array. + */ + public function __construct(PackedArray|ResolvesToArray|BSONArray|array|string $expression) + { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + if (is_array($expression) && ! array_is_list($expression)) { + throw new InvalidArgumentException('Expected $expression argument to be a list, got an associative array.'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/RoundOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/RoundOperator.php new file mode 100644 index 00000000..0deb8110 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/RoundOperator.php @@ -0,0 +1,62 @@ + 'number', 'place' => 'place']; + + /** + * @var Decimal128|Int64|ResolvesToNumber|float|int|string $number Can be any valid expression that resolves to a number. Specifically, the expression must resolve to an integer, double, decimal, or long. + * $round returns an error if the expression resolves to a non-numeric data type. + */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $number; + + /** @var Optional|ResolvesToInt|int|string $place Can be any valid expression that resolves to an integer between -20 and 100, exclusive. */ + public readonly Optional|ResolvesToInt|int|string $place; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $number Can be any valid expression that resolves to a number. Specifically, the expression must resolve to an integer, double, decimal, or long. + * $round returns an error if the expression resolves to a non-numeric data type. + * @param Optional|ResolvesToInt|int|string $place Can be any valid expression that resolves to an integer between -20 and 100, exclusive. + */ + public function __construct( + Decimal128|Int64|ResolvesToNumber|float|int|string $number, + Optional|ResolvesToInt|int|string $place = Optional::Undefined, + ) { + if (is_string($number) && ! str_starts_with($number, '$')) { + throw new InvalidArgumentException('Argument $number can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->number = $number; + if (is_string($place) && ! str_starts_with($place, '$')) { + throw new InvalidArgumentException('Argument $place can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->place = $place; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/RtrimOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/RtrimOperator.php new file mode 100644 index 00000000..46824f98 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/RtrimOperator.php @@ -0,0 +1,50 @@ + 'input', 'chars' => 'chars']; + + /** @var ResolvesToString|string $input The string to trim. The argument can be any valid expression that resolves to a string. */ + public readonly ResolvesToString|string $input; + + /** + * @var Optional|ResolvesToString|string $chars The character(s) to trim from the beginning of the input. + * The argument can be any valid expression that resolves to a string. The $ltrim operator breaks down the string into individual UTF code point to trim from input. + * If unspecified, $ltrim removes whitespace characters, including the null character. + */ + public readonly Optional|ResolvesToString|string $chars; + + /** + * @param ResolvesToString|string $input The string to trim. The argument can be any valid expression that resolves to a string. + * @param Optional|ResolvesToString|string $chars The character(s) to trim from the beginning of the input. + * The argument can be any valid expression that resolves to a string. The $ltrim operator breaks down the string into individual UTF code point to trim from input. + * If unspecified, $ltrim removes whitespace characters, including the null character. + */ + public function __construct( + ResolvesToString|string $input, + Optional|ResolvesToString|string $chars = Optional::Undefined, + ) { + $this->input = $input; + $this->chars = $chars; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/SecondOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/SecondOperator.php new file mode 100644 index 00000000..48ee9ad8 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/SecondOperator.php @@ -0,0 +1,56 @@ + 'date', 'timezone' => 'timezone']; + + /** @var DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date; + + /** @var Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ + public readonly Optional|ResolvesToString|string $timezone; + + /** + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + */ + public function __construct( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + ) { + if (is_string($date) && ! str_starts_with($date, '$')) { + throw new InvalidArgumentException('Argument $date can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->date = $date; + $this->timezone = $timezone; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/SetDifferenceOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/SetDifferenceOperator.php new file mode 100644 index 00000000..29789742 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/SetDifferenceOperator.php @@ -0,0 +1,67 @@ + 'expression1', 'expression2' => 'expression2']; + + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $expression1 The arguments can be any valid expression as long as they each resolve to an array. */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $expression1; + + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $expression2 The arguments can be any valid expression as long as they each resolve to an array. */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $expression2; + + /** + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression1 The arguments can be any valid expression as long as they each resolve to an array. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression2 The arguments can be any valid expression as long as they each resolve to an array. + */ + public function __construct( + PackedArray|ResolvesToArray|BSONArray|array|string $expression1, + PackedArray|ResolvesToArray|BSONArray|array|string $expression2, + ) { + if (is_string($expression1) && ! str_starts_with($expression1, '$')) { + throw new InvalidArgumentException('Argument $expression1 can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + if (is_array($expression1) && ! array_is_list($expression1)) { + throw new InvalidArgumentException('Expected $expression1 argument to be a list, got an associative array.'); + } + + $this->expression1 = $expression1; + if (is_string($expression2) && ! str_starts_with($expression2, '$')) { + throw new InvalidArgumentException('Argument $expression2 can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + if (is_array($expression2) && ! array_is_list($expression2)) { + throw new InvalidArgumentException('Expected $expression2 argument to be a list, got an associative array.'); + } + + $this->expression2 = $expression2; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/SetEqualsOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/SetEqualsOperator.php new file mode 100644 index 00000000..c743c8cc --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/SetEqualsOperator.php @@ -0,0 +1,50 @@ + 'expression']; + + /** @var list $expression */ + public readonly array $expression; + + /** + * @param BSONArray|PackedArray|ResolvesToArray|array|string ...$expression + * @no-named-arguments + */ + public function __construct(PackedArray|ResolvesToArray|BSONArray|array|string ...$expression) + { + if (\count($expression) < 1) { + throw new InvalidArgumentException(\sprintf('Expected at least %d values for $expression, got %d.', 1, \count($expression))); + } + + if (! array_is_list($expression)) { + throw new InvalidArgumentException('Expected $expression arguments to be a list (array), named arguments are not supported'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/SetFieldOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/SetFieldOperator.php new file mode 100644 index 00000000..66083277 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/SetFieldOperator.php @@ -0,0 +1,68 @@ + 'field', 'input' => 'input', 'value' => 'value']; + + /** @var ResolvesToString|string $field Field in the input object that you want to add, update, or remove. field can be any valid expression that resolves to a string constant. */ + public readonly ResolvesToString|string $field; + + /** @var Document|ResolvesToObject|Serializable|array|stdClass|string $input Document that contains the field that you want to add or update. input must resolve to an object, missing, null, or undefined. */ + public readonly Document|Serializable|ResolvesToObject|stdClass|array|string $input; + + /** + * @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $value The value that you want to assign to field. value can be any valid expression. + * Set to $$REMOVE to remove field from the input document. + */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $value; + + /** + * @param ResolvesToString|string $field Field in the input object that you want to add, update, or remove. field can be any valid expression that resolves to a string constant. + * @param Document|ResolvesToObject|Serializable|array|stdClass|string $input Document that contains the field that you want to add or update. input must resolve to an object, missing, null, or undefined. + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $value The value that you want to assign to field. value can be any valid expression. + * Set to $$REMOVE to remove field from the input document. + */ + public function __construct( + ResolvesToString|string $field, + Document|Serializable|ResolvesToObject|stdClass|array|string $input, + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $value, + ) { + $this->field = $field; + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->input = $input; + $this->value = $value; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/SetIntersectionOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/SetIntersectionOperator.php new file mode 100644 index 00000000..a27dd4e9 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/SetIntersectionOperator.php @@ -0,0 +1,50 @@ + 'expression']; + + /** @var list $expression */ + public readonly array $expression; + + /** + * @param BSONArray|PackedArray|ResolvesToArray|array|string ...$expression + * @no-named-arguments + */ + public function __construct(PackedArray|ResolvesToArray|BSONArray|array|string ...$expression) + { + if (\count($expression) < 1) { + throw new InvalidArgumentException(\sprintf('Expected at least %d values for $expression, got %d.', 1, \count($expression))); + } + + if (! array_is_list($expression)) { + throw new InvalidArgumentException('Expected $expression arguments to be a list (array), named arguments are not supported'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/SetIsSubsetOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/SetIsSubsetOperator.php new file mode 100644 index 00000000..8d9a63e4 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/SetIsSubsetOperator.php @@ -0,0 +1,67 @@ + 'expression1', 'expression2' => 'expression2']; + + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $expression1 */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $expression1; + + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $expression2 */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $expression2; + + /** + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression1 + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression2 + */ + public function __construct( + PackedArray|ResolvesToArray|BSONArray|array|string $expression1, + PackedArray|ResolvesToArray|BSONArray|array|string $expression2, + ) { + if (is_string($expression1) && ! str_starts_with($expression1, '$')) { + throw new InvalidArgumentException('Argument $expression1 can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + if (is_array($expression1) && ! array_is_list($expression1)) { + throw new InvalidArgumentException('Expected $expression1 argument to be a list, got an associative array.'); + } + + $this->expression1 = $expression1; + if (is_string($expression2) && ! str_starts_with($expression2, '$')) { + throw new InvalidArgumentException('Argument $expression2 can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + if (is_array($expression2) && ! array_is_list($expression2)) { + throw new InvalidArgumentException('Expected $expression2 argument to be a list, got an associative array.'); + } + + $this->expression2 = $expression2; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/SetUnionOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/SetUnionOperator.php new file mode 100644 index 00000000..5a7af765 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/SetUnionOperator.php @@ -0,0 +1,50 @@ + 'expression']; + + /** @var list $expression */ + public readonly array $expression; + + /** + * @param BSONArray|PackedArray|ResolvesToArray|array|string ...$expression + * @no-named-arguments + */ + public function __construct(PackedArray|ResolvesToArray|BSONArray|array|string ...$expression) + { + if (\count($expression) < 1) { + throw new InvalidArgumentException(\sprintf('Expected at least %d values for $expression, got %d.', 1, \count($expression))); + } + + if (! array_is_list($expression)) { + throw new InvalidArgumentException('Expected $expression arguments to be a list (array), named arguments are not supported'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/SinOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/SinOperator.php new file mode 100644 index 00000000..cc8f8235 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/SinOperator.php @@ -0,0 +1,50 @@ + 'expression']; + + /** + * @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression $sin takes any valid expression that resolves to a number. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the result to radians. + * By default $sin returns values as a double. $sin can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. + */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $sin takes any valid expression that resolves to a number. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the result to radians. + * By default $sin returns values as a double. $sin can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. + */ + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) + { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/SinhOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/SinhOperator.php new file mode 100644 index 00000000..763d2f94 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/SinhOperator.php @@ -0,0 +1,50 @@ + 'expression']; + + /** + * @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression $sinh takes any valid expression that resolves to a number, measured in radians. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the value to radians. + * By default $sinh returns values as a double. $sinh can also return values as a 128-bit decimal if the expression resolves to a 128-bit decimal value. + */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $sinh takes any valid expression that resolves to a number, measured in radians. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the value to radians. + * By default $sinh returns values as a double. $sinh can also return values as a 128-bit decimal if the expression resolves to a 128-bit decimal value. + */ + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) + { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/SizeOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/SizeOperator.php new file mode 100644 index 00000000..53b6cdd1 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/SizeOperator.php @@ -0,0 +1,52 @@ + 'expression']; + + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $expression The argument for $size can be any expression as long as it resolves to an array. */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $expression; + + /** + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression The argument for $size can be any expression as long as it resolves to an array. + */ + public function __construct(PackedArray|ResolvesToArray|BSONArray|array|string $expression) + { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + if (is_array($expression) && ! array_is_list($expression)) { + throw new InvalidArgumentException('Expected $expression argument to be a list, got an associative array.'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/SliceOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/SliceOperator.php new file mode 100644 index 00000000..71cc0741 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/SliceOperator.php @@ -0,0 +1,86 @@ + 'expression', 'n' => 'n', 'position' => 'position']; + + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $expression Any valid expression as long as it resolves to an array. */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $expression; + + /** + * @var ResolvesToInt|int|string $n Any valid expression as long as it resolves to an integer. If position is specified, n must resolve to a positive integer. + * If positive, $slice returns up to the first n elements in the array. If the position is specified, $slice returns the first n elements starting from the position. + * If negative, $slice returns up to the last n elements in the array. n cannot resolve to a negative number if is specified. + */ + public readonly ResolvesToInt|int|string $n; + + /** + * @var Optional|ResolvesToInt|int|string $position Any valid expression as long as it resolves to an integer. + * If positive, $slice determines the starting position from the start of the array. If position is greater than the number of elements, the $slice returns an empty array. + * If negative, $slice determines the starting position from the end of the array. If the absolute value of the is greater than the number of elements, the starting position is the start of the array. + */ + public readonly Optional|ResolvesToInt|int|string $position; + + /** + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression Any valid expression as long as it resolves to an array. + * @param ResolvesToInt|int|string $n Any valid expression as long as it resolves to an integer. If position is specified, n must resolve to a positive integer. + * If positive, $slice returns up to the first n elements in the array. If the position is specified, $slice returns the first n elements starting from the position. + * If negative, $slice returns up to the last n elements in the array. n cannot resolve to a negative number if is specified. + * @param Optional|ResolvesToInt|int|string $position Any valid expression as long as it resolves to an integer. + * If positive, $slice determines the starting position from the start of the array. If position is greater than the number of elements, the $slice returns an empty array. + * If negative, $slice determines the starting position from the end of the array. If the absolute value of the is greater than the number of elements, the starting position is the start of the array. + */ + public function __construct( + PackedArray|ResolvesToArray|BSONArray|array|string $expression, + ResolvesToInt|int|string $n, + Optional|ResolvesToInt|int|string $position = Optional::Undefined, + ) { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + if (is_array($expression) && ! array_is_list($expression)) { + throw new InvalidArgumentException('Expected $expression argument to be a list, got an associative array.'); + } + + $this->expression = $expression; + if (is_string($n) && ! str_starts_with($n, '$')) { + throw new InvalidArgumentException('Argument $n can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->n = $n; + if (is_string($position) && ! str_starts_with($position, '$')) { + throw new InvalidArgumentException('Argument $position can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->position = $position; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/SortArrayOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/SortArrayOperator.php new file mode 100644 index 00000000..6b1d26e0 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/SortArrayOperator.php @@ -0,0 +1,69 @@ + 'input', 'sortBy' => 'sortBy']; + + /** + * @var BSONArray|PackedArray|ResolvesToArray|array|string $input The array to be sorted. + * The result is null if the expression: is missing, evaluates to null, or evaluates to undefined + * If the expression evaluates to any other non-array value, the document returns an error. + */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $input; + + /** @var Document|Serializable|Sort|array|int|stdClass $sortBy The document specifies a sort ordering. */ + public readonly Document|Serializable|Sort|stdClass|array|int $sortBy; + + /** + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input The array to be sorted. + * The result is null if the expression: is missing, evaluates to null, or evaluates to undefined + * If the expression evaluates to any other non-array value, the document returns an error. + * @param Document|Serializable|Sort|array|int|stdClass $sortBy The document specifies a sort ordering. + */ + public function __construct( + PackedArray|ResolvesToArray|BSONArray|array|string $input, + Document|Serializable|Sort|stdClass|array|int $sortBy, + ) { + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + if (is_array($input) && ! array_is_list($input)) { + throw new InvalidArgumentException('Expected $input argument to be a list, got an associative array.'); + } + + $this->input = $input; + $this->sortBy = $sortBy; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/SplitOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/SplitOperator.php new file mode 100644 index 00000000..2e54ef5a --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/SplitOperator.php @@ -0,0 +1,41 @@ + 'string', 'delimiter' => 'delimiter']; + + /** @var ResolvesToString|string $string The string to be split. string expression can be any valid expression as long as it resolves to a string. */ + public readonly ResolvesToString|string $string; + + /** @var ResolvesToString|string $delimiter The delimiter to use when splitting the string expression. delimiter can be any valid expression as long as it resolves to a string. */ + public readonly ResolvesToString|string $delimiter; + + /** + * @param ResolvesToString|string $string The string to be split. string expression can be any valid expression as long as it resolves to a string. + * @param ResolvesToString|string $delimiter The delimiter to use when splitting the string expression. delimiter can be any valid expression as long as it resolves to a string. + */ + public function __construct(ResolvesToString|string $string, ResolvesToString|string $delimiter) + { + $this->string = $string; + $this->delimiter = $delimiter; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/SqrtOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/SqrtOperator.php new file mode 100644 index 00000000..9453fb77 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/SqrtOperator.php @@ -0,0 +1,46 @@ + 'number']; + + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $number The argument can be any valid expression as long as it resolves to a non-negative number. */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $number; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $number The argument can be any valid expression as long as it resolves to a non-negative number. + */ + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $number) + { + if (is_string($number) && ! str_starts_with($number, '$')) { + throw new InvalidArgumentException('Argument $number can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->number = $number; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/StdDevPopOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/StdDevPopOperator.php new file mode 100644 index 00000000..dae7344a --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/StdDevPopOperator.php @@ -0,0 +1,52 @@ + 'expression']; + + /** @var list $expression */ + public readonly array $expression; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string ...$expression + * @no-named-arguments + */ + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string ...$expression) + { + if (\count($expression) < 1) { + throw new InvalidArgumentException(\sprintf('Expected at least %d values for $expression, got %d.', 1, \count($expression))); + } + + if (! array_is_list($expression)) { + throw new InvalidArgumentException('Expected $expression arguments to be a list (array), named arguments are not supported'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/StdDevSampOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/StdDevSampOperator.php new file mode 100644 index 00000000..55af36f5 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/StdDevSampOperator.php @@ -0,0 +1,51 @@ + 'expression']; + + /** @var list $expression */ + public readonly array $expression; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string ...$expression + * @no-named-arguments + */ + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string ...$expression) + { + if (\count($expression) < 1) { + throw new InvalidArgumentException(\sprintf('Expected at least %d values for $expression, got %d.', 1, \count($expression))); + } + + if (! array_is_list($expression)) { + throw new InvalidArgumentException('Expected $expression arguments to be a list (array), named arguments are not supported'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/StrLenBytesOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/StrLenBytesOperator.php new file mode 100644 index 00000000..39ae8dbe --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/StrLenBytesOperator.php @@ -0,0 +1,36 @@ + 'expression']; + + /** @var ResolvesToString|string $expression */ + public readonly ResolvesToString|string $expression; + + /** + * @param ResolvesToString|string $expression + */ + public function __construct(ResolvesToString|string $expression) + { + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/StrLenCPOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/StrLenCPOperator.php new file mode 100644 index 00000000..8add7c3f --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/StrLenCPOperator.php @@ -0,0 +1,36 @@ + 'expression']; + + /** @var ResolvesToString|string $expression */ + public readonly ResolvesToString|string $expression; + + /** + * @param ResolvesToString|string $expression + */ + public function __construct(ResolvesToString|string $expression) + { + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/StrcasecmpOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/StrcasecmpOperator.php new file mode 100644 index 00000000..efcb0e41 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/StrcasecmpOperator.php @@ -0,0 +1,41 @@ + 'expression1', 'expression2' => 'expression2']; + + /** @var ResolvesToString|string $expression1 */ + public readonly ResolvesToString|string $expression1; + + /** @var ResolvesToString|string $expression2 */ + public readonly ResolvesToString|string $expression2; + + /** + * @param ResolvesToString|string $expression1 + * @param ResolvesToString|string $expression2 + */ + public function __construct(ResolvesToString|string $expression1, ResolvesToString|string $expression2) + { + $this->expression1 = $expression1; + $this->expression2 = $expression2; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/StringFieldPath.php b/vendor/mongodb/mongodb/src/Builder/Expression/StringFieldPath.php new file mode 100644 index 00000000..487d3478 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/StringFieldPath.php @@ -0,0 +1,29 @@ +name = $name; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/SubstrBytesOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/SubstrBytesOperator.php new file mode 100644 index 00000000..ff11d234 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/SubstrBytesOperator.php @@ -0,0 +1,61 @@ + 'string', 'start' => 'start', 'length' => 'length']; + + /** @var ResolvesToString|string $string */ + public readonly ResolvesToString|string $string; + + /** @var ResolvesToInt|int|string $start If start is a negative number, $substr returns an empty string "". */ + public readonly ResolvesToInt|int|string $start; + + /** @var ResolvesToInt|int|string $length If length is a negative number, $substr returns a substring that starts at the specified index and includes the rest of the string. */ + public readonly ResolvesToInt|int|string $length; + + /** + * @param ResolvesToString|string $string + * @param ResolvesToInt|int|string $start If start is a negative number, $substr returns an empty string "". + * @param ResolvesToInt|int|string $length If length is a negative number, $substr returns a substring that starts at the specified index and includes the rest of the string. + */ + public function __construct( + ResolvesToString|string $string, + ResolvesToInt|int|string $start, + ResolvesToInt|int|string $length, + ) { + $this->string = $string; + if (is_string($start) && ! str_starts_with($start, '$')) { + throw new InvalidArgumentException('Argument $start can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->start = $start; + if (is_string($length) && ! str_starts_with($length, '$')) { + throw new InvalidArgumentException('Argument $length can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->length = $length; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/SubstrCPOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/SubstrCPOperator.php new file mode 100644 index 00000000..e2c7e89e --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/SubstrCPOperator.php @@ -0,0 +1,61 @@ + 'string', 'start' => 'start', 'length' => 'length']; + + /** @var ResolvesToString|string $string */ + public readonly ResolvesToString|string $string; + + /** @var ResolvesToInt|int|string $start If start is a negative number, $substr returns an empty string "". */ + public readonly ResolvesToInt|int|string $start; + + /** @var ResolvesToInt|int|string $length If length is a negative number, $substr returns a substring that starts at the specified index and includes the rest of the string. */ + public readonly ResolvesToInt|int|string $length; + + /** + * @param ResolvesToString|string $string + * @param ResolvesToInt|int|string $start If start is a negative number, $substr returns an empty string "". + * @param ResolvesToInt|int|string $length If length is a negative number, $substr returns a substring that starts at the specified index and includes the rest of the string. + */ + public function __construct( + ResolvesToString|string $string, + ResolvesToInt|int|string $start, + ResolvesToInt|int|string $length, + ) { + $this->string = $string; + if (is_string($start) && ! str_starts_with($start, '$')) { + throw new InvalidArgumentException('Argument $start can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->start = $start; + if (is_string($length) && ! str_starts_with($length, '$')) { + throw new InvalidArgumentException('Argument $length can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->length = $length; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/SubstrOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/SubstrOperator.php new file mode 100644 index 00000000..3547f533 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/SubstrOperator.php @@ -0,0 +1,61 @@ + 'string', 'start' => 'start', 'length' => 'length']; + + /** @var ResolvesToString|string $string */ + public readonly ResolvesToString|string $string; + + /** @var ResolvesToInt|int|string $start If start is a negative number, $substr returns an empty string "". */ + public readonly ResolvesToInt|int|string $start; + + /** @var ResolvesToInt|int|string $length If length is a negative number, $substr returns a substring that starts at the specified index and includes the rest of the string. */ + public readonly ResolvesToInt|int|string $length; + + /** + * @param ResolvesToString|string $string + * @param ResolvesToInt|int|string $start If start is a negative number, $substr returns an empty string "". + * @param ResolvesToInt|int|string $length If length is a negative number, $substr returns a substring that starts at the specified index and includes the rest of the string. + */ + public function __construct( + ResolvesToString|string $string, + ResolvesToInt|int|string $start, + ResolvesToInt|int|string $length, + ) { + $this->string = $string; + if (is_string($start) && ! str_starts_with($start, '$')) { + throw new InvalidArgumentException('Argument $start can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->start = $start; + if (is_string($length) && ! str_starts_with($length, '$')) { + throw new InvalidArgumentException('Argument $length can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->length = $length; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/SubtractOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/SubtractOperator.php new file mode 100644 index 00000000..351f520c --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/SubtractOperator.php @@ -0,0 +1,59 @@ + 'expression1', 'expression2' => 'expression2']; + + /** @var DateTimeInterface|Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int|string $expression1 */ + public readonly DateTimeInterface|Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int|string $expression1; + + /** @var DateTimeInterface|Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int|string $expression2 */ + public readonly DateTimeInterface|Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int|string $expression2; + + /** + * @param DateTimeInterface|Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int|string $expression1 + * @param DateTimeInterface|Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int|string $expression2 + */ + public function __construct( + DateTimeInterface|Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int|string $expression1, + DateTimeInterface|Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int|string $expression2, + ) { + if (is_string($expression1) && ! str_starts_with($expression1, '$')) { + throw new InvalidArgumentException('Argument $expression1 can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->expression1 = $expression1; + if (is_string($expression2) && ! str_starts_with($expression2, '$')) { + throw new InvalidArgumentException('Argument $expression2 can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->expression2 = $expression2; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/SumOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/SumOperator.php new file mode 100644 index 00000000..04bfaf06 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/SumOperator.php @@ -0,0 +1,54 @@ + 'expression']; + + /** @var list $expression */ + public readonly array $expression; + + /** + * @param BSONArray|Decimal128|Int64|PackedArray|ResolvesToArray|ResolvesToNumber|array|float|int|string ...$expression + * @no-named-arguments + */ + public function __construct( + Decimal128|Int64|PackedArray|ResolvesToArray|ResolvesToNumber|BSONArray|array|float|int|string ...$expression, + ) { + if (\count($expression) < 1) { + throw new InvalidArgumentException(\sprintf('Expected at least %d values for $expression, got %d.', 1, \count($expression))); + } + + if (! array_is_list($expression)) { + throw new InvalidArgumentException('Expected $expression arguments to be a list (array), named arguments are not supported'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/SwitchOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/SwitchOperator.php new file mode 100644 index 00000000..7af40b0f --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/SwitchOperator.php @@ -0,0 +1,70 @@ + 'branches', 'default' => 'default']; + + /** + * @var BSONArray|PackedArray|array $branches An array of control branch documents. Each branch is a document with the following fields: + * - case Can be any valid expression that resolves to a boolean. If the result is not a boolean, it is coerced to a boolean value. More information about how MongoDB evaluates expressions as either true or false can be found here. + * - then Can be any valid expression. + * The branches array must contain at least one branch document. + */ + public readonly PackedArray|BSONArray|array $branches; + + /** + * @var Optional|DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $default The path to take if no branch case expression evaluates to true. + * Although optional, if default is unspecified and no branch case evaluates to true, $switch returns an error. + */ + public readonly Optional|DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $default; + + /** + * @param BSONArray|PackedArray|array $branches An array of control branch documents. Each branch is a document with the following fields: + * - case Can be any valid expression that resolves to a boolean. If the result is not a boolean, it is coerced to a boolean value. More information about how MongoDB evaluates expressions as either true or false can be found here. + * - then Can be any valid expression. + * The branches array must contain at least one branch document. + * @param Optional|DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $default The path to take if no branch case expression evaluates to true. + * Although optional, if default is unspecified and no branch case evaluates to true, $switch returns an error. + */ + public function __construct( + PackedArray|BSONArray|array $branches, + Optional|DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $default = Optional::Undefined, + ) { + if (is_array($branches) && ! array_is_list($branches)) { + throw new InvalidArgumentException('Expected $branches argument to be a list, got an associative array.'); + } + + $this->branches = $branches; + $this->default = $default; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/TanOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/TanOperator.php new file mode 100644 index 00000000..c783b039 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/TanOperator.php @@ -0,0 +1,50 @@ + 'expression']; + + /** + * @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression $tan takes any valid expression that resolves to a number. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the result to radians. + * By default $tan returns values as a double. $tan can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. + */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $tan takes any valid expression that resolves to a number. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the result to radians. + * By default $tan returns values as a double. $tan can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. + */ + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) + { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/TanhOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/TanhOperator.php new file mode 100644 index 00000000..e6f8bb61 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/TanhOperator.php @@ -0,0 +1,50 @@ + 'expression']; + + /** + * @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression $tanh takes any valid expression that resolves to a number, measured in radians. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the value to radians. + * By default $tanh returns values as a double. $tanh can also return values as a 128-bit decimal if the expression resolves to a 128-bit decimal value. + */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $tanh takes any valid expression that resolves to a number, measured in radians. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the value to radians. + * By default $tanh returns values as a double. $tanh can also return values as a 128-bit decimal if the expression resolves to a 128-bit decimal value. + */ + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) + { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/TimestampFieldPath.php b/vendor/mongodb/mongodb/src/Builder/Expression/TimestampFieldPath.php new file mode 100644 index 00000000..5aac9492 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/TimestampFieldPath.php @@ -0,0 +1,29 @@ +name = $name; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/ToBoolOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/ToBoolOperator.php new file mode 100644 index 00000000..6affe2ea --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/ToBoolOperator.php @@ -0,0 +1,42 @@ + 'expression']; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ) { + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/ToDateOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/ToDateOperator.php new file mode 100644 index 00000000..9c5a42b1 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/ToDateOperator.php @@ -0,0 +1,42 @@ + 'expression']; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ) { + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/ToDecimalOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/ToDecimalOperator.php new file mode 100644 index 00000000..b1440e9a --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/ToDecimalOperator.php @@ -0,0 +1,42 @@ + 'expression']; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ) { + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/ToDoubleOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/ToDoubleOperator.php new file mode 100644 index 00000000..8c0d336f --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/ToDoubleOperator.php @@ -0,0 +1,42 @@ + 'expression']; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ) { + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/ToHashedIndexKeyOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/ToHashedIndexKeyOperator.php new file mode 100644 index 00000000..15f91954 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/ToHashedIndexKeyOperator.php @@ -0,0 +1,41 @@ + 'value']; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $value key or string to hash */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $value; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $value key or string to hash + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $value, + ) { + $this->value = $value; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/ToIntOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/ToIntOperator.php new file mode 100644 index 00000000..a769d69a --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/ToIntOperator.php @@ -0,0 +1,42 @@ + 'expression']; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ) { + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/ToLongOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/ToLongOperator.php new file mode 100644 index 00000000..7b68c2f5 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/ToLongOperator.php @@ -0,0 +1,42 @@ + 'expression']; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ) { + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/ToLowerOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/ToLowerOperator.php new file mode 100644 index 00000000..50060588 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/ToLowerOperator.php @@ -0,0 +1,36 @@ + 'expression']; + + /** @var ResolvesToString|string $expression */ + public readonly ResolvesToString|string $expression; + + /** + * @param ResolvesToString|string $expression + */ + public function __construct(ResolvesToString|string $expression) + { + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/ToObjectIdOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/ToObjectIdOperator.php new file mode 100644 index 00000000..bb70f957 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/ToObjectIdOperator.php @@ -0,0 +1,42 @@ + 'expression']; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ) { + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/ToStringOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/ToStringOperator.php new file mode 100644 index 00000000..4d0f5996 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/ToStringOperator.php @@ -0,0 +1,42 @@ + 'expression']; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ) { + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/ToUpperOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/ToUpperOperator.php new file mode 100644 index 00000000..60471196 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/ToUpperOperator.php @@ -0,0 +1,36 @@ + 'expression']; + + /** @var ResolvesToString|string $expression */ + public readonly ResolvesToString|string $expression; + + /** + * @param ResolvesToString|string $expression + */ + public function __construct(ResolvesToString|string $expression) + { + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/TrimOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/TrimOperator.php new file mode 100644 index 00000000..0b210e46 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/TrimOperator.php @@ -0,0 +1,51 @@ + 'input', 'chars' => 'chars']; + + /** @var ResolvesToString|string $input The string to trim. The argument can be any valid expression that resolves to a string. */ + public readonly ResolvesToString|string $input; + + /** + * @var Optional|ResolvesToString|string $chars The character(s) to trim from the beginning of the input. + * The argument can be any valid expression that resolves to a string. The $ltrim operator breaks down the string into individual UTF code point to trim from input. + * If unspecified, $ltrim removes whitespace characters, including the null character. + */ + public readonly Optional|ResolvesToString|string $chars; + + /** + * @param ResolvesToString|string $input The string to trim. The argument can be any valid expression that resolves to a string. + * @param Optional|ResolvesToString|string $chars The character(s) to trim from the beginning of the input. + * The argument can be any valid expression that resolves to a string. The $ltrim operator breaks down the string into individual UTF code point to trim from input. + * If unspecified, $ltrim removes whitespace characters, including the null character. + */ + public function __construct( + ResolvesToString|string $input, + Optional|ResolvesToString|string $chars = Optional::Undefined, + ) { + $this->input = $input; + $this->chars = $chars; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/TruncOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/TruncOperator.php new file mode 100644 index 00000000..b8e98c56 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/TruncOperator.php @@ -0,0 +1,62 @@ + 'number', 'place' => 'place']; + + /** + * @var Decimal128|Int64|ResolvesToNumber|float|int|string $number Can be any valid expression that resolves to a number. Specifically, the expression must resolve to an integer, double, decimal, or long. + * $trunc returns an error if the expression resolves to a non-numeric data type. + */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $number; + + /** @var Optional|ResolvesToInt|int|string $place Can be any valid expression that resolves to an integer between -20 and 100, exclusive. e.g. -20 < place < 100. Defaults to 0. */ + public readonly Optional|ResolvesToInt|int|string $place; + + /** + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $number Can be any valid expression that resolves to a number. Specifically, the expression must resolve to an integer, double, decimal, or long. + * $trunc returns an error if the expression resolves to a non-numeric data type. + * @param Optional|ResolvesToInt|int|string $place Can be any valid expression that resolves to an integer between -20 and 100, exclusive. e.g. -20 < place < 100. Defaults to 0. + */ + public function __construct( + Decimal128|Int64|ResolvesToNumber|float|int|string $number, + Optional|ResolvesToInt|int|string $place = Optional::Undefined, + ) { + if (is_string($number) && ! str_starts_with($number, '$')) { + throw new InvalidArgumentException('Argument $number can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->number = $number; + if (is_string($place) && ! str_starts_with($place, '$')) { + throw new InvalidArgumentException('Argument $place can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->place = $place; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/TsIncrementOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/TsIncrementOperator.php new file mode 100644 index 00000000..3e1e404c --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/TsIncrementOperator.php @@ -0,0 +1,46 @@ + 'expression']; + + /** @var ResolvesToTimestamp|Timestamp|int|string $expression */ + public readonly Timestamp|ResolvesToTimestamp|int|string $expression; + + /** + * @param ResolvesToTimestamp|Timestamp|int|string $expression + */ + public function __construct(Timestamp|ResolvesToTimestamp|int|string $expression) + { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/TsSecondOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/TsSecondOperator.php new file mode 100644 index 00000000..bea14d9e --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/TsSecondOperator.php @@ -0,0 +1,46 @@ + 'expression']; + + /** @var ResolvesToTimestamp|Timestamp|int|string $expression */ + public readonly Timestamp|ResolvesToTimestamp|int|string $expression; + + /** + * @param ResolvesToTimestamp|Timestamp|int|string $expression + */ + public function __construct(Timestamp|ResolvesToTimestamp|int|string $expression) + { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/TypeOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/TypeOperator.php new file mode 100644 index 00000000..78a25aa6 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/TypeOperator.php @@ -0,0 +1,41 @@ + 'expression']; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ) { + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/UnsetFieldOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/UnsetFieldOperator.php new file mode 100644 index 00000000..1d0fcf9d --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/UnsetFieldOperator.php @@ -0,0 +1,55 @@ + 'field', 'input' => 'input']; + + /** @var ResolvesToString|string $field Field in the input object that you want to add, update, or remove. field can be any valid expression that resolves to a string constant. */ + public readonly ResolvesToString|string $field; + + /** @var Document|ResolvesToObject|Serializable|array|stdClass|string $input Document that contains the field that you want to add or update. input must resolve to an object, missing, null, or undefined. */ + public readonly Document|Serializable|ResolvesToObject|stdClass|array|string $input; + + /** + * @param ResolvesToString|string $field Field in the input object that you want to add, update, or remove. field can be any valid expression that resolves to a string constant. + * @param Document|ResolvesToObject|Serializable|array|stdClass|string $input Document that contains the field that you want to add or update. input must resolve to an object, missing, null, or undefined. + */ + public function __construct( + ResolvesToString|string $field, + Document|Serializable|ResolvesToObject|stdClass|array|string $input, + ) { + $this->field = $field; + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->input = $input; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/Variable.php b/vendor/mongodb/mongodb/src/Builder/Expression/Variable.php new file mode 100644 index 00000000..99b0750b --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/Variable.php @@ -0,0 +1,28 @@ +name = $name; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/WeekOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/WeekOperator.php new file mode 100644 index 00000000..a895012d --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/WeekOperator.php @@ -0,0 +1,56 @@ + 'date', 'timezone' => 'timezone']; + + /** @var DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date; + + /** @var Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ + public readonly Optional|ResolvesToString|string $timezone; + + /** + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + */ + public function __construct( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + ) { + if (is_string($date) && ! str_starts_with($date, '$')) { + throw new InvalidArgumentException('Argument $date can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->date = $date; + $this->timezone = $timezone; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/YearOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/YearOperator.php new file mode 100644 index 00000000..314b1de9 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/YearOperator.php @@ -0,0 +1,56 @@ + 'date', 'timezone' => 'timezone']; + + /** @var DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date; + + /** @var Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ + public readonly Optional|ResolvesToString|string $timezone; + + /** + * @param DateTimeInterface|ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. + */ + public function __construct( + DateTimeInterface|ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, + Optional|ResolvesToString|string $timezone = Optional::Undefined, + ) { + if (is_string($date) && ! str_starts_with($date, '$')) { + throw new InvalidArgumentException('Argument $date can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->date = $date; + $this->timezone = $timezone; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Expression/ZipOperator.php b/vendor/mongodb/mongodb/src/Builder/Expression/ZipOperator.php new file mode 100644 index 00000000..cc98f9ec --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Expression/ZipOperator.php @@ -0,0 +1,86 @@ + 'inputs', 'useLongestLength' => 'useLongestLength', 'defaults' => 'defaults']; + + /** + * @var BSONArray|PackedArray|ResolvesToArray|array|string $inputs An array of expressions that resolve to arrays. The elements of these input arrays combine to form the arrays of the output array. + * If any of the inputs arrays resolves to a value of null or refers to a missing field, $zip returns null. + * If any of the inputs arrays does not resolve to an array or null nor refers to a missing field, $zip returns an error. + */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $inputs; + + /** + * @var Optional|bool $useLongestLength A boolean which specifies whether the length of the longest array determines the number of arrays in the output array. + * The default value is false: the shortest array length determines the number of arrays in the output array. + */ + public readonly Optional|bool $useLongestLength; + + /** + * @var Optional|BSONArray|PackedArray|array $defaults An array of default element values to use if the input arrays have different lengths. You must specify useLongestLength: true along with this field, or else $zip will return an error. + * If useLongestLength: true but defaults is empty or not specified, $zip uses null as the default value. + * If specifying a non-empty defaults, you must specify a default for each input array or else $zip will return an error. + */ + public readonly Optional|PackedArray|BSONArray|array $defaults; + + /** + * @param BSONArray|PackedArray|ResolvesToArray|array|string $inputs An array of expressions that resolve to arrays. The elements of these input arrays combine to form the arrays of the output array. + * If any of the inputs arrays resolves to a value of null or refers to a missing field, $zip returns null. + * If any of the inputs arrays does not resolve to an array or null nor refers to a missing field, $zip returns an error. + * @param Optional|bool $useLongestLength A boolean which specifies whether the length of the longest array determines the number of arrays in the output array. + * The default value is false: the shortest array length determines the number of arrays in the output array. + * @param Optional|BSONArray|PackedArray|array $defaults An array of default element values to use if the input arrays have different lengths. You must specify useLongestLength: true along with this field, or else $zip will return an error. + * If useLongestLength: true but defaults is empty or not specified, $zip uses null as the default value. + * If specifying a non-empty defaults, you must specify a default for each input array or else $zip will return an error. + */ + public function __construct( + PackedArray|ResolvesToArray|BSONArray|array|string $inputs, + Optional|bool $useLongestLength = Optional::Undefined, + Optional|PackedArray|BSONArray|array $defaults = Optional::Undefined, + ) { + if (is_string($inputs) && ! str_starts_with($inputs, '$')) { + throw new InvalidArgumentException('Argument $inputs can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + if (is_array($inputs) && ! array_is_list($inputs)) { + throw new InvalidArgumentException('Expected $inputs argument to be a list, got an associative array.'); + } + + $this->inputs = $inputs; + $this->useLongestLength = $useLongestLength; + if (is_array($defaults) && ! array_is_list($defaults)) { + throw new InvalidArgumentException('Expected $defaults argument to be a list, got an associative array.'); + } + + $this->defaults = $defaults; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Pipeline.php b/vendor/mongodb/mongodb/src/Builder/Pipeline.php new file mode 100644 index 00000000..e481277a --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Pipeline.php @@ -0,0 +1,60 @@ +|stdClass + * @implements IteratorAggregate + */ +final class Pipeline implements IteratorAggregate +{ + private readonly array $stages; + + /** + * @psalm-param stage|list ...$stagesOrPipelines + * + * @no-named-arguments + */ + public function __construct(StageInterface|Pipeline|array|stdClass ...$stagesOrPipelines) + { + if (! array_is_list($stagesOrPipelines)) { + throw new InvalidArgumentException('Named arguments are not supported for pipelines'); + } + + $stages = []; + + foreach ($stagesOrPipelines as $stageOrPipeline) { + if (is_array($stageOrPipeline) && array_is_list($stageOrPipeline)) { + $stages = array_merge($stages, $stageOrPipeline); + } elseif ($stageOrPipeline instanceof Pipeline) { + $stages = array_merge($stages, $stageOrPipeline->stages); + } else { + $stages[] = $stageOrPipeline; + } + } + + $this->stages = $stages; + } + + public function getIterator(): ArrayIterator + { + return new ArrayIterator($this->stages); + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query.php b/vendor/mongodb/mongodb/src/Builder/Query.php new file mode 100644 index 00000000..b19b293f --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query.php @@ -0,0 +1,61 @@ + 'value']; + + /** @var list $value */ + public readonly array $value; + + /** + * @param DateTimeInterface|FieldQueryInterface|Type|array|bool|float|int|null|stdClass|string ...$value + * @no-named-arguments + */ + public function __construct( + DateTimeInterface|Type|FieldQueryInterface|stdClass|array|bool|float|int|null|string ...$value, + ) { + if (\count($value) < 1) { + throw new InvalidArgumentException(\sprintf('Expected at least %d values for $value, got %d.', 1, \count($value))); + } + + if (! array_is_list($value)) { + throw new InvalidArgumentException('Expected $value arguments to be a list (array), named arguments are not supported'); + } + + $this->value = $value; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/AndOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/AndOperator.php new file mode 100644 index 00000000..8738591b --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/AndOperator.php @@ -0,0 +1,49 @@ + 'queries']; + + /** @var list $queries */ + public readonly array $queries; + + /** + * @param QueryInterface|array ...$queries + * @no-named-arguments + */ + public function __construct(QueryInterface|array ...$queries) + { + if (\count($queries) < 1) { + throw new InvalidArgumentException(\sprintf('Expected at least %d values for $queries, got %d.', 1, \count($queries))); + } + + if (! array_is_list($queries)) { + throw new InvalidArgumentException('Expected $queries arguments to be a list (array), named arguments are not supported'); + } + + $this->queries = $queries; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/BitsAllClearOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/BitsAllClearOperator.php new file mode 100644 index 00000000..072c031b --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/BitsAllClearOperator.php @@ -0,0 +1,48 @@ + 'bitmask']; + + /** @var BSONArray|Binary|PackedArray|array|int|string $bitmask */ + public readonly Binary|PackedArray|BSONArray|array|int|string $bitmask; + + /** + * @param BSONArray|Binary|PackedArray|array|int|string $bitmask + */ + public function __construct(Binary|PackedArray|BSONArray|array|int|string $bitmask) + { + if (is_array($bitmask) && ! array_is_list($bitmask)) { + throw new InvalidArgumentException('Expected $bitmask argument to be a list, got an associative array.'); + } + + $this->bitmask = $bitmask; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/BitsAllSetOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/BitsAllSetOperator.php new file mode 100644 index 00000000..a90e12f3 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/BitsAllSetOperator.php @@ -0,0 +1,48 @@ + 'bitmask']; + + /** @var BSONArray|Binary|PackedArray|array|int|string $bitmask */ + public readonly Binary|PackedArray|BSONArray|array|int|string $bitmask; + + /** + * @param BSONArray|Binary|PackedArray|array|int|string $bitmask + */ + public function __construct(Binary|PackedArray|BSONArray|array|int|string $bitmask) + { + if (is_array($bitmask) && ! array_is_list($bitmask)) { + throw new InvalidArgumentException('Expected $bitmask argument to be a list, got an associative array.'); + } + + $this->bitmask = $bitmask; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/BitsAnyClearOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/BitsAnyClearOperator.php new file mode 100644 index 00000000..0ae56d93 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/BitsAnyClearOperator.php @@ -0,0 +1,48 @@ + 'bitmask']; + + /** @var BSONArray|Binary|PackedArray|array|int|string $bitmask */ + public readonly Binary|PackedArray|BSONArray|array|int|string $bitmask; + + /** + * @param BSONArray|Binary|PackedArray|array|int|string $bitmask + */ + public function __construct(Binary|PackedArray|BSONArray|array|int|string $bitmask) + { + if (is_array($bitmask) && ! array_is_list($bitmask)) { + throw new InvalidArgumentException('Expected $bitmask argument to be a list, got an associative array.'); + } + + $this->bitmask = $bitmask; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/BitsAnySetOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/BitsAnySetOperator.php new file mode 100644 index 00000000..5a202c9d --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/BitsAnySetOperator.php @@ -0,0 +1,48 @@ + 'bitmask']; + + /** @var BSONArray|Binary|PackedArray|array|int|string $bitmask */ + public readonly Binary|PackedArray|BSONArray|array|int|string $bitmask; + + /** + * @param BSONArray|Binary|PackedArray|array|int|string $bitmask + */ + public function __construct(Binary|PackedArray|BSONArray|array|int|string $bitmask) + { + if (is_array($bitmask) && ! array_is_list($bitmask)) { + throw new InvalidArgumentException('Expected $bitmask argument to be a list, got an associative array.'); + } + + $this->bitmask = $bitmask; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/BoxOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/BoxOperator.php new file mode 100644 index 00000000..cce9cf8d --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/BoxOperator.php @@ -0,0 +1,47 @@ + 'value']; + + /** @var BSONArray|PackedArray|array $value */ + public readonly PackedArray|BSONArray|array $value; + + /** + * @param BSONArray|PackedArray|array $value + */ + public function __construct(PackedArray|BSONArray|array $value) + { + if (is_array($value) && ! array_is_list($value)) { + throw new InvalidArgumentException('Expected $value argument to be a list, got an associative array.'); + } + + $this->value = $value; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/CenterOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/CenterOperator.php new file mode 100644 index 00000000..f3a0b890 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/CenterOperator.php @@ -0,0 +1,47 @@ + 'value']; + + /** @var BSONArray|PackedArray|array $value */ + public readonly PackedArray|BSONArray|array $value; + + /** + * @param BSONArray|PackedArray|array $value + */ + public function __construct(PackedArray|BSONArray|array $value) + { + if (is_array($value) && ! array_is_list($value)) { + throw new InvalidArgumentException('Expected $value argument to be a list, got an associative array.'); + } + + $this->value = $value; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/CenterSphereOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/CenterSphereOperator.php new file mode 100644 index 00000000..350f535f --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/CenterSphereOperator.php @@ -0,0 +1,47 @@ + 'value']; + + /** @var BSONArray|PackedArray|array $value */ + public readonly PackedArray|BSONArray|array $value; + + /** + * @param BSONArray|PackedArray|array $value + */ + public function __construct(PackedArray|BSONArray|array $value) + { + if (is_array($value) && ! array_is_list($value)) { + throw new InvalidArgumentException('Expected $value argument to be a list, got an associative array.'); + } + + $this->value = $value; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/CommentOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/CommentOperator.php new file mode 100644 index 00000000..93849803 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/CommentOperator.php @@ -0,0 +1,37 @@ + 'comment']; + + /** @var string $comment */ + public readonly string $comment; + + /** + * @param string $comment + */ + public function __construct(string $comment) + { + $this->comment = $comment; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/ElemMatchOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/ElemMatchOperator.php new file mode 100644 index 00000000..59d59528 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/ElemMatchOperator.php @@ -0,0 +1,49 @@ + 'query']; + + /** @var DateTimeInterface|FieldQueryInterface|QueryInterface|Type|array|bool|float|int|null|stdClass|string $query */ + public readonly DateTimeInterface|Type|FieldQueryInterface|QueryInterface|stdClass|array|bool|float|int|null|string $query; + + /** + * @param DateTimeInterface|FieldQueryInterface|QueryInterface|Type|array|bool|float|int|null|stdClass|string $query + */ + public function __construct( + DateTimeInterface|Type|FieldQueryInterface|QueryInterface|stdClass|array|bool|float|int|null|string $query, + ) { + if (is_array($query)) { + $query = QueryObject::create($query); + } + + $this->query = $query; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/EqOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/EqOperator.php new file mode 100644 index 00000000..73eaae71 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/EqOperator.php @@ -0,0 +1,40 @@ + 'value']; + + /** @var DateTimeInterface|Type|array|bool|float|int|null|stdClass|string $value */ + public readonly DateTimeInterface|Type|stdClass|array|bool|float|int|null|string $value; + + /** + * @param DateTimeInterface|Type|array|bool|float|int|null|stdClass|string $value + */ + public function __construct(DateTimeInterface|Type|stdClass|array|bool|float|int|null|string $value) + { + $this->value = $value; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/ExistsOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/ExistsOperator.php new file mode 100644 index 00000000..1d0b0a29 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/ExistsOperator.php @@ -0,0 +1,37 @@ + 'exists']; + + /** @var bool $exists */ + public readonly bool $exists; + + /** + * @param bool $exists + */ + public function __construct(bool $exists = true) + { + $this->exists = $exists; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/ExprOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/ExprOperator.php new file mode 100644 index 00000000..15562f04 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/ExprOperator.php @@ -0,0 +1,42 @@ + 'expression']; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ) { + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/FactoryTrait.php b/vendor/mongodb/mongodb/src/Builder/Query/FactoryTrait.php new file mode 100644 index 00000000..cedc2adb --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/FactoryTrait.php @@ -0,0 +1,523 @@ + null]; + + /** @var Document|GeometryInterface|Serializable|array|stdClass $geometry */ + public readonly Document|Serializable|GeometryInterface|stdClass|array $geometry; + + /** + * @param Document|GeometryInterface|Serializable|array|stdClass $geometry + */ + public function __construct(Document|Serializable|GeometryInterface|stdClass|array $geometry) + { + $this->geometry = $geometry; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/GeoWithinOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/GeoWithinOperator.php new file mode 100644 index 00000000..258592f0 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/GeoWithinOperator.php @@ -0,0 +1,41 @@ + null]; + + /** @var Document|GeometryInterface|Serializable|array|stdClass $geometry */ + public readonly Document|Serializable|GeometryInterface|stdClass|array $geometry; + + /** + * @param Document|GeometryInterface|Serializable|array|stdClass $geometry + */ + public function __construct(Document|Serializable|GeometryInterface|stdClass|array $geometry) + { + $this->geometry = $geometry; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/GeometryOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/GeometryOperator.php new file mode 100644 index 00000000..fe52be97 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/GeometryOperator.php @@ -0,0 +1,64 @@ + 'type', 'coordinates' => 'coordinates', 'crs' => 'crs']; + + /** @var string $type */ + public readonly string $type; + + /** @var BSONArray|PackedArray|array $coordinates */ + public readonly PackedArray|BSONArray|array $coordinates; + + /** @var Optional|Document|Serializable|array|stdClass $crs */ + public readonly Optional|Document|Serializable|stdClass|array $crs; + + /** + * @param string $type + * @param BSONArray|PackedArray|array $coordinates + * @param Optional|Document|Serializable|array|stdClass $crs + */ + public function __construct( + string $type, + PackedArray|BSONArray|array $coordinates, + Optional|Document|Serializable|stdClass|array $crs = Optional::Undefined, + ) { + $this->type = $type; + if (is_array($coordinates) && ! array_is_list($coordinates)) { + throw new InvalidArgumentException('Expected $coordinates argument to be a list, got an associative array.'); + } + + $this->coordinates = $coordinates; + $this->crs = $crs; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/GtOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/GtOperator.php new file mode 100644 index 00000000..235e26c7 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/GtOperator.php @@ -0,0 +1,40 @@ + 'value']; + + /** @var DateTimeInterface|Type|array|bool|float|int|null|stdClass|string $value */ + public readonly DateTimeInterface|Type|stdClass|array|bool|float|int|null|string $value; + + /** + * @param DateTimeInterface|Type|array|bool|float|int|null|stdClass|string $value + */ + public function __construct(DateTimeInterface|Type|stdClass|array|bool|float|int|null|string $value) + { + $this->value = $value; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/GteOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/GteOperator.php new file mode 100644 index 00000000..05d8e596 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/GteOperator.php @@ -0,0 +1,40 @@ + 'value']; + + /** @var DateTimeInterface|Type|array|bool|float|int|null|stdClass|string $value */ + public readonly DateTimeInterface|Type|stdClass|array|bool|float|int|null|string $value; + + /** + * @param DateTimeInterface|Type|array|bool|float|int|null|stdClass|string $value + */ + public function __construct(DateTimeInterface|Type|stdClass|array|bool|float|int|null|string $value) + { + $this->value = $value; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/InOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/InOperator.php new file mode 100644 index 00000000..e6f1456a --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/InOperator.php @@ -0,0 +1,47 @@ + 'value']; + + /** @var BSONArray|PackedArray|array $value */ + public readonly PackedArray|BSONArray|array $value; + + /** + * @param BSONArray|PackedArray|array $value + */ + public function __construct(PackedArray|BSONArray|array $value) + { + if (is_array($value) && ! array_is_list($value)) { + throw new InvalidArgumentException('Expected $value argument to be a list, got an associative array.'); + } + + $this->value = $value; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/JsonSchemaOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/JsonSchemaOperator.php new file mode 100644 index 00000000..3dc8b918 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/JsonSchemaOperator.php @@ -0,0 +1,40 @@ + 'schema']; + + /** @var Document|Serializable|array|stdClass $schema */ + public readonly Document|Serializable|stdClass|array $schema; + + /** + * @param Document|Serializable|array|stdClass $schema + */ + public function __construct(Document|Serializable|stdClass|array $schema) + { + $this->schema = $schema; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/LtOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/LtOperator.php new file mode 100644 index 00000000..b4c2dd44 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/LtOperator.php @@ -0,0 +1,40 @@ + 'value']; + + /** @var DateTimeInterface|Type|array|bool|float|int|null|stdClass|string $value */ + public readonly DateTimeInterface|Type|stdClass|array|bool|float|int|null|string $value; + + /** + * @param DateTimeInterface|Type|array|bool|float|int|null|stdClass|string $value + */ + public function __construct(DateTimeInterface|Type|stdClass|array|bool|float|int|null|string $value) + { + $this->value = $value; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/LteOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/LteOperator.php new file mode 100644 index 00000000..d0ca1fc9 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/LteOperator.php @@ -0,0 +1,40 @@ + 'value']; + + /** @var DateTimeInterface|Type|array|bool|float|int|null|stdClass|string $value */ + public readonly DateTimeInterface|Type|stdClass|array|bool|float|int|null|string $value; + + /** + * @param DateTimeInterface|Type|array|bool|float|int|null|stdClass|string $value + */ + public function __construct(DateTimeInterface|Type|stdClass|array|bool|float|int|null|string $value) + { + $this->value = $value; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/MaxDistanceOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/MaxDistanceOperator.php new file mode 100644 index 00000000..2aea7d4c --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/MaxDistanceOperator.php @@ -0,0 +1,39 @@ + 'value']; + + /** @var Decimal128|Int64|float|int $value */ + public readonly Decimal128|Int64|float|int $value; + + /** + * @param Decimal128|Int64|float|int $value + */ + public function __construct(Decimal128|Int64|float|int $value) + { + $this->value = $value; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/MinDistanceOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/MinDistanceOperator.php new file mode 100644 index 00000000..74aadb39 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/MinDistanceOperator.php @@ -0,0 +1,38 @@ + 'value']; + + /** @var Int64|float|int $value */ + public readonly Int64|float|int $value; + + /** + * @param Int64|float|int $value + */ + public function __construct(Int64|float|int $value) + { + $this->value = $value; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/ModOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/ModOperator.php new file mode 100644 index 00000000..bbabdfdc --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/ModOperator.php @@ -0,0 +1,44 @@ + 'divisor', 'remainder' => 'remainder']; + + /** @var Decimal128|Int64|float|int $divisor */ + public readonly Decimal128|Int64|float|int $divisor; + + /** @var Decimal128|Int64|float|int $remainder */ + public readonly Decimal128|Int64|float|int $remainder; + + /** + * @param Decimal128|Int64|float|int $divisor + * @param Decimal128|Int64|float|int $remainder + */ + public function __construct(Decimal128|Int64|float|int $divisor, Decimal128|Int64|float|int $remainder) + { + $this->divisor = $divisor; + $this->remainder = $remainder; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/NeOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/NeOperator.php new file mode 100644 index 00000000..e5a8cd31 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/NeOperator.php @@ -0,0 +1,40 @@ + 'value']; + + /** @var DateTimeInterface|Type|array|bool|float|int|null|stdClass|string $value */ + public readonly DateTimeInterface|Type|stdClass|array|bool|float|int|null|string $value; + + /** + * @param DateTimeInterface|Type|array|bool|float|int|null|stdClass|string $value + */ + public function __construct(DateTimeInterface|Type|stdClass|array|bool|float|int|null|string $value) + { + $this->value = $value; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/NearOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/NearOperator.php new file mode 100644 index 00000000..85be90ac --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/NearOperator.php @@ -0,0 +1,57 @@ + null, 'maxDistance' => '$maxDistance', 'minDistance' => '$minDistance']; + + /** @var Document|GeometryInterface|Serializable|array|stdClass $geometry */ + public readonly Document|Serializable|GeometryInterface|stdClass|array $geometry; + + /** @var Optional|Decimal128|Int64|float|int $maxDistance Distance in meters. Limits the results to those documents that are at most the specified distance from the center point. */ + public readonly Optional|Decimal128|Int64|float|int $maxDistance; + + /** @var Optional|Decimal128|Int64|float|int $minDistance Distance in meters. Limits the results to those documents that are at least the specified distance from the center point. */ + public readonly Optional|Decimal128|Int64|float|int $minDistance; + + /** + * @param Document|GeometryInterface|Serializable|array|stdClass $geometry + * @param Optional|Decimal128|Int64|float|int $maxDistance Distance in meters. Limits the results to those documents that are at most the specified distance from the center point. + * @param Optional|Decimal128|Int64|float|int $minDistance Distance in meters. Limits the results to those documents that are at least the specified distance from the center point. + */ + public function __construct( + Document|Serializable|GeometryInterface|stdClass|array $geometry, + Optional|Decimal128|Int64|float|int $maxDistance = Optional::Undefined, + Optional|Decimal128|Int64|float|int $minDistance = Optional::Undefined, + ) { + $this->geometry = $geometry; + $this->maxDistance = $maxDistance; + $this->minDistance = $minDistance; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/NearSphereOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/NearSphereOperator.php new file mode 100644 index 00000000..5494048b --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/NearSphereOperator.php @@ -0,0 +1,57 @@ + null, 'maxDistance' => '$maxDistance', 'minDistance' => '$minDistance']; + + /** @var Document|GeometryInterface|Serializable|array|stdClass $geometry */ + public readonly Document|Serializable|GeometryInterface|stdClass|array $geometry; + + /** @var Optional|Decimal128|Int64|float|int $maxDistance Distance in meters. */ + public readonly Optional|Decimal128|Int64|float|int $maxDistance; + + /** @var Optional|Decimal128|Int64|float|int $minDistance Distance in meters. Limits the results to those documents that are at least the specified distance from the center point. */ + public readonly Optional|Decimal128|Int64|float|int $minDistance; + + /** + * @param Document|GeometryInterface|Serializable|array|stdClass $geometry + * @param Optional|Decimal128|Int64|float|int $maxDistance Distance in meters. + * @param Optional|Decimal128|Int64|float|int $minDistance Distance in meters. Limits the results to those documents that are at least the specified distance from the center point. + */ + public function __construct( + Document|Serializable|GeometryInterface|stdClass|array $geometry, + Optional|Decimal128|Int64|float|int $maxDistance = Optional::Undefined, + Optional|Decimal128|Int64|float|int $minDistance = Optional::Undefined, + ) { + $this->geometry = $geometry; + $this->maxDistance = $maxDistance; + $this->minDistance = $minDistance; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/NinOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/NinOperator.php new file mode 100644 index 00000000..5c82c3fd --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/NinOperator.php @@ -0,0 +1,47 @@ + 'value']; + + /** @var BSONArray|PackedArray|array $value */ + public readonly PackedArray|BSONArray|array $value; + + /** + * @param BSONArray|PackedArray|array $value + */ + public function __construct(PackedArray|BSONArray|array $value) + { + if (is_array($value) && ! array_is_list($value)) { + throw new InvalidArgumentException('Expected $value argument to be a list, got an associative array.'); + } + + $this->value = $value; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/NorOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/NorOperator.php new file mode 100644 index 00000000..06bdc7e3 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/NorOperator.php @@ -0,0 +1,49 @@ + 'queries']; + + /** @var list $queries */ + public readonly array $queries; + + /** + * @param QueryInterface|array ...$queries + * @no-named-arguments + */ + public function __construct(QueryInterface|array ...$queries) + { + if (\count($queries) < 1) { + throw new InvalidArgumentException(\sprintf('Expected at least %d values for $queries, got %d.', 1, \count($queries))); + } + + if (! array_is_list($queries)) { + throw new InvalidArgumentException('Expected $queries arguments to be a list (array), named arguments are not supported'); + } + + $this->queries = $queries; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/NotOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/NotOperator.php new file mode 100644 index 00000000..b2ba0894 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/NotOperator.php @@ -0,0 +1,41 @@ + 'expression']; + + /** @var DateTimeInterface|FieldQueryInterface|Type|array|bool|float|int|null|stdClass|string $expression */ + public readonly DateTimeInterface|Type|FieldQueryInterface|stdClass|array|bool|float|int|null|string $expression; + + /** + * @param DateTimeInterface|FieldQueryInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public function __construct( + DateTimeInterface|Type|FieldQueryInterface|stdClass|array|bool|float|int|null|string $expression, + ) { + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/OrOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/OrOperator.php new file mode 100644 index 00000000..1b922fdb --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/OrOperator.php @@ -0,0 +1,49 @@ + 'queries']; + + /** @var list $queries */ + public readonly array $queries; + + /** + * @param QueryInterface|array ...$queries + * @no-named-arguments + */ + public function __construct(QueryInterface|array ...$queries) + { + if (\count($queries) < 1) { + throw new InvalidArgumentException(\sprintf('Expected at least %d values for $queries, got %d.', 1, \count($queries))); + } + + if (! array_is_list($queries)) { + throw new InvalidArgumentException('Expected $queries arguments to be a list (array), named arguments are not supported'); + } + + $this->queries = $queries; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/PolygonOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/PolygonOperator.php new file mode 100644 index 00000000..bba3aac0 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/PolygonOperator.php @@ -0,0 +1,47 @@ + 'points']; + + /** @var BSONArray|PackedArray|array $points */ + public readonly PackedArray|BSONArray|array $points; + + /** + * @param BSONArray|PackedArray|array $points + */ + public function __construct(PackedArray|BSONArray|array $points) + { + if (is_array($points) && ! array_is_list($points)) { + throw new InvalidArgumentException('Expected $points argument to be a list, got an associative array.'); + } + + $this->points = $points; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/RandOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/RandOperator.php new file mode 100644 index 00000000..ccf8a8d2 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/RandOperator.php @@ -0,0 +1,29 @@ + 'regex']; + + /** @var Regex $regex */ + public readonly Regex $regex; + + /** + * @param Regex $regex + */ + public function __construct(Regex $regex) + { + $this->regex = $regex; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/SampleRateOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/SampleRateOperator.php new file mode 100644 index 00000000..a027972d --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/SampleRateOperator.php @@ -0,0 +1,51 @@ + 'rate']; + + /** + * @var Int64|ResolvesToDouble|float|int|string $rate The selection process uses a uniform random distribution. The sample rate is a floating point number between 0 and 1, inclusive, which represents the probability that a given document will be selected as it passes through the pipeline. + * For example, a sample rate of 0.33 selects roughly one document in three. + */ + public readonly Int64|ResolvesToDouble|float|int|string $rate; + + /** + * @param Int64|ResolvesToDouble|float|int|string $rate The selection process uses a uniform random distribution. The sample rate is a floating point number between 0 and 1, inclusive, which represents the probability that a given document will be selected as it passes through the pipeline. + * For example, a sample rate of 0.33 selects roughly one document in three. + */ + public function __construct(Int64|ResolvesToDouble|float|int|string $rate) + { + if (is_string($rate) && ! str_starts_with($rate, '$')) { + throw new InvalidArgumentException('Argument $rate can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->rate = $rate; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/SizeOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/SizeOperator.php new file mode 100644 index 00000000..8ec123b1 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/SizeOperator.php @@ -0,0 +1,37 @@ + 'value']; + + /** @var int $value */ + public readonly int $value; + + /** + * @param int $value + */ + public function __construct(int $value) + { + $this->value = $value; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/TextOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/TextOperator.php new file mode 100644 index 00000000..7c1c0a7b --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/TextOperator.php @@ -0,0 +1,71 @@ + '$search', + 'language' => '$language', + 'caseSensitive' => '$caseSensitive', + 'diacriticSensitive' => '$diacriticSensitive', + ]; + + /** @var string $search A string of terms that MongoDB parses and uses to query the text index. MongoDB performs a logical OR search of the terms unless specified as a phrase. */ + public readonly string $search; + + /** + * @var Optional|string $language The language that determines the list of stop words for the search and the rules for the stemmer and tokenizer. If not specified, the search uses the default language of the index. + * If you specify a default_language value of none, then the text index parses through each word in the field, including stop words, and ignores suffix stemming. + */ + public readonly Optional|string $language; + + /** @var Optional|bool $caseSensitive A boolean flag to enable or disable case sensitive search. Defaults to false; i.e. the search defers to the case insensitivity of the text index. */ + public readonly Optional|bool $caseSensitive; + + /** + * @var Optional|bool $diacriticSensitive A boolean flag to enable or disable diacritic sensitive search against version 3 text indexes. Defaults to false; i.e. the search defers to the diacritic insensitivity of the text index. + * Text searches against earlier versions of the text index are inherently diacritic sensitive and cannot be diacritic insensitive. As such, the $diacriticSensitive option has no effect with earlier versions of the text index. + */ + public readonly Optional|bool $diacriticSensitive; + + /** + * @param string $search A string of terms that MongoDB parses and uses to query the text index. MongoDB performs a logical OR search of the terms unless specified as a phrase. + * @param Optional|string $language The language that determines the list of stop words for the search and the rules for the stemmer and tokenizer. If not specified, the search uses the default language of the index. + * If you specify a default_language value of none, then the text index parses through each word in the field, including stop words, and ignores suffix stemming. + * @param Optional|bool $caseSensitive A boolean flag to enable or disable case sensitive search. Defaults to false; i.e. the search defers to the case insensitivity of the text index. + * @param Optional|bool $diacriticSensitive A boolean flag to enable or disable diacritic sensitive search against version 3 text indexes. Defaults to false; i.e. the search defers to the diacritic insensitivity of the text index. + * Text searches against earlier versions of the text index are inherently diacritic sensitive and cannot be diacritic insensitive. As such, the $diacriticSensitive option has no effect with earlier versions of the text index. + */ + public function __construct( + string $search, + Optional|string $language = Optional::Undefined, + Optional|bool $caseSensitive = Optional::Undefined, + Optional|bool $diacriticSensitive = Optional::Undefined, + ) { + $this->search = $search; + $this->language = $language; + $this->caseSensitive = $caseSensitive; + $this->diacriticSensitive = $diacriticSensitive; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/TypeOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/TypeOperator.php new file mode 100644 index 00000000..e539ebfc --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/TypeOperator.php @@ -0,0 +1,49 @@ + 'type']; + + /** @var list $type */ + public readonly array $type; + + /** + * @param int|string ...$type + * @no-named-arguments + */ + public function __construct(int|string ...$type) + { + if (\count($type) < 1) { + throw new InvalidArgumentException(\sprintf('Expected at least %d values for $type, got %d.', 1, \count($type))); + } + + if (! array_is_list($type)) { + throw new InvalidArgumentException('Expected $type arguments to be a list (array), named arguments are not supported'); + } + + $this->type = $type; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Query/WhereOperator.php b/vendor/mongodb/mongodb/src/Builder/Query/WhereOperator.php new file mode 100644 index 00000000..e679f734 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Query/WhereOperator.php @@ -0,0 +1,44 @@ + 'function']; + + /** @var Javascript|string $function */ + public readonly Javascript|string $function; + + /** + * @param Javascript|string $function + */ + public function __construct(Javascript|string $function) + { + if (is_string($function)) { + $function = new Javascript($function); + } + + $this->function = $function; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Search.php b/vendor/mongodb/mongodb/src/Builder/Search.php new file mode 100644 index 00000000..7cab8464 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Search.php @@ -0,0 +1,10 @@ + 'path', + 'query' => 'query', + 'tokenOrder' => 'tokenOrder', + 'fuzzy' => 'fuzzy', + 'score' => 'score', + ]; + + /** @var array|string $path */ + public readonly array|string $path; + + /** @var string $query */ + public readonly string $query; + + /** @var Optional|string $tokenOrder */ + public readonly Optional|string $tokenOrder; + + /** @var Optional|Document|Serializable|array|stdClass $fuzzy */ + public readonly Optional|Document|Serializable|stdClass|array $fuzzy; + + /** @var Optional|Document|Serializable|array|stdClass $score */ + public readonly Optional|Document|Serializable|stdClass|array $score; + + /** + * @param array|string $path + * @param string $query + * @param Optional|string $tokenOrder + * @param Optional|Document|Serializable|array|stdClass $fuzzy + * @param Optional|Document|Serializable|array|stdClass $score + */ + public function __construct( + array|string $path, + string $query, + Optional|string $tokenOrder = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $fuzzy = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $score = Optional::Undefined, + ) { + $this->path = $path; + $this->query = $query; + $this->tokenOrder = $tokenOrder; + $this->fuzzy = $fuzzy; + $this->score = $score; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Search/CompoundOperator.php b/vendor/mongodb/mongodb/src/Builder/Search/CompoundOperator.php new file mode 100644 index 00000000..27b8c2ae --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Search/CompoundOperator.php @@ -0,0 +1,84 @@ + 'must', + 'mustNot' => 'mustNot', + 'should' => 'should', + 'filter' => 'filter', + 'minimumShouldMatch' => 'minimumShouldMatch', + 'score' => 'score', + ]; + + /** @var Optional|BSONArray|Document|PackedArray|SearchOperatorInterface|Serializable|array|stdClass $must */ + public readonly Optional|Document|PackedArray|Serializable|SearchOperatorInterface|BSONArray|stdClass|array $must; + + /** @var Optional|BSONArray|Document|PackedArray|SearchOperatorInterface|Serializable|array|stdClass $mustNot */ + public readonly Optional|Document|PackedArray|Serializable|SearchOperatorInterface|BSONArray|stdClass|array $mustNot; + + /** @var Optional|BSONArray|Document|PackedArray|SearchOperatorInterface|Serializable|array|stdClass $should */ + public readonly Optional|Document|PackedArray|Serializable|SearchOperatorInterface|BSONArray|stdClass|array $should; + + /** @var Optional|BSONArray|Document|PackedArray|SearchOperatorInterface|Serializable|array|stdClass $filter */ + public readonly Optional|Document|PackedArray|Serializable|SearchOperatorInterface|BSONArray|stdClass|array $filter; + + /** @var Optional|int $minimumShouldMatch */ + public readonly Optional|int $minimumShouldMatch; + + /** @var Optional|Document|Serializable|array|stdClass $score */ + public readonly Optional|Document|Serializable|stdClass|array $score; + + /** + * @param Optional|BSONArray|Document|PackedArray|SearchOperatorInterface|Serializable|array|stdClass $must + * @param Optional|BSONArray|Document|PackedArray|SearchOperatorInterface|Serializable|array|stdClass $mustNot + * @param Optional|BSONArray|Document|PackedArray|SearchOperatorInterface|Serializable|array|stdClass $should + * @param Optional|BSONArray|Document|PackedArray|SearchOperatorInterface|Serializable|array|stdClass $filter + * @param Optional|int $minimumShouldMatch + * @param Optional|Document|Serializable|array|stdClass $score + */ + public function __construct( + Optional|Document|PackedArray|Serializable|SearchOperatorInterface|BSONArray|stdClass|array $must = Optional::Undefined, + Optional|Document|PackedArray|Serializable|SearchOperatorInterface|BSONArray|stdClass|array $mustNot = Optional::Undefined, + Optional|Document|PackedArray|Serializable|SearchOperatorInterface|BSONArray|stdClass|array $should = Optional::Undefined, + Optional|Document|PackedArray|Serializable|SearchOperatorInterface|BSONArray|stdClass|array $filter = Optional::Undefined, + Optional|int $minimumShouldMatch = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $score = Optional::Undefined, + ) { + $this->must = $must; + $this->mustNot = $mustNot; + $this->should = $should; + $this->filter = $filter; + $this->minimumShouldMatch = $minimumShouldMatch; + $this->score = $score; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Search/EmbeddedDocumentOperator.php b/vendor/mongodb/mongodb/src/Builder/Search/EmbeddedDocumentOperator.php new file mode 100644 index 00000000..91f6c1f9 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Search/EmbeddedDocumentOperator.php @@ -0,0 +1,57 @@ + 'path', 'operator' => 'operator', 'score' => 'score']; + + /** @var array|string $path */ + public readonly array|string $path; + + /** @var Document|SearchOperatorInterface|Serializable|array|stdClass $operator */ + public readonly Document|Serializable|SearchOperatorInterface|stdClass|array $operator; + + /** @var Optional|Document|Serializable|array|stdClass $score */ + public readonly Optional|Document|Serializable|stdClass|array $score; + + /** + * @param array|string $path + * @param Document|SearchOperatorInterface|Serializable|array|stdClass $operator + * @param Optional|Document|Serializable|array|stdClass $score + */ + public function __construct( + array|string $path, + Document|Serializable|SearchOperatorInterface|stdClass|array $operator, + Optional|Document|Serializable|stdClass|array $score = Optional::Undefined, + ) { + $this->path = $path; + $this->operator = $operator; + $this->score = $score; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Search/EqualsOperator.php b/vendor/mongodb/mongodb/src/Builder/Search/EqualsOperator.php new file mode 100644 index 00000000..092a9ca4 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Search/EqualsOperator.php @@ -0,0 +1,60 @@ + 'path', 'value' => 'value', 'score' => 'score']; + + /** @var array|string $path */ + public readonly array|string $path; + + /** @var Binary|DateTimeInterface|Decimal128|Int64|ObjectId|UTCDateTime|bool|float|int|null|string $value */ + public readonly DateTimeInterface|Binary|Decimal128|Int64|ObjectId|UTCDateTime|bool|float|int|null|string $value; + + /** @var Optional|Document|Serializable|array|stdClass $score */ + public readonly Optional|Document|Serializable|stdClass|array $score; + + /** + * @param array|string $path + * @param Binary|DateTimeInterface|Decimal128|Int64|ObjectId|UTCDateTime|bool|float|int|null|string $value + * @param Optional|Document|Serializable|array|stdClass $score + */ + public function __construct( + array|string $path, + DateTimeInterface|Binary|Decimal128|Int64|ObjectId|UTCDateTime|bool|float|int|null|string $value, + Optional|Document|Serializable|stdClass|array $score = Optional::Undefined, + ) { + $this->path = $path; + $this->value = $value; + $this->score = $score; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Search/ExistsOperator.php b/vendor/mongodb/mongodb/src/Builder/Search/ExistsOperator.php new file mode 100644 index 00000000..4330f130 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Search/ExistsOperator.php @@ -0,0 +1,48 @@ + 'path', 'score' => 'score']; + + /** @var array|string $path */ + public readonly array|string $path; + + /** @var Optional|Document|Serializable|array|stdClass $score */ + public readonly Optional|Document|Serializable|stdClass|array $score; + + /** + * @param array|string $path + * @param Optional|Document|Serializable|array|stdClass $score + */ + public function __construct( + array|string $path, + Optional|Document|Serializable|stdClass|array $score = Optional::Undefined, + ) { + $this->path = $path; + $this->score = $score; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Search/FacetOperator.php b/vendor/mongodb/mongodb/src/Builder/Search/FacetOperator.php new file mode 100644 index 00000000..15fc1083 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Search/FacetOperator.php @@ -0,0 +1,49 @@ + 'facets', 'operator' => 'operator']; + + /** @var Document|Serializable|array|stdClass $facets */ + public readonly Document|Serializable|stdClass|array $facets; + + /** @var Optional|Document|SearchOperatorInterface|Serializable|array|stdClass $operator */ + public readonly Optional|Document|Serializable|SearchOperatorInterface|stdClass|array $operator; + + /** + * @param Document|Serializable|array|stdClass $facets + * @param Optional|Document|SearchOperatorInterface|Serializable|array|stdClass $operator + */ + public function __construct( + Document|Serializable|stdClass|array $facets, + Optional|Document|Serializable|SearchOperatorInterface|stdClass|array $operator = Optional::Undefined, + ) { + $this->facets = $facets; + $this->operator = $operator; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Search/FactoryTrait.php b/vendor/mongodb/mongodb/src/Builder/Search/FactoryTrait.php new file mode 100644 index 00000000..c5f3b009 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Search/FactoryTrait.php @@ -0,0 +1,346 @@ + 'path', 'relation' => 'relation', 'geometry' => 'geometry', 'score' => 'score']; + + /** @var array|string $path */ + public readonly array|string $path; + + /** @var string $relation */ + public readonly string $relation; + + /** @var Document|GeometryInterface|Serializable|array|stdClass $geometry */ + public readonly Document|Serializable|GeometryInterface|stdClass|array $geometry; + + /** @var Optional|Document|Serializable|array|stdClass $score */ + public readonly Optional|Document|Serializable|stdClass|array $score; + + /** + * @param array|string $path + * @param string $relation + * @param Document|GeometryInterface|Serializable|array|stdClass $geometry + * @param Optional|Document|Serializable|array|stdClass $score + */ + public function __construct( + array|string $path, + string $relation, + Document|Serializable|GeometryInterface|stdClass|array $geometry, + Optional|Document|Serializable|stdClass|array $score = Optional::Undefined, + ) { + $this->path = $path; + $this->relation = $relation; + $this->geometry = $geometry; + $this->score = $score; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Search/GeoWithinOperator.php b/vendor/mongodb/mongodb/src/Builder/Search/GeoWithinOperator.php new file mode 100644 index 00000000..dcf60569 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Search/GeoWithinOperator.php @@ -0,0 +1,76 @@ + 'path', + 'box' => 'box', + 'circle' => 'circle', + 'geometry' => 'geometry', + 'score' => 'score', + ]; + + /** @var array|string $path */ + public readonly array|string $path; + + /** @var Optional|Document|Serializable|array|stdClass $box */ + public readonly Optional|Document|Serializable|stdClass|array $box; + + /** @var Optional|Document|Serializable|array|stdClass $circle */ + public readonly Optional|Document|Serializable|stdClass|array $circle; + + /** @var Optional|Document|GeometryInterface|Serializable|array|stdClass $geometry */ + public readonly Optional|Document|Serializable|GeometryInterface|stdClass|array $geometry; + + /** @var Optional|Document|Serializable|array|stdClass $score */ + public readonly Optional|Document|Serializable|stdClass|array $score; + + /** + * @param array|string $path + * @param Optional|Document|Serializable|array|stdClass $box + * @param Optional|Document|Serializable|array|stdClass $circle + * @param Optional|Document|GeometryInterface|Serializable|array|stdClass $geometry + * @param Optional|Document|Serializable|array|stdClass $score + */ + public function __construct( + array|string $path, + Optional|Document|Serializable|stdClass|array $box = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $circle = Optional::Undefined, + Optional|Document|Serializable|GeometryInterface|stdClass|array $geometry = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $score = Optional::Undefined, + ) { + $this->path = $path; + $this->box = $box; + $this->circle = $circle; + $this->geometry = $geometry; + $this->score = $score; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Search/InOperator.php b/vendor/mongodb/mongodb/src/Builder/Search/InOperator.php new file mode 100644 index 00000000..b9aaf587 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Search/InOperator.php @@ -0,0 +1,66 @@ + 'path', 'value' => 'value', 'score' => 'score']; + + /** @var array|string $path */ + public readonly array|string $path; + + /** @var BSONArray|DateTimeInterface|PackedArray|Type|array|bool|float|int|null|stdClass|string $value */ + public readonly DateTimeInterface|PackedArray|Type|BSONArray|stdClass|array|bool|float|int|null|string $value; + + /** @var Optional|Document|Serializable|array|stdClass $score */ + public readonly Optional|Document|Serializable|stdClass|array $score; + + /** + * @param array|string $path + * @param BSONArray|DateTimeInterface|PackedArray|Type|array|bool|float|int|null|stdClass|string $value + * @param Optional|Document|Serializable|array|stdClass $score + */ + public function __construct( + array|string $path, + DateTimeInterface|PackedArray|Type|BSONArray|stdClass|array|bool|float|int|null|string $value, + Optional|Document|Serializable|stdClass|array $score = Optional::Undefined, + ) { + $this->path = $path; + if (is_array($value) && ! array_is_list($value)) { + throw new InvalidArgumentException('Expected $value argument to be a list, got an associative array.'); + } + + $this->value = $value; + $this->score = $score; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Search/MoreLikeThisOperator.php b/vendor/mongodb/mongodb/src/Builder/Search/MoreLikeThisOperator.php new file mode 100644 index 00000000..689508d5 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Search/MoreLikeThisOperator.php @@ -0,0 +1,52 @@ + 'like', 'score' => 'score']; + + /** @var BSONArray|Document|PackedArray|Serializable|array|stdClass $like */ + public readonly Document|PackedArray|Serializable|BSONArray|stdClass|array $like; + + /** @var Optional|Document|Serializable|array|stdClass $score */ + public readonly Optional|Document|Serializable|stdClass|array $score; + + /** + * @param BSONArray|Document|PackedArray|Serializable|array|stdClass $like + * @param Optional|Document|Serializable|array|stdClass $score + */ + public function __construct( + Document|PackedArray|Serializable|BSONArray|stdClass|array $like, + Optional|Document|Serializable|stdClass|array $score = Optional::Undefined, + ) { + $this->like = $like; + $this->score = $score; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Search/NearOperator.php b/vendor/mongodb/mongodb/src/Builder/Search/NearOperator.php new file mode 100644 index 00000000..b22013ea --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Search/NearOperator.php @@ -0,0 +1,65 @@ + 'path', 'origin' => 'origin', 'pivot' => 'pivot', 'score' => 'score']; + + /** @var array|string $path */ + public readonly array|string $path; + + /** @var DateTimeInterface|Decimal128|Document|GeometryInterface|Int64|Serializable|UTCDateTime|array|float|int|stdClass $origin */ + public readonly DateTimeInterface|Decimal128|Document|Int64|Serializable|UTCDateTime|GeometryInterface|stdClass|array|float|int $origin; + + /** @var Decimal128|Int64|float|int $pivot */ + public readonly Decimal128|Int64|float|int $pivot; + + /** @var Optional|Document|Serializable|array|stdClass $score */ + public readonly Optional|Document|Serializable|stdClass|array $score; + + /** + * @param array|string $path + * @param DateTimeInterface|Decimal128|Document|GeometryInterface|Int64|Serializable|UTCDateTime|array|float|int|stdClass $origin + * @param Decimal128|Int64|float|int $pivot + * @param Optional|Document|Serializable|array|stdClass $score + */ + public function __construct( + array|string $path, + DateTimeInterface|Decimal128|Document|Int64|Serializable|UTCDateTime|GeometryInterface|stdClass|array|float|int $origin, + Decimal128|Int64|float|int $pivot, + Optional|Document|Serializable|stdClass|array $score = Optional::Undefined, + ) { + $this->path = $path; + $this->origin = $origin; + $this->pivot = $pivot; + $this->score = $score; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Search/PhraseOperator.php b/vendor/mongodb/mongodb/src/Builder/Search/PhraseOperator.php new file mode 100644 index 00000000..2bbb707a --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Search/PhraseOperator.php @@ -0,0 +1,83 @@ + 'path', + 'query' => 'query', + 'slop' => 'slop', + 'synonyms' => 'synonyms', + 'score' => 'score', + ]; + + /** @var array|string $path */ + public readonly array|string $path; + + /** @var BSONArray|PackedArray|array|string $query */ + public readonly PackedArray|BSONArray|array|string $query; + + /** @var Optional|int $slop */ + public readonly Optional|int $slop; + + /** @var Optional|string $synonyms */ + public readonly Optional|string $synonyms; + + /** @var Optional|Document|Serializable|array|stdClass $score */ + public readonly Optional|Document|Serializable|stdClass|array $score; + + /** + * @param array|string $path + * @param BSONArray|PackedArray|array|string $query + * @param Optional|int $slop + * @param Optional|string $synonyms + * @param Optional|Document|Serializable|array|stdClass $score + */ + public function __construct( + array|string $path, + PackedArray|BSONArray|array|string $query, + Optional|int $slop = Optional::Undefined, + Optional|string $synonyms = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $score = Optional::Undefined, + ) { + $this->path = $path; + if (is_array($query) && ! array_is_list($query)) { + throw new InvalidArgumentException('Expected $query argument to be a list, got an associative array.'); + } + + $this->query = $query; + $this->slop = $slop; + $this->synonyms = $synonyms; + $this->score = $score; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Search/QueryStringOperator.php b/vendor/mongodb/mongodb/src/Builder/Search/QueryStringOperator.php new file mode 100644 index 00000000..edc4d347 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Search/QueryStringOperator.php @@ -0,0 +1,40 @@ + 'defaultPath', 'query' => 'query']; + + /** @var array|string $defaultPath */ + public readonly array|string $defaultPath; + + /** @var string $query */ + public readonly string $query; + + /** + * @param array|string $defaultPath + * @param string $query + */ + public function __construct(array|string $defaultPath, string $query) + { + $this->defaultPath = $defaultPath; + $this->query = $query; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Search/RangeOperator.php b/vendor/mongodb/mongodb/src/Builder/Search/RangeOperator.php new file mode 100644 index 00000000..e277f2b0 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Search/RangeOperator.php @@ -0,0 +1,86 @@ + 'path', + 'gt' => 'gt', + 'gte' => 'gte', + 'lt' => 'lt', + 'lte' => 'lte', + 'score' => 'score', + ]; + + /** @var array|string $path */ + public readonly array|string $path; + + /** @var Optional|DateTimeInterface|Decimal128|Int64|ObjectId|UTCDateTime|float|int|string $gt */ + public readonly Optional|DateTimeInterface|Decimal128|Int64|ObjectId|UTCDateTime|float|int|string $gt; + + /** @var Optional|DateTimeInterface|Decimal128|Int64|ObjectId|UTCDateTime|float|int|string $gte */ + public readonly Optional|DateTimeInterface|Decimal128|Int64|ObjectId|UTCDateTime|float|int|string $gte; + + /** @var Optional|DateTimeInterface|Decimal128|Int64|ObjectId|UTCDateTime|float|int|string $lt */ + public readonly Optional|DateTimeInterface|Decimal128|Int64|ObjectId|UTCDateTime|float|int|string $lt; + + /** @var Optional|DateTimeInterface|Decimal128|Int64|ObjectId|UTCDateTime|float|int|string $lte */ + public readonly Optional|DateTimeInterface|Decimal128|Int64|ObjectId|UTCDateTime|float|int|string $lte; + + /** @var Optional|Document|Serializable|array|stdClass $score */ + public readonly Optional|Document|Serializable|stdClass|array $score; + + /** + * @param array|string $path + * @param Optional|DateTimeInterface|Decimal128|Int64|ObjectId|UTCDateTime|float|int|string $gt + * @param Optional|DateTimeInterface|Decimal128|Int64|ObjectId|UTCDateTime|float|int|string $gte + * @param Optional|DateTimeInterface|Decimal128|Int64|ObjectId|UTCDateTime|float|int|string $lt + * @param Optional|DateTimeInterface|Decimal128|Int64|ObjectId|UTCDateTime|float|int|string $lte + * @param Optional|Document|Serializable|array|stdClass $score + */ + public function __construct( + array|string $path, + Optional|DateTimeInterface|Decimal128|Int64|ObjectId|UTCDateTime|float|int|string $gt = Optional::Undefined, + Optional|DateTimeInterface|Decimal128|Int64|ObjectId|UTCDateTime|float|int|string $gte = Optional::Undefined, + Optional|DateTimeInterface|Decimal128|Int64|ObjectId|UTCDateTime|float|int|string $lt = Optional::Undefined, + Optional|DateTimeInterface|Decimal128|Int64|ObjectId|UTCDateTime|float|int|string $lte = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $score = Optional::Undefined, + ) { + $this->path = $path; + $this->gt = $gt; + $this->gte = $gte; + $this->lt = $lt; + $this->lte = $lte; + $this->score = $score; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Search/RegexOperator.php b/vendor/mongodb/mongodb/src/Builder/Search/RegexOperator.php new file mode 100644 index 00000000..6b2c2d63 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Search/RegexOperator.php @@ -0,0 +1,67 @@ + 'path', + 'query' => 'query', + 'allowAnalyzedField' => 'allowAnalyzedField', + 'score' => 'score', + ]; + + /** @var array|string $path */ + public readonly array|string $path; + + /** @var string $query */ + public readonly string $query; + + /** @var Optional|bool $allowAnalyzedField */ + public readonly Optional|bool $allowAnalyzedField; + + /** @var Optional|Document|Serializable|array|stdClass $score */ + public readonly Optional|Document|Serializable|stdClass|array $score; + + /** + * @param array|string $path + * @param string $query + * @param Optional|bool $allowAnalyzedField + * @param Optional|Document|Serializable|array|stdClass $score + */ + public function __construct( + array|string $path, + string $query, + Optional|bool $allowAnalyzedField = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $score = Optional::Undefined, + ) { + $this->path = $path; + $this->query = $query; + $this->allowAnalyzedField = $allowAnalyzedField; + $this->score = $score; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Search/TextOperator.php b/vendor/mongodb/mongodb/src/Builder/Search/TextOperator.php new file mode 100644 index 00000000..4ade6b43 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Search/TextOperator.php @@ -0,0 +1,81 @@ + 'path', + 'query' => 'query', + 'fuzzy' => 'fuzzy', + 'matchCriteria' => 'matchCriteria', + 'synonyms' => 'synonyms', + 'score' => 'score', + ]; + + /** @var array|string $path */ + public readonly array|string $path; + + /** @var string $query */ + public readonly string $query; + + /** @var Optional|Document|Serializable|array|stdClass $fuzzy */ + public readonly Optional|Document|Serializable|stdClass|array $fuzzy; + + /** @var Optional|string $matchCriteria */ + public readonly Optional|string $matchCriteria; + + /** @var Optional|string $synonyms */ + public readonly Optional|string $synonyms; + + /** @var Optional|Document|Serializable|array|stdClass $score */ + public readonly Optional|Document|Serializable|stdClass|array $score; + + /** + * @param array|string $path + * @param string $query + * @param Optional|Document|Serializable|array|stdClass $fuzzy + * @param Optional|string $matchCriteria + * @param Optional|string $synonyms + * @param Optional|Document|Serializable|array|stdClass $score + */ + public function __construct( + array|string $path, + string $query, + Optional|Document|Serializable|stdClass|array $fuzzy = Optional::Undefined, + Optional|string $matchCriteria = Optional::Undefined, + Optional|string $synonyms = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $score = Optional::Undefined, + ) { + $this->path = $path; + $this->query = $query; + $this->fuzzy = $fuzzy; + $this->matchCriteria = $matchCriteria; + $this->synonyms = $synonyms; + $this->score = $score; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Search/WildcardOperator.php b/vendor/mongodb/mongodb/src/Builder/Search/WildcardOperator.php new file mode 100644 index 00000000..ee481910 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Search/WildcardOperator.php @@ -0,0 +1,66 @@ + 'path', + 'query' => 'query', + 'allowAnalyzedField' => 'allowAnalyzedField', + 'score' => 'score', + ]; + + /** @var array|string $path */ + public readonly array|string $path; + + /** @var string $query */ + public readonly string $query; + + /** @var Optional|bool $allowAnalyzedField */ + public readonly Optional|bool $allowAnalyzedField; + + /** @var Optional|Document|Serializable|array|stdClass $score */ + public readonly Optional|Document|Serializable|stdClass|array $score; + + /** + * @param array|string $path + * @param string $query + * @param Optional|bool $allowAnalyzedField + * @param Optional|Document|Serializable|array|stdClass $score + */ + public function __construct( + array|string $path, + string $query, + Optional|bool $allowAnalyzedField = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $score = Optional::Undefined, + ) { + $this->path = $path; + $this->query = $query; + $this->allowAnalyzedField = $allowAnalyzedField; + $this->score = $score; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage.php b/vendor/mongodb/mongodb/src/Builder/Stage.php new file mode 100644 index 00000000..2dbbfd97 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage.php @@ -0,0 +1,37 @@ +|bool|float|int|string|null ...$queries The query predicates to match + */ + public static function match(DateTimeInterface|QueryInterface|FieldQueryInterface|Type|stdClass|array|bool|float|int|string|null ...$queries): MatchStage + { + // Override the generated method to allow variadic arguments + return self::generatedMatch($queries); + } + + private function __construct() + { + // This class cannot be instantiated + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/AddFieldsStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/AddFieldsStage.php new file mode 100644 index 00000000..f6385a39 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/AddFieldsStage.php @@ -0,0 +1,56 @@ + 'expression']; + + /** @var stdClass $expression Specify the name of each field to add and set its value to an aggregation expression or an empty object. */ + public readonly stdClass $expression; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string ...$expression Specify the name of each field to add and set its value to an aggregation expression or an empty object. + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string ...$expression, + ) { + if (\count($expression) < 1) { + throw new InvalidArgumentException(\sprintf('Expected at least %d values for $expression, got %d.', 1, \count($expression))); + } + + foreach($expression as $key => $value) { + if (! is_string($key)) { + throw new InvalidArgumentException('Expected $expression arguments to be a map (object), named arguments (:) or array unpacking ...[\'\' => ] must be used'); + } + } + + $expression = (object) $expression; + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/BucketAutoStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/BucketAutoStage.php new file mode 100644 index 00000000..21975208 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/BucketAutoStage.php @@ -0,0 +1,77 @@ + 'groupBy', + 'buckets' => 'buckets', + 'output' => 'output', + 'granularity' => 'granularity', + ]; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $groupBy An expression to group documents by. To specify a field path, prefix the field name with a dollar sign $ and enclose it in quotes. */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $groupBy; + + /** @var int $buckets A positive 32-bit integer that specifies the number of buckets into which input documents are grouped. */ + public readonly int $buckets; + + /** + * @var Optional|Document|Serializable|array|stdClass $output A document that specifies the fields to include in the output documents in addition to the _id field. To specify the field to include, you must use accumulator expressions. + * The default count field is not included in the output document when output is specified. Explicitly specify the count expression as part of the output document to include it. + */ + public readonly Optional|Document|Serializable|stdClass|array $output; + + /** + * @var Optional|string $granularity A string that specifies the preferred number series to use to ensure that the calculated boundary edges end on preferred round numbers or their powers of 10. + * Available only if the all groupBy values are numeric and none of them are NaN. + */ + public readonly Optional|string $granularity; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $groupBy An expression to group documents by. To specify a field path, prefix the field name with a dollar sign $ and enclose it in quotes. + * @param int $buckets A positive 32-bit integer that specifies the number of buckets into which input documents are grouped. + * @param Optional|Document|Serializable|array|stdClass $output A document that specifies the fields to include in the output documents in addition to the _id field. To specify the field to include, you must use accumulator expressions. + * The default count field is not included in the output document when output is specified. Explicitly specify the count expression as part of the output document to include it. + * @param Optional|string $granularity A string that specifies the preferred number series to use to ensure that the calculated boundary edges end on preferred round numbers or their powers of 10. + * Available only if the all groupBy values are numeric and none of them are NaN. + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $groupBy, + int $buckets, + Optional|Document|Serializable|stdClass|array $output = Optional::Undefined, + Optional|string $granularity = Optional::Undefined, + ) { + $this->groupBy = $groupBy; + $this->buckets = $buckets; + $this->output = $output; + $this->granularity = $granularity; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/BucketStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/BucketStage.php new file mode 100644 index 00000000..334f73dd --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/BucketStage.php @@ -0,0 +1,101 @@ + 'groupBy', + 'boundaries' => 'boundaries', + 'default' => 'default', + 'output' => 'output', + ]; + + /** + * @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $groupBy An expression to group documents by. To specify a field path, prefix the field name with a dollar sign $ and enclose it in quotes. + * Unless $bucket includes a default specification, each input document must resolve the groupBy field path or expression to a value that falls within one of the ranges specified by the boundaries. + */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $groupBy; + + /** + * @var BSONArray|PackedArray|array $boundaries An array of values based on the groupBy expression that specify the boundaries for each bucket. Each adjacent pair of values acts as the inclusive lower boundary and the exclusive upper boundary for the bucket. You must specify at least two boundaries. + * The specified values must be in ascending order and all of the same type. The exception is if the values are of mixed numeric types, such as: + */ + public readonly PackedArray|BSONArray|array $boundaries; + + /** + * @var Optional|DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $default A literal that specifies the _id of an additional bucket that contains all documents whose groupBy expression result does not fall into a bucket specified by boundaries. + * If unspecified, each input document must resolve the groupBy expression to a value within one of the bucket ranges specified by boundaries or the operation throws an error. + * The default value must be less than the lowest boundaries value, or greater than or equal to the highest boundaries value. + * The default value can be of a different type than the entries in boundaries. + */ + public readonly Optional|DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $default; + + /** + * @var Optional|Document|Serializable|array|stdClass $output A document that specifies the fields to include in the output documents in addition to the _id field. To specify the field to include, you must use accumulator expressions. + * If you do not specify an output document, the operation returns a count field containing the number of documents in each bucket. + * If you specify an output document, only the fields specified in the document are returned; i.e. the count field is not returned unless it is explicitly included in the output document. + */ + public readonly Optional|Document|Serializable|stdClass|array $output; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $groupBy An expression to group documents by. To specify a field path, prefix the field name with a dollar sign $ and enclose it in quotes. + * Unless $bucket includes a default specification, each input document must resolve the groupBy field path or expression to a value that falls within one of the ranges specified by the boundaries. + * @param BSONArray|PackedArray|array $boundaries An array of values based on the groupBy expression that specify the boundaries for each bucket. Each adjacent pair of values acts as the inclusive lower boundary and the exclusive upper boundary for the bucket. You must specify at least two boundaries. + * The specified values must be in ascending order and all of the same type. The exception is if the values are of mixed numeric types, such as: + * @param Optional|DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $default A literal that specifies the _id of an additional bucket that contains all documents whose groupBy expression result does not fall into a bucket specified by boundaries. + * If unspecified, each input document must resolve the groupBy expression to a value within one of the bucket ranges specified by boundaries or the operation throws an error. + * The default value must be less than the lowest boundaries value, or greater than or equal to the highest boundaries value. + * The default value can be of a different type than the entries in boundaries. + * @param Optional|Document|Serializable|array|stdClass $output A document that specifies the fields to include in the output documents in addition to the _id field. To specify the field to include, you must use accumulator expressions. + * If you do not specify an output document, the operation returns a count field containing the number of documents in each bucket. + * If you specify an output document, only the fields specified in the document are returned; i.e. the count field is not returned unless it is explicitly included in the output document. + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $groupBy, + PackedArray|BSONArray|array $boundaries, + Optional|DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $default = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $output = Optional::Undefined, + ) { + $this->groupBy = $groupBy; + if (is_array($boundaries) && ! array_is_list($boundaries)) { + throw new InvalidArgumentException('Expected $boundaries argument to be a list, got an associative array.'); + } + + $this->boundaries = $boundaries; + $this->default = $default; + $this->output = $output; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/ChangeStreamSplitLargeEventStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/ChangeStreamSplitLargeEventStage.php new file mode 100644 index 00000000..2539ddb1 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/ChangeStreamSplitLargeEventStage.php @@ -0,0 +1,30 @@ + 'allChangesForCluster', + 'fullDocument' => 'fullDocument', + 'fullDocumentBeforeChange' => 'fullDocumentBeforeChange', + 'resumeAfter' => 'resumeAfter', + 'showExpandedEvents' => 'showExpandedEvents', + 'startAfter' => 'startAfter', + 'startAtOperationTime' => 'startAtOperationTime', + ]; + + /** @var Optional|bool $allChangesForCluster A flag indicating whether the stream should report all changes that occur on the deployment, aside from those on internal databases or collections. */ + public readonly Optional|bool $allChangesForCluster; + + /** @var Optional|string $fullDocument Specifies whether change notifications include a copy of the full document when modified by update operations. */ + public readonly Optional|string $fullDocument; + + /** @var Optional|string $fullDocumentBeforeChange Valid values are "off", "whenAvailable", or "required". If set to "off", the "fullDocumentBeforeChange" field of the output document is always omitted. If set to "whenAvailable", the "fullDocumentBeforeChange" field will be populated with the pre-image of the document modified by the current change event if such a pre-image is available, and will be omitted otherwise. If set to "required", then the "fullDocumentBeforeChange" field is always populated and an exception is thrown if the pre-image is not available. */ + public readonly Optional|string $fullDocumentBeforeChange; + + /** @var Optional|int $resumeAfter Specifies a resume token as the logical starting point for the change stream. Cannot be used with startAfter or startAtOperationTime fields. */ + public readonly Optional|int $resumeAfter; + + /** + * @var Optional|bool $showExpandedEvents Specifies whether to include additional change events, such as such as DDL and index operations. + * New in MongoDB 6.0. + */ + public readonly Optional|bool $showExpandedEvents; + + /** @var Optional|Document|Serializable|array|stdClass $startAfter Specifies a resume token as the logical starting point for the change stream. Cannot be used with resumeAfter or startAtOperationTime fields. */ + public readonly Optional|Document|Serializable|stdClass|array $startAfter; + + /** @var Optional|Timestamp|int $startAtOperationTime Specifies a time as the logical starting point for the change stream. Cannot be used with resumeAfter or startAfter fields. */ + public readonly Optional|Timestamp|int $startAtOperationTime; + + /** + * @param Optional|bool $allChangesForCluster A flag indicating whether the stream should report all changes that occur on the deployment, aside from those on internal databases or collections. + * @param Optional|string $fullDocument Specifies whether change notifications include a copy of the full document when modified by update operations. + * @param Optional|string $fullDocumentBeforeChange Valid values are "off", "whenAvailable", or "required". If set to "off", the "fullDocumentBeforeChange" field of the output document is always omitted. If set to "whenAvailable", the "fullDocumentBeforeChange" field will be populated with the pre-image of the document modified by the current change event if such a pre-image is available, and will be omitted otherwise. If set to "required", then the "fullDocumentBeforeChange" field is always populated and an exception is thrown if the pre-image is not available. + * @param Optional|int $resumeAfter Specifies a resume token as the logical starting point for the change stream. Cannot be used with startAfter or startAtOperationTime fields. + * @param Optional|bool $showExpandedEvents Specifies whether to include additional change events, such as such as DDL and index operations. + * New in MongoDB 6.0. + * @param Optional|Document|Serializable|array|stdClass $startAfter Specifies a resume token as the logical starting point for the change stream. Cannot be used with resumeAfter or startAtOperationTime fields. + * @param Optional|Timestamp|int $startAtOperationTime Specifies a time as the logical starting point for the change stream. Cannot be used with resumeAfter or startAfter fields. + */ + public function __construct( + Optional|bool $allChangesForCluster = Optional::Undefined, + Optional|string $fullDocument = Optional::Undefined, + Optional|string $fullDocumentBeforeChange = Optional::Undefined, + Optional|int $resumeAfter = Optional::Undefined, + Optional|bool $showExpandedEvents = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $startAfter = Optional::Undefined, + Optional|Timestamp|int $startAtOperationTime = Optional::Undefined, + ) { + $this->allChangesForCluster = $allChangesForCluster; + $this->fullDocument = $fullDocument; + $this->fullDocumentBeforeChange = $fullDocumentBeforeChange; + $this->resumeAfter = $resumeAfter; + $this->showExpandedEvents = $showExpandedEvents; + $this->startAfter = $startAfter; + $this->startAtOperationTime = $startAtOperationTime; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/CollStatsStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/CollStatsStage.php new file mode 100644 index 00000000..d8424532 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/CollStatsStage.php @@ -0,0 +1,66 @@ + 'latencyStats', + 'storageStats' => 'storageStats', + 'count' => 'count', + 'queryExecStats' => 'queryExecStats', + ]; + + /** @var Optional|Document|Serializable|array|stdClass $latencyStats */ + public readonly Optional|Document|Serializable|stdClass|array $latencyStats; + + /** @var Optional|Document|Serializable|array|stdClass $storageStats */ + public readonly Optional|Document|Serializable|stdClass|array $storageStats; + + /** @var Optional|Document|Serializable|array|stdClass $count */ + public readonly Optional|Document|Serializable|stdClass|array $count; + + /** @var Optional|Document|Serializable|array|stdClass $queryExecStats */ + public readonly Optional|Document|Serializable|stdClass|array $queryExecStats; + + /** + * @param Optional|Document|Serializable|array|stdClass $latencyStats + * @param Optional|Document|Serializable|array|stdClass $storageStats + * @param Optional|Document|Serializable|array|stdClass $count + * @param Optional|Document|Serializable|array|stdClass $queryExecStats + */ + public function __construct( + Optional|Document|Serializable|stdClass|array $latencyStats = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $storageStats = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $count = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $queryExecStats = Optional::Undefined, + ) { + $this->latencyStats = $latencyStats; + $this->storageStats = $storageStats; + $this->count = $count; + $this->queryExecStats = $queryExecStats; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/CountStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/CountStage.php new file mode 100644 index 00000000..387da5ef --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/CountStage.php @@ -0,0 +1,38 @@ + 'field']; + + /** @var string $field Name of the output field which has the count as its value. It must be a non-empty string, must not start with $ and must not contain the . character. */ + public readonly string $field; + + /** + * @param string $field Name of the output field which has the count as its value. It must be a non-empty string, must not start with $ and must not contain the . character. + */ + public function __construct(string $field) + { + $this->field = $field; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/CurrentOpStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/CurrentOpStage.php new file mode 100644 index 00000000..3d0d6abb --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/CurrentOpStage.php @@ -0,0 +1,70 @@ + 'allUsers', + 'idleConnections' => 'idleConnections', + 'idleCursors' => 'idleCursors', + 'idleSessions' => 'idleSessions', + 'localOps' => 'localOps', + ]; + + /** @var Optional|bool $allUsers */ + public readonly Optional|bool $allUsers; + + /** @var Optional|bool $idleConnections */ + public readonly Optional|bool $idleConnections; + + /** @var Optional|bool $idleCursors */ + public readonly Optional|bool $idleCursors; + + /** @var Optional|bool $idleSessions */ + public readonly Optional|bool $idleSessions; + + /** @var Optional|bool $localOps */ + public readonly Optional|bool $localOps; + + /** + * @param Optional|bool $allUsers + * @param Optional|bool $idleConnections + * @param Optional|bool $idleCursors + * @param Optional|bool $idleSessions + * @param Optional|bool $localOps + */ + public function __construct( + Optional|bool $allUsers = Optional::Undefined, + Optional|bool $idleConnections = Optional::Undefined, + Optional|bool $idleCursors = Optional::Undefined, + Optional|bool $idleSessions = Optional::Undefined, + Optional|bool $localOps = Optional::Undefined, + ) { + $this->allUsers = $allUsers; + $this->idleConnections = $idleConnections; + $this->idleCursors = $idleCursors; + $this->idleSessions = $idleSessions; + $this->localOps = $localOps; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/DensifyStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/DensifyStage.php new file mode 100644 index 00000000..9ecff7bb --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/DensifyStage.php @@ -0,0 +1,70 @@ + 'field', 'range' => 'range', 'partitionByFields' => 'partitionByFields']; + + /** + * @var string $field The field to densify. The values of the specified field must either be all numeric values or all dates. + * Documents that do not contain the specified field continue through the pipeline unmodified. + * To specify a in an embedded document or in an array, use dot notation. + */ + public readonly string $field; + + /** @var Document|Serializable|array|stdClass $range Specification for range based densification. */ + public readonly Document|Serializable|stdClass|array $range; + + /** @var Optional|BSONArray|PackedArray|array $partitionByFields The field(s) that will be used as the partition keys. */ + public readonly Optional|PackedArray|BSONArray|array $partitionByFields; + + /** + * @param string $field The field to densify. The values of the specified field must either be all numeric values or all dates. + * Documents that do not contain the specified field continue through the pipeline unmodified. + * To specify a in an embedded document or in an array, use dot notation. + * @param Document|Serializable|array|stdClass $range Specification for range based densification. + * @param Optional|BSONArray|PackedArray|array $partitionByFields The field(s) that will be used as the partition keys. + */ + public function __construct( + string $field, + Document|Serializable|stdClass|array $range, + Optional|PackedArray|BSONArray|array $partitionByFields = Optional::Undefined, + ) { + $this->field = $field; + $this->range = $range; + if (is_array($partitionByFields) && ! array_is_list($partitionByFields)) { + throw new InvalidArgumentException('Expected $partitionByFields argument to be a list, got an associative array.'); + } + + $this->partitionByFields = $partitionByFields; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/DocumentsStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/DocumentsStage.php new file mode 100644 index 00000000..c020a9cb --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/DocumentsStage.php @@ -0,0 +1,64 @@ + 'documents']; + + /** + * @var BSONArray|PackedArray|ResolvesToArray|array|string $documents $documents accepts any valid expression that resolves to an array of objects. This includes: + * - system variables, such as $$NOW or $$SEARCH_META + * - $let expressions + * - variables in scope from $lookup expressions + * Expressions that do not resolve to a current document, like $myField or $$ROOT, will result in an error. + */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $documents; + + /** + * @param BSONArray|PackedArray|ResolvesToArray|array|string $documents $documents accepts any valid expression that resolves to an array of objects. This includes: + * - system variables, such as $$NOW or $$SEARCH_META + * - $let expressions + * - variables in scope from $lookup expressions + * Expressions that do not resolve to a current document, like $myField or $$ROOT, will result in an error. + */ + public function __construct(PackedArray|ResolvesToArray|BSONArray|array|string $documents) + { + if (is_string($documents) && ! str_starts_with($documents, '$')) { + throw new InvalidArgumentException('Argument $documents can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + if (is_array($documents) && ! array_is_list($documents)) { + throw new InvalidArgumentException('Expected $documents argument to be a list, got an associative array.'); + } + + $this->documents = $documents; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/FacetStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/FacetStage.php new file mode 100644 index 00000000..6dc36beb --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/FacetStage.php @@ -0,0 +1,55 @@ + 'facet']; + + /** @var stdClass $facet */ + public readonly stdClass $facet; + + /** + * @param BSONArray|PackedArray|Pipeline|array ...$facet + */ + public function __construct(PackedArray|Pipeline|BSONArray|array ...$facet) + { + if (\count($facet) < 1) { + throw new InvalidArgumentException(\sprintf('Expected at least %d values for $facet, got %d.', 1, \count($facet))); + } + + foreach($facet as $key => $value) { + if (! is_string($key)) { + throw new InvalidArgumentException('Expected $facet arguments to be a map (object), named arguments (:) or array unpacking ...[\'\' => ] must be used'); + } + } + + $facet = (object) $facet; + $this->facet = $facet; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/FactoryTrait.php b/vendor/mongodb/mongodb/src/Builder/Stage/FactoryTrait.php new file mode 100644 index 00000000..df5860de --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/FactoryTrait.php @@ -0,0 +1,739 @@ + in an embedded document or in an array, use dot notation. + * @param Document|Serializable|array|stdClass $range Specification for range based densification. + * @param Optional|BSONArray|PackedArray|array $partitionByFields The field(s) that will be used as the partition keys. + */ + public static function densify( + string $field, + Document|Serializable|stdClass|array $range, + Optional|PackedArray|BSONArray|array $partitionByFields = Optional::Undefined, + ): DensifyStage { + return new DensifyStage($field, $range, $partitionByFields); + } + + /** + * Returns literal documents from input values. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/documents/ + * @param BSONArray|PackedArray|ResolvesToArray|array|string $documents $documents accepts any valid expression that resolves to an array of objects. This includes: + * - system variables, such as $$NOW or $$SEARCH_META + * - $let expressions + * - variables in scope from $lookup expressions + * Expressions that do not resolve to a current document, like $myField or $$ROOT, will result in an error. + */ + public static function documents(PackedArray|ResolvesToArray|BSONArray|array|string $documents): DocumentsStage + { + return new DocumentsStage($documents); + } + + /** + * Processes multiple aggregation pipelines within a single stage on the same set of input documents. Enables the creation of multi-faceted aggregations capable of characterizing data across multiple dimensions, or facets, in a single stage. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/facet/ + * @param BSONArray|PackedArray|Pipeline|array ...$facet + */ + public static function facet(PackedArray|Pipeline|BSONArray|array ...$facet): FacetStage + { + return new FacetStage(...$facet); + } + + /** + * Populates null and missing field values within documents. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/fill/ + * @param Document|Serializable|array|stdClass $output Specifies an object containing each field for which to fill missing values. You can specify multiple fields in the output object. + * The object name is the name of the field to fill. The object value specifies how the field is filled. + * @param Optional|Document|Serializable|array|stdClass|string $partitionBy Specifies an expression to group the documents. In the $fill stage, a group of documents is known as a partition. + * If you omit partitionBy and partitionByFields, $fill uses one partition for the entire collection. + * partitionBy and partitionByFields are mutually exclusive. + * @param Optional|BSONArray|PackedArray|array $partitionByFields Specifies an array of fields as the compound key to group the documents. In the $fill stage, each group of documents is known as a partition. + * If you omit partitionBy and partitionByFields, $fill uses one partition for the entire collection. + * partitionBy and partitionByFields are mutually exclusive. + * @param Optional|Document|Serializable|array|stdClass $sortBy Specifies the field or fields to sort the documents within each partition. Uses the same syntax as the $sort stage. + */ + public static function fill( + Document|Serializable|stdClass|array $output, + Optional|Document|Serializable|stdClass|array|string $partitionBy = Optional::Undefined, + Optional|PackedArray|BSONArray|array $partitionByFields = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $sortBy = Optional::Undefined, + ): FillStage { + return new FillStage($output, $partitionBy, $partitionByFields, $sortBy); + } + + /** + * Returns an ordered stream of documents based on the proximity to a geospatial point. Incorporates the functionality of $match, $sort, and $limit for geospatial data. The output documents include an additional distance field and can include a location identifier field. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/geoNear/ + * @param Document|ResolvesToObject|Serializable|array|stdClass|string $near The point for which to find the closest documents. + * @param Optional|string $distanceField The output field that contains the calculated distance. To specify a field within an embedded document, use dot notation. + * @param Optional|Decimal128|Int64|float|int $distanceMultiplier The factor to multiply all distances returned by the query. For example, use the distanceMultiplier to convert radians, as returned by a spherical query, to kilometers by multiplying by the radius of the Earth. + * @param Optional|string $includeLocs This specifies the output field that identifies the location used to calculate the distance. This option is useful when a location field contains multiple locations. To specify a field within an embedded document, use dot notation. + * @param Optional|string $key Specify the geospatial indexed field to use when calculating the distance. + * @param Optional|Decimal128|Int64|float|int $maxDistance The maximum distance from the center point that the documents can be. MongoDB limits the results to those documents that fall within the specified distance from the center point. + * Specify the distance in meters if the specified point is GeoJSON and in radians if the specified point is legacy coordinate pairs. + * @param Optional|Decimal128|Int64|float|int $minDistance The minimum distance from the center point that the documents can be. MongoDB limits the results to those documents that fall outside the specified distance from the center point. + * Specify the distance in meters for GeoJSON data and in radians for legacy coordinate pairs. + * @param Optional|QueryInterface|array $query Limits the results to the documents that match the query. The query syntax is the usual MongoDB read operation query syntax. + * You cannot specify a $near predicate in the query field of the $geoNear stage. + * @param Optional|bool $spherical Determines how MongoDB calculates the distance between two points: + * - When true, MongoDB uses $nearSphere semantics and calculates distances using spherical geometry. + * - When false, MongoDB uses $near semantics: spherical geometry for 2dsphere indexes and planar geometry for 2d indexes. + * Default: false. + */ + public static function geoNear( + Document|Serializable|ResolvesToObject|stdClass|array|string $near, + Optional|string $distanceField = Optional::Undefined, + Optional|Decimal128|Int64|float|int $distanceMultiplier = Optional::Undefined, + Optional|string $includeLocs = Optional::Undefined, + Optional|string $key = Optional::Undefined, + Optional|Decimal128|Int64|float|int $maxDistance = Optional::Undefined, + Optional|Decimal128|Int64|float|int $minDistance = Optional::Undefined, + Optional|QueryInterface|array $query = Optional::Undefined, + Optional|bool $spherical = Optional::Undefined, + ): GeoNearStage { + return new GeoNearStage($near, $distanceField, $distanceMultiplier, $includeLocs, $key, $maxDistance, $minDistance, $query, $spherical); + } + + /** + * Performs a recursive search on a collection. To each output document, adds a new array field that contains the traversal results of the recursive search for that document. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/graphLookup/ + * @param string $from Target collection for the $graphLookup operation to search, recursively matching the connectFromField to the connectToField. The from collection must be in the same database as any other collections used in the operation. + * Starting in MongoDB 5.1, the collection specified in the from parameter can be sharded. + * @param BSONArray|DateTimeInterface|ExpressionInterface|PackedArray|Type|array|bool|float|int|null|stdClass|string $startWith Expression that specifies the value of the connectFromField with which to start the recursive search. Optionally, startWith may be array of values, each of which is individually followed through the traversal process. + * @param string $connectFromField Field name whose value $graphLookup uses to recursively match against the connectToField of other documents in the collection. If the value is an array, each element is individually followed through the traversal process. + * @param string $connectToField Field name in other documents against which to match the value of the field specified by the connectFromField parameter. + * @param string $as Name of the array field added to each output document. Contains the documents traversed in the $graphLookup stage to reach the document. + * @param Optional|int $maxDepth Non-negative integral number specifying the maximum recursion depth. + * @param Optional|string $depthField Name of the field to add to each traversed document in the search path. The value of this field is the recursion depth for the document, represented as a NumberLong. Recursion depth value starts at zero, so the first lookup corresponds to zero depth. + * @param Optional|QueryInterface|array $restrictSearchWithMatch A document specifying additional conditions for the recursive search. The syntax is identical to query filter syntax. + */ + public static function graphLookup( + string $from, + DateTimeInterface|PackedArray|Type|ExpressionInterface|BSONArray|stdClass|array|bool|float|int|null|string $startWith, + string $connectFromField, + string $connectToField, + string $as, + Optional|int $maxDepth = Optional::Undefined, + Optional|string $depthField = Optional::Undefined, + Optional|QueryInterface|array $restrictSearchWithMatch = Optional::Undefined, + ): GraphLookupStage { + return new GraphLookupStage($from, $startWith, $connectFromField, $connectToField, $as, $maxDepth, $depthField, $restrictSearchWithMatch); + } + + /** + * Groups input documents by a specified identifier expression and applies the accumulator expression(s), if specified, to each group. Consumes all input documents and outputs one document per each distinct group. The output documents only contain the identifier field and, if specified, accumulated fields. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/group/ + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $_id The _id expression specifies the group key. If you specify an _id value of null, or any other constant value, the $group stage returns a single document that aggregates values across all of the input documents. + * @param AccumulatorInterface|Document|Serializable|array|stdClass ...$field Computed using the accumulator operators. + */ + public static function group( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $_id, + Document|Serializable|AccumulatorInterface|stdClass|array ...$field, + ): GroupStage { + return new GroupStage($_id, ...$field); + } + + /** + * Returns statistics regarding the use of each index for the collection. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/indexStats/ + */ + public static function indexStats(): IndexStatsStage + { + return new IndexStatsStage(); + } + + /** + * Passes the first n documents unmodified to the pipeline where n is the specified limit. For each input document, outputs either one document (for the first n documents) or zero documents (after the first n documents). + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit/ + * @param int $limit + */ + public static function limit(int $limit): LimitStage + { + return new LimitStage($limit); + } + + /** + * Lists all active sessions recently in use on the currently connected mongos or mongod instance. These sessions may have not yet propagated to the system.sessions collection. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/listLocalSessions/ + * @param Optional|BSONArray|PackedArray|array $users Returns all sessions for the specified users. If running with access control, the authenticated user must have privileges with listSessions action on the cluster to list sessions for other users. + * @param Optional|bool $allUsers Returns all sessions for all users. If running with access control, the authenticated user must have privileges with listSessions action on the cluster. + */ + public static function listLocalSessions( + Optional|PackedArray|BSONArray|array $users = Optional::Undefined, + Optional|bool $allUsers = Optional::Undefined, + ): ListLocalSessionsStage { + return new ListLocalSessionsStage($users, $allUsers); + } + + /** + * Lists sampled queries for all collections or a specific collection. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/listSampledQueries/ + * @param Optional|string $namespace + */ + public static function listSampledQueries( + Optional|string $namespace = Optional::Undefined, + ): ListSampledQueriesStage { + return new ListSampledQueriesStage($namespace); + } + + /** + * Returns information about existing Atlas Search indexes on a specified collection. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/listSearchIndexes/ + * @param Optional|string $id The id of the index to return information about. + * @param Optional|string $name The name of the index to return information about. + */ + public static function listSearchIndexes( + Optional|string $id = Optional::Undefined, + Optional|string $name = Optional::Undefined, + ): ListSearchIndexesStage { + return new ListSearchIndexesStage($id, $name); + } + + /** + * Lists all sessions that have been active long enough to propagate to the system.sessions collection. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/listSessions/ + * @param Optional|BSONArray|PackedArray|array $users Returns all sessions for the specified users. If running with access control, the authenticated user must have privileges with listSessions action on the cluster to list sessions for other users. + * @param Optional|bool $allUsers Returns all sessions for all users. If running with access control, the authenticated user must have privileges with listSessions action on the cluster. + */ + public static function listSessions( + Optional|PackedArray|BSONArray|array $users = Optional::Undefined, + Optional|bool $allUsers = Optional::Undefined, + ): ListSessionsStage { + return new ListSessionsStage($users, $allUsers); + } + + /** + * Performs a left outer join to another collection in the same database to filter in documents from the "joined" collection for processing. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/lookup/ + * @param string $as Specifies the name of the new array field to add to the input documents. The new array field contains the matching documents from the from collection. If the specified name already exists in the input document, the existing field is overwritten. + * @param Optional|string $from Specifies the collection in the same database to perform the join with. + * from is optional, you can use a $documents stage in a $lookup stage instead. For an example, see Use a $documents Stage in a $lookup Stage. + * Starting in MongoDB 5.1, the collection specified in the from parameter can be sharded. + * @param Optional|string $localField Specifies the field from the documents input to the $lookup stage. $lookup performs an equality match on the localField to the foreignField from the documents of the from collection. If an input document does not contain the localField, the $lookup treats the field as having a value of null for matching purposes. + * @param Optional|string $foreignField Specifies the field from the documents in the from collection. $lookup performs an equality match on the foreignField to the localField from the input documents. If a document in the from collection does not contain the foreignField, the $lookup treats the value as null for matching purposes. + * @param Optional|Document|Serializable|array|stdClass $let Specifies variables to use in the pipeline stages. Use the variable expressions to access the fields from the joined collection's documents that are input to the pipeline. + * @param Optional|BSONArray|PackedArray|Pipeline|array $pipeline Specifies the pipeline to run on the joined collection. The pipeline determines the resulting documents from the joined collection. To return all documents, specify an empty pipeline []. + * The pipeline cannot include the $out stage or the $merge stage. Starting in v6.0, the pipeline can contain the Atlas Search $search stage as the first stage inside the pipeline. + * The pipeline cannot directly access the joined document fields. Instead, define variables for the joined document fields using the let option and then reference the variables in the pipeline stages. + */ + public static function lookup( + string $as, + Optional|string $from = Optional::Undefined, + Optional|string $localField = Optional::Undefined, + Optional|string $foreignField = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $let = Optional::Undefined, + Optional|PackedArray|Pipeline|BSONArray|array $pipeline = Optional::Undefined, + ): LookupStage { + return new LookupStage($as, $from, $localField, $foreignField, $let, $pipeline); + } + + /** + * Filters the document stream to allow only matching documents to pass unmodified into the next pipeline stage. $match uses standard MongoDB queries. For each input document, outputs either one document (a match) or zero documents (no match). + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/match/ + * @param QueryInterface|array $query + */ + public static function match(QueryInterface|array $query): MatchStage + { + return new MatchStage($query); + } + + /** + * Writes the resulting documents of the aggregation pipeline to a collection. The stage can incorporate (insert new documents, merge documents, replace documents, keep existing documents, fail the operation, process documents with a custom update pipeline) the results into an output collection. To use the $merge stage, it must be the last stage in the pipeline. + * New in MongoDB 4.2. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/merge/ + * @param Document|Serializable|array|stdClass|string $into The output collection. + * @param Optional|BSONArray|PackedArray|array|string $on Field or fields that act as a unique identifier for a document. The identifier determines if a results document matches an existing document in the output collection. + * @param Optional|Document|Serializable|array|stdClass $let Specifies variables for use in the whenMatched pipeline. + * @param Optional|BSONArray|PackedArray|Pipeline|array|string $whenMatched The behavior of $merge if a result document and an existing document in the collection have the same value for the specified on field(s). + * @param Optional|string $whenNotMatched The behavior of $merge if a result document does not match an existing document in the out collection. + */ + public static function merge( + Document|Serializable|stdClass|array|string $into, + Optional|PackedArray|BSONArray|array|string $on = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $let = Optional::Undefined, + Optional|PackedArray|Pipeline|BSONArray|array|string $whenMatched = Optional::Undefined, + Optional|string $whenNotMatched = Optional::Undefined, + ): MergeStage { + return new MergeStage($into, $on, $let, $whenMatched, $whenNotMatched); + } + + /** + * Writes the resulting documents of the aggregation pipeline to a collection. To use the $out stage, it must be the last stage in the pipeline. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/out/ + * @param Document|Serializable|array|stdClass|string $coll Target database name to write documents from $out to. + */ + public static function out(Document|Serializable|stdClass|array|string $coll): OutStage + { + return new OutStage($coll); + } + + /** + * Returns plan cache information for a collection. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/planCacheStats/ + */ + public static function planCacheStats(): PlanCacheStatsStage + { + return new PlanCacheStatsStage(); + } + + /** + * Reshapes each document in the stream, such as by adding new fields or removing existing fields. For each input document, outputs one document. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/project/ + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string ...$specification + */ + public static function project( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string ...$specification, + ): ProjectStage { + return new ProjectStage(...$specification); + } + + /** + * Reshapes each document in the stream by restricting the content for each document based on information stored in the documents themselves. Incorporates the functionality of $project and $match. Can be used to implement field level redaction. For each input document, outputs either one or zero documents. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/redact/ + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public static function redact( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ): RedactStage { + return new RedactStage($expression); + } + + /** + * Replaces a document with the specified embedded document. The operation replaces all existing fields in the input document, including the _id field. Specify a document embedded in the input document to promote the embedded document to the top level. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/replaceRoot/ + * @param Document|ResolvesToObject|Serializable|array|stdClass|string $newRoot + */ + public static function replaceRoot( + Document|Serializable|ResolvesToObject|stdClass|array|string $newRoot, + ): ReplaceRootStage { + return new ReplaceRootStage($newRoot); + } + + /** + * Replaces a document with the specified embedded document. The operation replaces all existing fields in the input document, including the _id field. Specify a document embedded in the input document to promote the embedded document to the top level. + * Alias for $replaceRoot. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/replaceWith/ + * @param Document|ResolvesToObject|Serializable|array|stdClass|string $expression + */ + public static function replaceWith( + Document|Serializable|ResolvesToObject|stdClass|array|string $expression, + ): ReplaceWithStage { + return new ReplaceWithStage($expression); + } + + /** + * Randomly selects the specified number of documents from its input. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/sample/ + * @param int $size The number of documents to randomly select. + */ + public static function sample(int $size): SampleStage + { + return new SampleStage($size); + } + + /** + * Performs a full-text search of the field or fields in an Atlas collection. + * NOTE: $search is only available for MongoDB Atlas clusters, and is not available for self-managed deployments. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/search/ + * @param Document|SearchOperatorInterface|Serializable|array|stdClass $operator Operator to search with. You can provide a specific operator or use + * the compound operator to run a compound query with multiple operators. + * @param Optional|string $index Name of the Atlas Search index to use. If omitted, defaults to "default". + * @param Optional|Document|Serializable|array|stdClass $highlight Specifies the highlighting options for displaying search terms in their original context. + * @param Optional|bool $concurrent Parallelize search across segments on dedicated search nodes. + * If you don't have separate search nodes on your cluster, + * Atlas Search ignores this flag. If omitted, defaults to false. + * @param Optional|Document|Serializable|array|stdClass $count Document that specifies the count options for retrieving a count of the results. + * @param Optional|string $searchAfter Reference point for retrieving results. searchAfter returns documents starting immediately following the specified reference point. + * @param Optional|string $searchBefore Reference point for retrieving results. searchBefore returns documents starting immediately before the specified reference point. + * @param Optional|bool $scoreDetails Flag that specifies whether to retrieve a detailed breakdown of the score for the documents in the results. If omitted, defaults to false. + * @param Optional|Document|Serializable|array|stdClass $sort Document that specifies the fields to sort the Atlas Search results by in ascending or descending order. + * @param Optional|bool $returnStoredSource Flag that specifies whether to perform a full document lookup on the backend database or return only stored source fields directly from Atlas Search. + * @param Optional|Document|Serializable|array|stdClass $tracking Document that specifies the tracking option to retrieve analytics information on the search terms. + */ + public static function search( + Document|Serializable|SearchOperatorInterface|stdClass|array $operator, + Optional|string $index = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $highlight = Optional::Undefined, + Optional|bool $concurrent = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $count = Optional::Undefined, + Optional|string $searchAfter = Optional::Undefined, + Optional|string $searchBefore = Optional::Undefined, + Optional|bool $scoreDetails = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $sort = Optional::Undefined, + Optional|bool $returnStoredSource = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $tracking = Optional::Undefined, + ): SearchStage { + return new SearchStage($operator, $index, $highlight, $concurrent, $count, $searchAfter, $searchBefore, $scoreDetails, $sort, $returnStoredSource, $tracking); + } + + /** + * Returns different types of metadata result documents for the Atlas Search query against an Atlas collection. + * NOTE: $searchMeta is only available for MongoDB Atlas clusters running MongoDB v4.4.9 or higher, and is not available for self-managed deployments. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/searchMeta/ + * @param Document|SearchOperatorInterface|Serializable|array|stdClass $operator Operator to search with. You can provide a specific operator or use + * the compound operator to run a compound query with multiple operators. + * @param Optional|string $index Name of the Atlas Search index to use. If omitted, defaults to default. + * @param Optional|Document|Serializable|array|stdClass $count Document that specifies the count options for retrieving a count of the results. + */ + public static function searchMeta( + Document|Serializable|SearchOperatorInterface|stdClass|array $operator, + Optional|string $index = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $count = Optional::Undefined, + ): SearchMetaStage { + return new SearchMetaStage($operator, $index, $count); + } + + /** + * Adds new fields to documents. Outputs documents that contain all existing fields from the input documents and newly added fields. + * Alias for $addFields. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/set/ + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string ...$field + */ + public static function set( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string ...$field, + ): SetStage { + return new SetStage(...$field); + } + + /** + * Groups documents into windows and applies one or more operators to the documents in each window. + * New in MongoDB 5.0. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/ + * @param Document|Serializable|array|stdClass $sortBy Specifies the field(s) to sort the documents by in the partition. Uses the same syntax as the $sort stage. Default is no sorting. + * @param Document|Serializable|array|stdClass $output Specifies the field(s) to append to the documents in the output returned by the $setWindowFields stage. Each field is set to the result returned by the window operator. + * A field can contain dots to specify embedded document fields and array fields. The semantics for the embedded document dotted notation in the $setWindowFields stage are the same as the $addFields and $set stages. + * @param Optional|DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $partitionBy Specifies an expression to group the documents. In the $setWindowFields stage, the group of documents is known as a partition. Default is one partition for the entire collection. + */ + public static function setWindowFields( + Document|Serializable|stdClass|array $sortBy, + Document|Serializable|stdClass|array $output, + Optional|DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $partitionBy = Optional::Undefined, + ): SetWindowFieldsStage { + return new SetWindowFieldsStage($sortBy, $output, $partitionBy); + } + + /** + * Provides data and size distribution information on sharded collections. + * New in MongoDB 6.0.3. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/shardedDataDistribution/ + */ + public static function shardedDataDistribution(): ShardedDataDistributionStage + { + return new ShardedDataDistributionStage(); + } + + /** + * Skips the first n documents where n is the specified skip number and passes the remaining documents unmodified to the pipeline. For each input document, outputs either zero documents (for the first n documents) or one document (if after the first n documents). + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/skip/ + * @param int $skip + */ + public static function skip(int $skip): SkipStage + { + return new SkipStage($skip); + } + + /** + * Reorders the document stream by a specified sort key. Only the order changes; the documents remain unmodified. For each input document, outputs one document. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/sort/ + * @param DateTimeInterface|ExpressionInterface|Sort|Type|array|bool|float|int|null|stdClass|string ...$sort + */ + public static function sort( + DateTimeInterface|Type|ExpressionInterface|Sort|stdClass|array|bool|float|int|null|string ...$sort, + ): SortStage { + return new SortStage(...$sort); + } + + /** + * Groups incoming documents based on the value of a specified expression, then computes the count of documents in each distinct group. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/sortByCount/ + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public static function sortByCount( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ): SortByCountStage { + return new SortByCountStage($expression); + } + + /** + * Performs a union of two collections; i.e. combines pipeline results from two collections into a single result set. + * New in MongoDB 4.4. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/unionWith/ + * @param string $coll The collection or view whose pipeline results you wish to include in the result set. + * @param Optional|BSONArray|PackedArray|Pipeline|array $pipeline An aggregation pipeline to apply to the specified coll. + * The pipeline cannot include the $out and $merge stages. Starting in v6.0, the pipeline can contain the Atlas Search $search stage as the first stage inside the pipeline. + */ + public static function unionWith( + string $coll, + Optional|PackedArray|Pipeline|BSONArray|array $pipeline = Optional::Undefined, + ): UnionWithStage { + return new UnionWithStage($coll, $pipeline); + } + + /** + * Removes or excludes fields from documents. + * Alias for $project stage that removes or excludes fields. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/unset/ + * @no-named-arguments + * @param FieldPath|string ...$field + */ + public static function unset(FieldPath|string ...$field): UnsetStage + { + return new UnsetStage(...$field); + } + + /** + * Deconstructs an array field from the input documents to output a document for each element. Each output document replaces the array with an element value. For each input document, outputs n documents where n is the number of array elements and can be zero for an empty array. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/unwind/ + * @param ArrayFieldPath|string $path Field path to an array field. + * @param Optional|string $includeArrayIndex The name of a new field to hold the array index of the element. The name cannot start with a dollar sign $. + * @param Optional|bool $preserveNullAndEmptyArrays If true, if the path is null, missing, or an empty array, $unwind outputs the document. + * If false, if path is null, missing, or an empty array, $unwind does not output a document. + * The default value is false. + */ + public static function unwind( + ArrayFieldPath|string $path, + Optional|string $includeArrayIndex = Optional::Undefined, + Optional|bool $preserveNullAndEmptyArrays = Optional::Undefined, + ): UnwindStage { + return new UnwindStage($path, $includeArrayIndex, $preserveNullAndEmptyArrays); + } + + /** + * The $vectorSearch stage performs an ANN or ENN search on a vector in the specified field. + * + * @see https://www.mongodb.com/docs/atlas/atlas-vector-search/vector-search-stage/ + * @param string $index Name of the Atlas Vector Search index to use. + * @param int $limit Number of documents to return in the results. This value can't exceed the value of numCandidates if you specify numCandidates. + * @param string $path Indexed vector type field to search. + * @param BSONArray|PackedArray|array $queryVector Array of numbers that represent the query vector. The number type must match the indexed field value type. + * @param Optional|bool $exact This is required if numCandidates is omitted. false to run ANN search. true to run ENN search. + * @param Optional|QueryInterface|array $filter Any match query that compares an indexed field with a boolean, date, objectId, number (not decimals), string, or UUID to use as a pre-filter. + * @param Optional|int $numCandidates This field is required if exact is false or omitted. + * Number of nearest neighbors to use during the search. Value must be less than or equal to (<=) 10000. You can't specify a number less than the number of documents to return (limit). + */ + public static function vectorSearch( + string $index, + int $limit, + string $path, + PackedArray|BSONArray|array $queryVector, + Optional|bool $exact = Optional::Undefined, + Optional|QueryInterface|array $filter = Optional::Undefined, + Optional|int $numCandidates = Optional::Undefined, + ): VectorSearchStage { + return new VectorSearchStage($index, $limit, $path, $queryVector, $exact, $filter, $numCandidates); + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/FillStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/FillStage.php new file mode 100644 index 00000000..f7b3b35e --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/FillStage.php @@ -0,0 +1,92 @@ + 'output', + 'partitionBy' => 'partitionBy', + 'partitionByFields' => 'partitionByFields', + 'sortBy' => 'sortBy', + ]; + + /** + * @var Document|Serializable|array|stdClass $output Specifies an object containing each field for which to fill missing values. You can specify multiple fields in the output object. + * The object name is the name of the field to fill. The object value specifies how the field is filled. + */ + public readonly Document|Serializable|stdClass|array $output; + + /** + * @var Optional|Document|Serializable|array|stdClass|string $partitionBy Specifies an expression to group the documents. In the $fill stage, a group of documents is known as a partition. + * If you omit partitionBy and partitionByFields, $fill uses one partition for the entire collection. + * partitionBy and partitionByFields are mutually exclusive. + */ + public readonly Optional|Document|Serializable|stdClass|array|string $partitionBy; + + /** + * @var Optional|BSONArray|PackedArray|array $partitionByFields Specifies an array of fields as the compound key to group the documents. In the $fill stage, each group of documents is known as a partition. + * If you omit partitionBy and partitionByFields, $fill uses one partition for the entire collection. + * partitionBy and partitionByFields are mutually exclusive. + */ + public readonly Optional|PackedArray|BSONArray|array $partitionByFields; + + /** @var Optional|Document|Serializable|array|stdClass $sortBy Specifies the field or fields to sort the documents within each partition. Uses the same syntax as the $sort stage. */ + public readonly Optional|Document|Serializable|stdClass|array $sortBy; + + /** + * @param Document|Serializable|array|stdClass $output Specifies an object containing each field for which to fill missing values. You can specify multiple fields in the output object. + * The object name is the name of the field to fill. The object value specifies how the field is filled. + * @param Optional|Document|Serializable|array|stdClass|string $partitionBy Specifies an expression to group the documents. In the $fill stage, a group of documents is known as a partition. + * If you omit partitionBy and partitionByFields, $fill uses one partition for the entire collection. + * partitionBy and partitionByFields are mutually exclusive. + * @param Optional|BSONArray|PackedArray|array $partitionByFields Specifies an array of fields as the compound key to group the documents. In the $fill stage, each group of documents is known as a partition. + * If you omit partitionBy and partitionByFields, $fill uses one partition for the entire collection. + * partitionBy and partitionByFields are mutually exclusive. + * @param Optional|Document|Serializable|array|stdClass $sortBy Specifies the field or fields to sort the documents within each partition. Uses the same syntax as the $sort stage. + */ + public function __construct( + Document|Serializable|stdClass|array $output, + Optional|Document|Serializable|stdClass|array|string $partitionBy = Optional::Undefined, + Optional|PackedArray|BSONArray|array $partitionByFields = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $sortBy = Optional::Undefined, + ) { + $this->output = $output; + $this->partitionBy = $partitionBy; + if (is_array($partitionByFields) && ! array_is_list($partitionByFields)) { + throw new InvalidArgumentException('Expected $partitionByFields argument to be a list, got an associative array.'); + } + + $this->partitionByFields = $partitionByFields; + $this->sortBy = $sortBy; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/FluentFactoryTrait.php b/vendor/mongodb/mongodb/src/Builder/Stage/FluentFactoryTrait.php new file mode 100644 index 00000000..1b9e542a --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/FluentFactoryTrait.php @@ -0,0 +1,832 @@ +|stdClass> */ + public array $pipeline = []; + + public function getPipeline(): Pipeline + { + return new Pipeline(...$this->pipeline); + } + + /** + * Filters the document stream to allow only matching documents to pass unmodified into the next pipeline stage. $match uses standard MongoDB queries. For each input document, outputs either one document (a match) or zero documents (no match). + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/match/ + * + * @param DateTimeInterface|QueryInterface|FieldQueryInterface|Type|stdClass|array|bool|float|int|string|null ...$queries The query predicates to match + */ + public function match( + DateTimeInterface|QueryInterface|FieldQueryInterface|Type|stdClass|array|string|int|float|bool|null ...$queries, + ): static { + $this->pipeline[] = Stage::match(...$queries); + + return $this; + } + + /** + * Adds new fields to documents. Outputs documents that contain all existing fields from the input documents and newly added fields. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/addFields/ + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string ...$expression Specify the name of each field to add and set its value to an aggregation expression or an empty object. + */ + public function addFields( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|string|int|float|bool|null ...$expression, + ): static { + $this->pipeline[] = Stage::addFields(...$expression); + + return $this; + } + + /** + * Categorizes incoming documents into groups, called buckets, based on a specified expression and bucket boundaries. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/bucket/ + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $groupBy An expression to group documents by. To specify a field path, prefix the field name with a dollar sign $ and enclose it in quotes. + * Unless $bucket includes a default specification, each input document must resolve the groupBy field path or expression to a value that falls within one of the ranges specified by the boundaries. + * @param BSONArray|PackedArray|array $boundaries An array of values based on the groupBy expression that specify the boundaries for each bucket. Each adjacent pair of values acts as the inclusive lower boundary and the exclusive upper boundary for the bucket. You must specify at least two boundaries. + * The specified values must be in ascending order and all of the same type. The exception is if the values are of mixed numeric types, such as: + * @param Optional|DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $default A literal that specifies the _id of an additional bucket that contains all documents whose groupBy expression result does not fall into a bucket specified by boundaries. + * If unspecified, each input document must resolve the groupBy expression to a value within one of the bucket ranges specified by boundaries or the operation throws an error. + * The default value must be less than the lowest boundaries value, or greater than or equal to the highest boundaries value. + * The default value can be of a different type than the entries in boundaries. + * @param Optional|Document|Serializable|array|stdClass $output A document that specifies the fields to include in the output documents in addition to the _id field. To specify the field to include, you must use accumulator expressions. + * If you do not specify an output document, the operation returns a count field containing the number of documents in each bucket. + * If you specify an output document, only the fields specified in the document are returned; i.e. the count field is not returned unless it is explicitly included in the output document. + */ + public function bucket( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|string|int|float|bool|null $groupBy, + PackedArray|BSONArray|array $boundaries, + Optional|DateTimeInterface|Type|ExpressionInterface|stdClass|array|string|int|float|bool|null $default = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $output = Optional::Undefined, + ): static { + $this->pipeline[] = Stage::bucket($groupBy, $boundaries, $default, $output); + + return $this; + } + + /** + * Categorizes incoming documents into a specific number of groups, called buckets, based on a specified expression. Bucket boundaries are automatically determined in an attempt to evenly distribute the documents into the specified number of buckets. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/bucketAuto/ + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $groupBy An expression to group documents by. To specify a field path, prefix the field name with a dollar sign $ and enclose it in quotes. + * @param int $buckets A positive 32-bit integer that specifies the number of buckets into which input documents are grouped. + * @param Optional|Document|Serializable|array|stdClass $output A document that specifies the fields to include in the output documents in addition to the _id field. To specify the field to include, you must use accumulator expressions. + * The default count field is not included in the output document when output is specified. Explicitly specify the count expression as part of the output document to include it. + * @param Optional|string $granularity A string that specifies the preferred number series to use to ensure that the calculated boundary edges end on preferred round numbers or their powers of 10. + * Available only if the all groupBy values are numeric and none of them are NaN. + */ + public function bucketAuto( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|string|int|float|bool|null $groupBy, + int $buckets, + Optional|Document|Serializable|stdClass|array $output = Optional::Undefined, + Optional|string $granularity = Optional::Undefined, + ): static { + $this->pipeline[] = Stage::bucketAuto($groupBy, $buckets, $output, $granularity); + + return $this; + } + + /** + * Returns a Change Stream cursor for the collection or database. This stage can only occur once in an aggregation pipeline and it must occur as the first stage. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/changeStream/ + * @param Optional|bool $allChangesForCluster A flag indicating whether the stream should report all changes that occur on the deployment, aside from those on internal databases or collections. + * @param Optional|string $fullDocument Specifies whether change notifications include a copy of the full document when modified by update operations. + * @param Optional|string $fullDocumentBeforeChange Valid values are "off", "whenAvailable", or "required". If set to "off", the "fullDocumentBeforeChange" field of the output document is always omitted. If set to "whenAvailable", the "fullDocumentBeforeChange" field will be populated with the pre-image of the document modified by the current change event if such a pre-image is available, and will be omitted otherwise. If set to "required", then the "fullDocumentBeforeChange" field is always populated and an exception is thrown if the pre-image is not available. + * @param Optional|int $resumeAfter Specifies a resume token as the logical starting point for the change stream. Cannot be used with startAfter or startAtOperationTime fields. + * @param Optional|bool $showExpandedEvents Specifies whether to include additional change events, such as such as DDL and index operations. + * New in MongoDB 6.0. + * @param Optional|Document|Serializable|array|stdClass $startAfter Specifies a resume token as the logical starting point for the change stream. Cannot be used with resumeAfter or startAtOperationTime fields. + * @param Optional|Timestamp|int $startAtOperationTime Specifies a time as the logical starting point for the change stream. Cannot be used with resumeAfter or startAfter fields. + */ + public function changeStream( + Optional|bool $allChangesForCluster = Optional::Undefined, + Optional|string $fullDocument = Optional::Undefined, + Optional|string $fullDocumentBeforeChange = Optional::Undefined, + Optional|int $resumeAfter = Optional::Undefined, + Optional|bool $showExpandedEvents = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $startAfter = Optional::Undefined, + Optional|Timestamp|int $startAtOperationTime = Optional::Undefined, + ): static { + $this->pipeline[] = Stage::changeStream($allChangesForCluster, $fullDocument, $fullDocumentBeforeChange, $resumeAfter, $showExpandedEvents, $startAfter, $startAtOperationTime); + + return $this; + } + + /** + * Splits large change stream events that exceed 16 MB into smaller fragments returned in a change stream cursor. + * You can only use $changeStreamSplitLargeEvent in a $changeStream pipeline and it must be the final stage in the pipeline. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/changeStreamSplitLargeEvent/ + */ + public function changeStreamSplitLargeEvent(): static + { + $this->pipeline[] = Stage::changeStreamSplitLargeEvent(); + + return $this; + } + + /** + * Returns statistics regarding a collection or view. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/collStats/ + * @param Optional|Document|Serializable|array|stdClass $latencyStats + * @param Optional|Document|Serializable|array|stdClass $storageStats + * @param Optional|Document|Serializable|array|stdClass $count + * @param Optional|Document|Serializable|array|stdClass $queryExecStats + */ + public function collStats( + Optional|Document|Serializable|stdClass|array $latencyStats = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $storageStats = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $count = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $queryExecStats = Optional::Undefined, + ): static { + $this->pipeline[] = Stage::collStats($latencyStats, $storageStats, $count, $queryExecStats); + + return $this; + } + + /** + * Returns a count of the number of documents at this stage of the aggregation pipeline. + * Distinct from the $count aggregation accumulator. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/count/ + * @param string $field Name of the output field which has the count as its value. It must be a non-empty string, must not start with $ and must not contain the . character. + */ + public function count(string $field): static + { + $this->pipeline[] = Stage::count($field); + + return $this; + } + + /** + * Returns information on active and/or dormant operations for the MongoDB deployment. To run, use the db.aggregate() method. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/currentOp/ + * @param Optional|bool $allUsers + * @param Optional|bool $idleConnections + * @param Optional|bool $idleCursors + * @param Optional|bool $idleSessions + * @param Optional|bool $localOps + */ + public function currentOp( + Optional|bool $allUsers = Optional::Undefined, + Optional|bool $idleConnections = Optional::Undefined, + Optional|bool $idleCursors = Optional::Undefined, + Optional|bool $idleSessions = Optional::Undefined, + Optional|bool $localOps = Optional::Undefined, + ): static { + $this->pipeline[] = Stage::currentOp($allUsers, $idleConnections, $idleCursors, $idleSessions, $localOps); + + return $this; + } + + /** + * Creates new documents in a sequence of documents where certain values in a field are missing. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/densify/ + * @param string $field The field to densify. The values of the specified field must either be all numeric values or all dates. + * Documents that do not contain the specified field continue through the pipeline unmodified. + * To specify a in an embedded document or in an array, use dot notation. + * @param Document|Serializable|array|stdClass $range Specification for range based densification. + * @param Optional|BSONArray|PackedArray|array $partitionByFields The field(s) that will be used as the partition keys. + */ + public function densify( + string $field, + Document|Serializable|stdClass|array $range, + Optional|PackedArray|BSONArray|array $partitionByFields = Optional::Undefined, + ): static { + $this->pipeline[] = Stage::densify($field, $range, $partitionByFields); + + return $this; + } + + /** + * Returns literal documents from input values. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/documents/ + * @param BSONArray|PackedArray|ResolvesToArray|array|string $documents $documents accepts any valid expression that resolves to an array of objects. This includes: + * - system variables, such as $$NOW or $$SEARCH_META + * - $let expressions + * - variables in scope from $lookup expressions + * Expressions that do not resolve to a current document, like $myField or $$ROOT, will result in an error. + */ + public function documents(PackedArray|ResolvesToArray|BSONArray|array|string $documents): static + { + $this->pipeline[] = Stage::documents($documents); + + return $this; + } + + /** + * Processes multiple aggregation pipelines within a single stage on the same set of input documents. Enables the creation of multi-faceted aggregations capable of characterizing data across multiple dimensions, or facets, in a single stage. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/facet/ + * @param BSONArray|PackedArray|Pipeline|array ...$facet + */ + public function facet(PackedArray|Pipeline|BSONArray|array ...$facet): static + { + $this->pipeline[] = Stage::facet(...$facet); + + return $this; + } + + /** + * Populates null and missing field values within documents. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/fill/ + * @param Document|Serializable|array|stdClass $output Specifies an object containing each field for which to fill missing values. You can specify multiple fields in the output object. + * The object name is the name of the field to fill. The object value specifies how the field is filled. + * @param Optional|Document|Serializable|array|stdClass|string $partitionBy Specifies an expression to group the documents. In the $fill stage, a group of documents is known as a partition. + * If you omit partitionBy and partitionByFields, $fill uses one partition for the entire collection. + * partitionBy and partitionByFields are mutually exclusive. + * @param Optional|BSONArray|PackedArray|array $partitionByFields Specifies an array of fields as the compound key to group the documents. In the $fill stage, each group of documents is known as a partition. + * If you omit partitionBy and partitionByFields, $fill uses one partition for the entire collection. + * partitionBy and partitionByFields are mutually exclusive. + * @param Optional|Document|Serializable|array|stdClass $sortBy Specifies the field or fields to sort the documents within each partition. Uses the same syntax as the $sort stage. + */ + public function fill( + Document|Serializable|stdClass|array $output, + Optional|Document|Serializable|stdClass|array|string $partitionBy = Optional::Undefined, + Optional|PackedArray|BSONArray|array $partitionByFields = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $sortBy = Optional::Undefined, + ): static { + $this->pipeline[] = Stage::fill($output, $partitionBy, $partitionByFields, $sortBy); + + return $this; + } + + /** + * Returns an ordered stream of documents based on the proximity to a geospatial point. Incorporates the functionality of $match, $sort, and $limit for geospatial data. The output documents include an additional distance field and can include a location identifier field. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/geoNear/ + * @param Document|ResolvesToObject|Serializable|array|stdClass|string $near The point for which to find the closest documents. + * @param Optional|string $distanceField The output field that contains the calculated distance. To specify a field within an embedded document, use dot notation. + * @param Optional|Decimal128|Int64|float|int $distanceMultiplier The factor to multiply all distances returned by the query. For example, use the distanceMultiplier to convert radians, as returned by a spherical query, to kilometers by multiplying by the radius of the Earth. + * @param Optional|string $includeLocs This specifies the output field that identifies the location used to calculate the distance. This option is useful when a location field contains multiple locations. To specify a field within an embedded document, use dot notation. + * @param Optional|string $key Specify the geospatial indexed field to use when calculating the distance. + * @param Optional|Decimal128|Int64|float|int $maxDistance The maximum distance from the center point that the documents can be. MongoDB limits the results to those documents that fall within the specified distance from the center point. + * Specify the distance in meters if the specified point is GeoJSON and in radians if the specified point is legacy coordinate pairs. + * @param Optional|Decimal128|Int64|float|int $minDistance The minimum distance from the center point that the documents can be. MongoDB limits the results to those documents that fall outside the specified distance from the center point. + * Specify the distance in meters for GeoJSON data and in radians for legacy coordinate pairs. + * @param Optional|QueryInterface|array $query Limits the results to the documents that match the query. The query syntax is the usual MongoDB read operation query syntax. + * You cannot specify a $near predicate in the query field of the $geoNear stage. + * @param Optional|bool $spherical Determines how MongoDB calculates the distance between two points: + * - When true, MongoDB uses $nearSphere semantics and calculates distances using spherical geometry. + * - When false, MongoDB uses $near semantics: spherical geometry for 2dsphere indexes and planar geometry for 2d indexes. + * Default: false. + */ + public function geoNear( + Document|Serializable|ResolvesToObject|stdClass|array|string $near, + Optional|string $distanceField = Optional::Undefined, + Optional|Decimal128|Int64|int|float $distanceMultiplier = Optional::Undefined, + Optional|string $includeLocs = Optional::Undefined, + Optional|string $key = Optional::Undefined, + Optional|Decimal128|Int64|int|float $maxDistance = Optional::Undefined, + Optional|Decimal128|Int64|int|float $minDistance = Optional::Undefined, + Optional|QueryInterface|array $query = Optional::Undefined, + Optional|bool $spherical = Optional::Undefined, + ): static { + $this->pipeline[] = Stage::geoNear($near, $distanceField, $distanceMultiplier, $includeLocs, $key, $maxDistance, $minDistance, $query, $spherical); + + return $this; + } + + /** + * Performs a recursive search on a collection. To each output document, adds a new array field that contains the traversal results of the recursive search for that document. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/graphLookup/ + * @param string $from Target collection for the $graphLookup operation to search, recursively matching the connectFromField to the connectToField. The from collection must be in the same database as any other collections used in the operation. + * Starting in MongoDB 5.1, the collection specified in the from parameter can be sharded. + * @param BSONArray|DateTimeInterface|ExpressionInterface|PackedArray|Type|array|bool|float|int|null|stdClass|string $startWith Expression that specifies the value of the connectFromField with which to start the recursive search. Optionally, startWith may be array of values, each of which is individually followed through the traversal process. + * @param string $connectFromField Field name whose value $graphLookup uses to recursively match against the connectToField of other documents in the collection. If the value is an array, each element is individually followed through the traversal process. + * @param string $connectToField Field name in other documents against which to match the value of the field specified by the connectFromField parameter. + * @param string $as Name of the array field added to each output document. Contains the documents traversed in the $graphLookup stage to reach the document. + * @param Optional|int $maxDepth Non-negative integral number specifying the maximum recursion depth. + * @param Optional|string $depthField Name of the field to add to each traversed document in the search path. The value of this field is the recursion depth for the document, represented as a NumberLong. Recursion depth value starts at zero, so the first lookup corresponds to zero depth. + * @param Optional|QueryInterface|array $restrictSearchWithMatch A document specifying additional conditions for the recursive search. The syntax is identical to query filter syntax. + */ + public function graphLookup( + string $from, + DateTimeInterface|PackedArray|Type|ExpressionInterface|BSONArray|stdClass|array|string|int|float|bool|null $startWith, + string $connectFromField, + string $connectToField, + string $as, + Optional|int $maxDepth = Optional::Undefined, + Optional|string $depthField = Optional::Undefined, + Optional|QueryInterface|array $restrictSearchWithMatch = Optional::Undefined, + ): static { + $this->pipeline[] = Stage::graphLookup($from, $startWith, $connectFromField, $connectToField, $as, $maxDepth, $depthField, $restrictSearchWithMatch); + + return $this; + } + + /** + * Groups input documents by a specified identifier expression and applies the accumulator expression(s), if specified, to each group. Consumes all input documents and outputs one document per each distinct group. The output documents only contain the identifier field and, if specified, accumulated fields. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/group/ + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $_id The _id expression specifies the group key. If you specify an _id value of null, or any other constant value, the $group stage returns a single document that aggregates values across all of the input documents. + * @param AccumulatorInterface|Document|Serializable|array|stdClass ...$field Computed using the accumulator operators. + */ + public function group( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|string|int|float|bool|null $_id, + Document|Serializable|AccumulatorInterface|stdClass|array ...$field, + ): static { + $this->pipeline[] = Stage::group($_id, ...$field); + + return $this; + } + + /** + * Returns statistics regarding the use of each index for the collection. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/indexStats/ + */ + public function indexStats(): static + { + $this->pipeline[] = Stage::indexStats(); + + return $this; + } + + /** + * Passes the first n documents unmodified to the pipeline where n is the specified limit. For each input document, outputs either one document (for the first n documents) or zero documents (after the first n documents). + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit/ + * @param int $limit + */ + public function limit(int $limit): static + { + $this->pipeline[] = Stage::limit($limit); + + return $this; + } + + /** + * Lists all active sessions recently in use on the currently connected mongos or mongod instance. These sessions may have not yet propagated to the system.sessions collection. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/listLocalSessions/ + * @param Optional|BSONArray|PackedArray|array $users Returns all sessions for the specified users. If running with access control, the authenticated user must have privileges with listSessions action on the cluster to list sessions for other users. + * @param Optional|bool $allUsers Returns all sessions for all users. If running with access control, the authenticated user must have privileges with listSessions action on the cluster. + */ + public function listLocalSessions( + Optional|PackedArray|BSONArray|array $users = Optional::Undefined, + Optional|bool $allUsers = Optional::Undefined, + ): static { + $this->pipeline[] = Stage::listLocalSessions($users, $allUsers); + + return $this; + } + + /** + * Lists sampled queries for all collections or a specific collection. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/listSampledQueries/ + * @param Optional|string $namespace + */ + public function listSampledQueries(Optional|string $namespace = Optional::Undefined): static + { + $this->pipeline[] = Stage::listSampledQueries($namespace); + + return $this; + } + + /** + * Returns information about existing Atlas Search indexes on a specified collection. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/listSearchIndexes/ + * @param Optional|string $id The id of the index to return information about. + * @param Optional|string $name The name of the index to return information about. + */ + public function listSearchIndexes( + Optional|string $id = Optional::Undefined, + Optional|string $name = Optional::Undefined, + ): static { + $this->pipeline[] = Stage::listSearchIndexes($id, $name); + + return $this; + } + + /** + * Lists all sessions that have been active long enough to propagate to the system.sessions collection. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/listSessions/ + * @param Optional|BSONArray|PackedArray|array $users Returns all sessions for the specified users. If running with access control, the authenticated user must have privileges with listSessions action on the cluster to list sessions for other users. + * @param Optional|bool $allUsers Returns all sessions for all users. If running with access control, the authenticated user must have privileges with listSessions action on the cluster. + */ + public function listSessions( + Optional|PackedArray|BSONArray|array $users = Optional::Undefined, + Optional|bool $allUsers = Optional::Undefined, + ): static { + $this->pipeline[] = Stage::listSessions($users, $allUsers); + + return $this; + } + + /** + * Performs a left outer join to another collection in the same database to filter in documents from the "joined" collection for processing. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/lookup/ + * @param string $as Specifies the name of the new array field to add to the input documents. The new array field contains the matching documents from the from collection. If the specified name already exists in the input document, the existing field is overwritten. + * @param Optional|string $from Specifies the collection in the same database to perform the join with. + * from is optional, you can use a $documents stage in a $lookup stage instead. For an example, see Use a $documents Stage in a $lookup Stage. + * Starting in MongoDB 5.1, the collection specified in the from parameter can be sharded. + * @param Optional|string $localField Specifies the field from the documents input to the $lookup stage. $lookup performs an equality match on the localField to the foreignField from the documents of the from collection. If an input document does not contain the localField, the $lookup treats the field as having a value of null for matching purposes. + * @param Optional|string $foreignField Specifies the field from the documents in the from collection. $lookup performs an equality match on the foreignField to the localField from the input documents. If a document in the from collection does not contain the foreignField, the $lookup treats the value as null for matching purposes. + * @param Optional|Document|Serializable|array|stdClass $let Specifies variables to use in the pipeline stages. Use the variable expressions to access the fields from the joined collection's documents that are input to the pipeline. + * @param Optional|BSONArray|PackedArray|Pipeline|array $pipeline Specifies the pipeline to run on the joined collection. The pipeline determines the resulting documents from the joined collection. To return all documents, specify an empty pipeline []. + * The pipeline cannot include the $out stage or the $merge stage. Starting in v6.0, the pipeline can contain the Atlas Search $search stage as the first stage inside the pipeline. + * The pipeline cannot directly access the joined document fields. Instead, define variables for the joined document fields using the let option and then reference the variables in the pipeline stages. + */ + public function lookup( + string $as, + Optional|string $from = Optional::Undefined, + Optional|string $localField = Optional::Undefined, + Optional|string $foreignField = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $let = Optional::Undefined, + Optional|PackedArray|Pipeline|BSONArray|array $pipeline = Optional::Undefined, + ): static { + $this->pipeline[] = Stage::lookup($as, $from, $localField, $foreignField, $let, $pipeline); + + return $this; + } + + /** + * Writes the resulting documents of the aggregation pipeline to a collection. The stage can incorporate (insert new documents, merge documents, replace documents, keep existing documents, fail the operation, process documents with a custom update pipeline) the results into an output collection. To use the $merge stage, it must be the last stage in the pipeline. + * New in MongoDB 4.2. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/merge/ + * @param Document|Serializable|array|stdClass|string $into The output collection. + * @param Optional|BSONArray|PackedArray|array|string $on Field or fields that act as a unique identifier for a document. The identifier determines if a results document matches an existing document in the output collection. + * @param Optional|Document|Serializable|array|stdClass $let Specifies variables for use in the whenMatched pipeline. + * @param Optional|BSONArray|PackedArray|Pipeline|array|string $whenMatched The behavior of $merge if a result document and an existing document in the collection have the same value for the specified on field(s). + * @param Optional|string $whenNotMatched The behavior of $merge if a result document does not match an existing document in the out collection. + */ + public function merge( + Document|Serializable|stdClass|array|string $into, + Optional|PackedArray|BSONArray|array|string $on = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $let = Optional::Undefined, + Optional|PackedArray|Pipeline|BSONArray|array|string $whenMatched = Optional::Undefined, + Optional|string $whenNotMatched = Optional::Undefined, + ): static { + $this->pipeline[] = Stage::merge($into, $on, $let, $whenMatched, $whenNotMatched); + + return $this; + } + + /** + * Writes the resulting documents of the aggregation pipeline to a collection. To use the $out stage, it must be the last stage in the pipeline. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/out/ + * @param Document|Serializable|array|stdClass|string $coll Target database name to write documents from $out to. + */ + public function out(Document|Serializable|stdClass|array|string $coll): static + { + $this->pipeline[] = Stage::out($coll); + + return $this; + } + + /** + * Returns plan cache information for a collection. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/planCacheStats/ + */ + public function planCacheStats(): static + { + $this->pipeline[] = Stage::planCacheStats(); + + return $this; + } + + /** + * Reshapes each document in the stream, such as by adding new fields or removing existing fields. For each input document, outputs one document. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/project/ + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string ...$specification + */ + public function project( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|string|int|float|bool|null ...$specification, + ): static { + $this->pipeline[] = Stage::project(...$specification); + + return $this; + } + + /** + * Reshapes each document in the stream by restricting the content for each document based on information stored in the documents themselves. Incorporates the functionality of $project and $match. Can be used to implement field level redaction. For each input document, outputs either one or zero documents. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/redact/ + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public function redact( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|string|int|float|bool|null $expression, + ): static { + $this->pipeline[] = Stage::redact($expression); + + return $this; + } + + /** + * Replaces a document with the specified embedded document. The operation replaces all existing fields in the input document, including the _id field. Specify a document embedded in the input document to promote the embedded document to the top level. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/replaceRoot/ + * @param Document|ResolvesToObject|Serializable|array|stdClass|string $newRoot + */ + public function replaceRoot(Document|Serializable|ResolvesToObject|stdClass|array|string $newRoot): static + { + $this->pipeline[] = Stage::replaceRoot($newRoot); + + return $this; + } + + /** + * Replaces a document with the specified embedded document. The operation replaces all existing fields in the input document, including the _id field. Specify a document embedded in the input document to promote the embedded document to the top level. + * Alias for $replaceRoot. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/replaceWith/ + * @param Document|ResolvesToObject|Serializable|array|stdClass|string $expression + */ + public function replaceWith(Document|Serializable|ResolvesToObject|stdClass|array|string $expression): static + { + $this->pipeline[] = Stage::replaceWith($expression); + + return $this; + } + + /** + * Randomly selects the specified number of documents from its input. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/sample/ + * @param int $size The number of documents to randomly select. + */ + public function sample(int $size): static + { + $this->pipeline[] = Stage::sample($size); + + return $this; + } + + /** + * Performs a full-text search of the field or fields in an Atlas collection. + * NOTE: $search is only available for MongoDB Atlas clusters, and is not available for self-managed deployments. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/search/ + * @param Document|SearchOperatorInterface|Serializable|array|stdClass $operator Operator to search with. You can provide a specific operator or use + * the compound operator to run a compound query with multiple operators. + * @param Optional|string $index Name of the Atlas Search index to use. If omitted, defaults to "default". + * @param Optional|Document|Serializable|array|stdClass $highlight Specifies the highlighting options for displaying search terms in their original context. + * @param Optional|bool $concurrent Parallelize search across segments on dedicated search nodes. + * If you don't have separate search nodes on your cluster, + * Atlas Search ignores this flag. If omitted, defaults to false. + * @param Optional|Document|Serializable|array|stdClass $count Document that specifies the count options for retrieving a count of the results. + * @param Optional|string $searchAfter Reference point for retrieving results. searchAfter returns documents starting immediately following the specified reference point. + * @param Optional|string $searchBefore Reference point for retrieving results. searchBefore returns documents starting immediately before the specified reference point. + * @param Optional|bool $scoreDetails Flag that specifies whether to retrieve a detailed breakdown of the score for the documents in the results. If omitted, defaults to false. + * @param Optional|Document|Serializable|array|stdClass $sort Document that specifies the fields to sort the Atlas Search results by in ascending or descending order. + * @param Optional|bool $returnStoredSource Flag that specifies whether to perform a full document lookup on the backend database or return only stored source fields directly from Atlas Search. + * @param Optional|Document|Serializable|array|stdClass $tracking Document that specifies the tracking option to retrieve analytics information on the search terms. + */ + public function search( + Document|Serializable|SearchOperatorInterface|stdClass|array $operator, + Optional|string $index = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $highlight = Optional::Undefined, + Optional|bool $concurrent = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $count = Optional::Undefined, + Optional|string $searchAfter = Optional::Undefined, + Optional|string $searchBefore = Optional::Undefined, + Optional|bool $scoreDetails = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $sort = Optional::Undefined, + Optional|bool $returnStoredSource = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $tracking = Optional::Undefined, + ): static { + $this->pipeline[] = Stage::search($operator, $index, $highlight, $concurrent, $count, $searchAfter, $searchBefore, $scoreDetails, $sort, $returnStoredSource, $tracking); + + return $this; + } + + /** + * Returns different types of metadata result documents for the Atlas Search query against an Atlas collection. + * NOTE: $searchMeta is only available for MongoDB Atlas clusters running MongoDB v4.4.9 or higher, and is not available for self-managed deployments. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/searchMeta/ + * @param Document|SearchOperatorInterface|Serializable|array|stdClass $operator Operator to search with. You can provide a specific operator or use + * the compound operator to run a compound query with multiple operators. + * @param Optional|string $index Name of the Atlas Search index to use. If omitted, defaults to default. + * @param Optional|Document|Serializable|array|stdClass $count Document that specifies the count options for retrieving a count of the results. + */ + public function searchMeta( + Document|Serializable|SearchOperatorInterface|stdClass|array $operator, + Optional|string $index = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $count = Optional::Undefined, + ): static { + $this->pipeline[] = Stage::searchMeta($operator, $index, $count); + + return $this; + } + + /** + * Adds new fields to documents. Outputs documents that contain all existing fields from the input documents and newly added fields. + * Alias for $addFields. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/set/ + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string ...$field + */ + public function set( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|string|int|float|bool|null ...$field, + ): static { + $this->pipeline[] = Stage::set(...$field); + + return $this; + } + + /** + * Groups documents into windows and applies one or more operators to the documents in each window. + * New in MongoDB 5.0. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/ + * @param Document|Serializable|array|stdClass $sortBy Specifies the field(s) to sort the documents by in the partition. Uses the same syntax as the $sort stage. Default is no sorting. + * @param Document|Serializable|array|stdClass $output Specifies the field(s) to append to the documents in the output returned by the $setWindowFields stage. Each field is set to the result returned by the window operator. + * A field can contain dots to specify embedded document fields and array fields. The semantics for the embedded document dotted notation in the $setWindowFields stage are the same as the $addFields and $set stages. + * @param Optional|DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $partitionBy Specifies an expression to group the documents. In the $setWindowFields stage, the group of documents is known as a partition. Default is one partition for the entire collection. + */ + public function setWindowFields( + Document|Serializable|stdClass|array $sortBy, + Document|Serializable|stdClass|array $output, + Optional|DateTimeInterface|Type|ExpressionInterface|stdClass|array|string|int|float|bool|null $partitionBy = Optional::Undefined, + ): static { + $this->pipeline[] = Stage::setWindowFields($sortBy, $output, $partitionBy); + + return $this; + } + + /** + * Provides data and size distribution information on sharded collections. + * New in MongoDB 6.0.3. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/shardedDataDistribution/ + */ + public function shardedDataDistribution(): static + { + $this->pipeline[] = Stage::shardedDataDistribution(); + + return $this; + } + + /** + * Skips the first n documents where n is the specified skip number and passes the remaining documents unmodified to the pipeline. For each input document, outputs either zero documents (for the first n documents) or one document (if after the first n documents). + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/skip/ + * @param int $skip + */ + public function skip(int $skip): static + { + $this->pipeline[] = Stage::skip($skip); + + return $this; + } + + /** + * Reorders the document stream by a specified sort key. Only the order changes; the documents remain unmodified. For each input document, outputs one document. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/sort/ + * @param DateTimeInterface|ExpressionInterface|Sort|Type|array|bool|float|int|null|stdClass|string ...$sort + */ + public function sort( + DateTimeInterface|Type|ExpressionInterface|Sort|stdClass|array|string|int|float|bool|null ...$sort, + ): static { + $this->pipeline[] = Stage::sort(...$sort); + + return $this; + } + + /** + * Groups incoming documents based on the value of a specified expression, then computes the count of documents in each distinct group. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/sortByCount/ + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public function sortByCount( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|string|int|float|bool|null $expression, + ): static { + $this->pipeline[] = Stage::sortByCount($expression); + + return $this; + } + + /** + * Performs a union of two collections; i.e. combines pipeline results from two collections into a single result set. + * New in MongoDB 4.4. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/unionWith/ + * @param string $coll The collection or view whose pipeline results you wish to include in the result set. + * @param Optional|BSONArray|PackedArray|Pipeline|array $pipeline An aggregation pipeline to apply to the specified coll. + * The pipeline cannot include the $out and $merge stages. Starting in v6.0, the pipeline can contain the Atlas Search $search stage as the first stage inside the pipeline. + */ + public function unionWith( + string $coll, + Optional|PackedArray|Pipeline|BSONArray|array $pipeline = Optional::Undefined, + ): static { + $this->pipeline[] = Stage::unionWith($coll, $pipeline); + + return $this; + } + + /** + * Removes or excludes fields from documents. + * Alias for $project stage that removes or excludes fields. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/unset/ + * @no-named-arguments + * @param FieldPath|string ...$field + */ + public function unset(FieldPath|string ...$field): static + { + $this->pipeline[] = Stage::unset(...$field); + + return $this; + } + + /** + * Deconstructs an array field from the input documents to output a document for each element. Each output document replaces the array with an element value. For each input document, outputs n documents where n is the number of array elements and can be zero for an empty array. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/unwind/ + * @param ArrayFieldPath|string $path Field path to an array field. + * @param Optional|string $includeArrayIndex The name of a new field to hold the array index of the element. The name cannot start with a dollar sign $. + * @param Optional|bool $preserveNullAndEmptyArrays If true, if the path is null, missing, or an empty array, $unwind outputs the document. + * If false, if path is null, missing, or an empty array, $unwind does not output a document. + * The default value is false. + */ + public function unwind( + ArrayFieldPath|string $path, + Optional|string $includeArrayIndex = Optional::Undefined, + Optional|bool $preserveNullAndEmptyArrays = Optional::Undefined, + ): static { + $this->pipeline[] = Stage::unwind($path, $includeArrayIndex, $preserveNullAndEmptyArrays); + + return $this; + } + + /** + * The $vectorSearch stage performs an ANN or ENN search on a vector in the specified field. + * + * @see https://www.mongodb.com/docs/atlas/atlas-vector-search/vector-search-stage/ + * @param string $index Name of the Atlas Vector Search index to use. + * @param int $limit Number of documents to return in the results. This value can't exceed the value of numCandidates if you specify numCandidates. + * @param string $path Indexed vector type field to search. + * @param BSONArray|PackedArray|array $queryVector Array of numbers that represent the query vector. The number type must match the indexed field value type. + * @param Optional|bool $exact This is required if numCandidates is omitted. false to run ANN search. true to run ENN search. + * @param Optional|QueryInterface|array $filter Any match query that compares an indexed field with a boolean, date, objectId, number (not decimals), string, or UUID to use as a pre-filter. + * @param Optional|int $numCandidates This field is required if exact is false or omitted. + * Number of nearest neighbors to use during the search. Value must be less than or equal to (<=) 10000. You can't specify a number less than the number of documents to return (limit). + */ + public function vectorSearch( + string $index, + int $limit, + string $path, + PackedArray|BSONArray|array $queryVector, + Optional|bool $exact = Optional::Undefined, + Optional|QueryInterface|array $filter = Optional::Undefined, + Optional|int $numCandidates = Optional::Undefined, + ): static { + $this->pipeline[] = Stage::vectorSearch($index, $limit, $path, $queryVector, $exact, $filter, $numCandidates); + + return $this; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/GeoNearStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/GeoNearStage.php new file mode 100644 index 00000000..21600a5b --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/GeoNearStage.php @@ -0,0 +1,139 @@ + 'near', + 'distanceField' => 'distanceField', + 'distanceMultiplier' => 'distanceMultiplier', + 'includeLocs' => 'includeLocs', + 'key' => 'key', + 'maxDistance' => 'maxDistance', + 'minDistance' => 'minDistance', + 'query' => 'query', + 'spherical' => 'spherical', + ]; + + /** @var Document|ResolvesToObject|Serializable|array|stdClass|string $near The point for which to find the closest documents. */ + public readonly Document|Serializable|ResolvesToObject|stdClass|array|string $near; + + /** @var Optional|string $distanceField The output field that contains the calculated distance. To specify a field within an embedded document, use dot notation. */ + public readonly Optional|string $distanceField; + + /** @var Optional|Decimal128|Int64|float|int $distanceMultiplier The factor to multiply all distances returned by the query. For example, use the distanceMultiplier to convert radians, as returned by a spherical query, to kilometers by multiplying by the radius of the Earth. */ + public readonly Optional|Decimal128|Int64|float|int $distanceMultiplier; + + /** @var Optional|string $includeLocs This specifies the output field that identifies the location used to calculate the distance. This option is useful when a location field contains multiple locations. To specify a field within an embedded document, use dot notation. */ + public readonly Optional|string $includeLocs; + + /** @var Optional|string $key Specify the geospatial indexed field to use when calculating the distance. */ + public readonly Optional|string $key; + + /** + * @var Optional|Decimal128|Int64|float|int $maxDistance The maximum distance from the center point that the documents can be. MongoDB limits the results to those documents that fall within the specified distance from the center point. + * Specify the distance in meters if the specified point is GeoJSON and in radians if the specified point is legacy coordinate pairs. + */ + public readonly Optional|Decimal128|Int64|float|int $maxDistance; + + /** + * @var Optional|Decimal128|Int64|float|int $minDistance The minimum distance from the center point that the documents can be. MongoDB limits the results to those documents that fall outside the specified distance from the center point. + * Specify the distance in meters for GeoJSON data and in radians for legacy coordinate pairs. + */ + public readonly Optional|Decimal128|Int64|float|int $minDistance; + + /** + * @var Optional|QueryInterface|array $query Limits the results to the documents that match the query. The query syntax is the usual MongoDB read operation query syntax. + * You cannot specify a $near predicate in the query field of the $geoNear stage. + */ + public readonly Optional|QueryInterface|array $query; + + /** + * @var Optional|bool $spherical Determines how MongoDB calculates the distance between two points: + * - When true, MongoDB uses $nearSphere semantics and calculates distances using spherical geometry. + * - When false, MongoDB uses $near semantics: spherical geometry for 2dsphere indexes and planar geometry for 2d indexes. + * Default: false. + */ + public readonly Optional|bool $spherical; + + /** + * @param Document|ResolvesToObject|Serializable|array|stdClass|string $near The point for which to find the closest documents. + * @param Optional|string $distanceField The output field that contains the calculated distance. To specify a field within an embedded document, use dot notation. + * @param Optional|Decimal128|Int64|float|int $distanceMultiplier The factor to multiply all distances returned by the query. For example, use the distanceMultiplier to convert radians, as returned by a spherical query, to kilometers by multiplying by the radius of the Earth. + * @param Optional|string $includeLocs This specifies the output field that identifies the location used to calculate the distance. This option is useful when a location field contains multiple locations. To specify a field within an embedded document, use dot notation. + * @param Optional|string $key Specify the geospatial indexed field to use when calculating the distance. + * @param Optional|Decimal128|Int64|float|int $maxDistance The maximum distance from the center point that the documents can be. MongoDB limits the results to those documents that fall within the specified distance from the center point. + * Specify the distance in meters if the specified point is GeoJSON and in radians if the specified point is legacy coordinate pairs. + * @param Optional|Decimal128|Int64|float|int $minDistance The minimum distance from the center point that the documents can be. MongoDB limits the results to those documents that fall outside the specified distance from the center point. + * Specify the distance in meters for GeoJSON data and in radians for legacy coordinate pairs. + * @param Optional|QueryInterface|array $query Limits the results to the documents that match the query. The query syntax is the usual MongoDB read operation query syntax. + * You cannot specify a $near predicate in the query field of the $geoNear stage. + * @param Optional|bool $spherical Determines how MongoDB calculates the distance between two points: + * - When true, MongoDB uses $nearSphere semantics and calculates distances using spherical geometry. + * - When false, MongoDB uses $near semantics: spherical geometry for 2dsphere indexes and planar geometry for 2d indexes. + * Default: false. + */ + public function __construct( + Document|Serializable|ResolvesToObject|stdClass|array|string $near, + Optional|string $distanceField = Optional::Undefined, + Optional|Decimal128|Int64|float|int $distanceMultiplier = Optional::Undefined, + Optional|string $includeLocs = Optional::Undefined, + Optional|string $key = Optional::Undefined, + Optional|Decimal128|Int64|float|int $maxDistance = Optional::Undefined, + Optional|Decimal128|Int64|float|int $minDistance = Optional::Undefined, + Optional|QueryInterface|array $query = Optional::Undefined, + Optional|bool $spherical = Optional::Undefined, + ) { + if (is_string($near) && ! str_starts_with($near, '$')) { + throw new InvalidArgumentException('Argument $near can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->near = $near; + $this->distanceField = $distanceField; + $this->distanceMultiplier = $distanceMultiplier; + $this->includeLocs = $includeLocs; + $this->key = $key; + $this->maxDistance = $maxDistance; + $this->minDistance = $minDistance; + if (is_array($query)) { + $query = QueryObject::create($query); + } + + $this->query = $query; + $this->spherical = $spherical; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/GraphLookupStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/GraphLookupStage.php new file mode 100644 index 00000000..d15b51bd --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/GraphLookupStage.php @@ -0,0 +1,115 @@ + 'from', + 'startWith' => 'startWith', + 'connectFromField' => 'connectFromField', + 'connectToField' => 'connectToField', + 'as' => 'as', + 'maxDepth' => 'maxDepth', + 'depthField' => 'depthField', + 'restrictSearchWithMatch' => 'restrictSearchWithMatch', + ]; + + /** + * @var string $from Target collection for the $graphLookup operation to search, recursively matching the connectFromField to the connectToField. The from collection must be in the same database as any other collections used in the operation. + * Starting in MongoDB 5.1, the collection specified in the from parameter can be sharded. + */ + public readonly string $from; + + /** @var BSONArray|DateTimeInterface|ExpressionInterface|PackedArray|Type|array|bool|float|int|null|stdClass|string $startWith Expression that specifies the value of the connectFromField with which to start the recursive search. Optionally, startWith may be array of values, each of which is individually followed through the traversal process. */ + public readonly DateTimeInterface|PackedArray|Type|ExpressionInterface|BSONArray|stdClass|array|bool|float|int|null|string $startWith; + + /** @var string $connectFromField Field name whose value $graphLookup uses to recursively match against the connectToField of other documents in the collection. If the value is an array, each element is individually followed through the traversal process. */ + public readonly string $connectFromField; + + /** @var string $connectToField Field name in other documents against which to match the value of the field specified by the connectFromField parameter. */ + public readonly string $connectToField; + + /** @var string $as Name of the array field added to each output document. Contains the documents traversed in the $graphLookup stage to reach the document. */ + public readonly string $as; + + /** @var Optional|int $maxDepth Non-negative integral number specifying the maximum recursion depth. */ + public readonly Optional|int $maxDepth; + + /** @var Optional|string $depthField Name of the field to add to each traversed document in the search path. The value of this field is the recursion depth for the document, represented as a NumberLong. Recursion depth value starts at zero, so the first lookup corresponds to zero depth. */ + public readonly Optional|string $depthField; + + /** @var Optional|QueryInterface|array $restrictSearchWithMatch A document specifying additional conditions for the recursive search. The syntax is identical to query filter syntax. */ + public readonly Optional|QueryInterface|array $restrictSearchWithMatch; + + /** + * @param string $from Target collection for the $graphLookup operation to search, recursively matching the connectFromField to the connectToField. The from collection must be in the same database as any other collections used in the operation. + * Starting in MongoDB 5.1, the collection specified in the from parameter can be sharded. + * @param BSONArray|DateTimeInterface|ExpressionInterface|PackedArray|Type|array|bool|float|int|null|stdClass|string $startWith Expression that specifies the value of the connectFromField with which to start the recursive search. Optionally, startWith may be array of values, each of which is individually followed through the traversal process. + * @param string $connectFromField Field name whose value $graphLookup uses to recursively match against the connectToField of other documents in the collection. If the value is an array, each element is individually followed through the traversal process. + * @param string $connectToField Field name in other documents against which to match the value of the field specified by the connectFromField parameter. + * @param string $as Name of the array field added to each output document. Contains the documents traversed in the $graphLookup stage to reach the document. + * @param Optional|int $maxDepth Non-negative integral number specifying the maximum recursion depth. + * @param Optional|string $depthField Name of the field to add to each traversed document in the search path. The value of this field is the recursion depth for the document, represented as a NumberLong. Recursion depth value starts at zero, so the first lookup corresponds to zero depth. + * @param Optional|QueryInterface|array $restrictSearchWithMatch A document specifying additional conditions for the recursive search. The syntax is identical to query filter syntax. + */ + public function __construct( + string $from, + DateTimeInterface|PackedArray|Type|ExpressionInterface|BSONArray|stdClass|array|bool|float|int|null|string $startWith, + string $connectFromField, + string $connectToField, + string $as, + Optional|int $maxDepth = Optional::Undefined, + Optional|string $depthField = Optional::Undefined, + Optional|QueryInterface|array $restrictSearchWithMatch = Optional::Undefined, + ) { + $this->from = $from; + if (is_array($startWith) && ! array_is_list($startWith)) { + throw new InvalidArgumentException('Expected $startWith argument to be a list, got an associative array.'); + } + + $this->startWith = $startWith; + $this->connectFromField = $connectFromField; + $this->connectToField = $connectToField; + $this->as = $as; + $this->maxDepth = $maxDepth; + $this->depthField = $depthField; + if (is_array($restrictSearchWithMatch)) { + $restrictSearchWithMatch = QueryObject::create($restrictSearchWithMatch); + } + + $this->restrictSearchWithMatch = $restrictSearchWithMatch; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/GroupStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/GroupStage.php new file mode 100644 index 00000000..8577b4ad --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/GroupStage.php @@ -0,0 +1,61 @@ + '_id', 'field' => null]; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $_id The _id expression specifies the group key. If you specify an _id value of null, or any other constant value, the $group stage returns a single document that aggregates values across all of the input documents. */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $_id; + + /** @var stdClass $field Computed using the accumulator operators. */ + public readonly stdClass $field; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $_id The _id expression specifies the group key. If you specify an _id value of null, or any other constant value, the $group stage returns a single document that aggregates values across all of the input documents. + * @param AccumulatorInterface|Document|Serializable|array|stdClass ...$field Computed using the accumulator operators. + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $_id, + Document|Serializable|AccumulatorInterface|stdClass|array ...$field, + ) { + $this->_id = $_id; + foreach($field as $key => $value) { + if (! is_string($key)) { + throw new InvalidArgumentException('Expected $field arguments to be a map (object), named arguments (:) or array unpacking ...[\'\' => ] must be used'); + } + } + + $field = (object) $field; + $this->field = $field; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/IndexStatsStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/IndexStatsStage.php new file mode 100644 index 00000000..0baaf8a1 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/IndexStatsStage.php @@ -0,0 +1,29 @@ + 'limit']; + + /** @var int $limit */ + public readonly int $limit; + + /** + * @param int $limit + */ + public function __construct(int $limit) + { + $this->limit = $limit; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/ListLocalSessionsStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/ListLocalSessionsStage.php new file mode 100644 index 00000000..f438b014 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/ListLocalSessionsStage.php @@ -0,0 +1,55 @@ + 'users', 'allUsers' => 'allUsers']; + + /** @var Optional|BSONArray|PackedArray|array $users Returns all sessions for the specified users. If running with access control, the authenticated user must have privileges with listSessions action on the cluster to list sessions for other users. */ + public readonly Optional|PackedArray|BSONArray|array $users; + + /** @var Optional|bool $allUsers Returns all sessions for all users. If running with access control, the authenticated user must have privileges with listSessions action on the cluster. */ + public readonly Optional|bool $allUsers; + + /** + * @param Optional|BSONArray|PackedArray|array $users Returns all sessions for the specified users. If running with access control, the authenticated user must have privileges with listSessions action on the cluster to list sessions for other users. + * @param Optional|bool $allUsers Returns all sessions for all users. If running with access control, the authenticated user must have privileges with listSessions action on the cluster. + */ + public function __construct( + Optional|PackedArray|BSONArray|array $users = Optional::Undefined, + Optional|bool $allUsers = Optional::Undefined, + ) { + if (is_array($users) && ! array_is_list($users)) { + throw new InvalidArgumentException('Expected $users argument to be a list, got an associative array.'); + } + + $this->users = $users; + $this->allUsers = $allUsers; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/ListSampledQueriesStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/ListSampledQueriesStage.php new file mode 100644 index 00000000..afa24259 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/ListSampledQueriesStage.php @@ -0,0 +1,38 @@ + 'namespace']; + + /** @var Optional|string $namespace */ + public readonly Optional|string $namespace; + + /** + * @param Optional|string $namespace + */ + public function __construct(Optional|string $namespace = Optional::Undefined) + { + $this->namespace = $namespace; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/ListSearchIndexesStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/ListSearchIndexesStage.php new file mode 100644 index 00000000..c6643ad3 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/ListSearchIndexesStage.php @@ -0,0 +1,45 @@ + 'id', 'name' => 'name']; + + /** @var Optional|string $id The id of the index to return information about. */ + public readonly Optional|string $id; + + /** @var Optional|string $name The name of the index to return information about. */ + public readonly Optional|string $name; + + /** + * @param Optional|string $id The id of the index to return information about. + * @param Optional|string $name The name of the index to return information about. + */ + public function __construct( + Optional|string $id = Optional::Undefined, + Optional|string $name = Optional::Undefined, + ) { + $this->id = $id; + $this->name = $name; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/ListSessionsStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/ListSessionsStage.php new file mode 100644 index 00000000..687425ce --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/ListSessionsStage.php @@ -0,0 +1,55 @@ + 'users', 'allUsers' => 'allUsers']; + + /** @var Optional|BSONArray|PackedArray|array $users Returns all sessions for the specified users. If running with access control, the authenticated user must have privileges with listSessions action on the cluster to list sessions for other users. */ + public readonly Optional|PackedArray|BSONArray|array $users; + + /** @var Optional|bool $allUsers Returns all sessions for all users. If running with access control, the authenticated user must have privileges with listSessions action on the cluster. */ + public readonly Optional|bool $allUsers; + + /** + * @param Optional|BSONArray|PackedArray|array $users Returns all sessions for the specified users. If running with access control, the authenticated user must have privileges with listSessions action on the cluster to list sessions for other users. + * @param Optional|bool $allUsers Returns all sessions for all users. If running with access control, the authenticated user must have privileges with listSessions action on the cluster. + */ + public function __construct( + Optional|PackedArray|BSONArray|array $users = Optional::Undefined, + Optional|bool $allUsers = Optional::Undefined, + ) { + if (is_array($users) && ! array_is_list($users)) { + throw new InvalidArgumentException('Expected $users argument to be a list, got an associative array.'); + } + + $this->users = $users; + $this->allUsers = $allUsers; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/LookupStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/LookupStage.php new file mode 100644 index 00000000..a9bf0d7e --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/LookupStage.php @@ -0,0 +1,103 @@ + 'as', + 'from' => 'from', + 'localField' => 'localField', + 'foreignField' => 'foreignField', + 'let' => 'let', + 'pipeline' => 'pipeline', + ]; + + /** @var string $as Specifies the name of the new array field to add to the input documents. The new array field contains the matching documents from the from collection. If the specified name already exists in the input document, the existing field is overwritten. */ + public readonly string $as; + + /** + * @var Optional|string $from Specifies the collection in the same database to perform the join with. + * from is optional, you can use a $documents stage in a $lookup stage instead. For an example, see Use a $documents Stage in a $lookup Stage. + * Starting in MongoDB 5.1, the collection specified in the from parameter can be sharded. + */ + public readonly Optional|string $from; + + /** @var Optional|string $localField Specifies the field from the documents input to the $lookup stage. $lookup performs an equality match on the localField to the foreignField from the documents of the from collection. If an input document does not contain the localField, the $lookup treats the field as having a value of null for matching purposes. */ + public readonly Optional|string $localField; + + /** @var Optional|string $foreignField Specifies the field from the documents in the from collection. $lookup performs an equality match on the foreignField to the localField from the input documents. If a document in the from collection does not contain the foreignField, the $lookup treats the value as null for matching purposes. */ + public readonly Optional|string $foreignField; + + /** @var Optional|Document|Serializable|array|stdClass $let Specifies variables to use in the pipeline stages. Use the variable expressions to access the fields from the joined collection's documents that are input to the pipeline. */ + public readonly Optional|Document|Serializable|stdClass|array $let; + + /** + * @var Optional|BSONArray|PackedArray|Pipeline|array $pipeline Specifies the pipeline to run on the joined collection. The pipeline determines the resulting documents from the joined collection. To return all documents, specify an empty pipeline []. + * The pipeline cannot include the $out stage or the $merge stage. Starting in v6.0, the pipeline can contain the Atlas Search $search stage as the first stage inside the pipeline. + * The pipeline cannot directly access the joined document fields. Instead, define variables for the joined document fields using the let option and then reference the variables in the pipeline stages. + */ + public readonly Optional|PackedArray|Pipeline|BSONArray|array $pipeline; + + /** + * @param string $as Specifies the name of the new array field to add to the input documents. The new array field contains the matching documents from the from collection. If the specified name already exists in the input document, the existing field is overwritten. + * @param Optional|string $from Specifies the collection in the same database to perform the join with. + * from is optional, you can use a $documents stage in a $lookup stage instead. For an example, see Use a $documents Stage in a $lookup Stage. + * Starting in MongoDB 5.1, the collection specified in the from parameter can be sharded. + * @param Optional|string $localField Specifies the field from the documents input to the $lookup stage. $lookup performs an equality match on the localField to the foreignField from the documents of the from collection. If an input document does not contain the localField, the $lookup treats the field as having a value of null for matching purposes. + * @param Optional|string $foreignField Specifies the field from the documents in the from collection. $lookup performs an equality match on the foreignField to the localField from the input documents. If a document in the from collection does not contain the foreignField, the $lookup treats the value as null for matching purposes. + * @param Optional|Document|Serializable|array|stdClass $let Specifies variables to use in the pipeline stages. Use the variable expressions to access the fields from the joined collection's documents that are input to the pipeline. + * @param Optional|BSONArray|PackedArray|Pipeline|array $pipeline Specifies the pipeline to run on the joined collection. The pipeline determines the resulting documents from the joined collection. To return all documents, specify an empty pipeline []. + * The pipeline cannot include the $out stage or the $merge stage. Starting in v6.0, the pipeline can contain the Atlas Search $search stage as the first stage inside the pipeline. + * The pipeline cannot directly access the joined document fields. Instead, define variables for the joined document fields using the let option and then reference the variables in the pipeline stages. + */ + public function __construct( + string $as, + Optional|string $from = Optional::Undefined, + Optional|string $localField = Optional::Undefined, + Optional|string $foreignField = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $let = Optional::Undefined, + Optional|PackedArray|Pipeline|BSONArray|array $pipeline = Optional::Undefined, + ) { + $this->as = $as; + $this->from = $from; + $this->localField = $localField; + $this->foreignField = $foreignField; + $this->let = $let; + if (is_array($pipeline) && ! array_is_list($pipeline)) { + throw new InvalidArgumentException('Expected $pipeline argument to be a list, got an associative array.'); + } + + $this->pipeline = $pipeline; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/MatchStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/MatchStage.php new file mode 100644 index 00000000..0c88db2c --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/MatchStage.php @@ -0,0 +1,45 @@ + 'query']; + + /** @var QueryInterface|array $query */ + public readonly QueryInterface|array $query; + + /** + * @param QueryInterface|array $query + */ + public function __construct(QueryInterface|array $query) + { + if (is_array($query)) { + $query = QueryObject::create($query); + } + + $this->query = $query; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/MergeStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/MergeStage.php new file mode 100644 index 00000000..2fc3e94d --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/MergeStage.php @@ -0,0 +1,89 @@ + 'into', + 'on' => 'on', + 'let' => 'let', + 'whenMatched' => 'whenMatched', + 'whenNotMatched' => 'whenNotMatched', + ]; + + /** @var Document|Serializable|array|stdClass|string $into The output collection. */ + public readonly Document|Serializable|stdClass|array|string $into; + + /** @var Optional|BSONArray|PackedArray|array|string $on Field or fields that act as a unique identifier for a document. The identifier determines if a results document matches an existing document in the output collection. */ + public readonly Optional|PackedArray|BSONArray|array|string $on; + + /** @var Optional|Document|Serializable|array|stdClass $let Specifies variables for use in the whenMatched pipeline. */ + public readonly Optional|Document|Serializable|stdClass|array $let; + + /** @var Optional|BSONArray|PackedArray|Pipeline|array|string $whenMatched The behavior of $merge if a result document and an existing document in the collection have the same value for the specified on field(s). */ + public readonly Optional|PackedArray|Pipeline|BSONArray|array|string $whenMatched; + + /** @var Optional|string $whenNotMatched The behavior of $merge if a result document does not match an existing document in the out collection. */ + public readonly Optional|string $whenNotMatched; + + /** + * @param Document|Serializable|array|stdClass|string $into The output collection. + * @param Optional|BSONArray|PackedArray|array|string $on Field or fields that act as a unique identifier for a document. The identifier determines if a results document matches an existing document in the output collection. + * @param Optional|Document|Serializable|array|stdClass $let Specifies variables for use in the whenMatched pipeline. + * @param Optional|BSONArray|PackedArray|Pipeline|array|string $whenMatched The behavior of $merge if a result document and an existing document in the collection have the same value for the specified on field(s). + * @param Optional|string $whenNotMatched The behavior of $merge if a result document does not match an existing document in the out collection. + */ + public function __construct( + Document|Serializable|stdClass|array|string $into, + Optional|PackedArray|BSONArray|array|string $on = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $let = Optional::Undefined, + Optional|PackedArray|Pipeline|BSONArray|array|string $whenMatched = Optional::Undefined, + Optional|string $whenNotMatched = Optional::Undefined, + ) { + $this->into = $into; + if (is_array($on) && ! array_is_list($on)) { + throw new InvalidArgumentException('Expected $on argument to be a list, got an associative array.'); + } + + $this->on = $on; + $this->let = $let; + if (is_array($whenMatched) && ! array_is_list($whenMatched)) { + throw new InvalidArgumentException('Expected $whenMatched argument to be a list, got an associative array.'); + } + + $this->whenMatched = $whenMatched; + $this->whenNotMatched = $whenNotMatched; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/OutStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/OutStage.php new file mode 100644 index 00000000..77959edc --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/OutStage.php @@ -0,0 +1,40 @@ + 'coll']; + + /** @var Document|Serializable|array|stdClass|string $coll Target database name to write documents from $out to. */ + public readonly Document|Serializable|stdClass|array|string $coll; + + /** + * @param Document|Serializable|array|stdClass|string $coll Target database name to write documents from $out to. + */ + public function __construct(Document|Serializable|stdClass|array|string $coll) + { + $this->coll = $coll; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/PlanCacheStatsStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/PlanCacheStatsStage.php new file mode 100644 index 00000000..5cfd7567 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/PlanCacheStatsStage.php @@ -0,0 +1,29 @@ + 'specification']; + + /** @var stdClass $specification */ + public readonly stdClass $specification; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string ...$specification + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string ...$specification, + ) { + if (\count($specification) < 1) { + throw new InvalidArgumentException(\sprintf('Expected at least %d values for $specification, got %d.', 1, \count($specification))); + } + + foreach($specification as $key => $value) { + if (! is_string($key)) { + throw new InvalidArgumentException('Expected $specification arguments to be a map (object), named arguments (:) or array unpacking ...[\'\' => ] must be used'); + } + } + + $specification = (object) $specification; + $this->specification = $specification; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/RedactStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/RedactStage.php new file mode 100644 index 00000000..0da03aba --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/RedactStage.php @@ -0,0 +1,42 @@ + 'expression']; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ) { + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/ReplaceRootStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/ReplaceRootStage.php new file mode 100644 index 00000000..2cf5c34b --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/ReplaceRootStage.php @@ -0,0 +1,49 @@ + 'newRoot']; + + /** @var Document|ResolvesToObject|Serializable|array|stdClass|string $newRoot */ + public readonly Document|Serializable|ResolvesToObject|stdClass|array|string $newRoot; + + /** + * @param Document|ResolvesToObject|Serializable|array|stdClass|string $newRoot + */ + public function __construct(Document|Serializable|ResolvesToObject|stdClass|array|string $newRoot) + { + if (is_string($newRoot) && ! str_starts_with($newRoot, '$')) { + throw new InvalidArgumentException('Argument $newRoot can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->newRoot = $newRoot; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/ReplaceWithStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/ReplaceWithStage.php new file mode 100644 index 00000000..95746bfa --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/ReplaceWithStage.php @@ -0,0 +1,50 @@ + 'expression']; + + /** @var Document|ResolvesToObject|Serializable|array|stdClass|string $expression */ + public readonly Document|Serializable|ResolvesToObject|stdClass|array|string $expression; + + /** + * @param Document|ResolvesToObject|Serializable|array|stdClass|string $expression + */ + public function __construct(Document|Serializable|ResolvesToObject|stdClass|array|string $expression) + { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/SampleStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/SampleStage.php new file mode 100644 index 00000000..c00b2bb2 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/SampleStage.php @@ -0,0 +1,37 @@ + 'size']; + + /** @var int $size The number of documents to randomly select. */ + public readonly int $size; + + /** + * @param int $size The number of documents to randomly select. + */ + public function __construct(int $size) + { + $this->size = $size; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/SearchMetaStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/SearchMetaStage.php new file mode 100644 index 00000000..14687161 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/SearchMetaStage.php @@ -0,0 +1,60 @@ + null, 'index' => 'index', 'count' => 'count']; + + /** + * @var Document|SearchOperatorInterface|Serializable|array|stdClass $operator Operator to search with. You can provide a specific operator or use + * the compound operator to run a compound query with multiple operators. + */ + public readonly Document|Serializable|SearchOperatorInterface|stdClass|array $operator; + + /** @var Optional|string $index Name of the Atlas Search index to use. If omitted, defaults to default. */ + public readonly Optional|string $index; + + /** @var Optional|Document|Serializable|array|stdClass $count Document that specifies the count options for retrieving a count of the results. */ + public readonly Optional|Document|Serializable|stdClass|array $count; + + /** + * @param Document|SearchOperatorInterface|Serializable|array|stdClass $operator Operator to search with. You can provide a specific operator or use + * the compound operator to run a compound query with multiple operators. + * @param Optional|string $index Name of the Atlas Search index to use. If omitted, defaults to default. + * @param Optional|Document|Serializable|array|stdClass $count Document that specifies the count options for retrieving a count of the results. + */ + public function __construct( + Document|Serializable|SearchOperatorInterface|stdClass|array $operator, + Optional|string $index = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $count = Optional::Undefined, + ) { + $this->operator = $operator; + $this->index = $index; + $this->count = $count; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/SearchStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/SearchStage.php new file mode 100644 index 00000000..1aac4a42 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/SearchStage.php @@ -0,0 +1,127 @@ + null, + 'index' => 'index', + 'highlight' => 'highlight', + 'concurrent' => 'concurrent', + 'count' => 'count', + 'searchAfter' => 'searchAfter', + 'searchBefore' => 'searchBefore', + 'scoreDetails' => 'scoreDetails', + 'sort' => 'sort', + 'returnStoredSource' => 'returnStoredSource', + 'tracking' => 'tracking', + ]; + + /** + * @var Document|SearchOperatorInterface|Serializable|array|stdClass $operator Operator to search with. You can provide a specific operator or use + * the compound operator to run a compound query with multiple operators. + */ + public readonly Document|Serializable|SearchOperatorInterface|stdClass|array $operator; + + /** @var Optional|string $index Name of the Atlas Search index to use. If omitted, defaults to "default". */ + public readonly Optional|string $index; + + /** @var Optional|Document|Serializable|array|stdClass $highlight Specifies the highlighting options for displaying search terms in their original context. */ + public readonly Optional|Document|Serializable|stdClass|array $highlight; + + /** + * @var Optional|bool $concurrent Parallelize search across segments on dedicated search nodes. + * If you don't have separate search nodes on your cluster, + * Atlas Search ignores this flag. If omitted, defaults to false. + */ + public readonly Optional|bool $concurrent; + + /** @var Optional|Document|Serializable|array|stdClass $count Document that specifies the count options for retrieving a count of the results. */ + public readonly Optional|Document|Serializable|stdClass|array $count; + + /** @var Optional|string $searchAfter Reference point for retrieving results. searchAfter returns documents starting immediately following the specified reference point. */ + public readonly Optional|string $searchAfter; + + /** @var Optional|string $searchBefore Reference point for retrieving results. searchBefore returns documents starting immediately before the specified reference point. */ + public readonly Optional|string $searchBefore; + + /** @var Optional|bool $scoreDetails Flag that specifies whether to retrieve a detailed breakdown of the score for the documents in the results. If omitted, defaults to false. */ + public readonly Optional|bool $scoreDetails; + + /** @var Optional|Document|Serializable|array|stdClass $sort Document that specifies the fields to sort the Atlas Search results by in ascending or descending order. */ + public readonly Optional|Document|Serializable|stdClass|array $sort; + + /** @var Optional|bool $returnStoredSource Flag that specifies whether to perform a full document lookup on the backend database or return only stored source fields directly from Atlas Search. */ + public readonly Optional|bool $returnStoredSource; + + /** @var Optional|Document|Serializable|array|stdClass $tracking Document that specifies the tracking option to retrieve analytics information on the search terms. */ + public readonly Optional|Document|Serializable|stdClass|array $tracking; + + /** + * @param Document|SearchOperatorInterface|Serializable|array|stdClass $operator Operator to search with. You can provide a specific operator or use + * the compound operator to run a compound query with multiple operators. + * @param Optional|string $index Name of the Atlas Search index to use. If omitted, defaults to "default". + * @param Optional|Document|Serializable|array|stdClass $highlight Specifies the highlighting options for displaying search terms in their original context. + * @param Optional|bool $concurrent Parallelize search across segments on dedicated search nodes. + * If you don't have separate search nodes on your cluster, + * Atlas Search ignores this flag. If omitted, defaults to false. + * @param Optional|Document|Serializable|array|stdClass $count Document that specifies the count options for retrieving a count of the results. + * @param Optional|string $searchAfter Reference point for retrieving results. searchAfter returns documents starting immediately following the specified reference point. + * @param Optional|string $searchBefore Reference point for retrieving results. searchBefore returns documents starting immediately before the specified reference point. + * @param Optional|bool $scoreDetails Flag that specifies whether to retrieve a detailed breakdown of the score for the documents in the results. If omitted, defaults to false. + * @param Optional|Document|Serializable|array|stdClass $sort Document that specifies the fields to sort the Atlas Search results by in ascending or descending order. + * @param Optional|bool $returnStoredSource Flag that specifies whether to perform a full document lookup on the backend database or return only stored source fields directly from Atlas Search. + * @param Optional|Document|Serializable|array|stdClass $tracking Document that specifies the tracking option to retrieve analytics information on the search terms. + */ + public function __construct( + Document|Serializable|SearchOperatorInterface|stdClass|array $operator, + Optional|string $index = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $highlight = Optional::Undefined, + Optional|bool $concurrent = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $count = Optional::Undefined, + Optional|string $searchAfter = Optional::Undefined, + Optional|string $searchBefore = Optional::Undefined, + Optional|bool $scoreDetails = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $sort = Optional::Undefined, + Optional|bool $returnStoredSource = Optional::Undefined, + Optional|Document|Serializable|stdClass|array $tracking = Optional::Undefined, + ) { + $this->operator = $operator; + $this->index = $index; + $this->highlight = $highlight; + $this->concurrent = $concurrent; + $this->count = $count; + $this->searchAfter = $searchAfter; + $this->searchBefore = $searchBefore; + $this->scoreDetails = $scoreDetails; + $this->sort = $sort; + $this->returnStoredSource = $returnStoredSource; + $this->tracking = $tracking; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/SetStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/SetStage.php new file mode 100644 index 00000000..a9c2a53e --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/SetStage.php @@ -0,0 +1,57 @@ + 'field']; + + /** @var stdClass $field */ + public readonly stdClass $field; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string ...$field + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string ...$field, + ) { + if (\count($field) < 1) { + throw new InvalidArgumentException(\sprintf('Expected at least %d values for $field, got %d.', 1, \count($field))); + } + + foreach($field as $key => $value) { + if (! is_string($key)) { + throw new InvalidArgumentException('Expected $field arguments to be a map (object), named arguments (:) or array unpacking ...[\'\' => ] must be used'); + } + } + + $field = (object) $field; + $this->field = $field; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/SetWindowFieldsStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/SetWindowFieldsStage.php new file mode 100644 index 00000000..7d45bc5a --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/SetWindowFieldsStage.php @@ -0,0 +1,62 @@ + 'sortBy', 'output' => 'output', 'partitionBy' => 'partitionBy']; + + /** @var Document|Serializable|array|stdClass $sortBy Specifies the field(s) to sort the documents by in the partition. Uses the same syntax as the $sort stage. Default is no sorting. */ + public readonly Document|Serializable|stdClass|array $sortBy; + + /** + * @var Document|Serializable|array|stdClass $output Specifies the field(s) to append to the documents in the output returned by the $setWindowFields stage. Each field is set to the result returned by the window operator. + * A field can contain dots to specify embedded document fields and array fields. The semantics for the embedded document dotted notation in the $setWindowFields stage are the same as the $addFields and $set stages. + */ + public readonly Document|Serializable|stdClass|array $output; + + /** @var Optional|DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $partitionBy Specifies an expression to group the documents. In the $setWindowFields stage, the group of documents is known as a partition. Default is one partition for the entire collection. */ + public readonly Optional|DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $partitionBy; + + /** + * @param Document|Serializable|array|stdClass $sortBy Specifies the field(s) to sort the documents by in the partition. Uses the same syntax as the $sort stage. Default is no sorting. + * @param Document|Serializable|array|stdClass $output Specifies the field(s) to append to the documents in the output returned by the $setWindowFields stage. Each field is set to the result returned by the window operator. + * A field can contain dots to specify embedded document fields and array fields. The semantics for the embedded document dotted notation in the $setWindowFields stage are the same as the $addFields and $set stages. + * @param Optional|DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $partitionBy Specifies an expression to group the documents. In the $setWindowFields stage, the group of documents is known as a partition. Default is one partition for the entire collection. + */ + public function __construct( + Document|Serializable|stdClass|array $sortBy, + Document|Serializable|stdClass|array $output, + Optional|DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $partitionBy = Optional::Undefined, + ) { + $this->sortBy = $sortBy; + $this->output = $output; + $this->partitionBy = $partitionBy; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/ShardedDataDistributionStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/ShardedDataDistributionStage.php new file mode 100644 index 00000000..fe07d282 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/ShardedDataDistributionStage.php @@ -0,0 +1,30 @@ + 'skip']; + + /** @var int $skip */ + public readonly int $skip; + + /** + * @param int $skip + */ + public function __construct(int $skip) + { + $this->skip = $skip; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/SortByCountStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/SortByCountStage.php new file mode 100644 index 00000000..e616470b --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/SortByCountStage.php @@ -0,0 +1,42 @@ + 'expression']; + + /** @var DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression */ + public readonly DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression; + + /** + * @param DateTimeInterface|ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, + ) { + $this->expression = $expression; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/SortStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/SortStage.php new file mode 100644 index 00000000..fc8899a4 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/SortStage.php @@ -0,0 +1,57 @@ + 'sort']; + + /** @var stdClass $sort */ + public readonly stdClass $sort; + + /** + * @param DateTimeInterface|ExpressionInterface|Sort|Type|array|bool|float|int|null|stdClass|string ...$sort + */ + public function __construct( + DateTimeInterface|Type|ExpressionInterface|Sort|stdClass|array|bool|float|int|null|string ...$sort, + ) { + if (\count($sort) < 1) { + throw new InvalidArgumentException(\sprintf('Expected at least %d values for $sort, got %d.', 1, \count($sort))); + } + + foreach($sort as $key => $value) { + if (! is_string($key)) { + throw new InvalidArgumentException('Expected $sort arguments to be a map (object), named arguments (:) or array unpacking ...[\'\' => ] must be used'); + } + } + + $sort = (object) $sort; + $this->sort = $sort; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/UnionWithStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/UnionWithStage.php new file mode 100644 index 00000000..25ced13d --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/UnionWithStage.php @@ -0,0 +1,61 @@ + 'coll', 'pipeline' => 'pipeline']; + + /** @var string $coll The collection or view whose pipeline results you wish to include in the result set. */ + public readonly string $coll; + + /** + * @var Optional|BSONArray|PackedArray|Pipeline|array $pipeline An aggregation pipeline to apply to the specified coll. + * The pipeline cannot include the $out and $merge stages. Starting in v6.0, the pipeline can contain the Atlas Search $search stage as the first stage inside the pipeline. + */ + public readonly Optional|PackedArray|Pipeline|BSONArray|array $pipeline; + + /** + * @param string $coll The collection or view whose pipeline results you wish to include in the result set. + * @param Optional|BSONArray|PackedArray|Pipeline|array $pipeline An aggregation pipeline to apply to the specified coll. + * The pipeline cannot include the $out and $merge stages. Starting in v6.0, the pipeline can contain the Atlas Search $search stage as the first stage inside the pipeline. + */ + public function __construct( + string $coll, + Optional|PackedArray|Pipeline|BSONArray|array $pipeline = Optional::Undefined, + ) { + $this->coll = $coll; + if (is_array($pipeline) && ! array_is_list($pipeline)) { + throw new InvalidArgumentException('Expected $pipeline argument to be a list, got an associative array.'); + } + + $this->pipeline = $pipeline; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/UnsetStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/UnsetStage.php new file mode 100644 index 00000000..43575d8d --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/UnsetStage.php @@ -0,0 +1,51 @@ + 'field']; + + /** @var list $field */ + public readonly array $field; + + /** + * @param FieldPath|string ...$field + * @no-named-arguments + */ + public function __construct(FieldPath|string ...$field) + { + if (\count($field) < 1) { + throw new InvalidArgumentException(\sprintf('Expected at least %d values for $field, got %d.', 1, \count($field))); + } + + if (! array_is_list($field)) { + throw new InvalidArgumentException('Expected $field arguments to be a list (array), named arguments are not supported'); + } + + $this->field = $field; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/UnwindStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/UnwindStage.php new file mode 100644 index 00000000..9959f462 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/UnwindStage.php @@ -0,0 +1,63 @@ + 'path', + 'includeArrayIndex' => 'includeArrayIndex', + 'preserveNullAndEmptyArrays' => 'preserveNullAndEmptyArrays', + ]; + + /** @var ArrayFieldPath|string $path Field path to an array field. */ + public readonly ArrayFieldPath|string $path; + + /** @var Optional|string $includeArrayIndex The name of a new field to hold the array index of the element. The name cannot start with a dollar sign $. */ + public readonly Optional|string $includeArrayIndex; + + /** + * @var Optional|bool $preserveNullAndEmptyArrays If true, if the path is null, missing, or an empty array, $unwind outputs the document. + * If false, if path is null, missing, or an empty array, $unwind does not output a document. + * The default value is false. + */ + public readonly Optional|bool $preserveNullAndEmptyArrays; + + /** + * @param ArrayFieldPath|string $path Field path to an array field. + * @param Optional|string $includeArrayIndex The name of a new field to hold the array index of the element. The name cannot start with a dollar sign $. + * @param Optional|bool $preserveNullAndEmptyArrays If true, if the path is null, missing, or an empty array, $unwind outputs the document. + * If false, if path is null, missing, or an empty array, $unwind does not output a document. + * The default value is false. + */ + public function __construct( + ArrayFieldPath|string $path, + Optional|string $includeArrayIndex = Optional::Undefined, + Optional|bool $preserveNullAndEmptyArrays = Optional::Undefined, + ) { + $this->path = $path; + $this->includeArrayIndex = $includeArrayIndex; + $this->preserveNullAndEmptyArrays = $preserveNullAndEmptyArrays; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Stage/VectorSearchStage.php b/vendor/mongodb/mongodb/src/Builder/Stage/VectorSearchStage.php new file mode 100644 index 00000000..5a974c74 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Stage/VectorSearchStage.php @@ -0,0 +1,104 @@ + 'index', + 'limit' => 'limit', + 'path' => 'path', + 'queryVector' => 'queryVector', + 'exact' => 'exact', + 'filter' => 'filter', + 'numCandidates' => 'numCandidates', + ]; + + /** @var string $index Name of the Atlas Vector Search index to use. */ + public readonly string $index; + + /** @var int $limit Number of documents to return in the results. This value can't exceed the value of numCandidates if you specify numCandidates. */ + public readonly int $limit; + + /** @var string $path Indexed vector type field to search. */ + public readonly string $path; + + /** @var BSONArray|PackedArray|array $queryVector Array of numbers that represent the query vector. The number type must match the indexed field value type. */ + public readonly PackedArray|BSONArray|array $queryVector; + + /** @var Optional|bool $exact This is required if numCandidates is omitted. false to run ANN search. true to run ENN search. */ + public readonly Optional|bool $exact; + + /** @var Optional|QueryInterface|array $filter Any match query that compares an indexed field with a boolean, date, objectId, number (not decimals), string, or UUID to use as a pre-filter. */ + public readonly Optional|QueryInterface|array $filter; + + /** + * @var Optional|int $numCandidates This field is required if exact is false or omitted. + * Number of nearest neighbors to use during the search. Value must be less than or equal to (<=) 10000. You can't specify a number less than the number of documents to return (limit). + */ + public readonly Optional|int $numCandidates; + + /** + * @param string $index Name of the Atlas Vector Search index to use. + * @param int $limit Number of documents to return in the results. This value can't exceed the value of numCandidates if you specify numCandidates. + * @param string $path Indexed vector type field to search. + * @param BSONArray|PackedArray|array $queryVector Array of numbers that represent the query vector. The number type must match the indexed field value type. + * @param Optional|bool $exact This is required if numCandidates is omitted. false to run ANN search. true to run ENN search. + * @param Optional|QueryInterface|array $filter Any match query that compares an indexed field with a boolean, date, objectId, number (not decimals), string, or UUID to use as a pre-filter. + * @param Optional|int $numCandidates This field is required if exact is false or omitted. + * Number of nearest neighbors to use during the search. Value must be less than or equal to (<=) 10000. You can't specify a number less than the number of documents to return (limit). + */ + public function __construct( + string $index, + int $limit, + string $path, + PackedArray|BSONArray|array $queryVector, + Optional|bool $exact = Optional::Undefined, + Optional|QueryInterface|array $filter = Optional::Undefined, + Optional|int $numCandidates = Optional::Undefined, + ) { + $this->index = $index; + $this->limit = $limit; + $this->path = $path; + if (is_array($queryVector) && ! array_is_list($queryVector)) { + throw new InvalidArgumentException('Expected $queryVector argument to be a list, got an associative array.'); + } + + $this->queryVector = $queryVector; + $this->exact = $exact; + if (is_array($filter)) { + $filter = QueryObject::create($filter); + } + + $this->filter = $filter; + $this->numCandidates = $numCandidates; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Type/AccumulatorInterface.php b/vendor/mongodb/mongodb/src/Builder/Type/AccumulatorInterface.php new file mode 100644 index 00000000..c3aaad2a --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Type/AccumulatorInterface.php @@ -0,0 +1,14 @@ + $fieldQueries */ + public readonly array $fieldQueries; + + /** @param list $fieldQueries */ + public function __construct(array $fieldQueries) + { + if (! array_is_list($fieldQueries)) { + throw new InvalidArgumentException('Expected filters to be a list, invalid array given.'); + } + + // Flatten nested CombinedFieldQuery + $this->fieldQueries = array_reduce( + $fieldQueries, + /** + * @param list $fieldQueries + * + * @return list + */ + static function (array $fieldQueries, QueryInterface|FieldQueryInterface|Type|stdClass|array|bool|float|int|string|null $fieldQuery): array { + if ($fieldQuery instanceof CombinedFieldQuery) { + return array_merge($fieldQueries, $fieldQuery->fieldQueries); + } + + $fieldQueries[] = $fieldQuery; + + return $fieldQueries; + }, + [], + ); + + // Validate FieldQuery types and non-duplicate operators + /** @var array $seenOperators */ + $seenOperators = []; + foreach ($this->fieldQueries as $fieldQuery) { + if ($fieldQuery instanceof stdClass) { + $fieldQuery = get_object_vars($fieldQuery); + } + + if ($fieldQuery instanceof FieldQueryInterface && $fieldQuery instanceof OperatorInterface) { + $operator = $fieldQuery::NAME; + } elseif (is_array($fieldQuery)) { + if (count($fieldQuery) !== 1) { + throw new InvalidArgumentException(sprintf('Operator must contain exactly one key, %d given', count($fieldQuery))); + } + + $operator = array_key_first($fieldQuery); + if (! is_string($operator) || ! str_starts_with($operator, '$')) { + throw new InvalidArgumentException(sprintf('Operator must contain exactly one key starting with $, "%s" given', $operator)); + } + } else { + throw new InvalidArgumentException(sprintf('Expected filters to be a list of field query operators, array or stdClass, %s given', get_debug_type($fieldQuery))); + } + + if (array_key_exists($operator, $seenOperators)) { + throw new InvalidArgumentException(sprintf('Duplicate operator "%s" detected', $operator)); + } + + $seenOperators[$operator] = true; + } + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Type/DictionaryInterface.php b/vendor/mongodb/mongodb/src/Builder/Type/DictionaryInterface.php new file mode 100644 index 00000000..5d88abff --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Type/DictionaryInterface.php @@ -0,0 +1,10 @@ + */ + public const PROPERTIES = []; + + /** @var string|null */ + public const NAME = null; +} diff --git a/vendor/mongodb/mongodb/src/Builder/Type/Optional.php b/vendor/mongodb/mongodb/src/Builder/Type/Optional.php new file mode 100644 index 00000000..f7a4a878 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Type/Optional.php @@ -0,0 +1,17 @@ +|stdClass $operator Window operator to use in the $setWindowFields stage. + * @param Optional|array{string|int,string|int} $documents A window where the lower and upper boundaries are specified relative to the position of the current document read from the collection. + * @param Optional|array{string|numeric,string|numeric} $range Arguments passed to the init function. + * @param Optional|non-empty-string $unit Specifies the units for time range window boundaries. If omitted, default numeric range window boundaries are used. + */ + public function __construct( + Document|Serializable|WindowInterface|stdClass|array $operator, + Optional|array $documents = Optional::Undefined, + Optional|array $range = Optional::Undefined, + Optional|TimeUnit|string $unit = Optional::Undefined, + ) { + $this->operator = $operator; + + $window = null; + if ($documents !== Optional::Undefined) { + if (! array_is_list($documents) || count($documents) !== 2) { + throw new InvalidArgumentException('Expected $documents argument to be a list of 2 string or int'); + } + + if (! is_string($documents[0]) && ! is_int($documents[0]) || ! is_string($documents[1]) && ! is_int($documents[1])) { + throw new InvalidArgumentException(sprintf('Expected $documents argument to be a list of 2 string or int. Got [%s, %s]', get_debug_type($documents[0]), get_debug_type($documents[1]))); + } + + $window = new stdClass(); + $window->documents = $documents; + } + + if ($range !== Optional::Undefined) { + if (! array_is_list($range) || count($range) !== 2) { + throw new InvalidArgumentException('Expected $range argument to be a list of 2 string or numeric'); + } + + if (! is_string($range[0]) && ! is_numeric($range[0]) || ! is_string($range[1]) && ! is_numeric($range[1])) { + throw new InvalidArgumentException(sprintf('Expected $range argument to be a list of 2 string or numeric. Got [%s, %s]', get_debug_type($range[0]), get_debug_type($range[1]))); + } + + $window ??= new stdClass(); + $window->range = $range; + } + + if ($unit !== Optional::Undefined) { + $window ??= new stdClass(); + $window->unit = $unit; + } + + $this->window = $window ?? Optional::Undefined; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Type/QueryInterface.php b/vendor/mongodb/mongodb/src/Builder/Type/QueryInterface.php new file mode 100644 index 00000000..a396d533 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Type/QueryInterface.php @@ -0,0 +1,14 @@ + $queries */ + public static function create(array $queries): QueryInterface + { + // We don't wrap a single query in a QueryObject + if (count($queries) === 1 && isset($queries[0]) && $queries[0] instanceof QueryInterface) { + return $queries[0]; + } + + return new self($queries); + } + + /** @param array $queriesOrArrayOfQueries */ + private function __construct(array $queriesOrArrayOfQueries) + { + // If the first element is an array and not an operator, we assume variadic arguments were not used + if ( + count($queriesOrArrayOfQueries) === 1 && + isset($queriesOrArrayOfQueries[0]) && + is_array($queriesOrArrayOfQueries[0]) && + count($queriesOrArrayOfQueries[0]) > 0 && + ! str_starts_with((string) array_key_first($queriesOrArrayOfQueries[0]), '$') + ) { + $queriesOrArrayOfQueries = $queriesOrArrayOfQueries[0]; + } + + $seenQueryOperators = []; + $queries = []; + + foreach ($queriesOrArrayOfQueries as $fieldPath => $query) { + if ($query instanceof QueryInterface) { + if ($query instanceof OperatorInterface) { + if (isset($seenQueryOperators[$query::NAME])) { + throw new InvalidArgumentException(sprintf('Query operator "%s" cannot be used multiple times in the same query.', $query::NAME)); + } + + $seenQueryOperators[$query::NAME] = true; + } + + $queries[] = $query; + continue; + } + + // Convert list of filters into CombinedFieldQuery + if (self::isListOfFilters($query)) { + if (count($query) === 1) { + $query = $query[0]; + } else { + $query = new CombinedFieldQuery($query); + } + } + + $queries[$fieldPath] = $query; + } + + $this->queries = $queries; + } + + /** @psalm-assert-if-true list $values */ + private static function isListOfFilters(mixed $values): bool + { + if (! is_array($values) || ! array_is_list($values)) { + return false; + } + + /** @var mixed $value */ + foreach ($values as $value) { + if ($value instanceof FieldQueryInterface) { + return true; + } + } + + return false; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Type/SearchOperatorInterface.php b/vendor/mongodb/mongodb/src/Builder/Type/SearchOperatorInterface.php new file mode 100644 index 00000000..c144d4eb --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Type/SearchOperatorInterface.php @@ -0,0 +1,7 @@ + 1, + self::Desc => -1, + self::TextScore => ['$meta' => 'textScore'], + }; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Type/StageInterface.php b/vendor/mongodb/mongodb/src/Builder/Type/StageInterface.php new file mode 100644 index 00000000..6d4fcf2e --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Type/StageInterface.php @@ -0,0 +1,14 @@ +value; + } +} diff --git a/vendor/mongodb/mongodb/src/Builder/Type/WindowInterface.php b/vendor/mongodb/mongodb/src/Builder/Type/WindowInterface.php new file mode 100644 index 00000000..d3fc8c37 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Builder/Type/WindowInterface.php @@ -0,0 +1,14 @@ + is equivalent to $$CURRENT., rebinding + * CURRENT changes the meaning of $ accesses. + */ + public static function current(string $fieldPath = ''): ResolvesToAny + { + return new Expression\Variable('CURRENT' . ($fieldPath ? '.' . $fieldPath : '')); + } + + /** + * One of the allowed results of a $redact expression. + * + * $redact returns the fields at the current document level, excluding embedded documents. To include embedded + * documents and embedded documents within arrays, apply the $cond expression to the embedded documents to determine + * access for these embedded documents. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/redact/#mongodb-pipeline-pipe.-redact + */ + public static function descend(): ExpressionInterface + { + return new Expression\Variable('DESCEND'); + } + + /** + * One of the allowed results of a $redact expression. + * + * $redact returns or keeps all fields at this current document/embedded document level, without further inspection + * of the fields at this level. This applies even if the included field contains embedded documents that may have + * different access levels. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/redact/#mongodb-pipeline-pipe.-redact + */ + public static function keep(): ExpressionInterface + { + return new Expression\Variable('KEEP'); + } + + /** + * A variable that returns the current datetime value. + * NOW returns the same value for all members of the deployment and remains the same throughout all stages of the + * aggregation pipeline. + * + * New in MongoDB 4.2. + */ + public static function now(): ResolvesToDate + { + return new Expression\Variable('NOW'); + } + + /** + * One of the allowed results of a $redact expression. + * + * $redact excludes all fields at this current document/embedded document level, without further inspection of any + * of the excluded fields. This applies even if the excluded field contains embedded documents that may have + * different access levels. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/redact/#mongodb-pipeline-pipe.-redact + */ + public static function prune(): ExpressionInterface + { + return new Expression\Variable('PRUNE'); + } + + /** + * A variable which evaluates to the missing value. Allows for the conditional exclusion of fields. In a $project, + * a field set to the variable REMOVE is excluded from the output. + * Can be used with $cond operator for conditionally exclude fields. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/project/#std-label-remove-example + */ + public static function remove(): ResolvesToAny + { + return new Expression\Variable('REMOVE'); + } + + /** + * References the root document, i.e. the top-level document, currently being processed in the aggregation pipeline + * stage. + */ + public static function root(): ResolvesToObject + { + return new Expression\Variable('ROOT'); + } + + /** + * A variable that stores the metadata results of an Atlas Search query. In all supported aggregation pipeline + * stages, a field set to the variable $$SEARCH_META returns the metadata results for the query. + * For an example of its usage, see Atlas Search facet and count. + * + * @see https://www.mongodb.com/docs/atlas/atlas-search/query-syntax/#metadata-result-types + */ + public static function searchMeta(): ResolvesToObject + { + return new Expression\Variable('SEARCH_META'); + } + + /** + * Returns the roles assigned to the current user. + * For use cases that include USER_ROLES, see the find, aggregation, view, updateOne, updateMany, and findAndModify + * examples. + * + * New in MongoDB 7.0. + */ + public static function userRoles(): ResolvesToArray + { + return new Expression\Variable('USER_ROLES'); + } + + /** + * User-defined variable that can be used to store any BSON type. + * + * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/let/ + */ + public static function variable(string $name): Expression\Variable + { + return new Expression\Variable($name); + } + + private function __construct() + { + // This class cannot be instantiated + } +} diff --git a/vendor/mongodb/mongodb/src/BulkWriteResult.php b/vendor/mongodb/mongodb/src/BulkWriteResult.php new file mode 100644 index 00000000..4fb556e0 --- /dev/null +++ b/vendor/mongodb/mongodb/src/BulkWriteResult.php @@ -0,0 +1,179 @@ +isAcknowledged = $writeResult->isAcknowledged(); + } + + /** + * Return the number of documents that were deleted. + * + * This method should only be called if the write was acknowledged. + * + * @see BulkWriteResult::isAcknowledged() + * @return integer|null + * @throws BadMethodCallException if the write result is unacknowledged + */ + public function getDeletedCount() + { + if ($this->isAcknowledged) { + return $this->writeResult->getDeletedCount(); + } + + throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__); + } + + /** + * Return the number of documents that were inserted. + * + * This method should only be called if the write was acknowledged. + * + * @see BulkWriteResult::isAcknowledged() + * @return integer|null + * @throws BadMethodCallException if the write result is unacknowledged + */ + public function getInsertedCount() + { + if ($this->isAcknowledged) { + return $this->writeResult->getInsertedCount(); + } + + throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__); + } + + /** + * Return a map of the inserted documents' IDs. + * + * The index of each ID in the map corresponds to each document's position + * in the bulk operation. If a document had an ID prior to inserting (i.e. + * the driver did not generate an ID), the index will contain its "_id" + * field value. Any driver-generated ID will be a MongoDB\BSON\ObjectId + * instance. + * + * @return array + */ + public function getInsertedIds() + { + return $this->insertedIds; + } + + /** + * Return the number of documents that were matched by the filter. + * + * This method should only be called if the write was acknowledged. + * + * @see BulkWriteResult::isAcknowledged() + * @return integer|null + * @throws BadMethodCallException if the write result is unacknowledged + */ + public function getMatchedCount() + { + if ($this->isAcknowledged) { + return $this->writeResult->getMatchedCount(); + } + + throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__); + } + + /** + * Return the number of documents that were modified. + * + * This value is undefined (i.e. null) if the write executed as a legacy + * operation instead of command. + * + * This method should only be called if the write was acknowledged. + * + * @see BulkWriteResult::isAcknowledged() + * @return integer|null + * @throws BadMethodCallException if the write result is unacknowledged + */ + public function getModifiedCount() + { + if ($this->isAcknowledged) { + return $this->writeResult->getModifiedCount(); + } + + throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__); + } + + /** + * Return the number of documents that were upserted. + * + * This method should only be called if the write was acknowledged. + * + * @see BulkWriteResult::isAcknowledged() + * @return integer|null + * @throws BadMethodCallException if the write result is unacknowledged + */ + public function getUpsertedCount() + { + if ($this->isAcknowledged) { + return $this->writeResult->getUpsertedCount(); + } + + throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__); + } + + /** + * Return a map of the upserted documents' IDs. + * + * The index of each ID in the map corresponds to each document's position + * in bulk operation. If a document had an ID prior to upserting (i.e. the + * server did not need to generate an ID), this will contain its "_id". Any + * server-generated ID will be a MongoDB\BSON\ObjectId instance. + * + * This method should only be called if the write was acknowledged. + * + * @see BulkWriteResult::isAcknowledged() + * @return array + * @throws BadMethodCallException if the write result is unacknowledged + */ + public function getUpsertedIds() + { + if ($this->isAcknowledged) { + return $this->writeResult->getUpsertedIds(); + } + + throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__); + } + + /** + * Return whether this update was acknowledged by the server. + * + * If the update was not acknowledged, other fields from the WriteResult + * (e.g. matchedCount) will be undefined. + * + * @return boolean + */ + public function isAcknowledged() + { + return $this->isAcknowledged; + } +} diff --git a/vendor/mongodb/mongodb/src/ChangeStream.php b/vendor/mongodb/mongodb/src/ChangeStream.php new file mode 100644 index 00000000..55f25b03 --- /dev/null +++ b/vendor/mongodb/mongodb/src/ChangeStream.php @@ -0,0 +1,310 @@ + + */ +class ChangeStream implements Iterator +{ + /** + * @deprecated 1.4 + * @todo make this constant private in 2.0 (see: PHPLIB-360) + */ + public const CURSOR_NOT_FOUND = 43; + + private const RESUMABLE_ERROR_CODES = [ + 6, // HostUnreachable + 7, // HostNotFound + 89, // NetworkTimeout + 91, // ShutdownInProgress + 189, // PrimarySteppedDown + 262, // ExceededTimeLimit + 9001, // SocketException + 10107, // NotPrimary + 11600, // InterruptedAtShutdown + 11602, // InterruptedDueToReplStateChange + 13435, // NotPrimaryNoSecondaryOk + 13436, // NotPrimaryOrSecondary + 63, // StaleShardVersion + 150, // StaleEpoch + 13388, // StaleConfig + 234, // RetryChangeStream + 133, // FailedToSatisfyReadPreference + ]; + + private const WIRE_VERSION_FOR_RESUMABLE_CHANGE_STREAM_ERROR = 9; + + /** @var ResumeCallable|null */ + private $resumeCallable; + + private int $key = 0; + + /** + * Whether the change stream has advanced to its first result. This is used + * to determine whether $key should be incremented after an iteration event. + */ + private bool $hasAdvanced = false; + + /** + * @see https://php.net/iterator.current + * @return array|object|null + */ + #[ReturnTypeWillChange] + public function current() + { + $value = $this->iterator->current(); + + if (! $this->codec) { + return $value; + } + + assert($value instanceof Document); + + return $this->codec->decode($value); + } + + /** + * @return CursorId|Int64 + * @psalm-return ($asInt64 is true ? Int64 : CursorId) + */ + #[ReturnTypeWillChange] + public function getCursorId(bool $asInt64 = false) + { + if (! $asInt64) { + @trigger_error( + sprintf( + 'The method "%s" will no longer return a "%s" instance in the future. Pass "true" as argument to change to the new behavior and receive a "%s" instance instead.', + __METHOD__, + CursorId::class, + Int64::class, + ), + E_USER_DEPRECATED, + ); + } + + return $this->iterator->getInnerIterator()->getId($asInt64); + } + + /** + * Returns the resume token for the iterator's current position. + * + * Null may be returned if no change documents have been iterated and the + * server did not include a postBatchResumeToken in its aggregate or getMore + * command response. + * + * @return array|object|null + */ + public function getResumeToken() + { + return $this->iterator->getResumeToken(); + } + + /** + * @see https://php.net/iterator.key + * @return int|null + */ + #[ReturnTypeWillChange] + public function key() + { + if ($this->valid()) { + return $this->key; + } + + return null; + } + + /** + * @see https://php.net/iterator.next + * @return void + * @throws ResumeTokenException + */ + #[ReturnTypeWillChange] + public function next() + { + try { + $this->iterator->next(); + $this->onIteration($this->hasAdvanced); + } catch (RuntimeException $e) { + $this->resumeOrThrow($e); + } + } + + /** + * @see https://php.net/iterator.rewind + * @return void + * @throws ResumeTokenException + */ + #[ReturnTypeWillChange] + public function rewind() + { + try { + $this->iterator->rewind(); + /* Unlike next() and resume(), the decision to increment the key + * does not depend on whether the change stream has advanced. This + * ensures that multiple calls to rewind() do not alter state. */ + $this->onIteration(false); + } catch (RuntimeException $e) { + $this->resumeOrThrow($e); + } + } + + /** + * @see https://php.net/iterator.valid + * @return boolean + */ + #[ReturnTypeWillChange] + public function valid() + { + return $this->iterator->valid(); + } + + /** + * @internal + * + * @param ResumeCallable $resumeCallable + */ + public function __construct(private ChangeStreamIterator $iterator, callable $resumeCallable, private ?DocumentCodec $codec = null) + { + $this->resumeCallable = $resumeCallable; + + if ($codec) { + $this->iterator->getInnerIterator()->setTypeMap(['root' => 'bson']); + } + } + + /** + * Determines if an exception is a resumable error. + * + * @see https://github.com/mongodb/specifications/blob/master/source/change-streams/change-streams.rst#resumable-error + */ + private function isResumableError(RuntimeException $exception): bool + { + if ($exception instanceof ConnectionException) { + return true; + } + + if (! $exception instanceof ServerException) { + return false; + } + + if ($exception->getCode() === self::CURSOR_NOT_FOUND) { + return true; + } + + if (server_supports_feature($this->iterator->getServer(), self::WIRE_VERSION_FOR_RESUMABLE_CHANGE_STREAM_ERROR)) { + return $exception->hasErrorLabel('ResumableChangeStreamError'); + } + + return in_array($exception->getCode(), self::RESUMABLE_ERROR_CODES); + } + + /** + * Perform housekeeping after an iteration event. + * + * @param boolean $incrementKey Increment $key if there is a current result + * @throws ResumeTokenException + */ + private function onIteration(bool $incrementKey): void + { + /* If the cursorId is 0, the server has invalidated the cursor and we + * will never perform another getMore nor need to resume since any + * remaining results (up to and including the invalidate event) will + * have been received in the last response. Therefore, we can unset the + * resumeCallable. This will free any reference to Watch as well as the + * only reference to any implicit session created therein. */ + if ((string) $this->getCursorId(true) === '0') { + $this->resumeCallable = null; + } + + /* Return early if there is not a current result. Avoid any attempt to + * increment the iterator's key. */ + if (! $this->valid()) { + return; + } + + if ($incrementKey) { + $this->key++; + } + + $this->hasAdvanced = true; + } + + /** + * Recreates the ChangeStreamIterator after a resumable server error. + */ + private function resume(): void + { + if ($this->resumeCallable === null) { + throw new BadMethodCallException('Cannot resume a closed change stream.'); + } + + $this->iterator = call_user_func($this->resumeCallable, $this->getResumeToken(), $this->hasAdvanced); + + $this->iterator->rewind(); + + if ($this->codec) { + $this->iterator->getInnerIterator()->setTypeMap(['root' => 'bson']); + } + + $this->onIteration($this->hasAdvanced); + } + + /** + * Either resumes after a resumable error or re-throws the exception. + * + * @throws RuntimeException + */ + private function resumeOrThrow(RuntimeException $exception): void + { + if ($this->isResumableError($exception)) { + $this->resume(); + + return; + } + + throw $exception; + } +} diff --git a/vendor/mongodb/mongodb/src/Client.php b/vendor/mongodb/mongodb/src/Client.php new file mode 100644 index 00000000..32d064f6 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Client.php @@ -0,0 +1,495 @@ + BSONArray::class, + 'document' => BSONDocument::class, + 'root' => BSONDocument::class, + ]; + + private const HANDSHAKE_SEPARATOR = '/'; + + private static ?string $version = null; + + private Manager $manager; + + private ReadConcern $readConcern; + + private ReadPreference $readPreference; + + private string $uri; + + private array $typeMap; + + /** @psalm-var Encoder */ + private readonly Encoder $builderEncoder; + + private WriteConcern $writeConcern; + + /** + * Constructs a new Client instance. + * + * This is the preferred class for connecting to a MongoDB server or + * cluster of servers. It serves as a gateway for accessing individual + * databases and collections. + * + * Supported driver-specific options: + * + * * builderEncoder (MongoDB\Codec\Encoder): Encoder for query and + * aggregation builders. If not given, the default encoder will be used. + * + * * typeMap (array): Default type map for cursors and BSON documents. + * + * Other options are documented in MongoDB\Driver\Manager::__construct(). + * + * @see https://mongodb.com/docs/manual/reference/connection-string/ + * @see https://php.net/manual/en/mongodb-driver-manager.construct.php + * @see https://php.net/manual/en/mongodb.persistence.php#mongodb.persistence.typemaps + * @param string|null $uri MongoDB connection string. If none is provided, this defaults to self::DEFAULT_URI. + * @param array $uriOptions Additional connection string options + * @param array $driverOptions Driver-specific options + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverInvalidArgumentException for parameter/option parsing errors in the driver + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function __construct(?string $uri = null, array $uriOptions = [], array $driverOptions = []) + { + $driverOptions += ['typeMap' => self::DEFAULT_TYPE_MAP]; + + if (! is_array($driverOptions['typeMap'])) { + throw InvalidArgumentException::invalidType('"typeMap" driver option', $driverOptions['typeMap'], 'array'); + } + + if (isset($driverOptions['autoEncryption']['keyVaultClient'])) { + if ($driverOptions['autoEncryption']['keyVaultClient'] instanceof self) { + $driverOptions['autoEncryption']['keyVaultClient'] = $driverOptions['autoEncryption']['keyVaultClient']->manager; + } elseif (! $driverOptions['autoEncryption']['keyVaultClient'] instanceof Manager) { + throw InvalidArgumentException::invalidType('"keyVaultClient" autoEncryption option', $driverOptions['autoEncryption']['keyVaultClient'], [self::class, Manager::class]); + } + } + + if (isset($driverOptions['builderEncoder']) && ! $driverOptions['builderEncoder'] instanceof Encoder) { + throw InvalidArgumentException::invalidType('"builderEncoder" option', $driverOptions['builderEncoder'], Encoder::class); + } + + $driverOptions['driver'] = $this->mergeDriverInfo($driverOptions['driver'] ?? []); + + $this->uri = $uri ?? self::DEFAULT_URI; + $this->builderEncoder = $driverOptions['builderEncoder'] ?? new BuilderEncoder(); + $this->typeMap = $driverOptions['typeMap']; + + $driverOptions = array_diff_key($driverOptions, ['builderEncoder' => 1, 'typeMap' => 1]); + + $this->manager = new Manager($uri, $uriOptions, $driverOptions); + $this->readConcern = $this->manager->getReadConcern(); + $this->readPreference = $this->manager->getReadPreference(); + $this->writeConcern = $this->manager->getWriteConcern(); + } + + /** + * Return internal properties for debugging purposes. + * + * @see https://php.net/manual/en/language.oop5.magic.php#language.oop5.magic.debuginfo + * @return array + */ + public function __debugInfo() + { + return [ + 'manager' => $this->manager, + 'uri' => $this->uri, + 'typeMap' => $this->typeMap, + 'builderEncoder' => $this->builderEncoder, + 'writeConcern' => $this->writeConcern, + ]; + } + + /** + * Select a database. + * + * Note: databases whose names contain special characters (e.g. "-") may + * be selected with complex syntax (e.g. $client->{"that-database"}) or + * {@link selectDatabase()}. + * + * @see https://php.net/oop5.overloading#object.get + * @see https://php.net/types.string#language.types.string.parsing.complex + * @param string $databaseName Name of the database to select + * @return Database + */ + public function __get(string $databaseName) + { + return $this->getDatabase($databaseName); + } + + /** + * Return the connection string (i.e. URI). + * + * @return string + */ + public function __toString() + { + return $this->uri; + } + + /** + * Registers a monitoring event subscriber with this Client's Manager + * + * @see Manager::addSubscriber() + */ + final public function addSubscriber(Subscriber $subscriber): void + { + $this->manager->addSubscriber($subscriber); + } + + /** + * Returns a ClientEncryption instance for explicit encryption and decryption + * + * @param array $options Encryption options + * + * @return ClientEncryption + */ + public function createClientEncryption(array $options) + { + if (isset($options['keyVaultClient'])) { + if ($options['keyVaultClient'] instanceof self) { + $options['keyVaultClient'] = $options['keyVaultClient']->manager; + } elseif (! $options['keyVaultClient'] instanceof Manager) { + throw InvalidArgumentException::invalidType('"keyVaultClient" option', $options['keyVaultClient'], [self::class, Manager::class]); + } + } + + return $this->manager->createClientEncryption($options); + } + + /** + * Drop a database. + * + * @see DropDatabase::__construct() for supported options + * @param string $databaseName Database name + * @param array $options Additional options + * @return array|object Command result document + * @throws UnsupportedException if options are unsupported on the selected server + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function dropDatabase(string $databaseName, array $options = []) + { + if (! isset($options['typeMap'])) { + $options['typeMap'] = $this->typeMap; + } else { + @trigger_error(sprintf('The function %s() will return nothing in mongodb/mongodb v2.0, the "typeMap" option is deprecated', __FUNCTION__), E_USER_DEPRECATED); + } + + $server = select_server_for_write($this->manager, $options); + + if (! isset($options['writeConcern']) && ! is_in_transaction($options)) { + $options['writeConcern'] = $this->writeConcern; + } + + $operation = new DropDatabase($databaseName, $options); + + return $operation->execute($server); + } + + /** + * Returns a collection instance. + * + * If the collection does not exist in the database, it is not created when + * invoking this method. + * + * @see Collection::__construct() for supported options + * @throws InvalidArgumentException for parameter/option parsing errors + */ + public function getCollection(string $databaseName, string $collectionName, array $options = []): Collection + { + $options += ['typeMap' => $this->typeMap, 'builderEncoder' => $this->builderEncoder]; + + return new Collection($this->manager, $databaseName, $collectionName, $options); + } + + /** + * Returns a database instance. + * + * If the database does not exist on the server, it is not created when + * invoking this method. + * + * @see Database::__construct() for supported options + */ + public function getDatabase(string $databaseName, array $options = []): Database + { + $options += ['typeMap' => $this->typeMap, 'builderEncoder' => $this->builderEncoder]; + + return new Database($this->manager, $databaseName, $options); + } + + /** + * Return the Manager. + * + * @return Manager + */ + public function getManager() + { + return $this->manager; + } + + /** + * Return the read concern for this client. + * + * @see https://php.net/manual/en/mongodb-driver-readconcern.isdefault.php + * @return ReadConcern + */ + public function getReadConcern() + { + return $this->readConcern; + } + + /** + * Return the read preference for this client. + * + * @return ReadPreference + */ + public function getReadPreference() + { + return $this->readPreference; + } + + /** + * Return the type map for this client. + * + * @return array + */ + public function getTypeMap() + { + return $this->typeMap; + } + + /** + * Return the write concern for this client. + * + * @see https://php.net/manual/en/mongodb-driver-writeconcern.isdefault.php + * @return WriteConcern + */ + public function getWriteConcern() + { + return $this->writeConcern; + } + + /** + * List database names. + * + * @see ListDatabaseNames::__construct() for supported options + * @throws UnexpectedValueException if the command response was malformed + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function listDatabaseNames(array $options = []): Iterator + { + $operation = new ListDatabaseNames($options); + $server = select_server($this->manager, $options); + + return $operation->execute($server); + } + + /** + * List databases. + * + * @see ListDatabases::__construct() for supported options + * @return Iterator + * @throws UnexpectedValueException if the command response was malformed + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function listDatabases(array $options = []) + { + $operation = new ListDatabases($options); + $server = select_server($this->manager, $options); + + return $operation->execute($server); + } + + /** + * Unregisters a monitoring event subscriber with this Client's Manager + * + * @see Manager::removeSubscriber() + */ + final public function removeSubscriber(Subscriber $subscriber): void + { + $this->manager->removeSubscriber($subscriber); + } + + /** + * Select a collection. + * + * @see Collection::__construct() for supported options + * @param string $databaseName Name of the database containing the collection + * @param string $collectionName Name of the collection to select + * @param array $options Collection constructor options + * @return Collection + * @throws InvalidArgumentException for parameter/option parsing errors + */ + public function selectCollection(string $databaseName, string $collectionName, array $options = []) + { + return $this->getCollection($databaseName, $collectionName, $options); + } + + /** + * Select a database. + * + * @see Database::__construct() for supported options + * @param string $databaseName Name of the database to select + * @param array $options Database constructor options + * @return Database + * @throws InvalidArgumentException for parameter/option parsing errors + */ + public function selectDatabase(string $databaseName, array $options = []) + { + return $this->getDatabase($databaseName, $options); + } + + /** + * Start a new client session. + * + * @see https://php.net/manual/en/mongodb-driver-manager.startsession.php + * @param array $options Session options + * @return Session + */ + public function startSession(array $options = []) + { + return $this->manager->startSession($options); + } + + /** + * Create a change stream for watching changes to the cluster. + * + * @see Watch::__construct() for supported options + * @param array $pipeline Aggregation pipeline + * @param array $options Command options + * @return ChangeStream + * @throws InvalidArgumentException for parameter/option parsing errors + */ + public function watch(array $pipeline = [], array $options = []) + { + if (is_builder_pipeline($pipeline)) { + $pipeline = new Pipeline(...$pipeline); + } + + $pipeline = $this->builderEncoder->encodeIfSupported($pipeline); + + if (! isset($options['readPreference']) && ! is_in_transaction($options)) { + $options['readPreference'] = $this->readPreference; + } + + $server = select_server($this->manager, $options); + + if (! isset($options['readConcern']) && ! is_in_transaction($options)) { + $options['readConcern'] = $this->readConcern; + } + + if (! isset($options['typeMap'])) { + $options['typeMap'] = $this->typeMap; + } + + $operation = new Watch($this->manager, null, null, $pipeline, $options); + + return $operation->execute($server); + } + + private static function getVersion(): string + { + if (self::$version === null) { + try { + self::$version = InstalledVersions::getPrettyVersion('mongodb/mongodb') ?? 'unknown'; + } catch (Throwable) { + self::$version = 'error'; + } + } + + return self::$version; + } + + private function mergeDriverInfo(array $driver): array + { + $mergedDriver = [ + 'name' => 'PHPLIB', + 'version' => self::getVersion(), + ]; + + if (isset($driver['name'])) { + if (! is_string($driver['name'])) { + throw InvalidArgumentException::invalidType('"name" handshake option', $driver['name'], 'string'); + } + + $mergedDriver['name'] .= self::HANDSHAKE_SEPARATOR . $driver['name']; + } + + if (isset($driver['version'])) { + if (! is_string($driver['version'])) { + throw InvalidArgumentException::invalidType('"version" handshake option', $driver['version'], 'string'); + } + + $mergedDriver['version'] .= self::HANDSHAKE_SEPARATOR . $driver['version']; + } + + if (isset($driver['platform'])) { + $mergedDriver['platform'] = $driver['platform']; + } + + return $mergedDriver; + } +} diff --git a/vendor/mongodb/mongodb/src/Codec/Codec.php b/vendor/mongodb/mongodb/src/Codec/Codec.php new file mode 100644 index 00000000..26fddf2c --- /dev/null +++ b/vendor/mongodb/mongodb/src/Codec/Codec.php @@ -0,0 +1,31 @@ + + * @template-extends Encoder + */ +interface Codec extends Decoder, Encoder +{ +} diff --git a/vendor/mongodb/mongodb/src/Codec/DecodeIfSupported.php b/vendor/mongodb/mongodb/src/Codec/DecodeIfSupported.php new file mode 100644 index 00000000..7fd76801 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Codec/DecodeIfSupported.php @@ -0,0 +1,47 @@ +canDecode($value) ? $this->decode($value) : $value; + } +} diff --git a/vendor/mongodb/mongodb/src/Codec/Decoder.php b/vendor/mongodb/mongodb/src/Codec/Decoder.php new file mode 100644 index 00000000..432fb2dd --- /dev/null +++ b/vendor/mongodb/mongodb/src/Codec/Decoder.php @@ -0,0 +1,56 @@ + + */ +interface DocumentCodec extends Codec +{ + /** + * @psalm-param Document $value + * @psalm-return ObjectType + * @throws UnsupportedValueException if the decoder does not support the value + */ + public function decode(mixed $value): object; + + /** + * @psalm-param ObjectType $value + * @throws UnsupportedValueException if the encoder does not support the value + */ + public function encode(mixed $value): Document; +} diff --git a/vendor/mongodb/mongodb/src/Codec/EncodeIfSupported.php b/vendor/mongodb/mongodb/src/Codec/EncodeIfSupported.php new file mode 100644 index 00000000..33823cfd --- /dev/null +++ b/vendor/mongodb/mongodb/src/Codec/EncodeIfSupported.php @@ -0,0 +1,47 @@ +canEncode($value) ? $this->encode($value) : $value; + } +} diff --git a/vendor/mongodb/mongodb/src/Codec/Encoder.php b/vendor/mongodb/mongodb/src/Codec/Encoder.php new file mode 100644 index 00000000..0cd0d58c --- /dev/null +++ b/vendor/mongodb/mongodb/src/Codec/Encoder.php @@ -0,0 +1,56 @@ + BSONArray::class, + 'document' => BSONDocument::class, + 'root' => BSONDocument::class, + ]; + + private const WIRE_VERSION_FOR_READ_CONCERN_WITH_WRITE_STAGE = 8; + + /** @psalm-var Encoder */ + private readonly Encoder $builderEncoder; + + private ?DocumentCodec $codec = null; + + private ReadConcern $readConcern; + + private ReadPreference $readPreference; + + private array $typeMap; + + private WriteConcern $writeConcern; + + /** + * Constructs new Collection instance. + * + * This class provides methods for collection-specific operations, such as + * CRUD (i.e. create, read, update, and delete) and index management. + * + * Supported options: + * + * * builderEncoder (MongoDB\Codec\Encoder): Encoder for query and + * aggregation builders. If not given, the default encoder will be used. + * + * * codec (MongoDB\Codec\DocumentCodec): Codec used to decode documents + * from BSON to PHP objects. + * + * * readConcern (MongoDB\Driver\ReadConcern): The default read concern to + * use for collection operations. Defaults to the Manager's read concern. + * + * * readPreference (MongoDB\Driver\ReadPreference): The default read + * preference to use for collection operations. Defaults to the Manager's + * read preference. + * + * * typeMap (array): Default type map for cursors and BSON documents. + * + * * writeConcern (MongoDB\Driver\WriteConcern): The default write concern + * to use for collection operations. Defaults to the Manager's write + * concern. + * + * @param Manager $manager Manager instance from the driver + * @param string $databaseName Database name + * @param string $collectionName Collection name + * @param array $options Collection options + * @throws InvalidArgumentException for parameter/option parsing errors + */ + public function __construct(private Manager $manager, private string $databaseName, private string $collectionName, array $options = []) + { + if (strlen($databaseName) < 1) { + throw new InvalidArgumentException('$databaseName is invalid: ' . $databaseName); + } + + if (strlen($collectionName) < 1) { + throw new InvalidArgumentException('$collectionName is invalid: ' . $collectionName); + } + + if (isset($options['builderEncoder']) && ! $options['builderEncoder'] instanceof Encoder) { + throw InvalidArgumentException::invalidType('"builderEncoder" option', $options['builderEncoder'], Encoder::class); + } + + if (isset($options['codec']) && ! $options['codec'] instanceof DocumentCodec) { + throw InvalidArgumentException::invalidType('"codec" option', $options['codec'], DocumentCodec::class); + } + + if (isset($options['readConcern']) && ! $options['readConcern'] instanceof ReadConcern) { + throw InvalidArgumentException::invalidType('"readConcern" option', $options['readConcern'], ReadConcern::class); + } + + if (isset($options['readPreference']) && ! $options['readPreference'] instanceof ReadPreference) { + throw InvalidArgumentException::invalidType('"readPreference" option', $options['readPreference'], ReadPreference::class); + } + + if (isset($options['typeMap']) && ! is_array($options['typeMap'])) { + throw InvalidArgumentException::invalidType('"typeMap" option', $options['typeMap'], 'array'); + } + + if (isset($options['writeConcern']) && ! $options['writeConcern'] instanceof WriteConcern) { + throw InvalidArgumentException::invalidType('"writeConcern" option', $options['writeConcern'], WriteConcern::class); + } + + $this->builderEncoder = $options['builderEncoder'] ?? new BuilderEncoder(); + $this->codec = $options['codec'] ?? null; + $this->readConcern = $options['readConcern'] ?? $this->manager->getReadConcern(); + $this->readPreference = $options['readPreference'] ?? $this->manager->getReadPreference(); + $this->typeMap = $options['typeMap'] ?? self::DEFAULT_TYPE_MAP; + $this->writeConcern = $options['writeConcern'] ?? $this->manager->getWriteConcern(); + } + + /** + * Return internal properties for debugging purposes. + * + * @see https://php.net/manual/en/language.oop5.magic.php#language.oop5.magic.debuginfo + * @return array + */ + public function __debugInfo() + { + return [ + 'builderEncoder' => $this->builderEncoder, + 'codec' => $this->codec, + 'collectionName' => $this->collectionName, + 'databaseName' => $this->databaseName, + 'manager' => $this->manager, + 'readConcern' => $this->readConcern, + 'readPreference' => $this->readPreference, + 'typeMap' => $this->typeMap, + 'writeConcern' => $this->writeConcern, + ]; + } + + /** + * Return the collection namespace (e.g. "db.collection"). + * + * @see https://mongodb.com/docs/manual/core/databases-and-collections/ + * @return string + */ + public function __toString() + { + return $this->databaseName . '.' . $this->collectionName; + } + + /** + * Executes an aggregation framework pipeline on the collection. + * + * @see Aggregate::__construct() for supported options + * @param array $pipeline Aggregation pipeline + * @param array $options Command options + * @return CursorInterface&Iterator + * @throws UnexpectedValueException if the command response was malformed + * @throws UnsupportedException if options are not supported by the selected server + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function aggregate(array $pipeline, array $options = []) + { + if (is_builder_pipeline($pipeline)) { + $pipeline = new Pipeline(...$pipeline); + } + + $pipeline = $this->builderEncoder->encodeIfSupported($pipeline); + + $hasWriteStage = is_last_pipeline_operator_write($pipeline); + + $options = $this->inheritReadPreference($options); + + $server = $hasWriteStage + ? select_server_for_aggregate_write_stage($this->manager, $options) + : select_server($this->manager, $options); + + /* MongoDB 4.2 and later supports a read concern when an $out stage is + * being used, but earlier versions do not. + */ + if (! $hasWriteStage || server_supports_feature($server, self::WIRE_VERSION_FOR_READ_CONCERN_WITH_WRITE_STAGE)) { + $options = $this->inheritReadConcern($options); + } + + $options = $this->inheritCodecOrTypeMap($options); + + if ($hasWriteStage) { + $options = $this->inheritWriteOptions($options); + } + + $operation = new Aggregate($this->databaseName, $this->collectionName, $pipeline, $options); + + return $operation->execute($server); + } + + /** + * Executes multiple write operations. + * + * @see BulkWrite::__construct() for supported options + * @param array[] $operations List of write operations + * @param array $options Command options + * @return BulkWriteResult + * @throws UnsupportedException if options are not supported by the selected server + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function bulkWrite(array $operations, array $options = []) + { + $options = $this->inheritBuilderEncoder($options); + $options = $this->inheritWriteOptions($options); + $options = $this->inheritCodec($options); + + $operation = new BulkWrite($this->databaseName, $this->collectionName, $operations, $options); + + return $operation->execute(select_server_for_write($this->manager, $options)); + } + + /** + * Gets the number of documents matching the filter. + * + * @see Count::__construct() for supported options + * @param array|object $filter Query by which to filter documents + * @param array $options Command options + * @return integer + * @throws UnexpectedValueException if the command response was malformed + * @throws UnsupportedException if options are not supported by the selected server + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + * + * @deprecated 1.4 + */ + public function count(array|object $filter = [], array $options = []) + { + $filter = $this->builderEncoder->encodeIfSupported($filter); + $options = $this->inheritReadOptions($options); + + $operation = new Count($this->databaseName, $this->collectionName, $filter, $options); + + return $operation->execute(select_server($this->manager, $options)); + } + + /** + * Gets the number of documents matching the filter. + * + * @see CountDocuments::__construct() for supported options + * @param array|object $filter Query by which to filter documents + * @param array $options Command options + * @return integer + * @throws UnexpectedValueException if the command response was malformed + * @throws UnsupportedException if options are not supported by the selected server + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function countDocuments(array|object $filter = [], array $options = []) + { + $filter = $this->builderEncoder->encodeIfSupported($filter); + $options = $this->inheritReadOptions($options); + + $operation = new CountDocuments($this->databaseName, $this->collectionName, $filter, $options); + + return $operation->execute(select_server($this->manager, $options)); + } + + /** + * Create a single index for the collection. + * + * @see Collection::createIndexes() + * @see CreateIndexes::__construct() for supported command options + * @param array|object $key Document containing fields mapped to values, + * which denote order or an index type + * @param array $options Index and command options + * @return string The name of the created index + * @throws UnsupportedException if options are not supported by the selected server + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function createIndex(array|object $key, array $options = []) + { + $operationOptionKeys = ['comment' => 1, 'commitQuorum' => 1, 'maxTimeMS' => 1, 'session' => 1, 'writeConcern' => 1]; + $indexOptions = array_diff_key($options, $operationOptionKeys); + $operationOptions = array_intersect_key($options, $operationOptionKeys); + + return current($this->createIndexes([['key' => $key] + $indexOptions], $operationOptions)); + } + + /** + * Create one or more indexes for the collection. + * + * Each element in the $indexes array must have a "key" document, which + * contains fields mapped to an order or type. Other options may follow. + * For example: + * + * $indexes = [ + * // Create a unique index on the "username" field + * [ 'key' => [ 'username' => 1 ], 'unique' => true ], + * // Create a 2dsphere index on the "loc" field with a custom name + * [ 'key' => [ 'loc' => '2dsphere' ], 'name' => 'geo' ], + * ]; + * + * If the "name" option is unspecified, a name will be generated from the + * "key" document. + * + * @see https://mongodb.com/docs/manual/reference/command/createIndexes/ + * @see https://mongodb.com/docs/manual/reference/method/db.collection.createIndex/ + * @see CreateIndexes::__construct() for supported command options + * @param array[] $indexes List of index specifications + * @param array $options Command options + * @return string[] The names of the created indexes + * @throws UnsupportedException if options are not supported by the selected server + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function createIndexes(array $indexes, array $options = []) + { + $options = $this->inheritWriteOptions($options); + + $operation = new CreateIndexes($this->databaseName, $this->collectionName, $indexes, $options); + + return $operation->execute(select_server_for_write($this->manager, $options)); + } + + /** + * Create an Atlas Search index for the collection. + * Only available when used against a 7.0+ Atlas cluster. + * + * @see https://www.mongodb.com/docs/manual/reference/command/createSearchIndexes/ + * @see https://mongodb.com/docs/manual/reference/method/db.collection.createSearchIndex/ + * @param array|object $definition Atlas Search index mapping definition + * @param array{comment?: mixed, name?: string, type?: string} $options Index and command options + * @return string The name of the created search index + * @throws UnsupportedException if options are not supported by the selected server + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function createSearchIndex(array|object $definition, array $options = []): string + { + $indexOptionKeys = ['name' => 1, 'type' => 1]; + /** @psalm-var array{name?: string, type?: string} */ + $indexOptions = array_intersect_key($options, $indexOptionKeys); + /** @psalm-var array{comment?: mixed} */ + $operationOptions = array_diff_key($options, $indexOptionKeys); + + $names = $this->createSearchIndexes([['definition' => $definition] + $indexOptions], $operationOptions); + + return current($names); + } + + /** + * Create one or more Atlas Search indexes for the collection. + * Only available when used against a 7.0+ Atlas cluster. + * + * Each element in the $indexes array must have "definition" document and they may have a "name" string. + * The name can be omitted for a single index, in which case a name will be the default. + * For example: + * + * $indexes = [ + * // Create a search index with the default name on a single field + * ['definition' => ['mappings' => ['dynamic' => false, 'fields' => ['title' => ['type' => 'string']]]]], + * // Create a named search index on all fields + * ['name' => 'search_all', 'definition' => ['mappings' => ['dynamic' => true]]], + * ]; + * + * @see https://www.mongodb.com/docs/manual/reference/command/createSearchIndexes/ + * @see https://mongodb.com/docs/manual/reference/method/db.collection.createSearchIndex/ + * @param list $indexes List of search index specifications + * @param array{comment?: mixed} $options Command options + * @return string[] The names of the created search indexes + * @throws UnsupportedException if options are not supported by the selected server + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function createSearchIndexes(array $indexes, array $options = []): array + { + $operation = new CreateSearchIndexes($this->databaseName, $this->collectionName, $indexes, $options); + $server = select_server_for_write($this->manager, $options); + + return $operation->execute($server); + } + + /** + * Deletes all documents matching the filter. + * + * @see DeleteMany::__construct() for supported options + * @see https://mongodb.com/docs/manual/reference/command/delete/ + * @param array|object $filter Query by which to delete documents + * @param array $options Command options + * @return DeleteResult + * @throws UnsupportedException if options are not supported by the selected server + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function deleteMany(array|object $filter, array $options = []) + { + $filter = $this->builderEncoder->encodeIfSupported($filter); + $options = $this->inheritWriteOptions($options); + + $operation = new DeleteMany($this->databaseName, $this->collectionName, $filter, $options); + + return $operation->execute(select_server_for_write($this->manager, $options)); + } + + /** + * Deletes at most one document matching the filter. + * + * @see DeleteOne::__construct() for supported options + * @see https://mongodb.com/docs/manual/reference/command/delete/ + * @param array|object $filter Query by which to delete documents + * @param array $options Command options + * @return DeleteResult + * @throws UnsupportedException if options are not supported by the selected server + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function deleteOne(array|object $filter, array $options = []) + { + $filter = $this->builderEncoder->encodeIfSupported($filter); + $options = $this->inheritWriteOptions($options); + + $operation = new DeleteOne($this->databaseName, $this->collectionName, $filter, $options); + + return $operation->execute(select_server_for_write($this->manager, $options)); + } + + /** + * Finds the distinct values for a specified field across the collection. + * + * @see Distinct::__construct() for supported options + * @param string $fieldName Field for which to return distinct values + * @param array|object $filter Query by which to filter documents + * @param array $options Command options + * @return array + * @throws UnexpectedValueException if the command response was malformed + * @throws UnsupportedException if options are not supported by the selected server + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function distinct(string $fieldName, array|object $filter = [], array $options = []) + { + $filter = $this->builderEncoder->encodeIfSupported($filter); + $options = $this->inheritReadOptions($options); + $options = $this->inheritTypeMap($options); + + $operation = new Distinct($this->databaseName, $this->collectionName, $fieldName, $filter, $options); + + return $operation->execute(select_server($this->manager, $options)); + } + + /** + * Drop this collection. + * + * @see DropCollection::__construct() for supported options + * @param array $options Additional options + * @return array|object Command result document + * @throws UnsupportedException if options are not supported by the selected server + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function drop(array $options = []) + { + $options = $this->inheritWriteOptions($options); + $options = $this->inheritTypeMap($options, __FUNCTION__); + + $server = select_server_for_write($this->manager, $options); + + if (! isset($options['encryptedFields'])) { + $options['encryptedFields'] = get_encrypted_fields_from_driver($this->databaseName, $this->collectionName, $this->manager) + ?? get_encrypted_fields_from_server($this->databaseName, $this->collectionName, $this->manager, $server); + } + + $operation = isset($options['encryptedFields']) + ? new DropEncryptedCollection($this->databaseName, $this->collectionName, $options) + : new DropCollection($this->databaseName, $this->collectionName, $options); + + return $operation->execute($server); + } + + /** + * Drop a single index in the collection. + * + * @see DropIndexes::__construct() for supported options + * @param string|IndexInfo $indexName Index name or model object + * @param array $options Additional options + * @return array|object Command result document + * @throws UnsupportedException if options are not supported by the selected server + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function dropIndex(string|IndexInfo $indexName, array $options = []) + { + $indexName = (string) $indexName; + + if ($indexName === '*') { + throw new InvalidArgumentException('dropIndexes() must be used to drop multiple indexes'); + } + + $options = $this->inheritWriteOptions($options); + $options = $this->inheritTypeMap($options, __FUNCTION__); + + $operation = new DropIndexes($this->databaseName, $this->collectionName, $indexName, $options); + + return $operation->execute(select_server_for_write($this->manager, $options)); + } + + /** + * Drop all indexes in the collection. + * + * @see DropIndexes::__construct() for supported options + * @param array $options Additional options + * @return array|object Command result document + * @throws UnsupportedException if options are not supported by the selected server + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function dropIndexes(array $options = []) + { + $options = $this->inheritWriteOptions($options); + $options = $this->inheritTypeMap($options, __FUNCTION__); + + $operation = new DropIndexes($this->databaseName, $this->collectionName, '*', $options); + + return $operation->execute(select_server_for_write($this->manager, $options)); + } + + /** + * Drop a single Atlas Search index in the collection. + * Only available when used against a 7.0+ Atlas cluster. + * + * @param string $name Search index name + * @param array{comment?: mixed} $options Additional options + * @throws UnsupportedException if options are not supported by the selected server + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function dropSearchIndex(string $name, array $options = []): void + { + $operation = new DropSearchIndex($this->databaseName, $this->collectionName, $name); + $server = select_server_for_write($this->manager, $options); + + $operation->execute($server); + } + + /** + * Gets an estimated number of documents in the collection using the collection metadata. + * + * @see EstimatedDocumentCount::__construct() for supported options + * @param array $options Command options + * @return integer + * @throws UnexpectedValueException if the command response was malformed + * @throws UnsupportedException if options are not supported by the selected server + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function estimatedDocumentCount(array $options = []) + { + $options = $this->inheritReadOptions($options); + + $operation = new EstimatedDocumentCount($this->databaseName, $this->collectionName, $options); + + return $operation->execute(select_server($this->manager, $options)); + } + + /** + * Explains explainable commands. + * + * @see Explain::__construct() for supported options + * @see https://mongodb.com/docs/manual/reference/command/explain/ + * @param Explainable $explainable Command on which to run explain + * @param array $options Additional options + * @return array|object + * @throws UnsupportedException if explainable or options are not supported by the selected server + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function explain(Explainable $explainable, array $options = []) + { + $options = $this->inheritReadPreference($options); + $options = $this->inheritTypeMap($options); + + $operation = new Explain($this->databaseName, $explainable, $options); + + return $operation->execute(select_server($this->manager, $options)); + } + + /** + * Finds documents matching the query. + * + * @see Find::__construct() for supported options + * @see https://mongodb.com/docs/manual/crud/#read-operations + * @param array|object $filter Query by which to filter documents + * @param array $options Additional options + * @return CursorInterface&Iterator + * @throws UnsupportedException if options are not supported by the selected server + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function find(array|object $filter = [], array $options = []) + { + $filter = $this->builderEncoder->encodeIfSupported($filter); + $options = $this->inheritReadOptions($options); + $options = $this->inheritCodecOrTypeMap($options); + + $operation = new Find($this->databaseName, $this->collectionName, $filter, $options); + + return $operation->execute(select_server($this->manager, $options)); + } + + /** + * Finds a single document matching the query. + * + * @see FindOne::__construct() for supported options + * @see https://mongodb.com/docs/manual/crud/#read-operations + * @param array|object $filter Query by which to filter documents + * @param array $options Additional options + * @return array|object|null + * @throws UnsupportedException if options are not supported by the selected server + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function findOne(array|object $filter = [], array $options = []) + { + $filter = $this->builderEncoder->encodeIfSupported($filter); + $options = $this->inheritReadOptions($options); + $options = $this->inheritCodecOrTypeMap($options); + + $operation = new FindOne($this->databaseName, $this->collectionName, $filter, $options); + + return $operation->execute(select_server($this->manager, $options)); + } + + /** + * Finds a single document and deletes it, returning the original. + * + * The document to return may be null if no document matched the filter. + * + * @see FindOneAndDelete::__construct() for supported options + * @see https://mongodb.com/docs/manual/reference/command/findAndModify/ + * @param array|object $filter Query by which to filter documents + * @param array $options Command options + * @return array|object|null + * @throws UnexpectedValueException if the command response was malformed + * @throws UnsupportedException if options are not supported by the selected server + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function findOneAndDelete(array|object $filter, array $options = []) + { + $filter = $this->builderEncoder->encodeIfSupported($filter); + $options = $this->inheritWriteOptions($options); + $options = $this->inheritCodecOrTypeMap($options); + + $operation = new FindOneAndDelete($this->databaseName, $this->collectionName, $filter, $options); + + return $operation->execute(select_server_for_write($this->manager, $options)); + } + + /** + * Finds a single document and replaces it, returning either the original or + * the replaced document. + * + * The document to return may be null if no document matched the filter. By + * default, the original document is returned. Specify + * FindOneAndReplace::RETURN_DOCUMENT_AFTER for the "returnDocument" option + * to return the updated document. + * + * @see FindOneAndReplace::__construct() for supported options + * @see https://mongodb.com/docs/manual/reference/command/findAndModify/ + * @param array|object $filter Query by which to filter documents + * @param array|object $replacement Replacement document + * @param array $options Command options + * @return array|object|null + * @throws UnexpectedValueException if the command response was malformed + * @throws UnsupportedException if options are not supported by the selected server + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function findOneAndReplace(array|object $filter, array|object $replacement, array $options = []) + { + $filter = $this->builderEncoder->encodeIfSupported($filter); + $options = $this->inheritWriteOptions($options); + $options = $this->inheritCodecOrTypeMap($options); + + $operation = new FindOneAndReplace($this->databaseName, $this->collectionName, $filter, $replacement, $options); + + return $operation->execute(select_server_for_write($this->manager, $options)); + } + + /** + * Finds a single document and updates it, returning either the original or + * the updated document. + * + * The document to return may be null if no document matched the filter. By + * default, the original document is returned. Specify + * FindOneAndUpdate::RETURN_DOCUMENT_AFTER for the "returnDocument" option + * to return the updated document. + * + * @see FindOneAndReplace::__construct() for supported options + * @see https://mongodb.com/docs/manual/reference/command/findAndModify/ + * @param array|object $filter Query by which to filter documents + * @param array|object $update Update to apply to the matched document + * @param array $options Command options + * @return array|object|null + * @throws UnexpectedValueException if the command response was malformed + * @throws UnsupportedException if options are not supported by the selected server + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function findOneAndUpdate(array|object $filter, array|object $update, array $options = []) + { + $filter = $this->builderEncoder->encodeIfSupported($filter); + $options = $this->inheritWriteOptions($options); + $options = $this->inheritCodecOrTypeMap($options); + + $operation = new FindOneAndUpdate($this->databaseName, $this->collectionName, $filter, $update, $options); + + return $operation->execute(select_server_for_write($this->manager, $options)); + } + + /** + * Return the collection name. + * + * @return string + */ + public function getCollectionName() + { + return $this->collectionName; + } + + /** + * Return the database name. + * + * @return string + */ + public function getDatabaseName() + { + return $this->databaseName; + } + + /** + * Return the Manager. + * + * @return Manager + */ + public function getManager() + { + return $this->manager; + } + + /** + * Return the collection namespace. + * + * @see https://mongodb.com/docs/manual/reference/glossary/#term-namespace + * @return string + */ + public function getNamespace() + { + return $this->databaseName . '.' . $this->collectionName; + } + + /** + * Return the read concern for this collection. + * + * @see https://php.net/manual/en/mongodb-driver-readconcern.isdefault.php + * @return ReadConcern + */ + public function getReadConcern() + { + return $this->readConcern; + } + + /** + * Return the read preference for this collection. + * + * @return ReadPreference + */ + public function getReadPreference() + { + return $this->readPreference; + } + + /** + * Return the type map for this collection. + * + * @return array + */ + public function getTypeMap() + { + return $this->typeMap; + } + + /** + * Return the write concern for this collection. + * + * @see https://php.net/manual/en/mongodb-driver-writeconcern.isdefault.php + * @return WriteConcern + */ + public function getWriteConcern() + { + return $this->writeConcern; + } + + /** + * Inserts multiple documents. + * + * @see InsertMany::__construct() for supported options + * @see https://mongodb.com/docs/manual/reference/command/insert/ + * @param list $documents The documents to insert + * @param array $options Command options + * @return InsertManyResult + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function insertMany(array $documents, array $options = []) + { + $options = $this->inheritWriteOptions($options); + $options = $this->inheritCodec($options); + + $operation = new InsertMany($this->databaseName, $this->collectionName, $documents, $options); + + return $operation->execute(select_server_for_write($this->manager, $options)); + } + + /** + * Inserts one document. + * + * @see InsertOne::__construct() for supported options + * @see https://mongodb.com/docs/manual/reference/command/insert/ + * @param array|object $document The document to insert + * @param array $options Command options + * @return InsertOneResult + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function insertOne(array|object $document, array $options = []) + { + $options = $this->inheritWriteOptions($options); + $options = $this->inheritCodec($options); + + $operation = new InsertOne($this->databaseName, $this->collectionName, $document, $options); + + return $operation->execute(select_server_for_write($this->manager, $options)); + } + + /** + * Returns information for all indexes for the collection. + * + * @see ListIndexes::__construct() for supported options + * @return Iterator + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function listIndexes(array $options = []) + { + $operation = new ListIndexes($this->databaseName, $this->collectionName, $options); + + return $operation->execute(select_server($this->manager, $options)); + } + + /** + * Returns information for all Atlas Search indexes for the collection. + * Only available when used against a 7.0+ Atlas cluster. + * + * @param array $options Command options + * @return Countable&Iterator + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + * @see ListSearchIndexes::__construct() for supported options + */ + public function listSearchIndexes(array $options = []): Iterator + { + $options = $this->inheritTypeMap($options); + + $operation = new ListSearchIndexes($this->databaseName, $this->collectionName, $options); + $server = select_server($this->manager, $options); + + return $operation->execute($server); + } + + /** + * Executes a map-reduce aggregation on the collection. + * + * @see MapReduce::__construct() for supported options + * @see https://mongodb.com/docs/manual/reference/command/mapReduce/ + * @param JavascriptInterface $map Map function + * @param JavascriptInterface $reduce Reduce function + * @param string|array|object $out Output specification + * @param array $options Command options + * @return MapReduceResult + * @throws UnsupportedException if options are not supported by the selected server + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + * @throws UnexpectedValueException if the command response was malformed + */ + public function mapReduce(JavascriptInterface $map, JavascriptInterface $reduce, string|array|object $out, array $options = []) + { + @trigger_error(sprintf('The %s method is deprecated and will be removed in a version 2.0.', __METHOD__), E_USER_DEPRECATED); + + $hasOutputCollection = ! is_mapreduce_output_inline($out); + + // Check if the out option is inline because we will want to coerce a primary read preference if not + if ($hasOutputCollection) { + $options['readPreference'] = new ReadPreference(ReadPreference::PRIMARY); + } else { + $options = $this->inheritReadPreference($options); + } + + /* A "majority" read concern is not compatible with inline output, so + * avoid providing the Collection's read concern if it would conflict. + */ + if (! $hasOutputCollection || $this->readConcern->getLevel() !== ReadConcern::MAJORITY) { + $options = $this->inheritReadConcern($options); + } + + $options = $this->inheritWriteOptions($options); + $options = $this->inheritTypeMap($options); + + $operation = new MapReduce($this->databaseName, $this->collectionName, $map, $reduce, $out, $options); + + return $operation->execute(select_server_for_write($this->manager, $options)); + } + + /** + * Renames the collection. + * + * @see RenameCollection::__construct() for supported options + * @param string $toCollectionName New name of the collection + * @param string|null $toDatabaseName New database name of the collection. Defaults to the original database. + * @param array $options Additional options + * @return array|object Command result document + * @throws UnsupportedException if options are not supported by the selected server + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function rename(string $toCollectionName, ?string $toDatabaseName = null, array $options = []) + { + if (! isset($toDatabaseName)) { + $toDatabaseName = $this->databaseName; + } + + $options = $this->inheritWriteOptions($options); + $options = $this->inheritTypeMap($options); + + $operation = new RenameCollection($this->databaseName, $this->collectionName, $toDatabaseName, $toCollectionName, $options); + + return $operation->execute(select_server_for_write($this->manager, $options)); + } + + /** + * Replaces at most one document matching the filter. + * + * @see ReplaceOne::__construct() for supported options + * @see https://mongodb.com/docs/manual/reference/command/update/ + * @param array|object $filter Query by which to filter documents + * @param array|object $replacement Replacement document + * @param array $options Command options + * @return UpdateResult + * @throws UnsupportedException if options are not supported by the selected server + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function replaceOne(array|object $filter, array|object $replacement, array $options = []) + { + $filter = $this->builderEncoder->encodeIfSupported($filter); + $options = $this->inheritWriteOptions($options); + $options = $this->inheritCodec($options); + + $operation = new ReplaceOne($this->databaseName, $this->collectionName, $filter, $replacement, $options); + + return $operation->execute(select_server_for_write($this->manager, $options)); + } + + /** + * Updates all documents matching the filter. + * + * @see UpdateMany::__construct() for supported options + * @see https://mongodb.com/docs/manual/reference/command/update/ + * @param array|object $filter Query by which to filter documents + * @param array|object $update Update to apply to the matched documents + * @param array $options Command options + * @return UpdateResult + * @throws UnsupportedException if options are not supported by the selected server + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function updateMany(array|object $filter, array|object $update, array $options = []) + { + $filter = $this->builderEncoder->encodeIfSupported($filter); + $update = $this->builderEncoder->encodeIfSupported($update); + $options = $this->inheritWriteOptions($options); + + $operation = new UpdateMany($this->databaseName, $this->collectionName, $filter, $update, $options); + + return $operation->execute(select_server_for_write($this->manager, $options)); + } + + /** + * Updates at most one document matching the filter. + * + * @see UpdateOne::__construct() for supported options + * @see https://mongodb.com/docs/manual/reference/command/update/ + * @param array|object $filter Query by which to filter documents + * @param array|object $update Update to apply to the matched document + * @param array $options Command options + * @return UpdateResult + * @throws UnsupportedException if options are not supported by the selected server + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function updateOne(array|object $filter, array|object $update, array $options = []) + { + $filter = $this->builderEncoder->encodeIfSupported($filter); + $update = $this->builderEncoder->encodeIfSupported($update); + $options = $this->inheritWriteOptions($options); + + $operation = new UpdateOne($this->databaseName, $this->collectionName, $filter, $update, $options); + + return $operation->execute(select_server_for_write($this->manager, $options)); + } + + /** + * Update a single Atlas Search index in the collection. + * Only available when used against a 7.0+ Atlas cluster. + * + * @param string $name Search index name + * @param array|object $definition Atlas Search index definition + * @param array{comment?: mixed} $options Command options + * @throws UnsupportedException if options are not supported by the selected server + * @throws InvalidArgumentException for parameter parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function updateSearchIndex(string $name, array|object $definition, array $options = []): void + { + $operation = new UpdateSearchIndex($this->databaseName, $this->collectionName, $name, $definition, $options); + $server = select_server_for_write($this->manager, $options); + + $operation->execute($server); + } + + /** + * Create a change stream for watching changes to the collection. + * + * @see Watch::__construct() for supported options + * @param array $pipeline Aggregation pipeline + * @param array $options Command options + * @return ChangeStream + * @throws InvalidArgumentException for parameter/option parsing errors + */ + public function watch(array $pipeline = [], array $options = []) + { + if (is_builder_pipeline($pipeline)) { + $pipeline = new Pipeline(...$pipeline); + } + + $pipeline = $this->builderEncoder->encodeIfSupported($pipeline); + + $options = $this->inheritReadOptions($options); + $options = $this->inheritCodecOrTypeMap($options); + + $operation = new Watch($this->manager, $this->databaseName, $this->collectionName, $pipeline, $options); + + return $operation->execute(select_server($this->manager, $options)); + } + + /** + * Get a clone of this collection with different options. + * + * @see Collection::__construct() for supported options + * @param array $options Collection constructor options + * @return Collection + * @throws InvalidArgumentException for parameter/option parsing errors + */ + public function withOptions(array $options = []) + { + $options += [ + 'builderEncoder' => $this->builderEncoder, + 'codec' => $this->codec, + 'readConcern' => $this->readConcern, + 'readPreference' => $this->readPreference, + 'typeMap' => $this->typeMap, + 'writeConcern' => $this->writeConcern, + ]; + + return new Collection($this->manager, $this->databaseName, $this->collectionName, $options); + } + + private function inheritBuilderEncoder(array $options): array + { + return ['builderEncoder' => $this->builderEncoder] + $options; + } + + private function inheritCodec(array $options): array + { + // If the options contain a type map, don't inherit anything + if (isset($options['typeMap'])) { + return $options; + } + + if (! array_key_exists('codec', $options)) { + $options['codec'] = $this->codec; + } + + return $options; + } + + private function inheritCodecOrTypeMap(array $options): array + { + // If the options contain a type map, don't inherit anything + if (isset($options['typeMap'])) { + return $options; + } + + // If this collection does not use a codec, or if a codec was explicitly + // defined in the options, only inherit the type map (if possible) + if (! $this->codec || array_key_exists('codec', $options)) { + return $this->inheritTypeMap($options); + } + + // At this point, we know that we use a codec and the options array did + // not explicitly contain a codec, so we can inherit ours + $options['codec'] = $this->codec; + + return $options; + } + + private function inheritReadConcern(array $options): array + { + // ReadConcern and ReadPreference may not change within a transaction + if (! isset($options['readConcern']) && ! is_in_transaction($options)) { + $options['readConcern'] = $this->readConcern; + } + + return $options; + } + + private function inheritReadOptions(array $options): array + { + $options = $this->inheritReadConcern($options); + + return $this->inheritReadPreference($options); + } + + private function inheritReadPreference(array $options): array + { + // ReadConcern and ReadPreference may not change within a transaction + if (! isset($options['readPreference']) && ! is_in_transaction($options)) { + $options['readPreference'] = $this->readPreference; + } + + return $options; + } + + private function inheritTypeMap(array $options, ?string $deprecatedFunction = null): array + { + if ($deprecatedFunction !== null && isset($options['typeMap'])) { + @trigger_error(sprintf('The function %s() will return nothing in mongodb/mongodb v2.0, the "typeMap" option is deprecated', $deprecatedFunction), E_USER_DEPRECATED); + } + + // Only inherit the type map if no codec is used + if (! isset($options['typeMap']) && ! isset($options['codec'])) { + $options['typeMap'] = $this->typeMap; + } + + return $options; + } + + private function inheritWriteOptions(array $options): array + { + // WriteConcern may not change within a transaction + if (! is_in_transaction($options)) { + if (! isset($options['writeConcern'])) { + $options['writeConcern'] = $this->writeConcern; + } + } + + return $options; + } +} diff --git a/vendor/mongodb/mongodb/src/Command/ListCollections.php b/vendor/mongodb/mongodb/src/Command/ListCollections.php new file mode 100644 index 00000000..454e145f --- /dev/null +++ b/vendor/mongodb/mongodb/src/Command/ListCollections.php @@ -0,0 +1,147 @@ + + * @see Executable::execute() + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server): CachingIterator + { + /** @var Cursor $cursor */ + $cursor = $server->executeReadCommand($this->databaseName, $this->createCommand(), $this->createOptions()); + $cursor->setTypeMap(['root' => 'array', 'document' => 'array']); + + return new CachingIterator($cursor); + } + + /** + * Create the listCollections command. + */ + private function createCommand(): Command + { + $cmd = ['listCollections' => 1]; + + if (! empty($this->options['filter'])) { + $cmd['filter'] = (object) $this->options['filter']; + } + + foreach (['authorizedCollections', 'comment', 'maxTimeMS', 'nameOnly'] as $option) { + if (isset($this->options[$option])) { + $cmd[$option] = $this->options[$option]; + } + } + + return new Command($cmd); + } + + /** + * Create options for executing the command. + * + * Note: read preference is intentionally omitted, as the spec requires that + * the command be executed on the primary. + * + * @see https://php.net/manual/en/mongodb-driver-server.executecommand.php + */ + private function createOptions(): array + { + $options = []; + + if (isset($this->options['session'])) { + $options['session'] = $this->options['session']; + } + + return $options; + } +} diff --git a/vendor/mongodb/mongodb/src/Command/ListDatabases.php b/vendor/mongodb/mongodb/src/Command/ListDatabases.php new file mode 100644 index 00000000..5386559d --- /dev/null +++ b/vendor/mongodb/mongodb/src/Command/ListDatabases.php @@ -0,0 +1,152 @@ +executeReadCommand('admin', $this->createCommand(), $this->createOptions()); + $cursor->setTypeMap(['root' => 'array', 'document' => 'array']); + $result = current($cursor->toArray()); + + if (! isset($result['databases']) || ! is_array($result['databases'])) { + throw new UnexpectedValueException('listDatabases command did not return a "databases" array'); + } + + return $result['databases']; + } + + /** + * Create the listDatabases command. + */ + private function createCommand(): Command + { + $cmd = ['listDatabases' => 1]; + + if (! empty($this->options['filter'])) { + $cmd['filter'] = (object) $this->options['filter']; + } + + foreach (['authorizedDatabases', 'comment', 'maxTimeMS', 'nameOnly'] as $option) { + if (isset($this->options[$option])) { + $cmd[$option] = $this->options[$option]; + } + } + + return new Command($cmd); + } + + /** + * Create options for executing the command. + * + * Note: read preference is intentionally omitted, as the spec requires that + * the command be executed on the primary. + * + * @see https://php.net/manual/en/mongodb-driver-server.executecommand.php + */ + private function createOptions(): array + { + $options = []; + + if (isset($this->options['session'])) { + $options['session'] = $this->options['session']; + } + + return $options; + } +} diff --git a/vendor/mongodb/mongodb/src/Database.php b/vendor/mongodb/mongodb/src/Database.php new file mode 100644 index 00000000..0652a896 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Database.php @@ -0,0 +1,691 @@ + BSONArray::class, + 'document' => BSONDocument::class, + 'root' => BSONDocument::class, + ]; + + private const WIRE_VERSION_FOR_READ_CONCERN_WITH_WRITE_STAGE = 8; + + /** @psalm-var Encoder */ + private readonly Encoder $builderEncoder; + + private ReadConcern $readConcern; + + private ReadPreference $readPreference; + + private array $typeMap; + + private WriteConcern $writeConcern; + + /** + * Constructs new Database instance. + * + * This class provides methods for database-specific operations and serves + * as a gateway for accessing collections. + * + * Supported options: + * + * * builderEncoder (MongoDB\Codec\Encoder): Encoder for query and + * aggregation builders. If not given, the default encoder will be used. + * + * * readConcern (MongoDB\Driver\ReadConcern): The default read concern to + * use for database operations and selected collections. Defaults to the + * Manager's read concern. + * + * * readPreference (MongoDB\Driver\ReadPreference): The default read + * preference to use for database operations and selected collections. + * Defaults to the Manager's read preference. + * + * * typeMap (array): Default type map for cursors and BSON documents. + * + * * writeConcern (MongoDB\Driver\WriteConcern): The default write concern + * to use for database operations and selected collections. Defaults to + * the Manager's write concern. + * + * @param Manager $manager Manager instance from the driver + * @param string $databaseName Database name + * @param array $options Database options + * @throws InvalidArgumentException for parameter/option parsing errors + */ + public function __construct(private Manager $manager, private string $databaseName, array $options = []) + { + if (strlen($databaseName) < 1) { + throw new InvalidArgumentException('$databaseName is invalid: ' . $databaseName); + } + + if (isset($options['builderEncoder']) && ! $options['builderEncoder'] instanceof Encoder) { + throw InvalidArgumentException::invalidType('"builderEncoder" option', $options['builderEncoder'], Encoder::class); + } + + if (isset($options['readConcern']) && ! $options['readConcern'] instanceof ReadConcern) { + throw InvalidArgumentException::invalidType('"readConcern" option', $options['readConcern'], ReadConcern::class); + } + + if (isset($options['readPreference']) && ! $options['readPreference'] instanceof ReadPreference) { + throw InvalidArgumentException::invalidType('"readPreference" option', $options['readPreference'], ReadPreference::class); + } + + if (isset($options['typeMap']) && ! is_array($options['typeMap'])) { + throw InvalidArgumentException::invalidType('"typeMap" option', $options['typeMap'], 'array'); + } + + if (isset($options['writeConcern']) && ! $options['writeConcern'] instanceof WriteConcern) { + throw InvalidArgumentException::invalidType('"writeConcern" option', $options['writeConcern'], WriteConcern::class); + } + + $this->builderEncoder = $options['builderEncoder'] ?? new BuilderEncoder(); + $this->readConcern = $options['readConcern'] ?? $this->manager->getReadConcern(); + $this->readPreference = $options['readPreference'] ?? $this->manager->getReadPreference(); + $this->typeMap = $options['typeMap'] ?? self::DEFAULT_TYPE_MAP; + $this->writeConcern = $options['writeConcern'] ?? $this->manager->getWriteConcern(); + } + + /** + * Return internal properties for debugging purposes. + * + * @see https://php.net/manual/en/language.oop5.magic.php#language.oop5.magic.debuginfo + * @return array + */ + public function __debugInfo() + { + return [ + 'builderEncoder' => $this->builderEncoder, + 'databaseName' => $this->databaseName, + 'manager' => $this->manager, + 'readConcern' => $this->readConcern, + 'readPreference' => $this->readPreference, + 'typeMap' => $this->typeMap, + 'writeConcern' => $this->writeConcern, + ]; + } + + /** + * Select a collection within this database. + * + * Note: collections whose names contain special characters (e.g. ".") may + * be selected with complex syntax (e.g. $database->{"system.profile"}) or + * {@link selectCollection()}. + * + * @see https://php.net/oop5.overloading#object.get + * @see https://php.net/types.string#language.types.string.parsing.complex + * @param string $collectionName Name of the collection to select + * @return Collection + */ + public function __get(string $collectionName) + { + return $this->getCollection($collectionName); + } + + /** + * Return the database name. + * + * @return string + */ + public function __toString() + { + return $this->databaseName; + } + + /** + * Runs an aggregation framework pipeline on the database for pipeline + * stages that do not require an underlying collection, such as $currentOp + * and $listLocalSessions. Requires MongoDB >= 3.6 + * + * @see Aggregate::__construct() for supported options + * @param array $pipeline Aggregation pipeline + * @param array $options Command options + * @return Traversable + * @throws UnexpectedValueException if the command response was malformed + * @throws UnsupportedException if options are not supported by the selected server + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function aggregate(array $pipeline, array $options = []) + { + if (is_builder_pipeline($pipeline)) { + $pipeline = new Pipeline(...$pipeline); + } + + $pipeline = $this->builderEncoder->encodeIfSupported($pipeline); + + $hasWriteStage = is_last_pipeline_operator_write($pipeline); + + if (! isset($options['readPreference']) && ! is_in_transaction($options)) { + $options['readPreference'] = $this->readPreference; + } + + $server = $hasWriteStage + ? select_server_for_aggregate_write_stage($this->manager, $options) + : select_server($this->manager, $options); + + /* MongoDB 4.2 and later supports a read concern when an $out stage is + * being used, but earlier versions do not. + * + * A read concern is also not compatible with transactions. + */ + if ( + ! isset($options['readConcern']) && + ! is_in_transaction($options) && + ( ! $hasWriteStage || server_supports_feature($server, self::WIRE_VERSION_FOR_READ_CONCERN_WITH_WRITE_STAGE)) + ) { + $options['readConcern'] = $this->readConcern; + } + + if (! isset($options['typeMap'])) { + $options['typeMap'] = $this->typeMap; + } + + if ($hasWriteStage && ! isset($options['writeConcern']) && ! is_in_transaction($options)) { + $options['writeConcern'] = $this->writeConcern; + } + + $operation = new Aggregate($this->databaseName, null, $pipeline, $options); + + return $operation->execute($server); + } + + /** + * Execute a command on this database. + * + * @see DatabaseCommand::__construct() for supported options + * @param array|object $command Command document + * @param array $options Options for command execution + * @return Cursor + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function command(array|object $command, array $options = []) + { + if (! isset($options['typeMap'])) { + $options['typeMap'] = $this->typeMap; + } + + $operation = new DatabaseCommand($this->databaseName, $command, $options); + $server = select_server($this->manager, $options); + + return $operation->execute($server); + } + + /** + * Create a new collection explicitly. + * + * If the "encryptedFields" option is specified, this method additionally + * creates related metadata collections and an index on the encrypted + * collection. + * + * @see CreateCollection::__construct() for supported options + * @see https://github.com/mongodb/specifications/blob/master/source/client-side-encryption/client-side-encryption.rst#create-collection-helper + * @see https://www.mongodb.com/docs/manual/core/queryable-encryption/fundamentals/manage-collections/ + * @return array|object Command result document + * @throws UnsupportedException if options are not supported by the selected server + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function createCollection(string $collectionName, array $options = []) + { + if (! isset($options['typeMap'])) { + $options['typeMap'] = $this->typeMap; + } else { + @trigger_error(sprintf('The function %s() will return nothing in mongodb/mongodb v2.0, the "typeMap" option is deprecated', __FUNCTION__), E_USER_DEPRECATED); + } + + if (! isset($options['writeConcern']) && ! is_in_transaction($options)) { + $options['writeConcern'] = $this->writeConcern; + } + + if (! isset($options['encryptedFields'])) { + $options['encryptedFields'] = get_encrypted_fields_from_driver($this->databaseName, $collectionName, $this->manager); + } + + $operation = isset($options['encryptedFields']) + ? new CreateEncryptedCollection($this->databaseName, $collectionName, $options) + : new CreateCollection($this->databaseName, $collectionName, $options); + + $server = select_server_for_write($this->manager, $options); + + return $operation->execute($server); + } + + /** + * Create a new encrypted collection explicitly. + * + * The "encryptedFields" option is required. + * + * This method will automatically create data keys for any encrypted fields + * where "keyId" is null. A copy of the modified "encryptedFields" option + * will be returned in addition to the result from creating the collection. + * + * If any error is encountered creating data keys or the collection, a + * CreateEncryptedCollectionException will be thrown. The original exception + * and modified "encryptedFields" option can be accessed via the + * getPrevious() and getEncryptedFields() methods, respectively. + * + * @see CreateCollection::__construct() for supported options + * @return array A tuple containing the command result document from creating the collection and the modified "encryptedFields" option + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws CreateEncryptedCollectionException for any errors creating data keys or creating the collection + * @throws UnsupportedException if Queryable Encryption is not supported by the selected server + */ + public function createEncryptedCollection(string $collectionName, ClientEncryption $clientEncryption, string $kmsProvider, ?array $masterKey, array $options): array + { + if (! isset($options['typeMap'])) { + $options['typeMap'] = $this->typeMap; + } else { + @trigger_error(sprintf('The function %s() will return nothing in mongodb/mongodb v2.0, the "typeMap" option is deprecated', __FUNCTION__), E_USER_DEPRECATED); + } + + if (! isset($options['writeConcern']) && ! is_in_transaction($options)) { + $options['writeConcern'] = $this->writeConcern; + } + + $operation = new CreateEncryptedCollection($this->databaseName, $collectionName, $options); + $server = select_server_for_write($this->manager, $options); + + try { + $operation->createDataKeys($clientEncryption, $kmsProvider, $masterKey, $encryptedFields); + $result = $operation->execute($server); + + return [$result, $encryptedFields]; + } catch (Throwable $e) { + throw new CreateEncryptedCollectionException($e, $encryptedFields ?? []); + } + } + + /** + * Drop this database. + * + * @see DropDatabase::__construct() for supported options + * @param array $options Additional options + * @return array|object Command result document + * @throws UnsupportedException if options are unsupported on the selected server + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function drop(array $options = []) + { + if (! isset($options['typeMap'])) { + $options['typeMap'] = $this->typeMap; + } else { + @trigger_error(sprintf('The function %s() will return nothing in mongodb/mongodb v2.0, the "typeMap" option is deprecated', __FUNCTION__), E_USER_DEPRECATED); + } + + $server = select_server_for_write($this->manager, $options); + + if (! isset($options['writeConcern']) && ! is_in_transaction($options)) { + $options['writeConcern'] = $this->writeConcern; + } + + $operation = new DropDatabase($this->databaseName, $options); + + return $operation->execute($server); + } + + /** + * Drop a collection within this database. + * + * @see DropCollection::__construct() for supported options + * @param string $collectionName Collection name + * @param array $options Additional options + * @return array|object Command result document + * @throws UnsupportedException if options are unsupported on the selected server + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function dropCollection(string $collectionName, array $options = []) + { + if (! isset($options['typeMap'])) { + $options['typeMap'] = $this->typeMap; + } else { + @trigger_error(sprintf('The function %s() will return nothing in mongodb/mongodb v2.0, the "typeMap" option is deprecated', __FUNCTION__), E_USER_DEPRECATED); + } + + $server = select_server_for_write($this->manager, $options); + + if (! isset($options['writeConcern']) && ! is_in_transaction($options)) { + $options['writeConcern'] = $this->writeConcern; + } + + if (! isset($options['encryptedFields'])) { + $options['encryptedFields'] = get_encrypted_fields_from_driver($this->databaseName, $collectionName, $this->manager) + ?? get_encrypted_fields_from_server($this->databaseName, $collectionName, $this->manager, $server); + } + + $operation = isset($options['encryptedFields']) + ? new DropEncryptedCollection($this->databaseName, $collectionName, $options) + : new DropCollection($this->databaseName, $collectionName, $options); + + return $operation->execute($server); + } + + /** + * Returns a collection instance. + * + * If the collection does not exist in the database, it is not created when + * invoking this method. + * + * @see Collection::__construct() for supported options + * @throws InvalidArgumentException for parameter/option parsing errors + */ + public function getCollection(string $collectionName, array $options = []): Collection + { + $options += [ + 'builderEncoder' => $this->builderEncoder, + 'readConcern' => $this->readConcern, + 'readPreference' => $this->readPreference, + 'typeMap' => $this->typeMap, + 'writeConcern' => $this->writeConcern, + ]; + + return new Collection($this->manager, $this->databaseName, $collectionName, $options); + } + + /** + * Returns the database name. + * + * @return string + */ + public function getDatabaseName() + { + return $this->databaseName; + } + + /** + * Return the Manager. + * + * @return Manager + */ + public function getManager() + { + return $this->manager; + } + + /** + * Return the read concern for this database. + * + * @see https://php.net/manual/en/mongodb-driver-readconcern.isdefault.php + * @return ReadConcern + */ + public function getReadConcern() + { + return $this->readConcern; + } + + /** + * Return the read preference for this database. + * + * @return ReadPreference + */ + public function getReadPreference() + { + return $this->readPreference; + } + + /** + * Return the type map for this database. + * + * @return array + */ + public function getTypeMap() + { + return $this->typeMap; + } + + /** + * Return the write concern for this database. + * + * @see https://php.net/manual/en/mongodb-driver-writeconcern.isdefault.php + * @return WriteConcern + */ + public function getWriteConcern() + { + return $this->writeConcern; + } + + /** + * Returns the names of all collections in this database + * + * @see ListCollectionNames::__construct() for supported options + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function listCollectionNames(array $options = []): Iterator + { + $operation = new ListCollectionNames($this->databaseName, $options); + $server = select_server($this->manager, $options); + + return $operation->execute($server); + } + + /** + * Returns information for all collections in this database. + * + * @see ListCollections::__construct() for supported options + * @return Iterator + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function listCollections(array $options = []) + { + $operation = new ListCollections($this->databaseName, $options); + $server = select_server($this->manager, $options); + + return $operation->execute($server); + } + + /** + * Modifies a collection or view. + * + * @see ModifyCollection::__construct() for supported options + * @param string $collectionName Collection or view to modify + * @param array $collectionOptions Collection or view options to assign + * @param array $options Command options + * @return array|object + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function modifyCollection(string $collectionName, array $collectionOptions, array $options = []) + { + if (! isset($options['typeMap'])) { + $options['typeMap'] = $this->typeMap; + } + + $server = select_server_for_write($this->manager, $options); + + if (! isset($options['writeConcern']) && ! is_in_transaction($options)) { + $options['writeConcern'] = $this->writeConcern; + } + + $operation = new ModifyCollection($this->databaseName, $collectionName, $collectionOptions, $options); + + return $operation->execute($server); + } + + /** + * Rename a collection within this database. + * + * @see RenameCollection::__construct() for supported options + * @param string $fromCollectionName Collection name + * @param string $toCollectionName New name of the collection + * @param string|null $toDatabaseName New database name of the collection. Defaults to the original database. + * @param array $options Additional options + * @return array|object Command result document + * @throws UnsupportedException if options are unsupported on the selected server + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function renameCollection(string $fromCollectionName, string $toCollectionName, ?string $toDatabaseName = null, array $options = []) + { + if (! isset($toDatabaseName)) { + $toDatabaseName = $this->databaseName; + } + + if (! isset($options['typeMap'])) { + $options['typeMap'] = $this->typeMap; + } + + $server = select_server_for_write($this->manager, $options); + + if (! isset($options['writeConcern']) && ! is_in_transaction($options)) { + $options['writeConcern'] = $this->writeConcern; + } + + $operation = new RenameCollection($this->databaseName, $fromCollectionName, $toDatabaseName, $toCollectionName, $options); + + return $operation->execute($server); + } + + /** + * Select a collection within this database. + * + * @see Collection::__construct() for supported options + * @param string $collectionName Name of the collection to select + * @param array $options Collection constructor options + * @return Collection + * @throws InvalidArgumentException for parameter/option parsing errors + */ + public function selectCollection(string $collectionName, array $options = []) + { + return $this->getCollection($collectionName, $options); + } + + /** + * Select a GridFS bucket within this database. + * + * @see Bucket::__construct() for supported options + * @param array $options Bucket constructor options + * @return Bucket + * @throws InvalidArgumentException for parameter/option parsing errors + */ + public function selectGridFSBucket(array $options = []) + { + $options += [ + 'readConcern' => $this->readConcern, + 'readPreference' => $this->readPreference, + 'typeMap' => $this->typeMap, + 'writeConcern' => $this->writeConcern, + ]; + + return new Bucket($this->manager, $this->databaseName, $options); + } + + /** + * Create a change stream for watching changes to the database. + * + * @see Watch::__construct() for supported options + * @param array $pipeline Aggregation pipeline + * @param array $options Command options + * @return ChangeStream + * @throws InvalidArgumentException for parameter/option parsing errors + */ + public function watch(array $pipeline = [], array $options = []) + { + if (is_builder_pipeline($pipeline)) { + $pipeline = new Pipeline(...$pipeline); + } + + $pipeline = $this->builderEncoder->encodeIfSupported($pipeline); + + if (! isset($options['readPreference']) && ! is_in_transaction($options)) { + $options['readPreference'] = $this->readPreference; + } + + $server = select_server($this->manager, $options); + + if (! isset($options['readConcern']) && ! is_in_transaction($options)) { + $options['readConcern'] = $this->readConcern; + } + + if (! isset($options['typeMap'])) { + $options['typeMap'] = $this->typeMap; + } + + $operation = new Watch($this->manager, $this->databaseName, null, $pipeline, $options); + + return $operation->execute($server); + } + + /** + * Get a clone of this database with different options. + * + * @see Database::__construct() for supported options + * @param array $options Database constructor options + * @return Database + * @throws InvalidArgumentException for parameter/option parsing errors + */ + public function withOptions(array $options = []) + { + $options += [ + 'readConcern' => $this->readConcern, + 'readPreference' => $this->readPreference, + 'typeMap' => $this->typeMap, + 'writeConcern' => $this->writeConcern, + ]; + + return new Database($this->manager, $this->databaseName, $options); + } +} diff --git a/vendor/mongodb/mongodb/src/DeleteResult.php b/vendor/mongodb/mongodb/src/DeleteResult.php new file mode 100644 index 00000000..56f3f072 --- /dev/null +++ b/vendor/mongodb/mongodb/src/DeleteResult.php @@ -0,0 +1,65 @@ +isAcknowledged = $writeResult->isAcknowledged(); + } + + /** + * Return the number of documents that were deleted. + * + * This method should only be called if the write was acknowledged. + * + * @see DeleteResult::isAcknowledged() + * @return integer|null + * @throws BadMethodCallException if the write result is unacknowledged + */ + public function getDeletedCount() + { + if ($this->isAcknowledged) { + return $this->writeResult->getDeletedCount(); + } + + throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__); + } + + /** + * Return whether this delete was acknowledged by the server. + * + * If the delete was not acknowledged, other fields from the WriteResult + * (e.g. deletedCount) will be undefined. + * + * @return boolean + */ + public function isAcknowledged() + { + return $this->isAcknowledged; + } +} diff --git a/vendor/mongodb/mongodb/src/Exception/BadMethodCallException.php b/vendor/mongodb/mongodb/src/Exception/BadMethodCallException.php new file mode 100644 index 00000000..e1070982 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Exception/BadMethodCallException.php @@ -0,0 +1,47 @@ +getMessage()), 0, $previous); + } + + /** + * Returns the encryptedFields option in its last known state before the + * operation was interrupted. + * + * This can be used to infer which data keys were successfully created; + * however, it is possible that additional data keys were successfully + * created and are not present in the returned value. For example, if the + * operation was interrupted by a timeout error when creating a data key, + * the write may actually have succeeded on the server but the key will not + * be present in the returned value. + */ + public function getEncryptedFields(): array + { + return $this->encryptedFields; + } +} diff --git a/vendor/mongodb/mongodb/src/Exception/Exception.php b/vendor/mongodb/mongodb/src/Exception/Exception.php new file mode 100644 index 00000000..7bb3e0d3 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Exception/Exception.php @@ -0,0 +1,24 @@ + $expectedType Expected type as a string or an array containing one or more strings + * @return self + */ + public static function invalidType(string $name, mixed $value, string|array $expectedType) + { + if (is_array($expectedType)) { + $expectedType = self::expectedTypesToString($expectedType); + } + + return new self(sprintf('Expected %s to have type "%s" but found "%s"', $name, $expectedType, get_debug_type($value))); + } + + /** @param list $types */ + private static function expectedTypesToString(array $types): string + { + assert(count($types) > 0); + + if (count($types) < 3) { + return implode('" or "', $types); + } + + $lastType = array_pop($types); + + return sprintf('%s", or "%s', implode('", "', $types), $lastType); + } +} diff --git a/vendor/mongodb/mongodb/src/Exception/ResumeTokenException.php b/vendor/mongodb/mongodb/src/Exception/ResumeTokenException.php new file mode 100644 index 00000000..fc880827 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Exception/ResumeTokenException.php @@ -0,0 +1,45 @@ +value; + } + + public static function invalidDecodableValue(mixed $value): self + { + return new self(sprintf('Could not decode value of type "%s".', get_debug_type($value)), $value); + } + + public static function invalidEncodableValue(mixed $value): self + { + return new self(sprintf('Could not encode value of type "%s".', get_debug_type($value)), $value); + } + + private function __construct(string $message, private mixed $value) + { + parent::__construct($message); + } +} diff --git a/vendor/mongodb/mongodb/src/GridFS/Bucket.php b/vendor/mongodb/mongodb/src/GridFS/Bucket.php new file mode 100644 index 00000000..85046906 --- /dev/null +++ b/vendor/mongodb/mongodb/src/GridFS/Bucket.php @@ -0,0 +1,870 @@ + BSONArray::class, + 'document' => BSONDocument::class, + 'root' => BSONDocument::class, + ]; + + private const STREAM_WRAPPER_PROTOCOL = 'gridfs'; + + private ?DocumentCodec $codec = null; + + private CollectionWrapper $collectionWrapper; + + private string $bucketName; + + private bool $disableMD5; + + private int $chunkSizeBytes; + + private ReadConcern $readConcern; + + private ReadPreference $readPreference; + + private array $typeMap; + + private WriteConcern $writeConcern; + + /** + * Constructs a GridFS bucket. + * + * Supported options: + * + * * bucketName (string): The bucket name, which will be used as a prefix + * for the files and chunks collections. Defaults to "fs". + * + * * chunkSizeBytes (integer): The chunk size in bytes. Defaults to + * 261120 (i.e. 255 KiB). + * + * * disableMD5 (boolean): When true, no MD5 sum will be generated for + * each stored file. Defaults to "false". + * + * * readConcern (MongoDB\Driver\ReadConcern): Read concern. + * + * * readPreference (MongoDB\Driver\ReadPreference): Read preference. + * + * * typeMap (array): Default type map for cursors and BSON documents. + * + * * writeConcern (MongoDB\Driver\WriteConcern): Write concern. + * + * @param Manager $manager Manager instance from the driver + * @param string $databaseName Database name + * @param array $options Bucket options + * @throws InvalidArgumentException for parameter/option parsing errors + */ + public function __construct(private Manager $manager, private string $databaseName, array $options = []) + { + if (isset($options['disableMD5']) && $options['disableMD5'] === false) { + @trigger_error('Setting GridFS "disableMD5" option to "false" is deprecated since mongodb/mongodb 1.18 and will not be supported in version 2.0.', E_USER_DEPRECATED); + } + + $options += [ + 'bucketName' => self::DEFAULT_BUCKET_NAME, + 'chunkSizeBytes' => self::DEFAULT_CHUNK_SIZE_BYTES, + 'disableMD5' => false, + ]; + + if (! is_string($options['bucketName'])) { + throw InvalidArgumentException::invalidType('"bucketName" option', $options['bucketName'], 'string'); + } + + if (! is_integer($options['chunkSizeBytes'])) { + throw InvalidArgumentException::invalidType('"chunkSizeBytes" option', $options['chunkSizeBytes'], 'integer'); + } + + if ($options['chunkSizeBytes'] < 1) { + throw new InvalidArgumentException(sprintf('Expected "chunkSizeBytes" option to be >= 1, %d given', $options['chunkSizeBytes'])); + } + + if (isset($options['codec']) && ! $options['codec'] instanceof DocumentCodec) { + throw InvalidArgumentException::invalidType('"codec" option', $options['codec'], DocumentCodec::class); + } + + if (! is_bool($options['disableMD5'])) { + throw InvalidArgumentException::invalidType('"disableMD5" option', $options['disableMD5'], 'boolean'); + } + + if (isset($options['readConcern']) && ! $options['readConcern'] instanceof ReadConcern) { + throw InvalidArgumentException::invalidType('"readConcern" option', $options['readConcern'], ReadConcern::class); + } + + if (isset($options['readPreference']) && ! $options['readPreference'] instanceof ReadPreference) { + throw InvalidArgumentException::invalidType('"readPreference" option', $options['readPreference'], ReadPreference::class); + } + + if (isset($options['typeMap']) && ! is_array($options['typeMap'])) { + throw InvalidArgumentException::invalidType('"typeMap" option', $options['typeMap'], 'array'); + } + + if (isset($options['writeConcern']) && ! $options['writeConcern'] instanceof WriteConcern) { + throw InvalidArgumentException::invalidType('"writeConcern" option', $options['writeConcern'], WriteConcern::class); + } + + if (isset($options['codec']) && isset($options['typeMap'])) { + throw InvalidArgumentException::cannotCombineCodecAndTypeMap(); + } + + $this->bucketName = $options['bucketName']; + $this->chunkSizeBytes = $options['chunkSizeBytes']; + $this->codec = $options['codec'] ?? null; + $this->disableMD5 = $options['disableMD5']; + $this->readConcern = $options['readConcern'] ?? $this->manager->getReadConcern(); + $this->readPreference = $options['readPreference'] ?? $this->manager->getReadPreference(); + $this->typeMap = $options['typeMap'] ?? self::DEFAULT_TYPE_MAP; + $this->writeConcern = $options['writeConcern'] ?? $this->manager->getWriteConcern(); + + /* The codec option is intentionally omitted when constructing the files + * and chunks collections so as not to interfere with internal GridFS + * operations. Any codec will be manually applied when querying the + * files collection (i.e. find, findOne, and getFileDocumentForStream). + */ + $collectionOptions = array_intersect_key($options, ['readConcern' => 1, 'readPreference' => 1, 'typeMap' => 1, 'writeConcern' => 1]); + + $this->collectionWrapper = new CollectionWrapper($manager, $databaseName, $options['bucketName'], $collectionOptions); + $this->registerStreamWrapper(); + } + + /** + * Return internal properties for debugging purposes. + * + * @see https://php.net/manual/en/language.oop5.magic.php#language.oop5.magic.debuginfo + * @return array + */ + public function __debugInfo() + { + return [ + 'bucketName' => $this->bucketName, + 'codec' => $this->codec, + 'databaseName' => $this->databaseName, + 'disableMD5' => $this->disableMD5, + 'manager' => $this->manager, + 'chunkSizeBytes' => $this->chunkSizeBytes, + 'readConcern' => $this->readConcern, + 'readPreference' => $this->readPreference, + 'typeMap' => $this->typeMap, + 'writeConcern' => $this->writeConcern, + ]; + } + + /** + * Delete a file from the GridFS bucket. + * + * If the files collection document is not found, this method will still + * attempt to delete orphaned chunks. + * + * @param mixed $id File ID + * @return void + * @throws FileNotFoundException if no file could be selected + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function delete(mixed $id) + { + $file = $this->collectionWrapper->findFileById($id); + $this->collectionWrapper->deleteFileAndChunksById($id); + + if ($file === null) { + throw FileNotFoundException::byId($id, $this->getFilesNamespace()); + } + } + + /** + * Delete all the revisions of a file name from the GridFS bucket. + * + * @param string $filename Filename + * + * @throws FileNotFoundException if no file could be selected + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function deleteByName(string $filename): void + { + $count = $this->collectionWrapper->deleteFileAndChunksByFilename($filename); + + if ($count === 0) { + throw FileNotFoundException::byFilename($filename); + } + } + + /** + * Writes the contents of a GridFS file to a writable stream. + * + * @param mixed $id File ID + * @param resource $destination Writable Stream + * @return void + * @throws FileNotFoundException if no file could be selected + * @throws InvalidArgumentException if $destination is not a stream + * @throws StreamException if the file could not be uploaded + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function downloadToStream(mixed $id, $destination) + { + if (! is_resource($destination) || get_resource_type($destination) != 'stream') { + throw InvalidArgumentException::invalidType('$destination', $destination, 'resource'); + } + + $source = $this->openDownloadStream($id); + if (@stream_copy_to_stream($source, $destination) === false) { + throw StreamException::downloadFromIdFailed($id, $source, $destination); + } + } + + /** + * Writes the contents of a GridFS file, which is selected by name and + * revision, to a writable stream. + * + * Supported options: + * + * * revision (integer): Which revision (i.e. documents with the same + * filename and different uploadDate) of the file to retrieve. Defaults + * to -1 (i.e. the most recent revision). + * + * Revision numbers are defined as follows: + * + * * 0 = the original stored file + * * 1 = the first revision + * * 2 = the second revision + * * etc… + * * -2 = the second most recent revision + * * -1 = the most recent revision + * + * @param string $filename Filename + * @param resource $destination Writable Stream + * @param array $options Download options + * @return void + * @throws FileNotFoundException if no file could be selected + * @throws InvalidArgumentException if $destination is not a stream + * @throws StreamException if the file could not be uploaded + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function downloadToStreamByName(string $filename, $destination, array $options = []) + { + if (! is_resource($destination) || get_resource_type($destination) != 'stream') { + throw InvalidArgumentException::invalidType('$destination', $destination, 'resource'); + } + + $source = $this->openDownloadStreamByName($filename, $options); + if (@stream_copy_to_stream($source, $destination) === false) { + throw StreamException::downloadFromFilenameFailed($filename, $source, $destination); + } + } + + /** + * Drops the files and chunks collections associated with this GridFS + * bucket. + * + * @return void + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function drop() + { + $this->collectionWrapper->dropCollections(); + } + + /** + * Finds documents from the GridFS bucket's files collection matching the + * query. + * + * @see Find::__construct() for supported options + * @param array|object $filter Query by which to filter documents + * @param array $options Additional options + * @return CursorInterface&Iterator + * @throws UnsupportedException if options are not supported by the selected server + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function find(array|object $filter = [], array $options = []) + { + if ($this->codec && ! array_key_exists('codec', $options)) { + $options['codec'] = $this->codec; + } + + return $this->collectionWrapper->findFiles($filter, $options); + } + + /** + * Finds a single document from the GridFS bucket's files collection + * matching the query. + * + * @see FindOne::__construct() for supported options + * @param array|object $filter Query by which to filter documents + * @param array $options Additional options + * @return array|object|null + * @throws UnsupportedException if options are not supported by the selected server + * @throws InvalidArgumentException for parameter/option parsing errors + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function findOne(array|object $filter = [], array $options = []) + { + if ($this->codec && ! array_key_exists('codec', $options)) { + $options['codec'] = $this->codec; + } + + return $this->collectionWrapper->findOneFile($filter, $options); + } + + /** + * Return the bucket name. + * + * @return string + */ + public function getBucketName() + { + return $this->bucketName; + } + + /** + * Return the chunks collection. + * + * @return Collection + */ + public function getChunksCollection() + { + return $this->collectionWrapper->getChunksCollection(); + } + + /** + * Return the chunk size in bytes. + * + * @return integer + */ + public function getChunkSizeBytes() + { + return $this->chunkSizeBytes; + } + + /** + * Return the database name. + * + * @return string + */ + public function getDatabaseName() + { + return $this->databaseName; + } + + /** + * Gets the file document of the GridFS file associated with a stream. + * + * @param resource $stream GridFS stream + * @return array|object + * @throws InvalidArgumentException if $stream is not a GridFS stream + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function getFileDocumentForStream($stream) + { + $file = $this->getRawFileDocumentForStream($stream); + + if ($this->codec) { + return $this->codec->decode(Document::fromPHP($file)); + } + + // Filter the raw document through the specified type map + return apply_type_map_to_document($file, $this->typeMap); + } + + /** + * Gets the file document's ID of the GridFS file associated with a stream. + * + * @param resource $stream GridFS stream + * @return mixed + * @throws CorruptFileException if the file "_id" field does not exist + * @throws InvalidArgumentException if $stream is not a GridFS stream + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function getFileIdForStream($stream) + { + $file = $this->getRawFileDocumentForStream($stream); + + /* Filter the raw document through the specified type map, but override + * the root type so we can reliably access the ID. + */ + $typeMap = ['root' => 'stdClass'] + $this->typeMap; + $file = apply_type_map_to_document($file, $typeMap); + assert(is_object($file)); + + if (! isset($file->_id) && ! property_exists($file, '_id')) { + throw new CorruptFileException('file._id does not exist'); + } + + return $file->_id; + } + + /** + * Return the files collection. + * + * @return Collection + */ + public function getFilesCollection() + { + return $this->collectionWrapper->getFilesCollection(); + } + + /** + * Return the read concern for this GridFS bucket. + * + * @see https://php.net/manual/en/mongodb-driver-readconcern.isdefault.php + * @return ReadConcern + */ + public function getReadConcern() + { + return $this->readConcern; + } + + /** + * Return the read preference for this GridFS bucket. + * + * @return ReadPreference + */ + public function getReadPreference() + { + return $this->readPreference; + } + + /** + * Return the type map for this GridFS bucket. + * + * @return array + */ + public function getTypeMap() + { + return $this->typeMap; + } + + /** + * Return the write concern for this GridFS bucket. + * + * @see https://php.net/manual/en/mongodb-driver-writeconcern.isdefault.php + * @return WriteConcern + */ + public function getWriteConcern() + { + return $this->writeConcern; + } + + /** + * Opens a readable stream for reading a GridFS file. + * + * @param mixed $id File ID + * @return resource + * @throws FileNotFoundException if no file could be selected + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function openDownloadStream(mixed $id) + { + $file = $this->collectionWrapper->findFileById($id); + + if ($file === null) { + throw FileNotFoundException::byId($id, $this->getFilesNamespace()); + } + + return $this->openDownloadStreamByFile($file); + } + + /** + * Opens a readable stream to read a GridFS file, which is selected + * by name and revision. + * + * Supported options: + * + * * revision (integer): Which revision (i.e. documents with the same + * filename and different uploadDate) of the file to retrieve. Defaults + * to -1 (i.e. the most recent revision). + * + * Revision numbers are defined as follows: + * + * * 0 = the original stored file + * * 1 = the first revision + * * 2 = the second revision + * * etc… + * * -2 = the second most recent revision + * * -1 = the most recent revision + * + * @param string $filename Filename + * @param array $options Download options + * @return resource + * @throws FileNotFoundException if no file could be selected + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function openDownloadStreamByName(string $filename, array $options = []) + { + $options += ['revision' => -1]; + + $file = $this->collectionWrapper->findFileByFilenameAndRevision($filename, $options['revision']); + + if ($file === null) { + throw FileNotFoundException::byFilenameAndRevision($filename, $options['revision'], $this->getFilesNamespace()); + } + + return $this->openDownloadStreamByFile($file); + } + + /** + * Opens a writable stream for writing a GridFS file. + * + * Supported options: + * + * * _id (mixed): File document identifier. Defaults to a new ObjectId. + * + * * chunkSizeBytes (integer): The chunk size in bytes. Defaults to the + * bucket's chunk size. + * + * * disableMD5 (boolean): When true, no MD5 sum will be generated for + * the stored file. Defaults to "false". + * + * * metadata (document): User data for the "metadata" field of the files + * collection document. + * + * @param string $filename Filename + * @param array $options Upload options + * @return resource + */ + public function openUploadStream(string $filename, array $options = []) + { + $options += [ + 'chunkSizeBytes' => $this->chunkSizeBytes, + 'disableMD5' => $this->disableMD5, + ]; + + $path = $this->createPathForUpload(); + $context = stream_context_create([ + self::STREAM_WRAPPER_PROTOCOL => [ + 'collectionWrapper' => $this->collectionWrapper, + 'filename' => $filename, + 'options' => $options, + ], + ]); + + return fopen($path, 'w', false, $context); + } + + /** + * Register an alias to enable basic filename access for this bucket. + * + * For applications that need to interact with GridFS using only a filename + * string, a bucket can be registered with an alias. Files can then be + * accessed using the following pattern: + * + * gridfs:/// + * + * Read operations will always target the most recent revision of a file. + * + * @param non-empty-string string $alias The alias to use for the bucket + */ + public function registerGlobalStreamWrapperAlias(string $alias): void + { + if ($alias === '' || str_contains($alias, '/')) { + throw new InvalidArgumentException(sprintf('The bucket alias must be a non-empty string without any slash, "%s" given', $alias)); + } + + // Use a closure to expose the private method into another class + StreamWrapper::setContextResolver($alias, fn (string $path, string $mode, array $context) => $this->resolveStreamContext($path, $mode, $context)); + } + + /** + * Renames the GridFS file with the specified ID. + * + * @param mixed $id File ID + * @param string $newFilename New filename + * @return void + * @throws FileNotFoundException if no file could be selected + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function rename(mixed $id, string $newFilename) + { + $updateResult = $this->collectionWrapper->updateFilenameForId($id, $newFilename); + + if ($updateResult->getModifiedCount() === 1) { + return; + } + + /* If the update resulted in no modification, it's possible that the + * file did not exist, in which case we must raise an error. Checking + * the write result's matched count will be most efficient, but fall + * back to a findOne operation if necessary (i.e. legacy writes). + */ + $found = $updateResult->getMatchedCount() !== null + ? $updateResult->getMatchedCount() === 1 + : $this->collectionWrapper->findFileById($id) !== null; + + if (! $found) { + throw FileNotFoundException::byId($id, $this->getFilesNamespace()); + } + } + + /** + * Renames all the revisions of a file name in the GridFS bucket. + * + * @param string $filename Filename + * @param string $newFilename New filename + * + * @throws FileNotFoundException if no file could be selected + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function renameByName(string $filename, string $newFilename): void + { + $count = $this->collectionWrapper->updateFilenameForFilename($filename, $newFilename); + + if ($count === 0) { + throw FileNotFoundException::byFilename($filename); + } + } + + /** + * Writes the contents of a readable stream to a GridFS file. + * + * Supported options: + * + * * _id (mixed): File document identifier. Defaults to a new ObjectId. + * + * * chunkSizeBytes (integer): The chunk size in bytes. Defaults to the + * bucket's chunk size. + * + * * disableMD5 (boolean): When true, no MD5 sum will be generated for + * the stored file. Defaults to "false". + * + * * metadata (document): User data for the "metadata" field of the files + * collection document. + * + * @param string $filename Filename + * @param resource $source Readable stream + * @param array $options Stream options + * @return mixed ID of the newly created GridFS file + * @throws InvalidArgumentException if $source is not a GridFS stream + * @throws StreamException if the file could not be uploaded + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function uploadFromStream(string $filename, $source, array $options = []) + { + if (! is_resource($source) || get_resource_type($source) != 'stream') { + throw InvalidArgumentException::invalidType('$source', $source, 'resource'); + } + + $destination = $this->openUploadStream($filename, $options); + + if (@stream_copy_to_stream($source, $destination) === false) { + $destinationUri = $this->createPathForFile($this->getRawFileDocumentForStream($destination)); + + throw StreamException::uploadFailed($filename, $source, $destinationUri); + } + + return $this->getFileIdForStream($destination); + } + + /** + * Creates a path for an existing GridFS file. + * + * @param object $file GridFS file document + */ + private function createPathForFile(object $file): string + { + if (is_array($file->_id) || (is_object($file->_id) && ! method_exists($file->_id, '__toString'))) { + $id = Document::fromPHP(['_id' => $file->_id])->toRelaxedExtendedJSON(); + } else { + $id = (string) $file->_id; + } + + return sprintf( + '%s://%s/%s.files/%s', + self::STREAM_WRAPPER_PROTOCOL, + urlencode($this->databaseName), + urlencode($this->bucketName), + urlencode($id), + ); + } + + /** + * Creates a path for a new GridFS file, which does not yet have an ID. + */ + private function createPathForUpload(): string + { + return sprintf( + '%s://%s/%s.files', + self::STREAM_WRAPPER_PROTOCOL, + urlencode($this->databaseName), + urlencode($this->bucketName), + ); + } + + /** + * Returns the names of the files collection. + */ + private function getFilesNamespace(): string + { + return sprintf('%s.%s.files', $this->databaseName, $this->bucketName); + } + + /** + * Gets the file document of the GridFS file associated with a stream. + * + * This returns the raw document from the StreamWrapper, which does not + * respect the Bucket's type map. + * + * @param resource $stream GridFS stream + * @throws InvalidArgumentException + */ + private function getRawFileDocumentForStream($stream): object + { + if (! is_resource($stream) || get_resource_type($stream) != 'stream') { + throw InvalidArgumentException::invalidType('$stream', $stream, 'resource'); + } + + $metadata = stream_get_meta_data($stream); + + if (! isset($metadata['wrapper_data']) || ! $metadata['wrapper_data'] instanceof StreamWrapper) { + throw InvalidArgumentException::invalidType('$stream wrapper data', $metadata['wrapper_data'] ?? null, StreamWrapper::class); + } + + return $metadata['wrapper_data']->getFile(); + } + + /** + * Opens a readable stream for the GridFS file. + * + * @param object $file GridFS file document + * @return resource + */ + private function openDownloadStreamByFile(object $file) + { + $path = $this->createPathForFile($file); + $context = stream_context_create([ + self::STREAM_WRAPPER_PROTOCOL => [ + 'collectionWrapper' => $this->collectionWrapper, + 'file' => $file, + ], + ]); + + return fopen($path, 'r', false, $context); + } + + /** + * Registers the GridFS stream wrapper if it is not already registered. + */ + private function registerStreamWrapper(): void + { + if (in_array(self::STREAM_WRAPPER_PROTOCOL, stream_get_wrappers())) { + return; + } + + StreamWrapper::register(self::STREAM_WRAPPER_PROTOCOL); + } + + /** + * Create a stream context from the path and mode provided to fopen(). + * + * @see StreamWrapper::setContextResolver() + * + * @param string $path The full url provided to fopen(). It contains the filename. + * gridfs://database_name/collection_name.files/file_name + * @param array{revision?: int, chunkSizeBytes?: int, disableMD5?: bool} $context The options provided to fopen() + * + * @return array{collectionWrapper: CollectionWrapper, file: object}|array{collectionWrapper: CollectionWrapper, filename: string, options: array} + * + * @throws FileNotFoundException + * @throws LogicException + */ + private function resolveStreamContext(string $path, string $mode, array $context): array + { + // Fallback to an empty filename if the path does not contain one: "gridfs://alias" + $filename = explode('/', $path, 4)[3] ?? ''; + + if ($mode === 'r' || $mode === 'rb') { + $file = $this->collectionWrapper->findFileByFilenameAndRevision($filename, $context['revision'] ?? -1); + + if (! is_object($file)) { + throw FileNotFoundException::byFilenameAndRevision($filename, $context['revision'] ?? -1, $path); + } + + return [ + 'collectionWrapper' => $this->collectionWrapper, + 'file' => $file, + ]; + } + + if ($mode === 'w' || $mode === 'wb') { + return [ + 'collectionWrapper' => $this->collectionWrapper, + 'filename' => $filename, + 'options' => $context + [ + 'chunkSizeBytes' => $this->chunkSizeBytes, + 'disableMD5' => $this->disableMD5, + ], + ]; + } + + throw LogicException::openModeNotSupported($mode); + } +} diff --git a/vendor/mongodb/mongodb/src/GridFS/CollectionWrapper.php b/vendor/mongodb/mongodb/src/GridFS/CollectionWrapper.php new file mode 100644 index 00000000..09b06ba2 --- /dev/null +++ b/vendor/mongodb/mongodb/src/GridFS/CollectionWrapper.php @@ -0,0 +1,380 @@ +filesCollection = new Collection($manager, $databaseName, sprintf('%s.files', $bucketName), $collectionOptions); + $this->chunksCollection = new Collection($manager, $databaseName, sprintf('%s.chunks', $bucketName), $collectionOptions); + } + + /** + * Deletes all GridFS chunks for a given file ID. + */ + public function deleteChunksByFilesId(mixed $id): void + { + $this->chunksCollection->deleteMany(['files_id' => $id]); + } + + /** + * Delete all GridFS files and chunks for a given filename. + */ + public function deleteFileAndChunksByFilename(string $filename): int + { + /** @var iterable $files */ + $files = $this->findFiles(['filename' => $filename], [ + 'typeMap' => ['root' => 'array'], + 'projection' => ['_id' => 1], + ]); + + /** @var list $ids */ + $ids = []; + foreach ($files as $file) { + $ids[] = $file['_id']; + } + + $count = $this->filesCollection->deleteMany(['_id' => ['$in' => $ids]])->getDeletedCount(); + $this->chunksCollection->deleteMany(['files_id' => ['$in' => $ids]]); + + return $count; + } + + /** + * Deletes a GridFS file and related chunks by ID. + */ + public function deleteFileAndChunksById(mixed $id): void + { + $this->filesCollection->deleteOne(['_id' => $id]); + $this->chunksCollection->deleteMany(['files_id' => $id]); + } + + /** + * Drops the GridFS files and chunks collections. + */ + public function dropCollections(): void + { + $this->filesCollection->drop(['typeMap' => []]); + $this->chunksCollection->drop(['typeMap' => []]); + } + + /** + * Finds GridFS chunk documents for a given file ID and optional offset. + * + * @param mixed $id File ID + * @param integer $fromChunk Starting chunk (inclusive) + * @return CursorInterface&Iterator + */ + public function findChunksByFileId(mixed $id, int $fromChunk = 0) + { + return $this->chunksCollection->find( + [ + 'files_id' => $id, + 'n' => ['$gte' => $fromChunk], + ], + [ + 'sort' => ['n' => 1], + 'typeMap' => ['root' => 'stdClass'], + ], + ); + } + + /** + * Finds a GridFS file document for a given filename and revision. + * + * Revision numbers are defined as follows: + * + * * 0 = the original stored file + * * 1 = the first revision + * * 2 = the second revision + * * etc… + * * -2 = the second most recent revision + * * -1 = the most recent revision + * + * @see Bucket::downloadToStreamByName() + * @see Bucket::openDownloadStreamByName() + */ + public function findFileByFilenameAndRevision(string $filename, int $revision): ?object + { + if ($revision < 0) { + $skip = abs($revision) - 1; + $sortOrder = -1; + } else { + $skip = $revision; + $sortOrder = 1; + } + + $file = $this->filesCollection->findOne( + ['filename' => $filename], + [ + 'skip' => $skip, + 'sort' => ['uploadDate' => $sortOrder], + 'typeMap' => ['root' => 'stdClass'], + ], + ); + assert(is_object($file) || $file === null); + + return $file; + } + + /** + * Finds a GridFS file document for a given ID. + */ + public function findFileById(mixed $id): ?object + { + $file = $this->filesCollection->findOne( + ['_id' => $id], + ['typeMap' => ['root' => 'stdClass']], + ); + assert(is_object($file) || $file === null); + + return $file; + } + + /** + * Finds documents from the GridFS bucket's files collection. + * + * @see Find::__construct() for supported options + * @param array|object $filter Query by which to filter documents + * @param array $options Additional options + * @return CursorInterface&Iterator + */ + public function findFiles(array|object $filter, array $options = []) + { + return $this->filesCollection->find($filter, $options); + } + + /** + * Finds a single document from the GridFS bucket's files collection. + * + * @param array|object $filter Query by which to filter documents + * @param array $options Additional options + * @return array|object|null + */ + public function findOneFile(array|object $filter, array $options = []) + { + return $this->filesCollection->findOne($filter, $options); + } + + public function getBucketName(): string + { + return $this->bucketName; + } + + public function getChunksCollection(): Collection + { + return $this->chunksCollection; + } + + public function getDatabaseName(): string + { + return $this->databaseName; + } + + public function getFilesCollection(): Collection + { + return $this->filesCollection; + } + + /** + * Inserts a document into the chunks collection. + * + * @param array|object $chunk Chunk document + */ + public function insertChunk(array|object $chunk): void + { + if (! $this->checkedIndexes) { + $this->ensureIndexes(); + } + + $this->chunksCollection->insertOne($chunk); + } + + /** + * Inserts a document into the files collection. + * + * The file document should be inserted after all chunks have been inserted. + * + * @param array|object $file File document + */ + public function insertFile(array|object $file): void + { + if (! $this->checkedIndexes) { + $this->ensureIndexes(); + } + + $this->filesCollection->insertOne($file); + } + + /** + * Updates the filename field in the file document for all the files with a given filename. + */ + public function updateFilenameForFilename(string $filename, string $newFilename): int + { + return $this->filesCollection->updateMany( + ['filename' => $filename], + ['$set' => ['filename' => $newFilename]], + )->getMatchedCount(); + } + + /** + * Updates the filename field in the file document for a given ID. + */ + public function updateFilenameForId(mixed $id, string $filename): UpdateResult + { + return $this->filesCollection->updateOne( + ['_id' => $id], + ['$set' => ['filename' => $filename]], + ); + } + + /** + * Create an index on the chunks collection if it does not already exist. + */ + private function ensureChunksIndex(): void + { + $expectedIndex = ['files_id' => 1, 'n' => 1]; + + foreach ($this->chunksCollection->listIndexes() as $index) { + if ($index->isUnique() && $this->indexKeysMatch($expectedIndex, $index->getKey())) { + return; + } + } + + $this->chunksCollection->createIndex($expectedIndex, ['unique' => true]); + } + + /** + * Create an index on the files collection if it does not already exist. + */ + private function ensureFilesIndex(): void + { + $expectedIndex = ['filename' => 1, 'uploadDate' => 1]; + + foreach ($this->filesCollection->listIndexes() as $index) { + if ($this->indexKeysMatch($expectedIndex, $index->getKey())) { + return; + } + } + + $this->filesCollection->createIndex($expectedIndex); + } + + /** + * Ensure indexes on the files and chunks collections exist. + * + * This method is called once before the first write operation on a GridFS + * bucket. Indexes are only be created if the files collection is empty. + */ + private function ensureIndexes(): void + { + if ($this->checkedIndexes) { + return; + } + + $this->checkedIndexes = true; + + if (! $this->isFilesCollectionEmpty()) { + return; + } + + $this->ensureFilesIndex(); + $this->ensureChunksIndex(); + } + + private function indexKeysMatch(array $expectedKeys, array $actualKeys): bool + { + if (count($expectedKeys) !== count($actualKeys)) { + return false; + } + + $iterator = new MultipleIterator(MultipleIterator::MIT_NEED_ANY); + $iterator->attachIterator(new ArrayIterator($expectedKeys)); + $iterator->attachIterator(new ArrayIterator($actualKeys)); + + foreach ($iterator as $key => $value) { + [$expectedKey, $actualKey] = $key; + [$expectedValue, $actualValue] = $value; + + if ($expectedKey !== $actualKey) { + return false; + } + + /* Since we don't expect special indexes (e.g. text), we mark any + * index with a non-numeric definition as unequal. All others are + * compared against their int value to avoid differences due to + * some drivers using float values in the key specification. */ + if (! is_numeric($actualValue) || (int) $expectedValue !== (int) $actualValue) { + return false; + } + } + + return true; + } + + /** + * Returns whether the files collection is empty. + */ + private function isFilesCollectionEmpty(): bool + { + return null === $this->filesCollection->findOne([], [ + 'readPreference' => new ReadPreference(ReadPreference::PRIMARY), + 'projection' => ['_id' => 1], + 'typeMap' => [], + ]); + } +} diff --git a/vendor/mongodb/mongodb/src/GridFS/Exception/CorruptFileException.php b/vendor/mongodb/mongodb/src/GridFS/Exception/CorruptFileException.php new file mode 100644 index 00000000..db162290 --- /dev/null +++ b/vendor/mongodb/mongodb/src/GridFS/Exception/CorruptFileException.php @@ -0,0 +1,68 @@ + $id])->toRelaxedExtendedJSON(); + + return new self(sprintf('File "%s" not found in "%s"', $json, $namespace)); + } +} diff --git a/vendor/mongodb/mongodb/src/GridFS/Exception/LogicException.php b/vendor/mongodb/mongodb/src/GridFS/Exception/LogicException.php new file mode 100644 index 00000000..a6835423 --- /dev/null +++ b/vendor/mongodb/mongodb/src/GridFS/Exception/LogicException.php @@ -0,0 +1,78 @@ + $id])->toRelaxedExtendedJSON(); + $sourceMetadata = stream_get_meta_data($source); + $destinationMetadata = stream_get_meta_data($destination); + + return new self(sprintf('Downloading file from "%s" to "%s" failed. GridFS identifier: "%s"', $sourceMetadata['uri'], $destinationMetadata['uri'], $idString)); + } + + /** @param resource $source */ + public static function uploadFailed(string $filename, $source, string $destinationUri): self + { + $sourceMetadata = stream_get_meta_data($source); + + return new self(sprintf('Uploading file from "%s" to "%s" failed. GridFS filename: "%s"', $sourceMetadata['uri'], $destinationUri, $filename)); + } +} diff --git a/vendor/mongodb/mongodb/src/GridFS/ReadableStream.php b/vendor/mongodb/mongodb/src/GridFS/ReadableStream.php new file mode 100644 index 00000000..980e3e19 --- /dev/null +++ b/vendor/mongodb/mongodb/src/GridFS/ReadableStream.php @@ -0,0 +1,307 @@ +chunkSize) || ! is_integer($file->chunkSize) || $file->chunkSize < 1) { + throw new CorruptFileException('file.chunkSize is not an integer >= 1'); + } + + if (! isset($file->length) || ! is_integer($file->length) || $file->length < 0) { + throw new CorruptFileException('file.length is not an integer > 0'); + } + + if (! isset($file->_id) && ! property_exists($file, '_id')) { + throw new CorruptFileException('file._id does not exist'); + } + + $this->chunkSize = $file->chunkSize; + $this->length = $file->length; + + if ($this->length > 0) { + $this->numChunks = (integer) ceil($this->length / $this->chunkSize); + $this->expectedLastChunkSize = $this->length - (($this->numChunks - 1) * $this->chunkSize); + } + } + + /** + * Return internal properties for debugging purposes. + * + * @see https://php.net/manual/en/language.oop5.magic.php#language.oop5.magic.debuginfo + */ + public function __debugInfo(): array + { + return [ + 'bucketName' => $this->collectionWrapper->getBucketName(), + 'databaseName' => $this->collectionWrapper->getDatabaseName(), + 'file' => $this->file, + ]; + } + + public function close(): void + { + // Nothing to do + } + + public function getFile(): object + { + return $this->file; + } + + public function getSize(): int + { + return $this->length; + } + + /** + * Return whether the current read position is at the end of the stream. + */ + public function isEOF(): bool + { + if ($this->chunkOffset === $this->numChunks - 1) { + return $this->bufferOffset >= $this->expectedLastChunkSize; + } + + return $this->chunkOffset >= $this->numChunks; + } + + /** + * Read bytes from the stream. + * + * Note: this method may return a string smaller than the requested length + * if data is not available to be read. + * + * @param integer $length Number of bytes to read + * @throws InvalidArgumentException if $length is negative + */ + public function readBytes(int $length): string + { + if ($length < 0) { + throw new InvalidArgumentException(sprintf('$length must be >= 0; given: %d', $length)); + } + + if ($this->chunksIterator === null) { + $this->initChunksIterator(); + } + + if ($this->buffer === null && ! $this->initBufferFromCurrentChunk()) { + return ''; + } + + assert($this->buffer !== null); + + $data = ''; + + while (strlen($data) < $length) { + if ($this->bufferOffset >= strlen($this->buffer) && ! $this->initBufferFromNextChunk()) { + break; + } + + $initialDataLength = strlen($data); + $data .= substr($this->buffer, $this->bufferOffset, $length - $initialDataLength); + $this->bufferOffset += strlen($data) - $initialDataLength; + } + + return $data; + } + + /** + * Seeks the chunk and buffer offsets for the next read operation. + * + * @throws InvalidArgumentException if $offset is out of range + */ + public function seek(int $offset): void + { + if ($offset < 0 || $offset > $this->file->length) { + throw new InvalidArgumentException(sprintf('$offset must be >= 0 and <= %d; given: %d', $this->file->length, $offset)); + } + + /* Compute the offsets for the chunk and buffer (i.e. chunk data) from + * which we will expect to read after seeking. If the chunk offset + * changed, we'll also need to reset the buffer. + */ + $lastChunkOffset = $this->chunkOffset; + $this->chunkOffset = (integer) floor($offset / $this->chunkSize); + $this->bufferOffset = $offset % $this->chunkSize; + + if ($lastChunkOffset === $this->chunkOffset) { + return; + } + + if ($this->chunksIterator === null) { + return; + } + + // Clear the buffer since the current chunk will be changed + $this->buffer = null; + + /* If we are seeking to a previous chunk, we need to reinitialize the + * chunk iterator. + */ + if ($lastChunkOffset > $this->chunkOffset) { + $this->chunksIterator = null; + + return; + } + + /* If we are seeking to a subsequent chunk, we do not need to + * reinitalize the chunk iterator. Instead, we can move forward + * to $this->chunkOffset. + */ + $numChunks = $this->chunkOffset - $lastChunkOffset; + for ($i = 0; $i < $numChunks; $i++) { + $this->chunksIterator->next(); + } + } + + /** + * Return the current position of the stream. + * + * This is the offset within the stream where the next byte would be read. + */ + public function tell(): int + { + return ($this->chunkOffset * $this->chunkSize) + $this->bufferOffset; + } + + /** + * Initialize the buffer to the current chunk's data. + * + * @return boolean Whether there was a current chunk to read + * @throws CorruptFileException if an expected chunk could not be read successfully + */ + private function initBufferFromCurrentChunk(): bool + { + if ($this->chunkOffset === 0 && $this->numChunks === 0) { + return false; + } + + if ($this->chunksIterator === null) { + return false; + } + + if (! $this->chunksIterator->valid()) { + throw CorruptFileException::missingChunk($this->chunkOffset); + } + + $currentChunk = $this->chunksIterator->current(); + assert(is_object($currentChunk)); + + if ($currentChunk->n !== $this->chunkOffset) { + throw CorruptFileException::unexpectedIndex($currentChunk->n, $this->chunkOffset); + } + + if (! $currentChunk->data instanceof Binary) { + throw CorruptFileException::invalidChunkData($this->chunkOffset); + } + + $this->buffer = $currentChunk->data->getData(); + + $actualChunkSize = strlen($this->buffer); + + $expectedChunkSize = $this->chunkOffset === $this->numChunks - 1 + ? $this->expectedLastChunkSize + : $this->chunkSize; + + if ($actualChunkSize !== $expectedChunkSize) { + throw CorruptFileException::unexpectedSize($actualChunkSize, $expectedChunkSize); + } + + return true; + } + + /** + * Advance to the next chunk and initialize the buffer to its data. + * + * @return boolean Whether there was a next chunk to read + * @throws CorruptFileException if an expected chunk could not be read successfully + */ + private function initBufferFromNextChunk(): bool + { + if ($this->chunkOffset === $this->numChunks - 1) { + return false; + } + + if ($this->chunksIterator === null) { + return false; + } + + $this->bufferOffset = 0; + $this->chunkOffset++; + $this->chunksIterator->next(); + + return $this->initBufferFromCurrentChunk(); + } + + /** + * Initializes the chunk iterator starting from the current offset. + */ + private function initChunksIterator(): void + { + $this->chunksIterator = $this->collectionWrapper->findChunksByFileId($this->file->_id, $this->chunkOffset); + $this->chunksIterator->rewind(); + } +} diff --git a/vendor/mongodb/mongodb/src/GridFS/StreamWrapper.php b/vendor/mongodb/mongodb/src/GridFS/StreamWrapper.php new file mode 100644 index 00000000..cc1d89fc --- /dev/null +++ b/vendor/mongodb/mongodb/src/GridFS/StreamWrapper.php @@ -0,0 +1,425 @@ + */ + private static array $contextResolvers = []; + + public function __destruct() + { + /* Ensure the stream is closed so the last chunk is written. This is + * necessary because PHP would close the stream after all objects have + * been destructed. This can cause autoloading issues and possibly + * segmentation faults during PHP shutdown. */ + $this->stream_close(); + } + + /** + * Return the stream's file document. + */ + public function getFile(): object + { + assert($this->stream !== null); + + return $this->stream->getFile(); + } + + /** + * Register the GridFS stream wrapper. + * + * @param string $protocol Protocol to use for stream_wrapper_register() + */ + public static function register(string $protocol = 'gridfs'): void + { + if (in_array($protocol, stream_get_wrappers())) { + stream_wrapper_unregister($protocol); + } + + stream_wrapper_register($protocol, static::class, STREAM_IS_URL); + } + + /** + * Rename all revisions of a filename. + * + * @return true + * @throws FileNotFoundException + */ + public function rename(string $fromPath, string $toPath): bool + { + $prefix = implode('/', array_slice(explode('/', $fromPath, 4), 0, 3)) . '/'; + if (! str_starts_with($toPath, $prefix)) { + throw LogicException::renamePathMismatch($fromPath, $toPath); + } + + $context = $this->getContext($fromPath, 'w'); + + $newFilename = explode('/', $toPath, 4)[3] ?? ''; + $count = $context['collectionWrapper']->updateFilenameForFilename($context['filename'], $newFilename); + + if ($count === 0) { + throw FileNotFoundException::byFilename($fromPath); + } + + // If $count is null, the update is unacknowledged, the operation is considered successful. + return true; + } + + /** + * @see Bucket::resolveStreamContext() + * + * @param Closure(string, string, array):ContextOptions|null $resolver + */ + public static function setContextResolver(string $name, ?Closure $resolver): void + { + if ($resolver === null) { + unset(self::$contextResolvers[$name]); + } else { + self::$contextResolvers[$name] = $resolver; + } + } + + /** + * Closes the stream. + * + * @see https://php.net/manual/en/streamwrapper.stream-close.php + */ + public function stream_close(): void + { + if (! $this->stream) { + return; + } + + $this->stream->close(); + } + + /** + * Returns whether the file pointer is at the end of the stream. + * + * @see https://php.net/manual/en/streamwrapper.stream-eof.php + */ + public function stream_eof(): bool + { + if (! $this->stream instanceof ReadableStream) { + return false; + } + + return $this->stream->isEOF(); + } + + /** + * Opens the stream. + * + * @see https://php.net/manual/en/streamwrapper.stream-open.php + * @param string $path Path to the file resource + * @param string $mode Mode used to open the file (only "r" and "w" are supported) + * @param integer $options Additional flags set by the streams API + * @param string|null $openedPath Not used + */ + public function stream_open(string $path, string $mode, int $options, ?string &$openedPath): bool + { + if ($mode === 'r' || $mode === 'rb') { + return $this->initReadableStream($this->getContext($path, $mode)); + } + + if ($mode === 'w' || $mode === 'wb') { + return $this->initWritableStream($this->getContext($path, $mode)); + } + + throw LogicException::openModeNotSupported($mode); + } + + /** + * Read bytes from the stream. + * + * Note: this method may return a string smaller than the requested length + * if data is not available to be read. + * + * @see https://php.net/manual/en/streamwrapper.stream-read.php + * @param integer $length Number of bytes to read + */ + public function stream_read(int $length): string + { + if (! $this->stream instanceof ReadableStream) { + return ''; + } + + return $this->stream->readBytes($length); + } + + /** + * Return the current position of the stream. + * + * @see https://php.net/manual/en/streamwrapper.stream-seek.php + * @param integer $offset Stream offset to seek to + * @param integer $whence One of SEEK_SET, SEEK_CUR, or SEEK_END + * @return boolean True if the position was updated and false otherwise + */ + public function stream_seek(int $offset, int $whence = SEEK_SET): bool + { + assert($this->stream !== null); + + $size = $this->stream->getSize(); + + if ($whence === SEEK_CUR) { + $offset += $this->stream->tell(); + } + + if ($whence === SEEK_END) { + $offset += $size; + } + + // WritableStreams are always positioned at the end of the stream + if ($this->stream instanceof WritableStream) { + return $offset === $size; + } + + if ($offset < 0 || $offset > $size) { + return false; + } + + $this->stream->seek($offset); + + return true; + } + + /** + * Return information about the stream. + * + * @see https://php.net/manual/en/streamwrapper.stream-stat.php + */ + public function stream_stat(): array + { + assert($this->stream !== null); + + $stat = $this->getStatTemplate(); + + $stat[2] = $stat['mode'] = $this->stream instanceof ReadableStream + ? 0100444 // S_IFREG & S_IRUSR & S_IRGRP & S_IROTH + : 0100222; // S_IFREG & S_IWUSR & S_IWGRP & S_IWOTH + $stat[7] = $stat['size'] = $this->stream->getSize(); + + $file = $this->stream->getFile(); + + if (isset($file->uploadDate) && $file->uploadDate instanceof UTCDateTime) { + $timestamp = $file->uploadDate->toDateTime()->getTimestamp(); + $stat[9] = $stat['mtime'] = $timestamp; + $stat[10] = $stat['ctime'] = $timestamp; + } + + if (isset($file->chunkSize) && is_integer($file->chunkSize)) { + $stat[11] = $stat['blksize'] = $file->chunkSize; + } + + return $stat; + } + + /** + * Return the current position of the stream. + * + * @see https://php.net/manual/en/streamwrapper.stream-tell.php + * @return integer The current position of the stream + */ + public function stream_tell(): int + { + assert($this->stream !== null); + + return $this->stream->tell(); + } + + /** + * Write bytes to the stream. + * + * @see https://php.net/manual/en/streamwrapper.stream-write.php + * @param string $data Data to write + * @return integer The number of bytes written + */ + public function stream_write(string $data): int + { + if (! $this->stream instanceof WritableStream) { + return 0; + } + + return $this->stream->writeBytes($data); + } + + /** + * Remove all revisions of a filename. + * + * @return true + * @throws FileNotFoundException + */ + public function unlink(string $path): bool + { + $context = $this->getContext($path, 'w'); + $count = $context['collectionWrapper']->deleteFileAndChunksByFilename($context['filename']); + + if ($count === 0) { + throw FileNotFoundException::byFilename($path); + } + + // If $count is null, the update is unacknowledged, the operation is considered successful. + return true; + } + + /** @return false|array */ + public function url_stat(string $path, int $flags) + { + assert($this->stream === null); + + try { + $this->stream_open($path, 'r', 0, $openedPath); + } catch (FileNotFoundException) { + return false; + } + + return $this->stream_stat(); + } + + /** + * @return array{collectionWrapper: CollectionWrapper, file: object}|array{collectionWrapper: CollectionWrapper, filename: string, options: array} + * @psalm-return ($mode == 'r' or $mode == 'rb' ? array{collectionWrapper: CollectionWrapper, file: object} : array{collectionWrapper: CollectionWrapper, filename: string, options: array}) + */ + private function getContext(string $path, string $mode): array + { + $context = []; + + /** + * The Bucket methods { @see Bucket::openUploadStream() } and { @see Bucket::openDownloadStreamByFile() } + * always set an internal context. But the context can also be set by the user. + */ + if (is_resource($this->context)) { + $context = stream_context_get_options($this->context)['gridfs'] ?? []; + + if (! is_array($context)) { + throw LogicException::invalidContext($context); + } + } + + // When the stream is opened using fopen(), the context is not required, it can contain only options. + if (! isset($context['collectionWrapper'])) { + $bucketAlias = explode('/', $path, 4)[2] ?? ''; + + if (! isset(self::$contextResolvers[$bucketAlias])) { + throw LogicException::bucketAliasNotRegistered($bucketAlias); + } + + /** @see Bucket::resolveStreamContext() */ + $context = self::$contextResolvers[$bucketAlias]($path, $mode, $context); + } + + if (! $context['collectionWrapper'] instanceof CollectionWrapper) { + throw LogicException::invalidContextCollectionWrapper($context['collectionWrapper']); + } + + return $context; + } + + /** + * Returns a stat template with default values. + */ + private function getStatTemplate(): array + { + return [ + // phpcs:disable Squiz.Arrays.ArrayDeclaration.IndexNoNewline + 0 => 0, 'dev' => 0, + 1 => 0, 'ino' => 0, + 2 => 0, 'mode' => 0, + 3 => 0, 'nlink' => 0, + 4 => 0, 'uid' => 0, + 5 => 0, 'gid' => 0, + 6 => -1, 'rdev' => -1, + 7 => 0, 'size' => 0, + 8 => 0, 'atime' => 0, + 9 => 0, 'mtime' => 0, + 10 => 0, 'ctime' => 0, + 11 => -1, 'blksize' => -1, + 12 => -1, 'blocks' => -1, + // phpcs:enable + ]; + } + + /** + * Initialize the internal stream for reading. + * + * @param array{collectionWrapper: CollectionWrapper, file: object} $contextOptions + */ + private function initReadableStream(array $contextOptions): bool + { + $this->stream = new ReadableStream( + $contextOptions['collectionWrapper'], + $contextOptions['file'], + ); + + return true; + } + + /** + * Initialize the internal stream for writing. + * + * @param array{collectionWrapper: CollectionWrapper, filename: string, options: array} $contextOptions + */ + private function initWritableStream(array $contextOptions): bool + { + $this->stream = new WritableStream( + $contextOptions['collectionWrapper'], + $contextOptions['filename'], + $contextOptions['options'], + ); + + return true; + } +} diff --git a/vendor/mongodb/mongodb/src/GridFS/WritableStream.php b/vendor/mongodb/mongodb/src/GridFS/WritableStream.php new file mode 100644 index 00000000..65b35de9 --- /dev/null +++ b/vendor/mongodb/mongodb/src/GridFS/WritableStream.php @@ -0,0 +1,294 @@ + new ObjectId(), + 'chunkSizeBytes' => self::DEFAULT_CHUNK_SIZE_BYTES, + 'disableMD5' => false, + ]; + + if (isset($options['aliases']) && ! is_string_array($options['aliases'])) { + throw InvalidArgumentException::invalidType('"aliases" option', $options['aliases'], 'array of strings'); + } + + if (! is_integer($options['chunkSizeBytes'])) { + throw InvalidArgumentException::invalidType('"chunkSizeBytes" option', $options['chunkSizeBytes'], 'integer'); + } + + if ($options['chunkSizeBytes'] < 1) { + throw new InvalidArgumentException(sprintf('Expected "chunkSizeBytes" option to be >= 1, %d given', $options['chunkSizeBytes'])); + } + + if (! is_bool($options['disableMD5'])) { + throw InvalidArgumentException::invalidType('"disableMD5" option', $options['disableMD5'], 'boolean'); + } + + if (isset($options['contentType']) && ! is_string($options['contentType'])) { + throw InvalidArgumentException::invalidType('"contentType" option', $options['contentType'], 'string'); + } + + if (isset($options['metadata']) && ! is_document($options['metadata'])) { + throw InvalidArgumentException::expectedDocumentType('"metadata" option', $options['metadata']); + } + + $this->chunkSize = $options['chunkSizeBytes']; + $this->disableMD5 = $options['disableMD5']; + + if (! $this->disableMD5) { + $this->hashCtx = hash_init('md5'); + } + + $this->file = [ + '_id' => $options['_id'], + 'chunkSize' => $this->chunkSize, + 'filename' => $filename, + 'length' => null, + 'uploadDate' => null, + ] + array_intersect_key($options, ['aliases' => 1, 'contentType' => 1, 'metadata' => 1]); + } + + /** + * Return internal properties for debugging purposes. + * + * @see https://php.net/manual/en/language.oop5.magic.php#language.oop5.magic.debuginfo + */ + public function __debugInfo(): array + { + return [ + 'bucketName' => $this->collectionWrapper->getBucketName(), + 'databaseName' => $this->collectionWrapper->getDatabaseName(), + 'file' => $this->file, + ]; + } + + /** + * Closes an active stream and flushes all buffered data to GridFS. + */ + public function close(): void + { + if ($this->isClosed) { + // TODO: Should this be an error condition? e.g. BadMethodCallException + return; + } + + if (strlen($this->buffer) > 0) { + $this->insertChunkFromBuffer(); + } + + $this->fileCollectionInsert(); + $this->isClosed = true; + } + + /** + * Return the stream's file document. + */ + public function getFile(): object + { + return (object) $this->file; + } + + /** + * Return the stream's size in bytes. + * + * Note: this value will increase as more data is written to the stream. + */ + public function getSize(): int + { + return $this->length + strlen($this->buffer); + } + + /** + * Return the current position of the stream. + * + * This is the offset within the stream where the next byte would be + * written. Since seeking is not supported and writes are appended, this is + * always the end of the stream. + * + * @see WritableStream::getSize() + */ + public function tell(): int + { + return $this->getSize(); + } + + /** + * Inserts binary data into GridFS via chunks. + * + * Data will be buffered internally until chunkSizeBytes are accumulated, at + * which point a chunk document will be inserted and the buffer reset. + * + * @param string $data Binary data to write + */ + public function writeBytes(string $data): int + { + if ($this->isClosed) { + // TODO: Should this be an error condition? e.g. BadMethodCallException + return 0; + } + + $bytesRead = 0; + + while ($bytesRead != strlen($data)) { + $initialBufferLength = strlen($this->buffer); + $this->buffer .= substr($data, $bytesRead, $this->chunkSize - $initialBufferLength); + $bytesRead += strlen($this->buffer) - $initialBufferLength; + + if (strlen($this->buffer) == $this->chunkSize) { + $this->insertChunkFromBuffer(); + } + } + + return $bytesRead; + } + + private function abort(): void + { + try { + $this->collectionWrapper->deleteChunksByFilesId($this->file['_id']); + } catch (DriverRuntimeException) { + // We are already handling an error if abort() is called, so suppress this + } + + $this->isClosed = true; + } + + private function fileCollectionInsert(): void + { + $this->file['length'] = $this->length; + $this->file['uploadDate'] = new UTCDateTime(); + + if (! $this->disableMD5 && $this->hashCtx) { + $this->file['md5'] = hash_final($this->hashCtx); + } + + try { + $this->collectionWrapper->insertFile($this->file); + } catch (DriverRuntimeException $e) { + $this->abort(); + + throw $e; + } + } + + private function insertChunkFromBuffer(): void + { + if (strlen($this->buffer) == 0) { + return; + } + + $data = $this->buffer; + $this->buffer = ''; + + $chunk = [ + 'files_id' => $this->file['_id'], + 'n' => $this->chunkOffset, + 'data' => new Binary($data), + ]; + + if (! $this->disableMD5 && $this->hashCtx) { + hash_update($this->hashCtx, $data); + } + + try { + $this->collectionWrapper->insertChunk($chunk); + } catch (DriverRuntimeException $e) { + $this->abort(); + + throw $e; + } + + $this->length += strlen($data); + $this->chunkOffset++; + } +} diff --git a/vendor/mongodb/mongodb/src/InsertManyResult.php b/vendor/mongodb/mongodb/src/InsertManyResult.php new file mode 100644 index 00000000..6ad2a959 --- /dev/null +++ b/vendor/mongodb/mongodb/src/InsertManyResult.php @@ -0,0 +1,81 @@ +isAcknowledged = $writeResult->isAcknowledged(); + } + + /** + * Return the number of documents that were inserted. + * + * This method should only be called if the write was acknowledged. + * + * @see InsertManyResult::isAcknowledged() + * @return integer|null + * @throws BadMethodCallException if the write result is unacknowledged + */ + public function getInsertedCount() + { + if ($this->isAcknowledged) { + return $this->writeResult->getInsertedCount(); + } + + throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__); + } + + /** + * Return a map of the inserted documents' IDs. + * + * The index of each ID in the map corresponds to each document's position + * in the bulk operation. If a document had an ID prior to inserting (i.e. + * the driver did not generate an ID), the index will contain its "_id" + * field value. Any driver-generated ID will be a MongoDB\BSON\ObjectId + * instance. + * + * @return array + */ + public function getInsertedIds() + { + return $this->insertedIds; + } + + /** + * Return whether this insert result was acknowledged by the server. + * + * If the insert was not acknowledged, other fields from the WriteResult + * (e.g. insertedCount) will be undefined. + * + * @return boolean + */ + public function isAcknowledged() + { + return $this->writeResult->isAcknowledged(); + } +} diff --git a/vendor/mongodb/mongodb/src/InsertOneResult.php b/vendor/mongodb/mongodb/src/InsertOneResult.php new file mode 100644 index 00000000..9c72775c --- /dev/null +++ b/vendor/mongodb/mongodb/src/InsertOneResult.php @@ -0,0 +1,83 @@ +isAcknowledged = $writeResult->isAcknowledged(); + } + + /** + * Return the number of documents that were inserted. + * + * This method should only be called if the write was acknowledged. + * + * @see InsertOneResult::isAcknowledged() + * @return integer|null + * @throws BadMethodCallException if the write result is unacknowledged + */ + public function getInsertedCount() + { + if ($this->isAcknowledged) { + return $this->writeResult->getInsertedCount(); + } + + throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__); + } + + /** + * Return the inserted document's ID. + * + * If the document had an ID prior to inserting (i.e. the driver did not + * need to generate an ID), this will contain its "_id". Any + * driver-generated ID will be a MongoDB\BSON\ObjectId instance. + * + * @return mixed + */ + public function getInsertedId() + { + return $this->insertedId; + } + + /** + * Return whether this insert was acknowledged by the server. + * + * If the insert was not acknowledged, other fields from the WriteResult + * (e.g. insertedCount) will be undefined. + * + * If the insert was not acknowledged, other fields from the WriteResult + * (e.g. insertedCount) will be undefined and their getter methods should + * not be invoked. + * + * @return boolean + */ + public function isAcknowledged() + { + return $this->writeResult->isAcknowledged(); + } +} diff --git a/vendor/mongodb/mongodb/src/MapReduceResult.php b/vendor/mongodb/mongodb/src/MapReduceResult.php new file mode 100644 index 00000000..00a75116 --- /dev/null +++ b/vendor/mongodb/mongodb/src/MapReduceResult.php @@ -0,0 +1,111 @@ + + * @psalm-type MapReduceCallable = callable(): Traversable + */ +class MapReduceResult implements IteratorAggregate +{ + /** + * @var callable + * @psalm-var MapReduceCallable + */ + private $getIterator; + + private int $executionTimeMS; + + private array $counts; + + private array $timing; + + /** + * Returns various count statistics from the mapReduce command. + * + * @return array + */ + public function getCounts() + { + return $this->counts; + } + + /** + * Return the command execution time in milliseconds. + * + * @return integer + */ + public function getExecutionTimeMS() + { + return $this->executionTimeMS; + } + + /** + * Return the mapReduce results as a Traversable. + * + * @see https://php.net/iteratoraggregate.getiterator + * @return Traversable + */ + #[ReturnTypeWillChange] + public function getIterator() + { + return call_user_func($this->getIterator); + } + + /** + * Returns various timing statistics from the mapReduce command. + * + * Note: timing statistics are only available if the mapReduce command's + * "verbose" option was true; otherwise, an empty array will be returned. + * + * @return array + */ + public function getTiming() + { + return $this->timing; + } + + /** + * @internal + * @param callable $getIterator Callback that returns a Traversable for mapReduce results + * @param stdClass $result Result document from the mapReduce command + * @psalm-param MapReduceCallable $getIterator + */ + public function __construct(callable $getIterator, stdClass $result) + { + $this->getIterator = $getIterator; + $this->executionTimeMS = isset($result->timeMillis) ? (integer) $result->timeMillis : 0; + $this->counts = isset($result->counts) ? (array) $result->counts : []; + $this->timing = isset($result->timing) ? (array) $result->timing : []; + } +} diff --git a/vendor/mongodb/mongodb/src/Model/BSONArray.php b/vendor/mongodb/mongodb/src/Model/BSONArray.php new file mode 100644 index 00000000..f055f4cb --- /dev/null +++ b/vendor/mongodb/mongodb/src/Model/BSONArray.php @@ -0,0 +1,105 @@ + + */ +class BSONArray extends ArrayObject implements JsonSerializable, Serializable, Unserializable +{ + /** + * Clone this BSONArray. + */ + public function __clone() + { + foreach ($this as $key => $value) { + $this[$key] = recursive_copy($value); + } + } + + /** + * Factory method for var_export(). + * + * @see https://php.net/oop5.magic#object.set-state + * @see https://php.net/var-export + * @return self + */ + public static function __set_state(array $properties) + { + $array = new self(); + $array->exchangeArray($properties); + + return $array; + } + + /** + * Serialize the array to BSON. + * + * The array data will be numerically reindexed to ensure that it is stored + * as a BSON array. + * + * @see https://php.net/mongodb-bson-serializable.bsonserialize + * @return array + */ + #[ReturnTypeWillChange] + public function bsonSerialize() + { + return array_values($this->getArrayCopy()); + } + + /** + * Unserialize the document to BSON. + * + * @see https://php.net/mongodb-bson-unserializable.bsonunserialize + * @param array $data Array data + */ + #[ReturnTypeWillChange] + public function bsonUnserialize(array $data) + { + parent::__construct($data); + } + + /** + * Serialize the array to JSON. + * + * The array data will be numerically reindexed to ensure that it is stored + * as a JSON array. + * + * @see https://php.net/jsonserializable.jsonserialize + * @return array + */ + #[ReturnTypeWillChange] + public function jsonSerialize() + { + return array_values($this->getArrayCopy()); + } +} diff --git a/vendor/mongodb/mongodb/src/Model/BSONDocument.php b/vendor/mongodb/mongodb/src/Model/BSONDocument.php new file mode 100644 index 00000000..1ff8bc1e --- /dev/null +++ b/vendor/mongodb/mongodb/src/Model/BSONDocument.php @@ -0,0 +1,113 @@ + + */ +class BSONDocument extends ArrayObject implements JsonSerializable, Serializable, Unserializable +{ + /** + * Deep clone this BSONDocument. + */ + public function __clone() + { + foreach ($this as $key => $value) { + $this[$key] = recursive_copy($value); + } + } + + /** + * This overrides the parent constructor to allow property access of entries + * by default. + * + * @see https://php.net/arrayobject.construct + * @param array|stdClass $input + * @psalm-param class-string>|class-string> $iteratorClass + */ + public function __construct(array|stdClass $input = [], int $flags = ArrayObject::ARRAY_AS_PROPS, string $iteratorClass = ArrayIterator::class) + { + parent::__construct($input, $flags, $iteratorClass); + } + + /** + * Factory method for var_export(). + * + * @see https://php.net/oop5.magic#object.set-state + * @see https://php.net/var-export + * @return self + */ + public static function __set_state(array $properties) + { + $document = new self(); + $document->exchangeArray($properties); + + return $document; + } + + /** + * Serialize the document to BSON. + * + * @see https://php.net/mongodb-bson-serializable.bsonserialize + * @return stdClass + */ + #[ReturnTypeWillChange] + public function bsonSerialize() + { + return (object) $this->getArrayCopy(); + } + + /** + * Unserialize the document to BSON. + * + * @see https://php.net/mongodb-bson-unserializable.bsonunserialize + * @param array $data Array data + */ + #[ReturnTypeWillChange] + public function bsonUnserialize(array $data) + { + parent::__construct($data, ArrayObject::ARRAY_AS_PROPS); + } + + /** + * Serialize the array to JSON. + * + * @see https://php.net/jsonserializable.jsonserialize + * @return object + */ + #[ReturnTypeWillChange] + public function jsonSerialize() + { + return (object) $this->getArrayCopy(); + } +} diff --git a/vendor/mongodb/mongodb/src/Model/BSONIterator.php b/vendor/mongodb/mongodb/src/Model/BSONIterator.php new file mode 100644 index 00000000..2ca257c7 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Model/BSONIterator.php @@ -0,0 +1,152 @@ + + */ +class BSONIterator implements Iterator +{ + private const BSON_SIZE = 4; + + private string $buffer; + + private int $bufferLength; + + private array|object|null $current = null; + + private int $key = 0; + + private int $position = 0; + + /** + * @see https://php.net/iterator.current + * @return mixed + */ + #[ReturnTypeWillChange] + public function current() + { + return $this->current; + } + + /** + * @see https://php.net/iterator.key + * @return int + */ + #[ReturnTypeWillChange] + public function key() + { + return $this->key; + } + + /** + * @see https://php.net/iterator.next + * @return void + */ + #[ReturnTypeWillChange] + public function next() + { + $this->key++; + $this->current = null; + $this->advance(); + } + + /** + * @see https://php.net/iterator.rewind + * @return void + */ + #[ReturnTypeWillChange] + public function rewind() + { + $this->key = 0; + $this->position = 0; + $this->current = null; + $this->advance(); + } + + /** @see https://php.net/iterator.valid */ + #[ReturnTypeWillChange] + public function valid(): bool + { + return $this->current !== null; + } + + /** + * Constructs a BSON Iterator. + * + * Supported options: + * + * * typeMap (array): Type map for BSON deserialization. + * + * @internal + * @see https://php.net/manual/en/function.mongodb.bson-tophp.php + * @param string $data Concatenated, valid, BSON-encoded documents + * @param array $options Iterator options + * @throws InvalidArgumentException for parameter/option parsing errors + */ + public function __construct(string $data, private array $options = []) + { + if (isset($options['typeMap']) && ! is_array($options['typeMap'])) { + throw InvalidArgumentException::invalidType('"typeMap" option', $options['typeMap'], 'array'); + } + + if (! isset($options['typeMap'])) { + $this->options['typeMap'] = []; + } + + $this->buffer = $data; + $this->bufferLength = strlen($data); + } + + private function advance(): void + { + if ($this->position === $this->bufferLength) { + return; + } + + if ($this->bufferLength - $this->position < self::BSON_SIZE) { + throw new UnexpectedValueException(sprintf('Expected at least %d bytes; %d remaining', self::BSON_SIZE, $this->bufferLength - $this->position)); + } + + [, $documentLength] = unpack('V', substr($this->buffer, $this->position, self::BSON_SIZE)); + assert(is_int($documentLength)); + + if ($this->bufferLength - $this->position < $documentLength) { + throw new UnexpectedValueException(sprintf('Expected %d bytes; %d remaining', $documentLength, $this->bufferLength - $this->position)); + } + + $this->current = Document::fromBSON(substr($this->buffer, $this->position, $documentLength))->toPHP($this->options['typeMap']); + $this->position += $documentLength; + } +} diff --git a/vendor/mongodb/mongodb/src/Model/CachingIterator.php b/vendor/mongodb/mongodb/src/Model/CachingIterator.php new file mode 100644 index 00000000..15ba7ca1 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Model/CachingIterator.php @@ -0,0 +1,166 @@ + + */ +class CachingIterator implements Countable, Iterator +{ + private const FIELD_KEY = 0; + private const FIELD_VALUE = 1; + + /** @var list */ + private array $items = []; + + /** @var Iterator */ + private Iterator $iterator; + + private bool $iteratorAdvanced = false; + + private bool $iteratorExhausted = false; + + /** + * Initialize the iterator and stores the first item in the cache. This + * effectively rewinds the Traversable and the wrapping IteratorIterator. + * Additionally, this mimics behavior of the SPL iterators and allows users + * to omit an explicit call to rewind() before using the other methods. + * + * @param Traversable $traversable + */ + public function __construct(Traversable $traversable) + { + $this->iterator = $traversable instanceof Iterator ? $traversable : new IteratorIterator($traversable); + + $this->iterator->rewind(); + $this->storeCurrentItem(); + } + + /** @see https://php.net/countable.count */ + public function count(): int + { + $this->exhaustIterator(); + + return count($this->items); + } + + /** + * @see https://php.net/iterator.current + * @return mixed + */ + #[ReturnTypeWillChange] + public function current() + { + $currentItem = current($this->items); + + return $currentItem !== false ? $currentItem[self::FIELD_VALUE] : null; + } + + /** + * @see https://php.net/iterator.key + * @return mixed + * @psalm-return TKey|null + */ + #[ReturnTypeWillChange] + public function key() + { + $currentItem = current($this->items); + + return $currentItem !== false ? $currentItem[self::FIELD_KEY] : null; + } + + /** @see https://php.net/iterator.next */ + public function next(): void + { + if (! $this->iteratorExhausted) { + $this->iteratorAdvanced = true; + $this->iterator->next(); + + $this->storeCurrentItem(); + } + + next($this->items); + } + + /** @see https://php.net/iterator.rewind */ + public function rewind(): void + { + /* If the iterator has advanced, exhaust it now so that future iteration + * can rely on the cache. + */ + if ($this->iteratorAdvanced) { + $this->exhaustIterator(); + } + + reset($this->items); + } + + /** @see https://php.net/iterator.valid */ + public function valid(): bool + { + return $this->key() !== null; + } + + /** + * Ensures that the inner iterator is fully consumed and cached. + */ + private function exhaustIterator(): void + { + while (! $this->iteratorExhausted) { + $this->next(); + } + } + + /** + * Stores the current item in the cache. + */ + private function storeCurrentItem(): void + { + if (! $this->iterator->valid()) { + $this->iteratorExhausted = true; + + return; + } + + // Storing a new item in the internal cache + $this->items[] = [ + self::FIELD_KEY => $this->iterator->key(), + self::FIELD_VALUE => $this->iterator->current(), + ]; + } +} diff --git a/vendor/mongodb/mongodb/src/Model/CallbackIterator.php b/vendor/mongodb/mongodb/src/Model/CallbackIterator.php new file mode 100644 index 00000000..ea429ccb --- /dev/null +++ b/vendor/mongodb/mongodb/src/Model/CallbackIterator.php @@ -0,0 +1,92 @@ + + */ +class CallbackIterator implements Iterator +{ + /** @var callable(TValue, TKey): TCallbackValue */ + private $callback; + + /** @var Iterator */ + private Iterator $iterator; + + /** + * @param Traversable $traversable + * @param callable(TValue, TKey): TCallbackValue $callback + */ + public function __construct(Traversable $traversable, callable $callback) + { + $this->iterator = $traversable instanceof Iterator ? $traversable : new IteratorIterator($traversable); + $this->callback = $callback; + } + + /** + * @see https://php.net/iterator.current + * @return TCallbackValue + */ + #[ReturnTypeWillChange] + public function current() + { + return call_user_func($this->callback, $this->iterator->current(), $this->iterator->key()); + } + + /** + * @see https://php.net/iterator.key + * @return TKey + */ + #[ReturnTypeWillChange] + public function key() + { + return $this->iterator->key(); + } + + /** @see https://php.net/iterator.next */ + public function next(): void + { + $this->iterator->next(); + } + + /** @see https://php.net/iterator.rewind */ + public function rewind(): void + { + $this->iterator->rewind(); + } + + /** @see https://php.net/iterator.valid */ + public function valid(): bool + { + return $this->iterator->valid(); + } +} diff --git a/vendor/mongodb/mongodb/src/Model/ChangeStreamIterator.php b/vendor/mongodb/mongodb/src/Model/ChangeStreamIterator.php new file mode 100644 index 00000000..aa635dda --- /dev/null +++ b/vendor/mongodb/mongodb/src/Model/ChangeStreamIterator.php @@ -0,0 +1,322 @@ +&Iterator> + */ +class ChangeStreamIterator extends IteratorIterator implements CommandSubscriber +{ + private int $batchPosition = 0; + + private int $batchSize; + + private bool $isRewindNop; + + private bool $isValid = false; + + private array|object|null $resumeToken = null; + + private Server $server; + + /** + * @see https://php.net/iteratoriterator.current + * @return array|object|null + * @psalm-return TValue|null + */ + #[ReturnTypeWillChange] + public function current() + { + return $this->valid() ? parent::current() : null; + } + + /** + * Necessary to let psalm know that we're always expecting a cursor as inner + * iterator. This could be side-stepped due to the class not being final, + * but it's very much an invalid use-case. This method can be dropped in 2.0 + * once the class is final. + * + * @return CursorInterface&Iterator + */ + final public function getInnerIterator(): Iterator + { + $cursor = parent::getInnerIterator(); + assert($cursor instanceof CursorInterface); + assert($cursor instanceof Iterator); + + return $cursor; + } + + /** + * Returns the resume token for the iterator's current position. + * + * Null may be returned if no change documents have been iterated and the + * server did not include a postBatchResumeToken in its aggregate or getMore + * command response. + * + * @return array|object|null + */ + public function getResumeToken() + { + return $this->resumeToken; + } + + /** + * Returns the server the cursor is running on. + */ + public function getServer(): Server + { + return $this->server; + } + + /** + * @see https://php.net/iteratoriterator.key + * @return int|null + */ + #[ReturnTypeWillChange] + public function key() + { + return $this->valid() ? parent::key() : null; + } + + /** @see https://php.net/iteratoriterator.rewind */ + public function next(): void + { + /* Determine if advancing the iterator will execute a getMore command + * (i.e. we are already positioned at the end of the current batch). If + * so, rely on the APM callbacks to reset $batchPosition and update + * $batchSize. Otherwise, we can forgo APM and manually increment + * $batchPosition after calling next(). */ + $getMore = $this->isAtEndOfBatch(); + + if ($getMore) { + addSubscriber($this); + } + + try { + parent::next(); + + $this->onIteration(! $getMore); + } finally { + if ($getMore) { + removeSubscriber($this); + } + } + } + + /** @see https://php.net/iteratoriterator.rewind */ + public function rewind(): void + { + if ($this->isRewindNop) { + return; + } + + parent::rewind(); + + $this->onIteration(false); + } + + /** + * @see https://php.net/iteratoriterator.valid + * @psalm-assert-if-true TValue $this->current() + */ + public function valid(): bool + { + return $this->isValid; + } + + /** + * @internal + * @psalm-param CursorInterface&Iterator $cursor + */ + public function __construct(CursorInterface $cursor, int $firstBatchSize, array|object|null $initialResumeToken, private ?object $postBatchResumeToken = null) + { + if (! $cursor instanceof Iterator) { + throw InvalidArgumentException::invalidType( + '$cursor', + $cursor, + CursorInterface::class . '&' . Iterator::class, + ); + } + + if (isset($initialResumeToken) && ! is_document($initialResumeToken)) { + throw InvalidArgumentException::expectedDocumentType('$initialResumeToken', $initialResumeToken); + } + + parent::__construct($cursor); + + $this->batchSize = $firstBatchSize; + $this->isRewindNop = ($firstBatchSize === 0); + $this->resumeToken = $initialResumeToken; + $this->server = $cursor->getServer(); + } + + /** @internal */ + final public function commandFailed(CommandFailedEvent $event): void + { + } + + /** @internal */ + final public function commandStarted(CommandStartedEvent $event): void + { + if ($event->getCommandName() !== 'getMore') { + return; + } + + $this->batchPosition = 0; + $this->batchSize = 0; + $this->postBatchResumeToken = null; + } + + /** @internal */ + final public function commandSucceeded(CommandSucceededEvent $event): void + { + if ($event->getCommandName() !== 'getMore') { + return; + } + + $reply = $event->getReply(); + + if (! isset($reply->cursor->nextBatch) || ! is_array($reply->cursor->nextBatch)) { + throw new UnexpectedValueException('getMore command did not return a "cursor.nextBatch" array'); + } + + $this->batchSize = count($reply->cursor->nextBatch); + + if (isset($reply->cursor->postBatchResumeToken) && is_object($reply->cursor->postBatchResumeToken)) { + $this->postBatchResumeToken = $reply->cursor->postBatchResumeToken; + } + } + + /** + * Extracts the resume token (i.e. "_id" field) from a change document. + * + * @param array|object $document Change document + * @return array|object + * @throws InvalidArgumentException + * @throws ResumeTokenException if the resume token is not found or invalid + */ + private function extractResumeToken(array|object $document) + { + if (! is_document($document)) { + throw InvalidArgumentException::expectedDocumentType('$document', $document); + } + + if ($document instanceof Serializable) { + return $this->extractResumeToken($document->bsonSerialize()); + } + + if ($document instanceof Document) { + $resumeToken = $document->get('_id'); + + if ($resumeToken instanceof Document) { + $resumeToken = $resumeToken->toPHP(); + } + } else { + $resumeToken = is_array($document) + ? ($document['_id'] ?? null) + : ($document->_id ?? null); + } + + if (! isset($resumeToken)) { + $this->isValid = false; + + throw ResumeTokenException::notFound(); + } + + if (! is_array($resumeToken) && ! is_object($resumeToken)) { + $this->isValid = false; + + throw ResumeTokenException::invalidType($resumeToken); + } + + return $resumeToken; + } + + /** + * Return whether the iterator is positioned at the end of the batch. + */ + private function isAtEndOfBatch(): bool + { + return $this->batchPosition + 1 >= $this->batchSize; + } + + /** + * Perform housekeeping after an iteration event. + * + * @see https://github.com/mongodb/specifications/blob/master/source/change-streams/change-streams.rst#updating-the-cached-resume-token + */ + private function onIteration(bool $incrementBatchPosition): void + { + $this->isValid = parent::valid(); + + /* Disable rewind()'s NOP behavior once we advance to a valid position. + * This will allow the driver to throw a LogicException if rewind() is + * called after the cursor has advanced past its first element. */ + if ($this->isRewindNop && $this->valid()) { + $this->isRewindNop = false; + } + + if ($incrementBatchPosition && $this->valid()) { + $this->batchPosition++; + } + + /* If the iterator is positioned at the end of the batch, apply the + * postBatchResumeToken if it's available. This handles both the case + * where the current batch is empty (since onIteration() will be called + * after a successful getMore) and when the iterator has advanced to the + * last document in its current batch. Otherwise, extract a resume token + * from the current document if possible. */ + if ($this->isAtEndOfBatch() && $this->postBatchResumeToken !== null) { + $this->resumeToken = $this->postBatchResumeToken; + } elseif ($this->valid()) { + $this->resumeToken = $this->extractResumeToken($this->current()); + } + } +} diff --git a/vendor/mongodb/mongodb/src/Model/CodecCursor.php b/vendor/mongodb/mongodb/src/Model/CodecCursor.php new file mode 100644 index 00000000..642f3c3c --- /dev/null +++ b/vendor/mongodb/mongodb/src/Model/CodecCursor.php @@ -0,0 +1,144 @@ + + * @template-implements Iterator + */ +class CodecCursor implements CursorInterface, Iterator +{ + private const TYPEMAP = ['root' => 'bson']; + + /** @var TValue|null */ + private ?object $current = null; + + /** @return TValue */ + public function current(): ?object + { + if (! $this->current && $this->valid()) { + $value = $this->cursor->current(); + assert($value instanceof Document); + $this->current = $this->codec->decode($value); + } + + return $this->current; + } + + /** + * @template NativeClass of Object + * @param DocumentCodec $codec + * @return self + */ + public static function fromCursor(Cursor $cursor, DocumentCodec $codec): self + { + $cursor->setTypeMap(self::TYPEMAP); + + return new self($cursor, $codec); + } + + /** + * @return CursorId|Int64 + * @psalm-return ($asInt64 is true ? Int64 : CursorId) + */ + #[ReturnTypeWillChange] + public function getId(bool $asInt64 = false) + { + if (! $asInt64) { + @trigger_error( + sprintf( + 'The method "%s" will no longer return a "%s" instance in the future. Pass "true" as argument to change to the new behavior and receive a "%s" instance instead.', + __METHOD__, + CursorId::class, + Int64::class, + ), + E_USER_DEPRECATED, + ); + } + + return $this->cursor->getId($asInt64); + } + + public function getServer(): Server + { + return $this->cursor->getServer(); + } + + public function isDead(): bool + { + return $this->cursor->isDead(); + } + + public function key(): int + { + return $this->cursor->key(); + } + + public function next(): void + { + $this->current = null; + $this->cursor->next(); + } + + public function rewind(): void + { + $this->current = null; + $this->cursor->rewind(); + } + + public function setTypeMap(array $typemap): void + { + // Not supported + trigger_error(sprintf('Discarding type map for %s', __METHOD__), E_USER_WARNING); + } + + /** @return array */ + public function toArray(): array + { + return iterator_to_array($this); + } + + public function valid(): bool + { + return $this->cursor->valid(); + } + + /** @param DocumentCodec $codec */ + private function __construct(private Cursor $cursor, private DocumentCodec $codec) + { + } +} diff --git a/vendor/mongodb/mongodb/src/Model/CollectionInfo.php b/vendor/mongodb/mongodb/src/Model/CollectionInfo.php new file mode 100644 index 00000000..2850a4be --- /dev/null +++ b/vendor/mongodb/mongodb/src/Model/CollectionInfo.php @@ -0,0 +1,194 @@ + + */ +class CollectionInfo implements ArrayAccess +{ + /** @param array $info Collection info */ + public function __construct(private array $info) + { + } + + /** + * Return the collection info as an array. + * + * @see https://php.net/oop5.magic#language.oop5.magic.debuginfo + * @return array + */ + public function __debugInfo() + { + return $this->info; + } + + /** + * Return the maximum number of documents to keep in the capped collection. + * + * @deprecated 1.0 Deprecated in favor of using getOptions + * + * @return integer|null + */ + public function getCappedMax() + { + /* The MongoDB server might return this number as an integer or float */ + return isset($this->info['options']['max']) ? (integer) $this->info['options']['max'] : null; + } + + /** + * Return the maximum size (in bytes) of the capped collection. + * + * @deprecated 1.0 Deprecated in favor of using getOptions + * + * @return integer|null + */ + public function getCappedSize() + { + /* The MongoDB server might return this number as an integer or float */ + return isset($this->info['options']['size']) ? (integer) $this->info['options']['size'] : null; + } + + /** + * Return information about the _id index for the collection. + */ + public function getIdIndex(): array + { + return (array) ($this->info['idIndex'] ?? []); + } + + /** + * Return the "info" property of the server response. + * + * @see https://mongodb.com/docs/manual/reference/command/listCollections/#output + */ + public function getInfo(): array + { + return (array) ($this->info['info'] ?? []); + } + + /** + * Return the collection name. + * + * @see https://mongodb.com/docs/manual/reference/command/listCollections/#output + * @return string + */ + public function getName() + { + return (string) $this->info['name']; + } + + /** + * Return the collection options. + * + * @see https://mongodb.com/docs/manual/reference/command/listCollections/#output + * @return array + */ + public function getOptions() + { + return (array) ($this->info['options'] ?? []); + } + + /** + * Return the collection type. + * + * @see https://mongodb.com/docs/manual/reference/command/listCollections/#output + */ + public function getType(): string + { + return (string) $this->info['type']; + } + + /** + * Return whether the collection is a capped collection. + * + * @deprecated 1.0 Deprecated in favor of using getOptions + * + * @return boolean + */ + public function isCapped() + { + return ! empty($this->info['options']['capped']); + } + + /** + * Check whether a field exists in the collection information. + * + * @see https://php.net/arrayaccess.offsetexists + * @return boolean + * @psalm-param array-key $offset + */ + #[ReturnTypeWillChange] + public function offsetExists(mixed $offset) + { + return array_key_exists($offset, $this->info); + } + + /** + * Return the field's value from the collection information. + * + * @see https://php.net/arrayaccess.offsetget + * @return mixed + * @psalm-param array-key $offset + */ + #[ReturnTypeWillChange] + public function offsetGet(mixed $offset) + { + return $this->info[$offset]; + } + + /** + * Not supported. + * + * @see https://php.net/arrayaccess.offsetset + * @throws BadMethodCallException + * @return void + */ + #[ReturnTypeWillChange] + public function offsetSet(mixed $offset, mixed $value) + { + throw BadMethodCallException::classIsImmutable(self::class); + } + + /** + * Not supported. + * + * @see https://php.net/arrayaccess.offsetunset + * @throws BadMethodCallException + * @return void + */ + #[ReturnTypeWillChange] + public function offsetUnset(mixed $offset) + { + throw BadMethodCallException::classIsImmutable(self::class); + } +} diff --git a/vendor/mongodb/mongodb/src/Model/CollectionInfoCommandIterator.php b/vendor/mongodb/mongodb/src/Model/CollectionInfoCommandIterator.php new file mode 100644 index 00000000..543d8fc3 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Model/CollectionInfoCommandIterator.php @@ -0,0 +1,60 @@ +> + */ +class CollectionInfoCommandIterator extends IteratorIterator implements CollectionInfoIterator +{ + /** @param Traversable $iterator */ + public function __construct(Traversable $iterator, private ?string $databaseName = null) + { + parent::__construct($iterator); + } + + /** + * Return the current element as a CollectionInfo instance. + * + * @see CollectionInfoIterator::current() + * @see https://php.net/iterator.current + */ + public function current(): CollectionInfo + { + $info = parent::current(); + + if ($this->databaseName !== null && isset($info['idIndex']) && ! isset($info['idIndex']['ns'])) { + $info['idIndex']['ns'] = $this->databaseName . '.' . $info['name']; + } + + return new CollectionInfo($info); + } +} diff --git a/vendor/mongodb/mongodb/src/Model/CollectionInfoIterator.php b/vendor/mongodb/mongodb/src/Model/CollectionInfoIterator.php new file mode 100644 index 00000000..e7ebf498 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Model/CollectionInfoIterator.php @@ -0,0 +1,41 @@ + + */ +interface CollectionInfoIterator extends Iterator +{ + /** + * Return the current element as a CollectionInfo instance. + * + * @return CollectionInfo + */ + #[ReturnTypeWillChange] + public function current(); +} diff --git a/vendor/mongodb/mongodb/src/Model/DatabaseInfo.php b/vendor/mongodb/mongodb/src/Model/DatabaseInfo.php new file mode 100644 index 00000000..2803532f --- /dev/null +++ b/vendor/mongodb/mongodb/src/Model/DatabaseInfo.php @@ -0,0 +1,136 @@ + + */ +class DatabaseInfo implements ArrayAccess +{ + /** @param array $info Database info */ + public function __construct(private array $info) + { + } + + /** + * Return the database info as an array. + * + * @see https://php.net/oop5.magic#language.oop5.magic.debuginfo + * @return array + */ + public function __debugInfo() + { + return $this->info; + } + + /** + * Return the database name. + * + * @return string + */ + public function getName() + { + return (string) $this->info['name']; + } + + /** + * Return the databases size on disk (in bytes). + * + * @return integer + */ + public function getSizeOnDisk() + { + /* The MongoDB server might return this number as an integer or float */ + return (integer) $this->info['sizeOnDisk']; + } + + /** + * Return whether the database is empty. + * + * @return boolean + */ + public function isEmpty() + { + return (boolean) $this->info['empty']; + } + + /** + * Check whether a field exists in the database information. + * + * @see https://php.net/arrayaccess.offsetexists + * @return boolean + * @psalm-param array-key $offset + */ + #[ReturnTypeWillChange] + public function offsetExists(mixed $offset) + { + return array_key_exists($offset, $this->info); + } + + /** + * Return the field's value from the database information. + * + * @see https://php.net/arrayaccess.offsetget + * @return mixed + * @psalm-param array-key $offset + */ + #[ReturnTypeWillChange] + public function offsetGet(mixed $offset) + { + return $this->info[$offset]; + } + + /** + * Not supported. + * + * @see https://php.net/arrayaccess.offsetset + * @throws BadMethodCallException + * @return void + */ + #[ReturnTypeWillChange] + public function offsetSet(mixed $offset, mixed $value) + { + throw BadMethodCallException::classIsImmutable(self::class); + } + + /** + * Not supported. + * + * @see https://php.net/arrayaccess.offsetunset + * @throws BadMethodCallException + * @return void + */ + #[ReturnTypeWillChange] + public function offsetUnset(mixed $offset) + { + throw BadMethodCallException::classIsImmutable(self::class); + } +} diff --git a/vendor/mongodb/mongodb/src/Model/DatabaseInfoIterator.php b/vendor/mongodb/mongodb/src/Model/DatabaseInfoIterator.php new file mode 100644 index 00000000..72199bd3 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Model/DatabaseInfoIterator.php @@ -0,0 +1,41 @@ + + */ +interface DatabaseInfoIterator extends Iterator +{ + /** + * Return the current element as a DatabaseInfo instance. + * + * @return DatabaseInfo + */ + #[ReturnTypeWillChange] + public function current(); +} diff --git a/vendor/mongodb/mongodb/src/Model/DatabaseInfoLegacyIterator.php b/vendor/mongodb/mongodb/src/Model/DatabaseInfoLegacyIterator.php new file mode 100644 index 00000000..1348b0c5 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Model/DatabaseInfoLegacyIterator.php @@ -0,0 +1,92 @@ +databases)); + } + + /** + * Return the key of the current element. + * + * @see https://php.net/iterator.key + */ + public function key(): int + { + return key($this->databases); + } + + /** + * Move forward to next element. + * + * @see https://php.net/iterator.next + */ + public function next(): void + { + next($this->databases); + } + + /** + * Rewind the Iterator to the first element. + * + * @see https://php.net/iterator.rewind + */ + public function rewind(): void + { + reset($this->databases); + } + + /** + * Checks if current position is valid. + * + * @see https://php.net/iterator.valid + */ + public function valid(): bool + { + return key($this->databases) !== null; + } +} diff --git a/vendor/mongodb/mongodb/src/Model/IndexInfo.php b/vendor/mongodb/mongodb/src/Model/IndexInfo.php new file mode 100644 index 00000000..062c4085 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Model/IndexInfo.php @@ -0,0 +1,239 @@ + + */ +class IndexInfo implements ArrayAccess +{ + /** @param array $info Index info */ + public function __construct(private array $info) + { + } + + /** + * Return the collection info as an array. + * + * @see https://php.net/oop5.magic#language.oop5.magic.debuginfo + * @return array + */ + public function __debugInfo() + { + return $this->info; + } + + /** + * Return the index name to allow casting IndexInfo to string. + * + * @return string + */ + public function __toString() + { + return $this->getName(); + } + + /** + * Return the index key. + * + * @return array + */ + public function getKey() + { + return (array) $this->info['key']; + } + + /** + * Return the index name. + * + * @return string + */ + public function getName() + { + return (string) $this->info['name']; + } + + /** + * Return the index namespace (e.g. "db.collection"). + * + * @deprecated + * + * @return string + */ + public function getNamespace() + { + @trigger_error('MongoDB 4.4 drops support for the namespace in indexes, the method "IndexInfo::getNamespace()" will be removed in version 2.0', E_USER_DEPRECATED); + + return (string) $this->info['ns']; + } + + /** + * Return the index version. + * + * @return integer + */ + public function getVersion() + { + return (integer) $this->info['v']; + } + + /** + * Return whether or not this index is of type 2dsphere. + * + * @return boolean + */ + public function is2dSphere() + { + return array_search('2dsphere', $this->getKey(), true) !== false; + } + + /** + * Return whether or not this index is of type geoHaystack. + * + * @return boolean + * @deprecated Since 1.16: MongoDB 5.0 removes support for geoHaystack indexes. + */ + public function isGeoHaystack() + { + @trigger_error('MongoDB 5.0 removes support for "geoHaystack" indexes, the method "IndexInfo::isGeoHaystack()" will be removed in version 2.0', E_USER_DEPRECATED); + + return array_search('geoHaystack', $this->getKey(), true) !== false; + } + + /** + * Return whether this is a sparse index. + * + * @see https://mongodb.com/docs/manual/core/index-sparse/ + * @return boolean + */ + public function isSparse() + { + return ! empty($this->info['sparse']); + } + + /** + * Return whether or not this index is of type text. + * + * @return boolean + */ + public function isText() + { + return array_search('text', $this->getKey(), true) !== false; + } + + /** + * Return whether this is a TTL index. + * + * @see https://mongodb.com/docs/manual/core/index-ttl/ + * @return boolean + */ + public function isTtl() + { + return array_key_exists('expireAfterSeconds', $this->info); + } + + /** + * Return whether this is a unique index. + * + * @see https://mongodb.com/docs/manual/core/index-unique/ + * @return boolean + */ + public function isUnique() + { + return ! empty($this->info['unique']); + } + + /** + * Check whether a field exists in the index information. + * + * @see https://php.net/arrayaccess.offsetexists + * @return boolean + * @psalm-param array-key $offset + */ + #[ReturnTypeWillChange] + public function offsetExists(mixed $offset) + { + return array_key_exists($offset, $this->info); + } + + /** + * Return the field's value from the index information. + * + * This method satisfies the Enumerating Indexes specification's requirement + * that index fields be made accessible under their original names. It may + * also be used to access fields that do not have a helper method. + * + * @see https://php.net/arrayaccess.offsetget + * @see https://github.com/mongodb/specifications/blob/master/source/enumerate-indexes.rst#getting-full-index-information + * @return mixed + * @psalm-param array-key $offset + */ + #[ReturnTypeWillChange] + public function offsetGet(mixed $offset) + { + return $this->info[$offset]; + } + + /** + * Not supported. + * + * @see https://php.net/arrayaccess.offsetset + * @throws BadMethodCallException + * @return void + */ + #[ReturnTypeWillChange] + public function offsetSet(mixed $offset, mixed $value) + { + throw BadMethodCallException::classIsImmutable(self::class); + } + + /** + * Not supported. + * + * @see https://php.net/arrayaccess.offsetunset + * @throws BadMethodCallException + * @return void + */ + #[ReturnTypeWillChange] + public function offsetUnset(mixed $offset) + { + throw BadMethodCallException::classIsImmutable(self::class); + } +} diff --git a/vendor/mongodb/mongodb/src/Model/IndexInfoIterator.php b/vendor/mongodb/mongodb/src/Model/IndexInfoIterator.php new file mode 100644 index 00000000..b7929c20 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Model/IndexInfoIterator.php @@ -0,0 +1,41 @@ + + */ +interface IndexInfoIterator extends Iterator +{ + /** + * Return the current element as a IndexInfo instance. + * + * @return IndexInfo + */ + #[ReturnTypeWillChange] + public function current(); +} diff --git a/vendor/mongodb/mongodb/src/Model/IndexInfoIteratorIterator.php b/vendor/mongodb/mongodb/src/Model/IndexInfoIteratorIterator.php new file mode 100644 index 00000000..0bcc4bd8 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Model/IndexInfoIteratorIterator.php @@ -0,0 +1,64 @@ +> + */ +class IndexInfoIteratorIterator extends IteratorIterator implements IndexInfoIterator +{ + /** @param Traversable $iterator */ + public function __construct(Traversable $iterator, private ?string $ns = null) + { + parent::__construct($iterator); + } + + /** + * Return the current element as an IndexInfo instance. + * + * @see IndexInfoIterator::current() + * @see https://php.net/iterator.current + */ + public function current(): IndexInfo + { + $info = parent::current(); + + if (! array_key_exists('ns', $info) && $this->ns !== null) { + $info['ns'] = $this->ns; + } + + return new IndexInfo($info); + } +} diff --git a/vendor/mongodb/mongodb/src/Model/IndexInput.php b/vendor/mongodb/mongodb/src/Model/IndexInput.php new file mode 100644 index 00000000..657c2b6d --- /dev/null +++ b/vendor/mongodb/mongodb/src/Model/IndexInput.php @@ -0,0 +1,110 @@ + $order) { + if (! is_int($order) && ! is_float($order) && ! is_string($order)) { + throw InvalidArgumentException::invalidType(sprintf('order value for "%s" field within "key" option', $fieldName), $order, 'numeric or string'); + } + } + + if (! isset($index['name'])) { + $this->index['name'] = $this->generateIndexName($index['key']); + } + + if (! is_string($this->index['name'])) { + throw InvalidArgumentException::invalidType('"name" option', $this->index['name'], 'string'); + } + } + + /** + * Return the index name. + */ + public function __toString(): string + { + return $this->index['name']; + } + + /** + * Serialize the index information to BSON for index creation. + * + * @see \MongoDB\Collection::createIndexes() + * @see https://php.net/mongodb-bson-serializable.bsonserialize + */ + public function bsonSerialize(): stdClass + { + return (object) $this->index; + } + + /** + * Generate an index name from a key specification. + * + * @param array|object $document Document containing fields mapped to values, + * which denote order or an index type + * @throws InvalidArgumentException if $document is not an array or object + */ + private function generateIndexName(array|object $document): string + { + $document = document_to_array($document); + + $name = ''; + + foreach ($document as $field => $type) { + $name .= ($name !== '' ? '_' : '') . $field . '_' . $type; + } + + return $name; + } +} diff --git a/vendor/mongodb/mongodb/src/Model/SearchIndexInput.php b/vendor/mongodb/mongodb/src/Model/SearchIndexInput.php new file mode 100644 index 00000000..bad880a7 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Model/SearchIndexInput.php @@ -0,0 +1,73 @@ +index; + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/Aggregate.php b/vendor/mongodb/mongodb/src/Operation/Aggregate.php new file mode 100644 index 00000000..7c968a25 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/Aggregate.php @@ -0,0 +1,348 @@ +options['allowDiskUse']) && ! is_bool($this->options['allowDiskUse'])) { + throw InvalidArgumentException::invalidType('"allowDiskUse" option', $this->options['allowDiskUse'], 'boolean'); + } + + if (isset($this->options['batchSize']) && ! is_integer($this->options['batchSize'])) { + throw InvalidArgumentException::invalidType('"batchSize" option', $this->options['batchSize'], 'integer'); + } + + if (isset($this->options['bypassDocumentValidation']) && ! is_bool($this->options['bypassDocumentValidation'])) { + throw InvalidArgumentException::invalidType('"bypassDocumentValidation" option', $this->options['bypassDocumentValidation'], 'boolean'); + } + + if (isset($this->options['codec']) && ! $this->options['codec'] instanceof DocumentCodec) { + throw InvalidArgumentException::invalidType('"codec" option', $this->options['codec'], DocumentCodec::class); + } + + if (isset($this->options['collation']) && ! is_document($this->options['collation'])) { + throw InvalidArgumentException::expectedDocumentType('"collation" option', $this->options['collation']); + } + + if (isset($this->options['explain']) && ! is_bool($this->options['explain'])) { + throw InvalidArgumentException::invalidType('"explain" option', $this->options['explain'], 'boolean'); + } + + if (isset($this->options['hint']) && ! is_string($this->options['hint']) && ! is_document($this->options['hint'])) { + throw InvalidArgumentException::expectedDocumentOrStringType('"hint" option', $this->options['hint']); + } + + if (isset($this->options['let']) && ! is_document($this->options['let'])) { + throw InvalidArgumentException::expectedDocumentType('"let" option', $this->options['let']); + } + + if (isset($this->options['maxAwaitTimeMS']) && ! is_integer($this->options['maxAwaitTimeMS'])) { + throw InvalidArgumentException::invalidType('"maxAwaitTimeMS" option', $this->options['maxAwaitTimeMS'], 'integer'); + } + + if (isset($this->options['maxTimeMS']) && ! is_integer($this->options['maxTimeMS'])) { + throw InvalidArgumentException::invalidType('"maxTimeMS" option', $this->options['maxTimeMS'], 'integer'); + } + + if (isset($this->options['readConcern']) && ! $this->options['readConcern'] instanceof ReadConcern) { + throw InvalidArgumentException::invalidType('"readConcern" option', $this->options['readConcern'], ReadConcern::class); + } + + if (isset($this->options['readPreference']) && ! $this->options['readPreference'] instanceof ReadPreference) { + throw InvalidArgumentException::invalidType('"readPreference" option', $this->options['readPreference'], ReadPreference::class); + } + + if (isset($this->options['session']) && ! $this->options['session'] instanceof Session) { + throw InvalidArgumentException::invalidType('"session" option', $this->options['session'], Session::class); + } + + if (isset($this->options['typeMap']) && ! is_array($this->options['typeMap'])) { + throw InvalidArgumentException::invalidType('"typeMap" option', $this->options['typeMap'], 'array'); + } + + if (isset($this->options['writeConcern']) && ! $this->options['writeConcern'] instanceof WriteConcern) { + throw InvalidArgumentException::invalidType('"writeConcern" option', $this->options['writeConcern'], WriteConcern::class); + } + + if (isset($this->options['bypassDocumentValidation']) && ! $this->options['bypassDocumentValidation']) { + unset($this->options['bypassDocumentValidation']); + } + + if (isset($this->options['readConcern']) && $this->options['readConcern']->isDefault()) { + unset($this->options['readConcern']); + } + + if (isset($this->options['writeConcern']) && $this->options['writeConcern']->isDefault()) { + unset($this->options['writeConcern']); + } + + if (isset($this->options['codec']) && isset($this->options['typeMap'])) { + throw InvalidArgumentException::cannotCombineCodecAndTypeMap(); + } + + $this->isWrite = is_last_pipeline_operator_write($pipeline) && ! ($this->options['explain'] ?? false); + + if ($this->isWrite) { + /* Ignore batchSize for writes, since no documents are returned and + * a batchSize of zero could prevent the pipeline from executing. */ + unset($this->options['batchSize']); + } else { + unset($this->options['writeConcern']); + } + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return CursorInterface&Iterator + * @throws UnexpectedValueException if the command response was malformed + * @throws UnsupportedException if read concern or write concern is used and unsupported + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server) + { + $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); + if ($inTransaction) { + if (isset($this->options['readConcern'])) { + throw UnsupportedException::readConcernNotSupportedInTransaction(); + } + + if (isset($this->options['writeConcern'])) { + throw UnsupportedException::writeConcernNotSupportedInTransaction(); + } + } + + $command = new Command( + $this->createCommandDocument(), + $this->createCommandOptions(), + ); + + $cursor = $this->executeCommand($server, $command); + + if (isset($this->options['codec'])) { + return CodecCursor::fromCursor($cursor, $this->options['codec']); + } + + if (isset($this->options['typeMap'])) { + $cursor->setTypeMap($this->options['typeMap']); + } + + return $cursor; + } + + /** + * Returns the command document for this operation. + * + * @see Explainable::getCommandDocument() + * @return array + */ + public function getCommandDocument() + { + $cmd = $this->createCommandDocument(); + + // Read concern can change the query plan + if (isset($this->options['readConcern'])) { + $cmd['readConcern'] = $this->options['readConcern']; + } + + return $cmd; + } + + /** + * Create the aggregate command document. + */ + private function createCommandDocument(): array + { + $cmd = [ + 'aggregate' => $this->collectionName ?? 1, + 'pipeline' => $this->pipeline, + ]; + + foreach (['allowDiskUse', 'bypassDocumentValidation', 'comment', 'explain', 'maxTimeMS'] as $option) { + if (isset($this->options[$option])) { + $cmd[$option] = $this->options[$option]; + } + } + + foreach (['collation', 'let'] as $option) { + if (isset($this->options[$option])) { + $cmd[$option] = (object) $this->options[$option]; + } + } + + if (isset($this->options['hint'])) { + $cmd['hint'] = is_array($this->options['hint']) ? (object) $this->options['hint'] : $this->options['hint']; + } + + $cmd['cursor'] = isset($this->options['batchSize']) + ? ['batchSize' => $this->options['batchSize']] + : new stdClass(); + + return $cmd; + } + + private function createCommandOptions(): array + { + $cmdOptions = []; + + if (isset($this->options['maxAwaitTimeMS'])) { + $cmdOptions['maxAwaitTimeMS'] = $this->options['maxAwaitTimeMS']; + } + + return $cmdOptions; + } + + /** + * Execute the aggregate command using the appropriate Server method. + * + * @see https://php.net/manual/en/mongodb-driver-server.executecommand.php + * @see https://php.net/manual/en/mongodb-driver-server.executereadcommand.php + * @see https://php.net/manual/en/mongodb-driver-server.executereadwritecommand.php + */ + private function executeCommand(Server $server, Command $command): Cursor + { + $options = []; + + foreach (['readConcern', 'readPreference', 'session', 'writeConcern'] as $option) { + if (isset($this->options[$option])) { + $options[$option] = $this->options[$option]; + } + } + + if (! $this->isWrite) { + return $server->executeReadCommand($this->databaseName, $command, $options); + } + + /* Server::executeReadWriteCommand() does not support a "readPreference" + * option, so fall back to executeCommand(). This means that libmongoc + * will not apply any client-level options (e.g. writeConcern), but that + * should not be an issue as PHPLIB handles inheritance on its own. */ + if (isset($options['readPreference'])) { + return $server->executeCommand($this->databaseName, $command, $options); + } + + return $server->executeReadWriteCommand($this->databaseName, $command, $options); + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/BulkWrite.php b/vendor/mongodb/mongodb/src/Operation/BulkWrite.php new file mode 100644 index 00000000..c8f69567 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/BulkWrite.php @@ -0,0 +1,451 @@ + [ $filter, $options ] ], + * [ 'deleteOne' => [ $filter, $options ] ], + * [ 'insertOne' => [ $document ] ], + * [ 'replaceOne' => [ $filter, $replacement, $options ] ], + * [ 'updateMany' => [ $filter, $update, $options ] ], + * [ 'updateOne' => [ $filter, $update, $options ] ], + * ] + * + * Arguments correspond to the respective Operation classes; however, the + * writeConcern option is specified for the top-level bulk write operation + * instead of each individual operation. + * + * Supported options for deleteMany and deleteOne operations: + * + * * collation (document): Collation specification. + * + * Supported options for replaceOne, updateMany, and updateOne operations: + * + * * collation (document): Collation specification. + * + * * upsert (boolean): When true, a new document is created if no document + * matches the query. The default is false. + * + * Supported options for replaceOne and updateOne operations: + * + * * sort (document): Determines which document the operation modifies if + * the query selects multiple documents. + * + * This is not supported for server versions < 8.0 and will result in an + * exception at execution time if used. + * + * Supported options for updateMany and updateOne operations: + * + * * arrayFilters (document array): A set of filters specifying to which + * array elements an update should apply. + * + * Supported options for the bulk write operation: + * + * * builderEncoder (MongoDB\Codec\Encoder): Encoder for query and + * aggregation builders. If not given, the default encoder will be used. + * + * * bypassDocumentValidation (boolean): If true, allows the write to + * circumvent document level validation. The default is false. + * + * * codec (MongoDB\Codec\DocumentCodec): Codec used to decode documents + * from BSON to PHP objects. This option is also used to encode PHP + * objects into BSON for insertOne and replaceOne operations. + * + * * comment (mixed): BSON value to attach as a comment to this command(s) + * associated with this bulk write. + * + * This is not supported for servers versions < 4.4. + * + * * ordered (boolean): If true, when an insert fails, return without + * performing the remaining writes. If false, when a write fails, + * continue with the remaining writes, if any. The default is true. + * + * * let (document): Map of parameter names and values. Values must be + * constant or closed expressions that do not reference document fields. + * Parameters can then be accessed as variables in an aggregate + * expression context (e.g. "$$var"). + * + * * session (MongoDB\Driver\Session): Client session. + * + * * writeConcern (MongoDB\Driver\WriteConcern): Write concern. + * + * @param string $databaseName Database name + * @param string $collectionName Collection name + * @param array[] $operations List of write operations + * @param array $options Command options + * @throws InvalidArgumentException for parameter/option parsing errors + */ + public function __construct(private string $databaseName, private string $collectionName, array $operations, array $options = []) + { + if (empty($operations)) { + throw new InvalidArgumentException('$operations is empty'); + } + + if (! array_is_list($operations)) { + throw new InvalidArgumentException('$operations is not a list'); + } + + $options += ['ordered' => true]; + + if (isset($options['builderEncoder']) && ! $options['builderEncoder'] instanceof Encoder) { + throw InvalidArgumentException::invalidType('"builderEncoder" option', $options['builderEncoder'], Encoder::class); + } + + if (isset($options['bypassDocumentValidation']) && ! is_bool($options['bypassDocumentValidation'])) { + throw InvalidArgumentException::invalidType('"bypassDocumentValidation" option', $options['bypassDocumentValidation'], 'boolean'); + } + + if (isset($options['codec']) && ! $options['codec'] instanceof DocumentCodec) { + throw InvalidArgumentException::invalidType('"codec" option', $options['codec'], DocumentCodec::class); + } + + if (! is_bool($options['ordered'])) { + throw InvalidArgumentException::invalidType('"ordered" option', $options['ordered'], 'boolean'); + } + + if (isset($options['session']) && ! $options['session'] instanceof Session) { + throw InvalidArgumentException::invalidType('"session" option', $options['session'], Session::class); + } + + if (isset($options['writeConcern']) && ! $options['writeConcern'] instanceof WriteConcern) { + throw InvalidArgumentException::invalidType('"writeConcern" option', $options['writeConcern'], WriteConcern::class); + } + + if (isset($options['let']) && ! is_document($options['let'])) { + throw InvalidArgumentException::expectedDocumentType('"let" option', $options['let']); + } + + if (isset($options['bypassDocumentValidation']) && ! $options['bypassDocumentValidation']) { + unset($options['bypassDocumentValidation']); + } + + if (isset($options['writeConcern']) && $options['writeConcern']->isDefault()) { + unset($options['writeConcern']); + } + + $this->operations = $this->validateOperations($operations, $options['codec'] ?? null, $options['builderEncoder'] ?? new BuilderEncoder()); + $this->options = $options; + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return BulkWriteResult + * @throws UnsupportedException if write concern is used and unsupported + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server) + { + $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); + if ($inTransaction && isset($this->options['writeConcern'])) { + throw UnsupportedException::writeConcernNotSupportedInTransaction(); + } + + $bulk = new Bulk($this->createBulkWriteOptions()); + $insertedIds = []; + + foreach ($this->operations as $i => $operation) { + $type = key($operation); + $args = current($operation); + + switch ($type) { + case self::DELETE_MANY: + case self::DELETE_ONE: + $bulk->delete($args[0], $args[1]); + break; + + case self::INSERT_ONE: + $insertedIds[$i] = $bulk->insert($args[0]); + break; + + case self::UPDATE_MANY: + case self::UPDATE_ONE: + case self::REPLACE_ONE: + $bulk->update($args[0], $args[1], $args[2]); + break; + } + } + + $writeResult = $server->executeBulkWrite($this->databaseName . '.' . $this->collectionName, $bulk, $this->createExecuteOptions()); + + return new BulkWriteResult($writeResult, $insertedIds); + } + + /** + * Create options for constructing the bulk write. + * + * @see https://php.net/manual/en/mongodb-driver-bulkwrite.construct.php + */ + private function createBulkWriteOptions(): array + { + $options = ['ordered' => $this->options['ordered']]; + + foreach (['bypassDocumentValidation', 'comment'] as $option) { + if (isset($this->options[$option])) { + $options[$option] = $this->options[$option]; + } + } + + if (isset($this->options['let'])) { + $options['let'] = (object) $this->options['let']; + } + + return $options; + } + + /** + * Create options for executing the bulk write. + * + * @see https://php.net/manual/en/mongodb-driver-server.executebulkwrite.php + */ + private function createExecuteOptions(): array + { + $options = []; + + if (isset($this->options['session'])) { + $options['session'] = $this->options['session']; + } + + if (isset($this->options['writeConcern'])) { + $options['writeConcern'] = $this->options['writeConcern']; + } + + return $options; + } + + /** + * @param array[] $operations + * @return array[] + */ + private function validateOperations(array $operations, ?DocumentCodec $codec, Encoder $builderEncoder): array + { + foreach ($operations as $i => $operation) { + if (! is_array($operation)) { + throw InvalidArgumentException::invalidType(sprintf('$operations[%d]', $i), $operation, 'array'); + } + + if (count($operation) !== 1) { + throw new InvalidArgumentException(sprintf('Expected one element in $operation[%d], actually: %d', $i, count($operation))); + } + + $type = key($operation); + $args = current($operation); + + if (! isset($args[0]) && ! array_key_exists(0, $args)) { + throw new InvalidArgumentException(sprintf('Missing first argument for $operations[%d]["%s"]', $i, $type)); + } + + if (! is_document($args[0])) { + throw InvalidArgumentException::expectedDocumentType(sprintf('$operations[%d]["%s"][0]', $i, $type), $args[0]); + } + + switch ($type) { + case self::INSERT_ONE: + // $args[0] was already validated above. Since DocumentCodec::encode will always return a Document + // instance, there is no need to re-validate the returned value here. + if ($codec) { + $operations[$i][$type][0] = $codec->encode($args[0]); + } + + break; + + case self::DELETE_MANY: + case self::DELETE_ONE: + $operations[$i][$type][0] = $builderEncoder->encodeIfSupported($args[0]); + + if (! isset($args[1])) { + $args[1] = []; + } + + if (! is_array($args[1])) { + throw InvalidArgumentException::invalidType(sprintf('$operations[%d]["%s"][1]', $i, $type), $args[1], 'array'); + } + + $args[1]['limit'] = ($type === self::DELETE_ONE ? 1 : 0); + + if (isset($args[1]['collation']) && ! is_document($args[1]['collation'])) { + throw InvalidArgumentException::expectedDocumentType(sprintf('$operations[%d]["%s"][1]["collation"]', $i, $type), $args[1]['collation']); + } + + $operations[$i][$type][1] = $args[1]; + + break; + + case self::REPLACE_ONE: + $operations[$i][$type][0] = $builderEncoder->encodeIfSupported($args[0]); + + if (! isset($args[1]) && ! array_key_exists(1, $args)) { + throw new InvalidArgumentException(sprintf('Missing second argument for $operations[%d]["%s"]', $i, $type)); + } + + if ($codec) { + $operations[$i][$type][1] = $codec->encode($args[1]); + } + + if (! is_document($args[1])) { + throw InvalidArgumentException::expectedDocumentType(sprintf('$operations[%d]["%s"][1]', $i, $type), $args[1]); + } + + // Treat empty arrays as replacement documents for BC + if ($args[1] === []) { + $args[1] = (object) $args[1]; + } + + if (is_first_key_operator($args[1])) { + throw new InvalidArgumentException(sprintf('First key in $operations[%d]["%s"][1] is an update operator', $i, $type)); + } + + if (is_pipeline($args[1], true /* allowEmpty */)) { + throw new InvalidArgumentException(sprintf('$operations[%d]["%s"][1] is an update pipeline', $i, $type)); + } + + if (! isset($args[2])) { + $args[2] = []; + } + + if (! is_array($args[2])) { + throw InvalidArgumentException::invalidType(sprintf('$operations[%d]["%s"][2]', $i, $type), $args[2], 'array'); + } + + $args[2]['multi'] = false; + $args[2] += ['upsert' => false]; + + if (isset($args[2]['collation']) && ! is_document($args[2]['collation'])) { + throw InvalidArgumentException::expectedDocumentType(sprintf('$operations[%d]["%s"][2]["collation"]', $i, $type), $args[2]['collation']); + } + + if (isset($args[2]['sort']) && ! is_document($args[2]['sort'])) { + throw InvalidArgumentException::expectedDocumentType(sprintf('$operations[%d]["%s"][2]["sort"]', $i, $type), $args[2]['sort']); + } + + if (! is_bool($args[2]['upsert'])) { + throw InvalidArgumentException::invalidType(sprintf('$operations[%d]["%s"][2]["upsert"]', $i, $type), $args[2]['upsert'], 'boolean'); + } + + $operations[$i][$type][2] = $args[2]; + + break; + + case self::UPDATE_MANY: + case self::UPDATE_ONE: + $operations[$i][$type][0] = $builderEncoder->encodeIfSupported($args[0]); + + if (! isset($args[1]) && ! array_key_exists(1, $args)) { + throw new InvalidArgumentException(sprintf('Missing second argument for $operations[%d]["%s"]', $i, $type)); + } + + $operations[$i][$type][1] = $args[1] = $builderEncoder->encodeIfSupported($args[1]); + + if ((! is_document($args[1]) || ! is_first_key_operator($args[1])) && ! is_pipeline($args[1])) { + throw new InvalidArgumentException(sprintf('Expected update operator(s) or non-empty pipeline for $operations[%d]["%s"][1]', $i, $type)); + } + + if (! isset($args[2])) { + $args[2] = []; + } + + if (! is_array($args[2])) { + throw InvalidArgumentException::invalidType(sprintf('$operations[%d]["%s"][2]', $i, $type), $args[2], 'array'); + } + + $args[2]['multi'] = ($type === self::UPDATE_MANY); + $args[2] += ['upsert' => false]; + + if (isset($args[2]['arrayFilters']) && ! is_array($args[2]['arrayFilters'])) { + throw InvalidArgumentException::invalidType(sprintf('$operations[%d]["%s"][2]["arrayFilters"]', $i, $type), $args[2]['arrayFilters'], 'array'); + } + + if (isset($args[2]['collation']) && ! is_document($args[2]['collation'])) { + throw InvalidArgumentException::expectedDocumentType(sprintf('$operations[%d]["%s"][2]["collation"]', $i, $type), $args[2]['collation']); + } + + if (isset($args[2]['sort']) && ! is_document($args[2]['sort'])) { + throw InvalidArgumentException::expectedDocumentType(sprintf('$operations[%d]["%s"][2]["sort"]', $i, $type), $args[2]['sort']); + } + + if (isset($args[2]['sort']) && $args[2]['multi']) { + throw new InvalidArgumentException(sprintf('"sort" option cannot be used with $operations[%d]["%s"]', $i, $type)); + } + + if (! is_bool($args[2]['upsert'])) { + throw InvalidArgumentException::invalidType(sprintf('$operations[%d]["%s"][2]["upsert"]', $i, $type), $args[2]['upsert'], 'boolean'); + } + + $operations[$i][$type][2] = $args[2]; + + break; + + default: + throw new InvalidArgumentException(sprintf('Unknown operation type "%s" in $operations[%d]', $type, $i)); + } + } + + return $operations; + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/Count.php b/vendor/mongodb/mongodb/src/Operation/Count.php new file mode 100644 index 00000000..f3d2b7eb --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/Count.php @@ -0,0 +1,222 @@ +options['collation']) && ! is_document($this->options['collation'])) { + throw InvalidArgumentException::expectedDocumentType('"collation" option', $this->options['collation']); + } + + if (isset($this->options['hint']) && ! is_string($this->options['hint']) && ! is_document($this->options['hint'])) { + throw InvalidArgumentException::expectedDocumentOrStringType('"hint" option', $this->options['hint']); + } + + if (isset($this->options['limit']) && ! is_integer($this->options['limit'])) { + throw InvalidArgumentException::invalidType('"limit" option', $this->options['limit'], 'integer'); + } + + if (isset($this->options['maxTimeMS']) && ! is_integer($this->options['maxTimeMS'])) { + throw InvalidArgumentException::invalidType('"maxTimeMS" option', $this->options['maxTimeMS'], 'integer'); + } + + if (isset($this->options['readConcern']) && ! $this->options['readConcern'] instanceof ReadConcern) { + throw InvalidArgumentException::invalidType('"readConcern" option', $this->options['readConcern'], ReadConcern::class); + } + + if (isset($this->options['readPreference']) && ! $this->options['readPreference'] instanceof ReadPreference) { + throw InvalidArgumentException::invalidType('"readPreference" option', $this->options['readPreference'], ReadPreference::class); + } + + if (isset($this->options['session']) && ! $this->options['session'] instanceof Session) { + throw InvalidArgumentException::invalidType('"session" option', $this->options['session'], Session::class); + } + + if (isset($this->options['skip']) && ! is_integer($this->options['skip'])) { + throw InvalidArgumentException::invalidType('"skip" option', $this->options['skip'], 'integer'); + } + + if (isset($this->options['readConcern']) && $this->options['readConcern']->isDefault()) { + unset($this->options['readConcern']); + } + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return integer + * @throws UnexpectedValueException if the command response was malformed + * @throws UnsupportedException if read concern is used and unsupported + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server) + { + $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); + if ($inTransaction && isset($this->options['readConcern'])) { + throw UnsupportedException::readConcernNotSupportedInTransaction(); + } + + $cursor = $server->executeReadCommand($this->databaseName, new Command($this->createCommandDocument()), $this->createOptions()); + $result = current($cursor->toArray()); + + // Older server versions may return a float + if (! is_object($result) || ! isset($result->n) || ! (is_integer($result->n) || is_float($result->n))) { + throw new UnexpectedValueException('count command did not return a numeric "n" value'); + } + + return (integer) $result->n; + } + + /** + * Returns the command document for this operation. + * + * @see Explainable::getCommandDocument() + * @return array + */ + public function getCommandDocument() + { + $cmd = $this->createCommandDocument(); + + // Read concern can change the query plan + if (isset($this->options['readConcern'])) { + $cmd['readConcern'] = $this->options['readConcern']; + } + + return $cmd; + } + + /** + * Create the count command document. + */ + private function createCommandDocument(): array + { + $cmd = ['count' => $this->collectionName]; + + if ($this->filter !== []) { + $cmd['query'] = (object) $this->filter; + } + + if (isset($this->options['collation'])) { + $cmd['collation'] = (object) $this->options['collation']; + } + + if (isset($this->options['hint'])) { + $cmd['hint'] = is_array($this->options['hint']) ? (object) $this->options['hint'] : $this->options['hint']; + } + + foreach (['comment', 'limit', 'maxTimeMS', 'skip'] as $option) { + if (isset($this->options[$option])) { + $cmd[$option] = $this->options[$option]; + } + } + + return $cmd; + } + + /** + * Create options for executing the command. + * + * @see https://php.net/manual/en/mongodb-driver-server.executereadcommand.php + */ + private function createOptions(): array + { + $options = []; + + if (isset($this->options['readConcern'])) { + $options['readConcern'] = $this->options['readConcern']; + } + + if (isset($this->options['readPreference'])) { + $options['readPreference'] = $this->options['readPreference']; + } + + if (isset($this->options['session'])) { + $options['session'] = $this->options['session']; + } + + return $options; + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/CountDocuments.php b/vendor/mongodb/mongodb/src/Operation/CountDocuments.php new file mode 100644 index 00000000..954ea746 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/CountDocuments.php @@ -0,0 +1,152 @@ +aggregateOptions = array_intersect_key($options, ['collation' => 1, 'comment' => 1, 'hint' => 1, 'maxTimeMS' => 1, 'readConcern' => 1, 'readPreference' => 1, 'session' => 1]); + $this->countOptions = array_intersect_key($options, ['limit' => 1, 'skip' => 1]); + + $this->aggregate = $this->createAggregate(); + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return integer + * @throws UnexpectedValueException if the command response was malformed + * @throws UnsupportedException if collation or read concern is used and unsupported + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server) + { + $cursor = $this->aggregate->execute($server); + + $allResults = $cursor->toArray(); + + /* If there are no documents to count, the aggregation pipeline has no items to group, and + * hence the result is an empty array (PHPLIB-376) */ + if (count($allResults) == 0) { + return 0; + } + + $result = current($allResults); + if (! is_object($result) || ! isset($result->n) || ! (is_integer($result->n) || is_float($result->n))) { + throw new UnexpectedValueException('count command did not return a numeric "n" value'); + } + + return (integer) $result->n; + } + + private function createAggregate(): Aggregate + { + $pipeline = [ + ['$match' => (object) $this->filter], + ]; + + if (isset($this->countOptions['skip'])) { + $pipeline[] = ['$skip' => $this->countOptions['skip']]; + } + + if (isset($this->countOptions['limit'])) { + $pipeline[] = ['$limit' => $this->countOptions['limit']]; + } + + $pipeline[] = ['$group' => ['_id' => 1, 'n' => ['$sum' => 1]]]; + + return new Aggregate($this->databaseName, $this->collectionName, $pipeline, $this->aggregateOptions); + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/CreateCollection.php b/vendor/mongodb/mongodb/src/Operation/CreateCollection.php new file mode 100644 index 00000000..e0f267af --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/CreateCollection.php @@ -0,0 +1,307 @@ +options['autoIndexId']) && ! is_bool($this->options['autoIndexId'])) { + throw InvalidArgumentException::invalidType('"autoIndexId" option', $this->options['autoIndexId'], 'boolean'); + } + + if (isset($this->options['capped']) && ! is_bool($this->options['capped'])) { + throw InvalidArgumentException::invalidType('"capped" option', $this->options['capped'], 'boolean'); + } + + if (isset($this->options['changeStreamPreAndPostImages']) && ! is_document($this->options['changeStreamPreAndPostImages'])) { + throw InvalidArgumentException::expectedDocumentType('"changeStreamPreAndPostImages" option', $this->options['changeStreamPreAndPostImages']); + } + + if (isset($this->options['clusteredIndex']) && ! is_document($this->options['clusteredIndex'])) { + throw InvalidArgumentException::expectedDocumentType('"clusteredIndex" option', $this->options['clusteredIndex']); + } + + if (isset($this->options['collation']) && ! is_document($this->options['collation'])) { + throw InvalidArgumentException::expectedDocumentType('"collation" option', $this->options['collation']); + } + + if (isset($this->options['encryptedFields']) && ! is_document($this->options['encryptedFields'])) { + throw InvalidArgumentException::expectedDocumentType('"encryptedFields" option', $this->options['encryptedFields']); + } + + if (isset($this->options['expireAfterSeconds']) && ! is_integer($this->options['expireAfterSeconds'])) { + throw InvalidArgumentException::invalidType('"expireAfterSeconds" option', $this->options['expireAfterSeconds'], 'integer'); + } + + if (isset($this->options['flags']) && ! is_integer($this->options['flags'])) { + throw InvalidArgumentException::invalidType('"flags" option', $this->options['flags'], 'integer'); + } + + if (isset($this->options['indexOptionDefaults']) && ! is_document($this->options['indexOptionDefaults'])) { + throw InvalidArgumentException::expectedDocumentType('"indexOptionDefaults" option', $this->options['indexOptionDefaults']); + } + + if (isset($this->options['max']) && ! is_integer($this->options['max'])) { + throw InvalidArgumentException::invalidType('"max" option', $this->options['max'], 'integer'); + } + + if (isset($this->options['maxTimeMS']) && ! is_integer($this->options['maxTimeMS'])) { + throw InvalidArgumentException::invalidType('"maxTimeMS" option', $this->options['maxTimeMS'], 'integer'); + } + + if (isset($this->options['pipeline']) && ! is_array($this->options['pipeline'])) { + throw InvalidArgumentException::invalidType('"pipeline" option', $this->options['pipeline'], 'array'); + } + + if (isset($this->options['session']) && ! $this->options['session'] instanceof Session) { + throw InvalidArgumentException::invalidType('"session" option', $this->options['session'], Session::class); + } + + if (isset($this->options['size']) && ! is_integer($this->options['size'])) { + throw InvalidArgumentException::invalidType('"size" option', $this->options['size'], 'integer'); + } + + if (isset($this->options['storageEngine']) && ! is_document($this->options['storageEngine'])) { + throw InvalidArgumentException::expectedDocumentType('"storageEngine" option', $this->options['storageEngine']); + } + + if (isset($this->options['timeseries']) && ! is_document($this->options['timeseries'])) { + throw InvalidArgumentException::expectedDocumentType('"timeseries" option', $this->options['timeseries']); + } + + if (isset($this->options['typeMap']) && ! is_array($this->options['typeMap'])) { + throw InvalidArgumentException::invalidType('"typeMap" option', $this->options['typeMap'], 'array'); + } + + if (isset($this->options['validationAction']) && ! is_string($this->options['validationAction'])) { + throw InvalidArgumentException::invalidType('"validationAction" option', $this->options['validationAction'], 'string'); + } + + if (isset($this->options['validationLevel']) && ! is_string($this->options['validationLevel'])) { + throw InvalidArgumentException::invalidType('"validationLevel" option', $this->options['validationLevel'], 'string'); + } + + if (isset($this->options['validator']) && ! is_document($this->options['validator'])) { + throw InvalidArgumentException::expectedDocumentType('"validator" option', $this->options['validator']); + } + + if (isset($this->options['viewOn']) && ! is_string($this->options['viewOn'])) { + throw InvalidArgumentException::invalidType('"viewOn" option', $this->options['viewOn'], 'string'); + } + + if (isset($this->options['writeConcern']) && ! $this->options['writeConcern'] instanceof WriteConcern) { + throw InvalidArgumentException::invalidType('"writeConcern" option', $this->options['writeConcern'], WriteConcern::class); + } + + if (isset($this->options['writeConcern']) && $this->options['writeConcern']->isDefault()) { + unset($this->options['writeConcern']); + } + + if (isset($this->options['autoIndexId'])) { + trigger_error('The "autoIndexId" option is deprecated and will be removed in version 2.0', E_USER_DEPRECATED); + } + + if (isset($this->options['flags'])) { + trigger_error('The "flags" option is deprecated and will be removed in version 2.0', E_USER_DEPRECATED); + } + + if (isset($this->options['pipeline']) && ! is_pipeline($this->options['pipeline'], true /* allowEmpty */)) { + throw new InvalidArgumentException('"pipeline" option is not a valid aggregation pipeline'); + } + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return array|object Command result document + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server) + { + $cursor = $server->executeWriteCommand($this->databaseName, $this->createCommand(), $this->createOptions()); + + if (isset($this->options['typeMap'])) { + $cursor->setTypeMap($this->options['typeMap']); + } + + return current($cursor->toArray()); + } + + /** + * Create the create command. + */ + private function createCommand(): Command + { + $cmd = ['create' => $this->collectionName]; + + foreach (['autoIndexId', 'capped', 'comment', 'expireAfterSeconds', 'flags', 'max', 'maxTimeMS', 'pipeline', 'size', 'validationAction', 'validationLevel', 'viewOn'] as $option) { + if (isset($this->options[$option])) { + $cmd[$option] = $this->options[$option]; + } + } + + foreach (['changeStreamPreAndPostImages', 'clusteredIndex', 'collation', 'encryptedFields', 'indexOptionDefaults', 'storageEngine', 'timeseries', 'validator'] as $option) { + if (isset($this->options[$option])) { + $cmd[$option] = (object) $this->options[$option]; + } + } + + return new Command($cmd); + } + + /** + * Create options for executing the command. + * + * @see https://php.net/manual/en/mongodb-driver-server.executewritecommand.php + */ + private function createOptions(): array + { + $options = []; + + if (isset($this->options['session'])) { + $options['session'] = $this->options['session']; + } + + if (isset($this->options['writeConcern'])) { + $options['writeConcern'] = $this->options['writeConcern']; + } + + return $options; + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/CreateEncryptedCollection.php b/vendor/mongodb/mongodb/src/Operation/CreateEncryptedCollection.php new file mode 100644 index 00000000..a5cde651 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/CreateEncryptedCollection.php @@ -0,0 +1,179 @@ + */ + private array $createMetadataCollections; + + private CreateIndexes $createSafeContentIndex; + + /** + * @see CreateCollection::__construct() for supported options + * @param string $databaseName Database name + * @param string $collectionName Collection name + * @param array $options CreateCollection options + * @throws InvalidArgumentException for parameter/option parsing errors + */ + public function __construct(private string $databaseName, private string $collectionName, private array $options) + { + if (! isset($this->options['encryptedFields'])) { + throw new InvalidArgumentException('"encryptedFields" option is required'); + } + + if (! is_document($this->options['encryptedFields'])) { + throw InvalidArgumentException::expectedDocumentType('"encryptedFields" option', $this->options['encryptedFields']); + } + + $this->createCollection = new CreateCollection($databaseName, $collectionName, $this->options); + + /** @psalm-var array{ecocCollection?: ?string, escCollection?: ?string} */ + $encryptedFields = document_to_array($this->options['encryptedFields']); + $enxcolOptions = ['clusteredIndex' => ['key' => ['_id' => 1], 'unique' => true]]; + + $this->createMetadataCollections = [ + new CreateCollection($databaseName, $encryptedFields['escCollection'] ?? 'enxcol_.' . $collectionName . '.esc', $enxcolOptions), + new CreateCollection($databaseName, $encryptedFields['ecocCollection'] ?? 'enxcol_.' . $collectionName . '.ecoc', $enxcolOptions), + ]; + + $this->createSafeContentIndex = new CreateIndexes($databaseName, $collectionName, [['key' => ['__safeContent__' => 1]]]); + } + + /** + * Create data keys for any encrypted fields where "keyId" is null. + * + * This method should be called before execute(), as it may modify the + * "encryptedFields" option and reconstruct the internal CreateCollection + * operation used for creating the encrypted collection. + * + * The $encryptedFields reference parameter may be used to determine which + * data keys have been created. + * + * @see \MongoDB\Database::createEncryptedCollection() + * @see https://www.php.net/manual/en/mongodb-driver-clientencryption.createdatakey.php + * @throws DriverRuntimeException for errors creating a data key + */ + public function createDataKeys(ClientEncryption $clientEncryption, string $kmsProvider, ?array $masterKey, ?array &$encryptedFields = null): void + { + /** @psalm-var array{fields: list|Serializable|PackedArray} */ + $encryptedFields = document_to_array($this->options['encryptedFields']); + + // NOP if there are no fields to examine + if (! isset($encryptedFields['fields'])) { + return; + } + + // Allow PackedArray or Serializable object for the fields array + if ($encryptedFields['fields'] instanceof PackedArray) { + /** @psalm-var array */ + $encryptedFields['fields'] = $encryptedFields['fields']->toPHP([ + 'array' => 'array', + 'document' => 'object', + 'root' => 'array', + ]); + } elseif ($encryptedFields['fields'] instanceof Serializable) { + $encryptedFields['fields'] = $encryptedFields['fields']->bsonSerialize(); + } + + // Skip invalid types and defer to the server to raise an error + if (! is_array($encryptedFields['fields'])) { + return; + } + + $createDataKeyArgs = [ + $kmsProvider, + $masterKey !== null ? ['masterKey' => $masterKey] : [], + ]; + + foreach ($encryptedFields['fields'] as $i => $field) { + // Skip invalid types and defer to the server to raise an error + if (! is_array($field) && ! is_object($field)) { + continue; + } + + $field = document_to_array($field); + + if (array_key_exists('keyId', $field) && $field['keyId'] === null) { + $field['keyId'] = $clientEncryption->createDataKey(...$createDataKeyArgs); + $encryptedFields['fields'][$i] = $field; + } + } + + $this->options['encryptedFields'] = $encryptedFields; + $this->createCollection = new CreateCollection($this->databaseName, $this->collectionName, $this->options); + } + + /** + * @see Executable::execute() + * @return array|object Command result document from creating the encrypted collection + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + * @throws UnsupportedException if the server does not support Queryable Encryption + */ + public function execute(Server $server) + { + if (! server_supports_feature($server, self::WIRE_VERSION_FOR_QUERYABLE_ENCRYPTION_V2)) { + throw new UnsupportedException('Driver support of Queryable Encryption is incompatible with server. Upgrade server to use Queryable Encryption.'); + } + + foreach ($this->createMetadataCollections as $createMetadataCollection) { + $createMetadataCollection->execute($server); + } + + $result = $this->createCollection->execute($server); + + $this->createSafeContentIndex->execute($server); + + return $result; + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/CreateIndexes.php b/vendor/mongodb/mongodb/src/Operation/CreateIndexes.php new file mode 100644 index 00000000..e2ac0881 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/CreateIndexes.php @@ -0,0 +1,192 @@ + */ + private array $indexes = []; + + /** + * Constructs a createIndexes command. + * + * Supported options: + * + * * comment (mixed): BSON value to attach as a comment to this command. + * + * This is not supported for servers versions < 4.4. + * + * * commitQuorum (integer|string): Specifies how many data-bearing members + * of a replica set, including the primary, must complete the index + * builds successfully before the primary marks the indexes as ready. + * + * * maxTimeMS (integer): The maximum amount of time to allow the query to + * run. + * + * * session (MongoDB\Driver\Session): Client session. + * + * * writeConcern (MongoDB\Driver\WriteConcern): Write concern. + * + * @param string $databaseName Database name + * @param string $collectionName Collection name + * @param array[] $indexes List of index specifications + * @param array $options Command options + * @throws InvalidArgumentException for parameter/option parsing errors + */ + public function __construct(private string $databaseName, private string $collectionName, array $indexes, private array $options = []) + { + if (empty($indexes)) { + throw new InvalidArgumentException('$indexes is empty'); + } + + if (! array_is_list($indexes)) { + throw new InvalidArgumentException('$indexes is not a list'); + } + + foreach ($indexes as $i => $index) { + if (! is_array($index)) { + throw InvalidArgumentException::invalidType(sprintf('$index[%d]', $i), $index, 'array'); + } + + $this->indexes[] = new IndexInput($index); + } + + if (isset($this->options['commitQuorum']) && ! is_string($this->options['commitQuorum']) && ! is_integer($this->options['commitQuorum'])) { + throw InvalidArgumentException::invalidType('"commitQuorum" option', $this->options['commitQuorum'], ['integer', 'string']); + } + + if (isset($this->options['maxTimeMS']) && ! is_integer($this->options['maxTimeMS'])) { + throw InvalidArgumentException::invalidType('"maxTimeMS" option', $this->options['maxTimeMS'], 'integer'); + } + + if (isset($this->options['session']) && ! $this->options['session'] instanceof Session) { + throw InvalidArgumentException::invalidType('"session" option', $this->options['session'], Session::class); + } + + if (isset($this->options['writeConcern']) && ! $this->options['writeConcern'] instanceof WriteConcern) { + throw InvalidArgumentException::invalidType('"writeConcern" option', $this->options['writeConcern'], WriteConcern::class); + } + + if (isset($this->options['writeConcern']) && $this->options['writeConcern']->isDefault()) { + unset($this->options['writeConcern']); + } + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return string[] The names of the created indexes + * @throws UnsupportedException if write concern is used and unsupported + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server) + { + $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); + if ($inTransaction && isset($this->options['writeConcern'])) { + throw UnsupportedException::writeConcernNotSupportedInTransaction(); + } + + $this->executeCommand($server); + + return array_map( + 'strval', + $this->indexes, + ); + } + + /** + * Create options for executing the command. + * + * @see https://php.net/manual/en/mongodb-driver-server.executewritecommand.php + */ + private function createOptions(): array + { + $options = []; + + if (isset($this->options['session'])) { + $options['session'] = $this->options['session']; + } + + if (isset($this->options['writeConcern'])) { + $options['writeConcern'] = $this->options['writeConcern']; + } + + return $options; + } + + /** + * Create one or more indexes for the collection using the createIndexes + * command. + * + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + private function executeCommand(Server $server): void + { + $cmd = [ + 'createIndexes' => $this->collectionName, + 'indexes' => $this->indexes, + ]; + + if (isset($this->options['commitQuorum'])) { + /* Drivers MUST manually raise an error if this option is specified + * when creating an index on a pre 4.4 server. */ + if (! server_supports_feature($server, self::WIRE_VERSION_FOR_COMMIT_QUORUM)) { + throw UnsupportedException::commitQuorumNotSupported(); + } + + $cmd['commitQuorum'] = $this->options['commitQuorum']; + } + + foreach (['comment', 'maxTimeMS'] as $option) { + if (isset($this->options[$option])) { + $cmd[$option] = $this->options[$option]; + } + } + + $server->executeWriteCommand($this->databaseName, new Command($cmd), $this->createOptions()); + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/CreateSearchIndexes.php b/vendor/mongodb/mongodb/src/Operation/CreateSearchIndexes.php new file mode 100644 index 00000000..d5be6111 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/CreateSearchIndexes.php @@ -0,0 +1,96 @@ + $index) { + if (! is_array($index)) { + throw InvalidArgumentException::invalidType(sprintf('$indexes[%d]', $i), $index, 'array'); + } + + $this->indexes[] = new SearchIndexInput($index); + } + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return string[] The names of the created indexes + * @throws UnsupportedException if write concern is used and unsupported + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server): array + { + $cmd = [ + 'createSearchIndexes' => $this->collectionName, + 'indexes' => $this->indexes, + ]; + + if (isset($this->options['comment'])) { + $cmd['comment'] = $this->options['comment']; + } + + $cursor = $server->executeCommand($this->databaseName, new Command($cmd)); + + /** @var object{indexesCreated: list} $result */ + $result = current($cursor->toArray()); + + return array_column($result->indexesCreated, 'name'); + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/DatabaseCommand.php b/vendor/mongodb/mongodb/src/Operation/DatabaseCommand.php new file mode 100644 index 00000000..7ea406ba --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/DatabaseCommand.php @@ -0,0 +1,119 @@ +options['readPreference']) && ! $this->options['readPreference'] instanceof ReadPreference) { + throw InvalidArgumentException::invalidType('"readPreference" option', $this->options['readPreference'], ReadPreference::class); + } + + if (isset($this->options['session']) && ! $this->options['session'] instanceof Session) { + throw InvalidArgumentException::invalidType('"session" option', $this->options['session'], Session::class); + } + + if (isset($this->options['typeMap']) && ! is_array($this->options['typeMap'])) { + throw InvalidArgumentException::invalidType('"typeMap" option', $this->options['typeMap'], 'array'); + } + + $this->command = $command instanceof Command ? $command : new Command($command); + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return Cursor + */ + public function execute(Server $server) + { + $cursor = $server->executeCommand($this->databaseName, $this->command, $this->createOptions()); + + if (isset($this->options['typeMap'])) { + $cursor->setTypeMap($this->options['typeMap']); + } + + return $cursor; + } + + /** + * Create options for executing the command. + * + * @see https://php.net/manual/en/mongodb-driver-server.executecommand.php + */ + private function createOptions(): array + { + $options = []; + + if (isset($this->options['readPreference'])) { + $options['readPreference'] = $this->options['readPreference']; + } + + if (isset($this->options['session'])) { + $options['session'] = $this->options['session']; + } + + return $options; + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/Delete.php b/vendor/mongodb/mongodb/src/Operation/Delete.php new file mode 100644 index 00000000..c5826a6d --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/Delete.php @@ -0,0 +1,231 @@ +options['collation']) && ! is_document($this->options['collation'])) { + throw InvalidArgumentException::expectedDocumentType('"collation" option', $this->options['collation']); + } + + if (isset($this->options['hint']) && ! is_string($this->options['hint']) && ! is_document($this->options['hint'])) { + throw InvalidArgumentException::expectedDocumentOrStringType('"hint" option', $this->options['hint']); + } + + if (isset($this->options['session']) && ! $this->options['session'] instanceof Session) { + throw InvalidArgumentException::invalidType('"session" option', $this->options['session'], Session::class); + } + + if (isset($this->options['writeConcern']) && ! $this->options['writeConcern'] instanceof WriteConcern) { + throw InvalidArgumentException::invalidType('"writeConcern" option', $this->options['writeConcern'], WriteConcern::class); + } + + if (isset($this->options['let']) && ! is_document($this->options['let'])) { + throw InvalidArgumentException::expectedDocumentType('"let" option', $this->options['let']); + } + + if (isset($this->options['writeConcern']) && $this->options['writeConcern']->isDefault()) { + unset($this->options['writeConcern']); + } + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return DeleteResult + * @throws UnsupportedException if hint or write concern is used and unsupported + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server) + { + /* CRUD spec requires a client-side error when using "hint" with an + * unacknowledged write concern on an unsupported server. */ + if ( + isset($this->options['writeConcern']) && ! is_write_concern_acknowledged($this->options['writeConcern']) && + isset($this->options['hint']) && ! server_supports_feature($server, self::WIRE_VERSION_FOR_HINT) + ) { + throw UnsupportedException::hintNotSupported(); + } + + $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); + if ($inTransaction && isset($this->options['writeConcern'])) { + throw UnsupportedException::writeConcernNotSupportedInTransaction(); + } + + $bulk = new Bulk($this->createBulkWriteOptions()); + $bulk->delete($this->filter, $this->createDeleteOptions()); + + $writeResult = $server->executeBulkWrite($this->databaseName . '.' . $this->collectionName, $bulk, $this->createExecuteOptions()); + + return new DeleteResult($writeResult); + } + + /** + * Returns the command document for this operation. + * + * @see Explainable::getCommandDocument() + * @return array + */ + public function getCommandDocument() + { + $cmd = ['delete' => $this->collectionName, 'deletes' => [['q' => $this->filter] + $this->createDeleteOptions()]]; + + if (isset($this->options['comment'])) { + $cmd['comment'] = $this->options['comment']; + } + + if (isset($this->options['let'])) { + $cmd['let'] = (object) $this->options['let']; + } + + return $cmd; + } + + /** + * Create options for constructing the bulk write. + * + * @see https://php.net/manual/en/mongodb-driver-bulkwrite.construct.php + */ + private function createBulkWriteOptions(): array + { + $options = []; + + if (isset($this->options['comment'])) { + $options['comment'] = $this->options['comment']; + } + + if (isset($this->options['let'])) { + $options['let'] = (object) $this->options['let']; + } + + return $options; + } + + /** + * Create options for the delete command. + * + * Note that these options are different from the bulk write options, which + * are created in createExecuteOptions(). + */ + private function createDeleteOptions(): array + { + $deleteOptions = ['limit' => $this->limit]; + + if (isset($this->options['collation'])) { + $deleteOptions['collation'] = (object) $this->options['collation']; + } + + if (isset($this->options['hint'])) { + $deleteOptions['hint'] = $this->options['hint']; + } + + return $deleteOptions; + } + + /** + * Create options for executing the bulk write. + * + * @see https://php.net/manual/en/mongodb-driver-server.executebulkwrite.php + */ + private function createExecuteOptions(): array + { + $options = []; + + if (isset($this->options['session'])) { + $options['session'] = $this->options['session']; + } + + if (isset($this->options['writeConcern'])) { + $options['writeConcern'] = $this->options['writeConcern']; + } + + return $options; + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/DeleteMany.php b/vendor/mongodb/mongodb/src/Operation/DeleteMany.php new file mode 100644 index 00000000..d6d443b3 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/DeleteMany.php @@ -0,0 +1,99 @@ +delete = new Delete($databaseName, $collectionName, $filter, 0, $options); + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return DeleteResult + * @throws UnsupportedException if collation is used and unsupported + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server) + { + return $this->delete->execute($server); + } + + /** + * Returns the command document for this operation. + * + * @see Explainable::getCommandDocument() + * @return array + */ + public function getCommandDocument() + { + return $this->delete->getCommandDocument(); + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/DeleteOne.php b/vendor/mongodb/mongodb/src/Operation/DeleteOne.php new file mode 100644 index 00000000..8bbdb45c --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/DeleteOne.php @@ -0,0 +1,99 @@ +delete = new Delete($databaseName, $collectionName, $filter, 1, $options); + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return DeleteResult + * @throws UnsupportedException if collation is used and unsupported + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server) + { + return $this->delete->execute($server); + } + + /** + * Returns the command document for this operation. + * + * @see Explainable::getCommandDocument() + * @return array + */ + public function getCommandDocument() + { + return $this->delete->getCommandDocument(); + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/Distinct.php b/vendor/mongodb/mongodb/src/Operation/Distinct.php new file mode 100644 index 00000000..bd69cde1 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/Distinct.php @@ -0,0 +1,226 @@ +options['collation']) && ! is_document($this->options['collation'])) { + throw InvalidArgumentException::expectedDocumentType('"collation" option', $this->options['collation']); + } + + if (isset($this->options['hint']) && ! is_string($this->options['hint']) && ! is_document($this->options['hint'])) { + throw InvalidArgumentException::expectedDocumentOrStringType('"hint" option', $this->options['hint']); + } + + if (isset($this->options['maxTimeMS']) && ! is_integer($this->options['maxTimeMS'])) { + throw InvalidArgumentException::invalidType('"maxTimeMS" option', $this->options['maxTimeMS'], 'integer'); + } + + if (isset($this->options['readConcern']) && ! $this->options['readConcern'] instanceof ReadConcern) { + throw InvalidArgumentException::invalidType('"readConcern" option', $this->options['readConcern'], ReadConcern::class); + } + + if (isset($this->options['readPreference']) && ! $this->options['readPreference'] instanceof ReadPreference) { + throw InvalidArgumentException::invalidType('"readPreference" option', $this->options['readPreference'], ReadPreference::class); + } + + if (isset($this->options['session']) && ! $this->options['session'] instanceof Session) { + throw InvalidArgumentException::invalidType('"session" option', $this->options['session'], Session::class); + } + + if (isset($this->options['typeMap']) && ! is_array($this->options['typeMap'])) { + throw InvalidArgumentException::invalidType('"typeMap" option', $this->options['typeMap'], 'array'); + } + + if (isset($this->options['readConcern']) && $this->options['readConcern']->isDefault()) { + unset($this->options['readConcern']); + } + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return array + * @throws UnexpectedValueException if the command response was malformed + * @throws UnsupportedException if read concern is used and unsupported + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server) + { + $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); + if ($inTransaction && isset($this->options['readConcern'])) { + throw UnsupportedException::readConcernNotSupportedInTransaction(); + } + + $cursor = $server->executeReadCommand($this->databaseName, new Command($this->createCommandDocument()), $this->createOptions()); + + if (isset($this->options['typeMap'])) { + $cursor->setTypeMap(create_field_path_type_map($this->options['typeMap'], 'values.$')); + } + + $result = current($cursor->toArray()); + + if (! is_object($result) || ! isset($result->values) || ! is_array($result->values)) { + throw new UnexpectedValueException('distinct command did not return a "values" array'); + } + + return $result->values; + } + + /** + * Returns the command document for this operation. + * + * @see Explainable::getCommandDocument() + * @return array + */ + public function getCommandDocument() + { + $cmd = $this->createCommandDocument(); + + // Read concern can change the query plan + if (isset($this->options['readConcern'])) { + $cmd['readConcern'] = $this->options['readConcern']; + } + + return $cmd; + } + + /** + * Create the distinct command document. + */ + private function createCommandDocument(): array + { + $cmd = [ + 'distinct' => $this->collectionName, + 'key' => $this->fieldName, + ]; + + if ($this->filter !== []) { + $cmd['query'] = (object) $this->filter; + } + + if (isset($this->options['collation'])) { + $cmd['collation'] = (object) $this->options['collation']; + } + + if (isset($this->options['hint'])) { + /** @psalm-var string|object */ + $cmd['hint'] = is_array($this->options['hint']) ? (object) $this->options['hint'] : $this->options['hint']; + } + + foreach (['comment', 'maxTimeMS'] as $option) { + if (isset($this->options[$option])) { + $cmd[$option] = $this->options[$option]; + } + } + + return $cmd; + } + + /** + * Create options for executing the command. + * + * @see https://php.net/manual/en/mongodb-driver-server.executereadcommand.php + */ + private function createOptions(): array + { + $options = []; + + if (isset($this->options['readConcern'])) { + $options['readConcern'] = $this->options['readConcern']; + } + + if (isset($this->options['readPreference'])) { + $options['readPreference'] = $this->options['readPreference']; + } + + if (isset($this->options['session'])) { + $options['session'] = $this->options['session']; + } + + return $options; + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/DropCollection.php b/vendor/mongodb/mongodb/src/Operation/DropCollection.php new file mode 100644 index 00000000..d19859de --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/DropCollection.php @@ -0,0 +1,153 @@ +options['session']) && ! $this->options['session'] instanceof Session) { + throw InvalidArgumentException::invalidType('"session" option', $this->options['session'], Session::class); + } + + if (isset($this->options['typeMap']) && ! is_array($this->options['typeMap'])) { + throw InvalidArgumentException::invalidType('"typeMap" option', $this->options['typeMap'], 'array'); + } + + if (isset($this->options['writeConcern']) && ! $this->options['writeConcern'] instanceof WriteConcern) { + throw InvalidArgumentException::invalidType('"writeConcern" option', $this->options['writeConcern'], WriteConcern::class); + } + + if (isset($this->options['writeConcern']) && $this->options['writeConcern']->isDefault()) { + unset($this->options['writeConcern']); + } + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return array|object Command result document + * @throws UnsupportedException if write concern is used and unsupported + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server) + { + $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); + if ($inTransaction && isset($this->options['writeConcern'])) { + throw UnsupportedException::writeConcernNotSupportedInTransaction(); + } + + try { + $cursor = $server->executeWriteCommand($this->databaseName, $this->createCommand(), $this->createOptions()); + } catch (CommandException $e) { + /* The server may return an error if the collection does not exist. + * Check for an error code and return the command reply instead of + * throwing. */ + if ($e->getCode() === self::ERROR_CODE_NAMESPACE_NOT_FOUND) { + return $e->getResultDocument(); + } + + throw $e; + } + + if (isset($this->options['typeMap'])) { + $cursor->setTypeMap($this->options['typeMap']); + } + + return current($cursor->toArray()); + } + + /** + * Create the drop command. + */ + private function createCommand(): Command + { + $cmd = ['drop' => $this->collectionName]; + + if (isset($this->options['comment'])) { + $cmd['comment'] = $this->options['comment']; + } + + return new Command($cmd); + } + + /** + * Create options for executing the command. + * + * @see https://php.net/manual/en/mongodb-driver-server.executewritecommand.php + */ + private function createOptions(): array + { + $options = []; + + if (isset($this->options['session'])) { + $options['session'] = $this->options['session']; + } + + if (isset($this->options['writeConcern'])) { + $options['writeConcern'] = $this->options['writeConcern']; + } + + return $options; + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/DropDatabase.php b/vendor/mongodb/mongodb/src/Operation/DropDatabase.php new file mode 100644 index 00000000..29088790 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/DropDatabase.php @@ -0,0 +1,131 @@ +options['session']) && ! $this->options['session'] instanceof Session) { + throw InvalidArgumentException::invalidType('"session" option', $this->options['session'], Session::class); + } + + if (isset($this->options['typeMap']) && ! is_array($this->options['typeMap'])) { + throw InvalidArgumentException::invalidType('"typeMap" option', $this->options['typeMap'], 'array'); + } + + if (isset($this->options['writeConcern']) && ! $this->options['writeConcern'] instanceof WriteConcern) { + throw InvalidArgumentException::invalidType('"writeConcern" option', $this->options['writeConcern'], WriteConcern::class); + } + + if (isset($this->options['writeConcern']) && $this->options['writeConcern']->isDefault()) { + unset($this->options['writeConcern']); + } + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return array|object Command result document + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server) + { + $cursor = $server->executeWriteCommand($this->databaseName, $this->createCommand(), $this->createOptions()); + + if (isset($this->options['typeMap'])) { + $cursor->setTypeMap($this->options['typeMap']); + } + + return current($cursor->toArray()); + } + + /** + * Create the dropDatabase command. + */ + private function createCommand(): Command + { + $cmd = ['dropDatabase' => 1]; + + if (isset($this->options['comment'])) { + $cmd['comment'] = $this->options['comment']; + } + + return new Command($cmd); + } + + /** + * Create options for executing the command. + * + * @see https://php.net/manual/en/mongodb-driver-server.executewritecommand.php + */ + private function createOptions(): array + { + $options = []; + + if (isset($this->options['session'])) { + $options['session'] = $this->options['session']; + } + + if (isset($this->options['writeConcern'])) { + $options['writeConcern'] = $this->options['writeConcern']; + } + + return $options; + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/DropEncryptedCollection.php b/vendor/mongodb/mongodb/src/Operation/DropEncryptedCollection.php new file mode 100644 index 00000000..491a8e9e --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/DropEncryptedCollection.php @@ -0,0 +1,100 @@ + */ + private array $dropMetadataCollections; + + /** + * Constructs an operation to drop an encrypted collection and its related + * metadata collections. + * + * The following option is supported in addition to the options for + * DropCollection: + * + * * encryptedFields (document): Configuration for encrypted fields. + * See: https://www.mongodb.com/docs/manual/core/queryable-encryption/fundamentals/encrypt-and-query/ + * + * @see DropCollection::__construct() for supported options + * @param string $databaseName Database name + * @param string $collectionName Collection name + * @param array $options DropCollection options + * @throws InvalidArgumentException for parameter/option parsing errors + */ + public function __construct(string $databaseName, string $collectionName, array $options) + { + if (! isset($options['encryptedFields'])) { + throw new InvalidArgumentException('"encryptedFields" option is required'); + } + + if (! is_document($options['encryptedFields'])) { + throw InvalidArgumentException::expectedDocumentType('"encryptedFields" option', $options['encryptedFields']); + } + + /** @psalm-var array{ecocCollection?: ?string, escCollection?: ?string} */ + $encryptedFields = document_to_array($options['encryptedFields']); + + $this->dropMetadataCollections = [ + new DropCollection($databaseName, $encryptedFields['escCollection'] ?? 'enxcol_.' . $collectionName . '.esc'), + new DropCollection($databaseName, $encryptedFields['ecocCollection'] ?? 'enxcol_.' . $collectionName . '.ecoc'), + ]; + + // DropCollection does not use the "encryptedFields" option + unset($options['encryptedFields']); + + $this->dropCollection = new DropCollection($databaseName, $collectionName, $options); + } + + /** + * @see Executable::execute() + * @return array|object Command result document from dropping the encrypted collection + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server) + { + foreach ($this->dropMetadataCollections as $dropMetadataCollection) { + $dropMetadataCollection->execute($server); + } + + return $this->dropCollection->execute($server); + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/DropIndexes.php b/vendor/mongodb/mongodb/src/Operation/DropIndexes.php new file mode 100644 index 00000000..8fde88b4 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/DropIndexes.php @@ -0,0 +1,156 @@ +options['maxTimeMS']) && ! is_integer($this->options['maxTimeMS'])) { + throw InvalidArgumentException::invalidType('"maxTimeMS" option', $this->options['maxTimeMS'], 'integer'); + } + + if (isset($this->options['session']) && ! $this->options['session'] instanceof Session) { + throw InvalidArgumentException::invalidType('"session" option', $this->options['session'], Session::class); + } + + if (isset($this->options['typeMap']) && ! is_array($this->options['typeMap'])) { + throw InvalidArgumentException::invalidType('"typeMap" option', $this->options['typeMap'], 'array'); + } + + if (isset($this->options['writeConcern']) && ! $this->options['writeConcern'] instanceof WriteConcern) { + throw InvalidArgumentException::invalidType('"writeConcern" option', $this->options['writeConcern'], WriteConcern::class); + } + + if (isset($this->options['writeConcern']) && $this->options['writeConcern']->isDefault()) { + unset($this->options['writeConcern']); + } + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return array|object Command result document + * @throws UnsupportedException if write concern is used and unsupported + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server) + { + $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); + if ($inTransaction && isset($this->options['writeConcern'])) { + throw UnsupportedException::writeConcernNotSupportedInTransaction(); + } + + $cursor = $server->executeWriteCommand($this->databaseName, $this->createCommand(), $this->createOptions()); + + if (isset($this->options['typeMap'])) { + $cursor->setTypeMap($this->options['typeMap']); + } + + return current($cursor->toArray()); + } + + /** + * Create the dropIndexes command. + */ + private function createCommand(): Command + { + $cmd = [ + 'dropIndexes' => $this->collectionName, + 'index' => $this->indexName, + ]; + + foreach (['comment', 'maxTimeMS'] as $option) { + if (isset($this->options[$option])) { + $cmd[$option] = $this->options[$option]; + } + } + + return new Command($cmd); + } + + /** + * Create options for executing the command. + * + * @see https://php.net/manual/en/mongodb-driver-server.executewritecommand.php + */ + private function createOptions(): array + { + $options = []; + + if (isset($this->options['session'])) { + $options['session'] = $this->options['session']; + } + + if (isset($this->options['writeConcern'])) { + $options['writeConcern'] = $this->options['writeConcern']; + } + + return $options; + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/DropSearchIndex.php b/vendor/mongodb/mongodb/src/Operation/DropSearchIndex.php new file mode 100644 index 00000000..e65adee6 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/DropSearchIndex.php @@ -0,0 +1,82 @@ + $this->collectionName, + 'name' => $this->name, + ]; + + if (isset($this->options['comment'])) { + $cmd['comment'] = $this->options['comment']; + } + + try { + $server->executeCommand($this->databaseName, new Command($cmd)); + } catch (CommandException $e) { + // Drop operations are idempotent. The server may return an error if the collection does not exist. + if ($e->getCode() !== self::ERROR_CODE_NAMESPACE_NOT_FOUND) { + throw $e; + } + } + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/EstimatedDocumentCount.php b/vendor/mongodb/mongodb/src/Operation/EstimatedDocumentCount.php new file mode 100644 index 00000000..db876c71 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/EstimatedDocumentCount.php @@ -0,0 +1,118 @@ +options = array_intersect_key($options, ['comment' => 1, 'maxTimeMS' => 1, 'readConcern' => 1, 'readPreference' => 1, 'session' => 1]); + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return integer + * @throws UnexpectedValueException if the command response was malformed + * @throws UnsupportedException if collation or read concern is used and unsupported + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server) + { + return $this->createCount()->execute($server); + } + + /** + * Returns the command document for this operation. + * + * @see Explainable::getCommandDocument() + * @return array + */ + public function getCommandDocument() + { + return $this->createCount()->getCommandDocument(); + } + + private function createCount(): Count + { + return new Count($this->databaseName, $this->collectionName, [], $this->options); + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/Executable.php b/vendor/mongodb/mongodb/src/Operation/Executable.php new file mode 100644 index 00000000..5bd8c68b --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/Executable.php @@ -0,0 +1,38 @@ +options['readPreference']) && ! $this->options['readPreference'] instanceof ReadPreference) { + throw InvalidArgumentException::invalidType('"readPreference" option', $this->options['readPreference'], ReadPreference::class); + } + + if (isset($this->options['session']) && ! $this->options['session'] instanceof Session) { + throw InvalidArgumentException::invalidType('"session" option', $this->options['session'], Session::class); + } + + if (isset($this->options['typeMap']) && ! is_array($this->options['typeMap'])) { + throw InvalidArgumentException::invalidType('"typeMap" option', $this->options['typeMap'], 'array'); + } + + if (isset($this->options['verbosity']) && ! is_string($this->options['verbosity'])) { + throw InvalidArgumentException::invalidType('"verbosity" option', $this->options['verbosity'], 'string'); + } + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return array|object + * @throws UnsupportedException if the server does not support explaining the operation + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server) + { + $cursor = $server->executeCommand($this->databaseName, $this->createCommand(), $this->createOptions()); + + if (isset($this->options['typeMap'])) { + $cursor->setTypeMap($this->options['typeMap']); + } + + return current($cursor->toArray()); + } + + /** + * Create the explain command. + */ + private function createCommand(): Command + { + $cmd = ['explain' => $this->explainable->getCommandDocument()]; + + foreach (['comment', 'verbosity'] as $option) { + if (isset($this->options[$option])) { + $cmd[$option] = $this->options[$option]; + } + } + + return new Command($cmd); + } + + /** + * Create options for executing the command. + * + * @see https://php.net/manual/en/mongodb-driver-server.executecommand.php + */ + private function createOptions(): array + { + $options = []; + + if (isset($this->options['readPreference'])) { + $options['readPreference'] = $this->options['readPreference']; + } + + if (isset($this->options['session'])) { + $options['session'] = $this->options['session']; + } + + return $options; + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/Explainable.php b/vendor/mongodb/mongodb/src/Operation/Explainable.php new file mode 100644 index 00000000..f380e1c3 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/Explainable.php @@ -0,0 +1,34 @@ +options['allowDiskUse']) && ! is_bool($this->options['allowDiskUse'])) { + throw InvalidArgumentException::invalidType('"allowDiskUse" option', $this->options['allowDiskUse'], 'boolean'); + } + + if (isset($this->options['allowPartialResults']) && ! is_bool($this->options['allowPartialResults'])) { + throw InvalidArgumentException::invalidType('"allowPartialResults" option', $this->options['allowPartialResults'], 'boolean'); + } + + if (isset($this->options['batchSize']) && ! is_integer($this->options['batchSize'])) { + throw InvalidArgumentException::invalidType('"batchSize" option', $this->options['batchSize'], 'integer'); + } + + if (isset($this->options['codec']) && ! $this->options['codec'] instanceof DocumentCodec) { + throw InvalidArgumentException::invalidType('"codec" option', $this->options['codec'], DocumentCodec::class); + } + + if (isset($this->options['collation']) && ! is_document($this->options['collation'])) { + throw InvalidArgumentException::expectedDocumentType('"collation" option', $this->options['collation']); + } + + if (isset($this->options['cursorType'])) { + if (! is_integer($this->options['cursorType'])) { + throw InvalidArgumentException::invalidType('"cursorType" option', $this->options['cursorType'], 'integer'); + } + + if ( + $this->options['cursorType'] !== self::NON_TAILABLE && + $this->options['cursorType'] !== self::TAILABLE && + $this->options['cursorType'] !== self::TAILABLE_AWAIT + ) { + throw new InvalidArgumentException('Invalid value for "cursorType" option: ' . $this->options['cursorType']); + } + } + + if (isset($this->options['hint']) && ! is_string($this->options['hint']) && ! is_document($this->options['hint'])) { + throw InvalidArgumentException::expectedDocumentOrStringType('"hint" option', $this->options['hint']); + } + + if (isset($this->options['limit']) && ! is_integer($this->options['limit'])) { + throw InvalidArgumentException::invalidType('"limit" option', $this->options['limit'], 'integer'); + } + + if (isset($this->options['max']) && ! is_document($this->options['max'])) { + throw InvalidArgumentException::expectedDocumentType('"max" option', $this->options['max']); + } + + if (isset($this->options['maxAwaitTimeMS']) && ! is_integer($this->options['maxAwaitTimeMS'])) { + throw InvalidArgumentException::invalidType('"maxAwaitTimeMS" option', $this->options['maxAwaitTimeMS'], 'integer'); + } + + if (isset($this->options['maxScan']) && ! is_integer($this->options['maxScan'])) { + throw InvalidArgumentException::invalidType('"maxScan" option', $this->options['maxScan'], 'integer'); + } + + if (isset($this->options['maxTimeMS']) && ! is_integer($this->options['maxTimeMS'])) { + throw InvalidArgumentException::invalidType('"maxTimeMS" option', $this->options['maxTimeMS'], 'integer'); + } + + if (isset($this->options['min']) && ! is_document($this->options['min'])) { + throw InvalidArgumentException::expectedDocumentType('"min" option', $this->options['min']); + } + + if (isset($this->options['modifiers']) && ! is_document($this->options['modifiers'])) { + throw InvalidArgumentException::expectedDocumentType('"modifiers" option', $this->options['modifiers']); + } + + if (isset($this->options['noCursorTimeout']) && ! is_bool($this->options['noCursorTimeout'])) { + throw InvalidArgumentException::invalidType('"noCursorTimeout" option', $this->options['noCursorTimeout'], 'boolean'); + } + + if (isset($this->options['oplogReplay']) && ! is_bool($this->options['oplogReplay'])) { + throw InvalidArgumentException::invalidType('"oplogReplay" option', $this->options['oplogReplay'], 'boolean'); + } + + if (isset($this->options['projection']) && ! is_document($this->options['projection'])) { + throw InvalidArgumentException::expectedDocumentType('"projection" option', $this->options['projection']); + } + + if (isset($this->options['readConcern']) && ! $this->options['readConcern'] instanceof ReadConcern) { + throw InvalidArgumentException::invalidType('"readConcern" option', $this->options['readConcern'], ReadConcern::class); + } + + if (isset($this->options['readPreference']) && ! $this->options['readPreference'] instanceof ReadPreference) { + throw InvalidArgumentException::invalidType('"readPreference" option', $this->options['readPreference'], ReadPreference::class); + } + + if (isset($this->options['returnKey']) && ! is_bool($this->options['returnKey'])) { + throw InvalidArgumentException::invalidType('"returnKey" option', $this->options['returnKey'], 'boolean'); + } + + if (isset($this->options['session']) && ! $this->options['session'] instanceof Session) { + throw InvalidArgumentException::invalidType('"session" option', $this->options['session'], Session::class); + } + + if (isset($this->options['showRecordId']) && ! is_bool($this->options['showRecordId'])) { + throw InvalidArgumentException::invalidType('"showRecordId" option', $this->options['showRecordId'], 'boolean'); + } + + if (isset($this->options['skip']) && ! is_integer($this->options['skip'])) { + throw InvalidArgumentException::invalidType('"skip" option', $this->options['skip'], 'integer'); + } + + if (isset($this->options['snapshot']) && ! is_bool($this->options['snapshot'])) { + throw InvalidArgumentException::invalidType('"snapshot" option', $this->options['snapshot'], 'boolean'); + } + + if (isset($this->options['sort']) && ! is_document($this->options['sort'])) { + throw InvalidArgumentException::expectedDocumentType('"sort" option', $this->options['sort']); + } + + if (isset($this->options['typeMap']) && ! is_array($this->options['typeMap'])) { + throw InvalidArgumentException::invalidType('"typeMap" option', $this->options['typeMap'], 'array'); + } + + if (isset($this->options['let']) && ! is_document($this->options['let'])) { + throw InvalidArgumentException::expectedDocumentType('"let" option', $this->options['let']); + } + + if (isset($this->options['readConcern']) && $this->options['readConcern']->isDefault()) { + unset($this->options['readConcern']); + } + + if (isset($this->options['codec']) && isset($this->options['typeMap'])) { + throw InvalidArgumentException::cannotCombineCodecAndTypeMap(); + } + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return CursorInterface&Iterator + * @throws UnsupportedException if read concern is used and unsupported + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server) + { + $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); + if ($inTransaction && isset($this->options['readConcern'])) { + throw UnsupportedException::readConcernNotSupportedInTransaction(); + } + + $cursor = $server->executeQuery($this->databaseName . '.' . $this->collectionName, new Query($this->filter, $this->createQueryOptions()), $this->createExecuteOptions()); + + if (isset($this->options['codec'])) { + return CodecCursor::fromCursor($cursor, $this->options['codec']); + } + + if (isset($this->options['typeMap'])) { + $cursor->setTypeMap($this->options['typeMap']); + } + + return $cursor; + } + + /** + * Returns the command document for this operation. + * + * @see Explainable::getCommandDocument() + * @return array + */ + public function getCommandDocument() + { + $cmd = ['find' => $this->collectionName, 'filter' => (object) $this->filter]; + + $options = $this->createQueryOptions(); + + if (empty($options)) { + return $cmd; + } + + // maxAwaitTimeMS is a Query level option so should not be considered here + unset($options['maxAwaitTimeMS']); + + $modifierFallback = [ + ['allowPartialResults', 'partial'], + ['comment', '$comment'], + ['hint', '$hint'], + ['maxScan', '$maxScan'], + ['max', '$max'], + ['maxTimeMS', '$maxTimeMS'], + ['min', '$min'], + ['returnKey', '$returnKey'], + ['showRecordId', '$showDiskLoc'], + ['sort', '$orderby'], + ['snapshot', '$snapshot'], + ]; + + foreach ($modifierFallback as $modifier) { + if (! isset($options[$modifier[0]]) && isset($options['modifiers'][$modifier[1]])) { + $options[$modifier[0]] = $options['modifiers'][$modifier[1]]; + } + } + + unset($options['modifiers']); + + return $cmd + $options; + } + + /** + * Create options for executing the command. + * + * @see https://php.net/manual/en/mongodb-driver-server.executequery.php + */ + private function createExecuteOptions(): array + { + $options = []; + + if (isset($this->options['readPreference'])) { + $options['readPreference'] = $this->options['readPreference']; + } + + if (isset($this->options['session'])) { + $options['session'] = $this->options['session']; + } + + return $options; + } + + /** + * Create options for the find query. + * + * Note that these are separate from the options for executing the command, + * which are created in createExecuteOptions(). + */ + private function createQueryOptions(): array + { + $options = []; + + if (isset($this->options['cursorType'])) { + if ($this->options['cursorType'] === self::TAILABLE) { + $options['tailable'] = true; + } + + if ($this->options['cursorType'] === self::TAILABLE_AWAIT) { + $options['tailable'] = true; + $options['awaitData'] = true; + } + } + + foreach (['allowDiskUse', 'allowPartialResults', 'batchSize', 'comment', 'hint', 'limit', 'maxAwaitTimeMS', 'maxScan', 'maxTimeMS', 'noCursorTimeout', 'oplogReplay', 'projection', 'readConcern', 'returnKey', 'showRecordId', 'skip', 'snapshot', 'sort'] as $option) { + if (isset($this->options[$option])) { + $options[$option] = $this->options[$option]; + } + } + + foreach (['collation', 'let', 'max', 'min'] as $option) { + if (isset($this->options[$option])) { + $options[$option] = (object) $this->options[$option]; + } + } + + if (! empty($this->options['modifiers'])) { + /** @psalm-var array|object */ + $modifiers = $this->options['modifiers']; + $options['modifiers'] = is_object($modifiers) ? document_to_array($modifiers) : $modifiers; + } + + // Ensure no cursor is left behind when limit == batchSize by increasing batchSize + if (isset($options['limit'], $options['batchSize']) && $options['limit'] === $options['batchSize']) { + assert(is_integer($options['batchSize'])); + $options['batchSize']++; + } + + if (isset($options['limit']) && $options['limit'] === 1) { + $options['singleBatch'] = true; + } + + return $options; + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/FindAndModify.php b/vendor/mongodb/mongodb/src/Operation/FindAndModify.php new file mode 100644 index 00000000..07944db3 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/FindAndModify.php @@ -0,0 +1,351 @@ += 4.4. Using this option in + * other contexts will result in an exception at execution time. + * + * * maxTimeMS (integer): The maximum amount of time to allow the query to + * run. + * + * * new (boolean): When true, returns the modified document rather than + * the original. This option is ignored for remove operations. The + * The default is false. + * + * * query (document): Query by which to filter documents. + * + * * remove (boolean): When true, removes the matched document. This option + * cannot be true if the update option is set. The default is false. + * + * * session (MongoDB\Driver\Session): Client session. + * + * * sort (document): Determines which document the operation modifies if + * the query selects multiple documents. + * + * * typeMap (array): Type map for BSON deserialization. + * + * * update (document): Update or replacement to apply to the matched + * document. This option cannot be set if the remove option is true. + * + * * upsert (boolean): When true, a new document is created if no document + * matches the query. This option is ignored for remove operations. The + * default is false. + * + * * let (document): Map of parameter names and values. Values must be + * constant or closed expressions that do not reference document fields. + * Parameters can then be accessed as variables in an aggregate + * expression context (e.g. "$$var"). + * + * * writeConcern (MongoDB\Driver\WriteConcern): Write concern. + * + * @param string $databaseName Database name + * @param string $collectionName Collection name + * @param array $options Command options + * @throws InvalidArgumentException for parameter/option parsing errors + */ + public function __construct(private string $databaseName, private string $collectionName, array $options) + { + $options += ['remove' => false]; + + if (isset($options['arrayFilters']) && ! is_array($options['arrayFilters'])) { + throw InvalidArgumentException::invalidType('"arrayFilters" option', $options['arrayFilters'], 'array'); + } + + if (isset($options['bypassDocumentValidation']) && ! is_bool($options['bypassDocumentValidation'])) { + throw InvalidArgumentException::invalidType('"bypassDocumentValidation" option', $options['bypassDocumentValidation'], 'boolean'); + } + + if (isset($options['codec']) && ! $options['codec'] instanceof DocumentCodec) { + throw InvalidArgumentException::invalidType('"codec" option', $options['codec'], DocumentCodec::class); + } + + if (isset($options['collation']) && ! is_document($options['collation'])) { + throw InvalidArgumentException::expectedDocumentType('"collation" option', $options['collation']); + } + + if (isset($options['fields']) && ! is_document($options['fields'])) { + throw InvalidArgumentException::expectedDocumentType('"fields" option', $options['fields']); + } + + if (isset($options['hint']) && ! is_string($options['hint']) && ! is_document($options['hint'])) { + throw InvalidArgumentException::expectedDocumentOrStringType('"hint" option', $options['hint']); + } + + if (isset($options['maxTimeMS']) && ! is_integer($options['maxTimeMS'])) { + throw InvalidArgumentException::invalidType('"maxTimeMS" option', $options['maxTimeMS'], 'integer'); + } + + if (array_key_exists('new', $options) && ! is_bool($options['new'])) { + throw InvalidArgumentException::invalidType('"new" option', $options['new'], 'boolean'); + } + + if (isset($options['query']) && ! is_document($options['query'])) { + throw InvalidArgumentException::expectedDocumentType('"query" option', $options['query']); + } + + if (! is_bool($options['remove'])) { + throw InvalidArgumentException::invalidType('"remove" option', $options['remove'], 'boolean'); + } + + if (isset($options['session']) && ! $options['session'] instanceof Session) { + throw InvalidArgumentException::invalidType('"session" option', $options['session'], Session::class); + } + + if (isset($options['sort']) && ! is_document($options['sort'])) { + throw InvalidArgumentException::expectedDocumentType('"sort" option', $options['sort']); + } + + if (isset($options['typeMap']) && ! is_array($options['typeMap'])) { + throw InvalidArgumentException::invalidType('"typeMap" option', $options['typeMap'], 'array'); + } + + if (isset($options['update']) && ! is_array($options['update']) && ! is_object($options['update'])) { + throw InvalidArgumentException::invalidType('"update" option', $options['update'], 'array or object'); + } + + if (isset($options['writeConcern']) && ! $options['writeConcern'] instanceof WriteConcern) { + throw InvalidArgumentException::invalidType('"writeConcern" option', $options['writeConcern'], WriteConcern::class); + } + + if (array_key_exists('upsert', $options) && ! is_bool($options['upsert'])) { + throw InvalidArgumentException::invalidType('"upsert" option', $options['upsert'], 'boolean'); + } + + if (isset($options['let']) && ! is_document($options['let'])) { + throw InvalidArgumentException::expectedDocumentType('"let" option', $options['let']); + } + + if (isset($options['bypassDocumentValidation']) && ! $options['bypassDocumentValidation']) { + unset($options['bypassDocumentValidation']); + } + + if (! (isset($options['update']) xor $options['remove'])) { + throw new InvalidArgumentException('The "remove" option must be true or an "update" document must be specified, but not both'); + } + + if (isset($options['writeConcern']) && $options['writeConcern']->isDefault()) { + unset($options['writeConcern']); + } + + if (isset($options['codec']) && isset($options['typeMap'])) { + throw InvalidArgumentException::cannotCombineCodecAndTypeMap(); + } + + $this->options = $options; + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return array|object|null + * @throws UnexpectedValueException if the command response was malformed + * @throws UnsupportedException if hint or write concern is used and unsupported + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server) + { + /* Server versions >= 4.2.0 raise errors for unsupported update options. + * For previous versions, the CRUD spec requires a client-side error. */ + if (isset($this->options['hint']) && ! server_supports_feature($server, self::WIRE_VERSION_FOR_UNSUPPORTED_OPTION_SERVER_SIDE_ERROR)) { + throw UnsupportedException::hintNotSupported(); + } + + /* CRUD spec requires a client-side error when using "hint" with an + * unacknowledged write concern on an unsupported server. */ + if ( + isset($this->options['writeConcern']) && ! is_write_concern_acknowledged($this->options['writeConcern']) && + isset($this->options['hint']) && ! server_supports_feature($server, self::WIRE_VERSION_FOR_HINT) + ) { + throw UnsupportedException::hintNotSupported(); + } + + $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); + if ($inTransaction && isset($this->options['writeConcern'])) { + throw UnsupportedException::writeConcernNotSupportedInTransaction(); + } + + $cursor = $server->executeWriteCommand($this->databaseName, new Command($this->createCommandDocument()), $this->createOptions()); + + if (isset($this->options['codec'])) { + $cursor->setTypeMap(['root' => 'bson']); + $result = current($cursor->toArray()); + assert($result instanceof Document); + + $value = $result->get('value'); + + return $value === null ? $value : $this->options['codec']->decode($value); + } + + if (isset($this->options['typeMap'])) { + $cursor->setTypeMap(create_field_path_type_map($this->options['typeMap'], 'value')); + } + + $result = current($cursor->toArray()); + + return is_object($result) ? ($result->value ?? null) : null; + } + + /** + * Returns the command document for this operation. + * + * @see Explainable::getCommandDocument() + * @return array + */ + public function getCommandDocument() + { + return $this->createCommandDocument(); + } + + /** + * Create the findAndModify command document. + */ + private function createCommandDocument(): array + { + $cmd = ['findAndModify' => $this->collectionName]; + + if ($this->options['remove']) { + $cmd['remove'] = true; + } else { + if (isset($this->options['new'])) { + $cmd['new'] = $this->options['new']; + } + + if (isset($this->options['upsert'])) { + $cmd['upsert'] = $this->options['upsert']; + } + } + + foreach (['collation', 'fields', 'let', 'query', 'sort'] as $option) { + if (isset($this->options[$option])) { + $cmd[$option] = (object) $this->options[$option]; + } + } + + if (isset($this->options['update'])) { + /** @psalm-var array|object */ + $update = $this->options['update']; + /* A non-empty pipeline will encode as a BSON array, so leave it + * as-is. Cast anything else to an object since a BSON document is + * likely expected. This includes empty arrays, which historically + * can be used to represent empty replacement documents. + * + * This also allows an empty pipeline expressed as a PackedArray or + * Serializable to still encode as a BSON array, since the object + * cast will have no effect. */ + $cmd['update'] = is_pipeline($update) ? $update : (object) $update; + } + + foreach (['arrayFilters', 'bypassDocumentValidation', 'comment', 'hint', 'maxTimeMS'] as $option) { + if (isset($this->options[$option])) { + $cmd[$option] = $this->options[$option]; + } + } + + return $cmd; + } + + /** + * Create options for executing the command. + * + * @see https://php.net/manual/en/mongodb-driver-server.executewritecommand.php + */ + private function createOptions(): array + { + $options = []; + + if (isset($this->options['session'])) { + $options['session'] = $this->options['session']; + } + + if (isset($this->options['writeConcern'])) { + $options['writeConcern'] = $this->options['writeConcern']; + } + + return $options; + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/FindOne.php b/vendor/mongodb/mongodb/src/Operation/FindOne.php new file mode 100644 index 00000000..161d01dd --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/FindOne.php @@ -0,0 +1,145 @@ +find = new Find( + $databaseName, + $collectionName, + $filter, + ['limit' => 1] + $options, + ); + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return array|object|null + * @throws UnsupportedException if collation or read concern is used and unsupported + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server) + { + $cursor = $this->find->execute($server); + $document = current($cursor->toArray()); + + return $document === false ? null : $document; + } + + /** + * Returns the command document for this operation. + * + * @see Explainable::getCommandDocument() + * @return array + */ + public function getCommandDocument() + { + return $this->find->getCommandDocument(); + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/FindOneAndDelete.php b/vendor/mongodb/mongodb/src/Operation/FindOneAndDelete.php new file mode 100644 index 00000000..a560ee4c --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/FindOneAndDelete.php @@ -0,0 +1,132 @@ +findAndModify = new FindAndModify( + $databaseName, + $collectionName, + ['query' => $filter, 'remove' => true] + $options, + ); + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return array|object|null + * @throws UnsupportedException if collation or write concern is used and unsupported + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server) + { + return $this->findAndModify->execute($server); + } + + /** + * Returns the command document for this operation. + * + * @see Explainable::getCommandDocument() + * @return array + */ + public function getCommandDocument() + { + return $this->findAndModify->getCommandDocument(); + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/FindOneAndReplace.php b/vendor/mongodb/mongodb/src/Operation/FindOneAndReplace.php new file mode 100644 index 00000000..dfd76130 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/FindOneAndReplace.php @@ -0,0 +1,202 @@ +validateReplacement($replacement, $options['codec'] ?? null); + + $this->findAndModify = new FindAndModify( + $databaseName, + $collectionName, + ['query' => $filter, 'update' => $replacement] + $options, + ); + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return array|object|null + * @throws UnsupportedException if collation or write concern is used and unsupported + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server) + { + return $this->findAndModify->execute($server); + } + + /** + * Returns the command document for this operation. + * + * @see Explainable::getCommandDocument() + * @return array + */ + public function getCommandDocument() + { + return $this->findAndModify->getCommandDocument(); + } + + /** @return array|object */ + private function validateReplacement(array|object $replacement, ?DocumentCodec $codec) + { + if (isset($codec)) { + $replacement = $codec->encode($replacement); + } + + if (! is_document($replacement)) { + throw InvalidArgumentException::expectedDocumentType('$replacement', $replacement); + } + + // Treat empty arrays as replacement documents for BC + if ($replacement === []) { + $replacement = (object) $replacement; + } + + if (is_first_key_operator($replacement)) { + throw new InvalidArgumentException('First key in $replacement is an update operator'); + } + + if (is_pipeline($replacement, true /* allowEmpty */)) { + throw new InvalidArgumentException('$replacement is an update pipeline'); + } + + return $replacement; + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/FindOneAndUpdate.php b/vendor/mongodb/mongodb/src/Operation/FindOneAndUpdate.php new file mode 100644 index 00000000..3566c982 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/FindOneAndUpdate.php @@ -0,0 +1,175 @@ +findAndModify = new FindAndModify( + $databaseName, + $collectionName, + ['query' => $filter, 'update' => $update] + $options, + ); + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return array|object|null + * @throws UnsupportedException if collation or write concern is used and unsupported + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server) + { + return $this->findAndModify->execute($server); + } + + /** + * Returns the command document for this operation. + * + * @see Explainable::getCommandDocument() + * @return array + */ + public function getCommandDocument() + { + return $this->findAndModify->getCommandDocument(); + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/InsertMany.php b/vendor/mongodb/mongodb/src/Operation/InsertMany.php new file mode 100644 index 00000000..5e227cbc --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/InsertMany.php @@ -0,0 +1,207 @@ + */ + private array $documents; + + private array $options; + + /** + * Constructs an insert command. + * + * Supported options: + * + * * bypassDocumentValidation (boolean): If true, allows the write to + * circumvent document level validation. + * + * * codec (MongoDB\Codec\DocumentCodec): Codec used to encode PHP objects + * into BSON. + * + * * comment (mixed): BSON value to attach as a comment to the command(s) + * associated with this insert. + * + * This is not supported for servers versions < 4.4. + * + * * ordered (boolean): If true, when an insert fails, return without + * performing the remaining writes. If false, when a write fails, + * continue with the remaining writes, if any. The default is true. + * + * * session (MongoDB\Driver\Session): Client session. + * + * * writeConcern (MongoDB\Driver\WriteConcern): Write concern. + * + * @param string $databaseName Database name + * @param string $collectionName Collection name + * @param list $documents List of documents to insert + * @param array $options Command options + * @throws InvalidArgumentException for parameter/option parsing errors + */ + public function __construct(private string $databaseName, private string $collectionName, array $documents, array $options = []) + { + $options += ['ordered' => true]; + + if (isset($options['bypassDocumentValidation']) && ! is_bool($options['bypassDocumentValidation'])) { + throw InvalidArgumentException::invalidType('"bypassDocumentValidation" option', $options['bypassDocumentValidation'], 'boolean'); + } + + if (isset($options['codec']) && ! $options['codec'] instanceof DocumentCodec) { + throw InvalidArgumentException::invalidType('"codec" option', $options['codec'], DocumentCodec::class); + } + + if (! is_bool($options['ordered'])) { + throw InvalidArgumentException::invalidType('"ordered" option', $options['ordered'], 'boolean'); + } + + if (isset($options['session']) && ! $options['session'] instanceof Session) { + throw InvalidArgumentException::invalidType('"session" option', $options['session'], Session::class); + } + + if (isset($options['writeConcern']) && ! $options['writeConcern'] instanceof WriteConcern) { + throw InvalidArgumentException::invalidType('"writeConcern" option', $options['writeConcern'], WriteConcern::class); + } + + if (isset($options['bypassDocumentValidation']) && ! $options['bypassDocumentValidation']) { + unset($options['bypassDocumentValidation']); + } + + if (isset($options['writeConcern']) && $options['writeConcern']->isDefault()) { + unset($options['writeConcern']); + } + + $this->documents = $this->validateDocuments($documents, $options['codec'] ?? null); + $this->options = $options; + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return InsertManyResult + * @throws UnsupportedException if write concern is used and unsupported + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server) + { + $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); + if ($inTransaction && isset($this->options['writeConcern'])) { + throw UnsupportedException::writeConcernNotSupportedInTransaction(); + } + + $bulk = new Bulk($this->createBulkWriteOptions()); + $insertedIds = []; + + foreach ($this->documents as $i => $document) { + $insertedIds[$i] = $bulk->insert($document); + } + + $writeResult = $server->executeBulkWrite($this->databaseName . '.' . $this->collectionName, $bulk, $this->createExecuteOptions()); + + return new InsertManyResult($writeResult, $insertedIds); + } + + /** + * Create options for constructing the bulk write. + * + * @see https://php.net/manual/en/mongodb-driver-bulkwrite.construct.php + */ + private function createBulkWriteOptions(): array + { + $options = ['ordered' => $this->options['ordered']]; + + foreach (['bypassDocumentValidation', 'comment'] as $option) { + if (isset($this->options[$option])) { + $options[$option] = $this->options[$option]; + } + } + + return $options; + } + + /** + * Create options for executing the bulk write. + * + * @see https://php.net/manual/en/mongodb-driver-server.executebulkwrite.php + */ + private function createExecuteOptions(): array + { + $options = []; + + if (isset($this->options['session'])) { + $options['session'] = $this->options['session']; + } + + if (isset($this->options['writeConcern'])) { + $options['writeConcern'] = $this->options['writeConcern']; + } + + return $options; + } + + /** + * @param list $documents + * @return list + */ + private function validateDocuments(array $documents, ?DocumentCodec $codec): array + { + if (empty($documents)) { + throw new InvalidArgumentException('$documents is empty'); + } + + if (! array_is_list($documents)) { + throw new InvalidArgumentException('$documents is not a list'); + } + + foreach ($documents as $i => $document) { + if ($codec) { + $document = $documents[$i] = $codec->encode($document); + } + + if (! is_document($document)) { + throw InvalidArgumentException::expectedDocumentType(sprintf('$documents[%d]', $i), $document); + } + } + + return $documents; + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/InsertOne.php b/vendor/mongodb/mongodb/src/Operation/InsertOne.php new file mode 100644 index 00000000..6d8f58cd --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/InsertOne.php @@ -0,0 +1,174 @@ +options['bypassDocumentValidation']) && ! is_bool($this->options['bypassDocumentValidation'])) { + throw InvalidArgumentException::invalidType('"bypassDocumentValidation" option', $this->options['bypassDocumentValidation'], 'boolean'); + } + + if (isset($this->options['codec']) && ! $this->options['codec'] instanceof DocumentCodec) { + throw InvalidArgumentException::invalidType('"codec" option', $this->options['codec'], DocumentCodec::class); + } + + if (isset($this->options['session']) && ! $this->options['session'] instanceof Session) { + throw InvalidArgumentException::invalidType('"session" option', $this->options['session'], Session::class); + } + + if (isset($this->options['writeConcern']) && ! $this->options['writeConcern'] instanceof WriteConcern) { + throw InvalidArgumentException::invalidType('"writeConcern" option', $this->options['writeConcern'], WriteConcern::class); + } + + if (isset($this->options['bypassDocumentValidation']) && ! $this->options['bypassDocumentValidation']) { + unset($this->options['bypassDocumentValidation']); + } + + if (isset($this->options['writeConcern']) && $this->options['writeConcern']->isDefault()) { + unset($this->options['writeConcern']); + } + + $this->document = $this->validateDocument($document, $this->options['codec'] ?? null); + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return InsertOneResult + * @throws UnsupportedException if write concern is used and unsupported + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server) + { + $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); + if (isset($this->options['writeConcern']) && $inTransaction) { + throw UnsupportedException::writeConcernNotSupportedInTransaction(); + } + + $bulk = new Bulk($this->createBulkWriteOptions()); + + $insertedId = $bulk->insert($this->document); + + $writeResult = $server->executeBulkWrite($this->databaseName . '.' . $this->collectionName, $bulk, $this->createExecuteOptions()); + + return new InsertOneResult($writeResult, $insertedId); + } + + /** + * Create options for constructing the bulk write. + * + * @see https://php.net/manual/en/mongodb-driver-bulkwrite.construct.php + */ + private function createBulkWriteOptions(): array + { + $options = []; + + foreach (['bypassDocumentValidation', 'comment'] as $option) { + if (isset($this->options[$option])) { + $options[$option] = $this->options[$option]; + } + } + + return $options; + } + + /** + * Create options for executing the bulk write. + * + * @see https://php.net/manual/en/mongodb-driver-server.executebulkwrite.php + */ + private function createExecuteOptions(): array + { + $options = []; + + if (isset($this->options['session'])) { + $options['session'] = $this->options['session']; + } + + if (isset($this->options['writeConcern'])) { + $options['writeConcern'] = $this->options['writeConcern']; + } + + return $options; + } + + /** @return array|object */ + private function validateDocument(array|object $document, ?DocumentCodec $codec) + { + if ($codec) { + $document = $codec->encode($document); + } + + if (! is_document($document)) { + throw InvalidArgumentException::expectedDocumentType('$document', $document); + } + + return $document; + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/ListCollectionNames.php b/vendor/mongodb/mongodb/src/Operation/ListCollectionNames.php new file mode 100644 index 00000000..fe0ea12c --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/ListCollectionNames.php @@ -0,0 +1,83 @@ +listCollections = new ListCollectionsCommand($databaseName, ['nameOnly' => true] + $options); + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return Iterator + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server): Iterator + { + return new CallbackIterator( + $this->listCollections->execute($server), + fn (array $collectionInfo): string => (string) $collectionInfo['name'], + ); + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/ListCollections.php b/vendor/mongodb/mongodb/src/Operation/ListCollections.php new file mode 100644 index 00000000..6a877b17 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/ListCollections.php @@ -0,0 +1,81 @@ +listCollections = new ListCollectionsCommand($databaseName, ['nameOnly' => false] + $options); + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return Iterator + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server) + { + return new CollectionInfoCommandIterator($this->listCollections->execute($server), $this->databaseName); + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/ListDatabaseNames.php b/vendor/mongodb/mongodb/src/Operation/ListDatabaseNames.php new file mode 100644 index 00000000..f7301c16 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/ListDatabaseNames.php @@ -0,0 +1,84 @@ +listDatabases = new ListDatabasesCommand(['nameOnly' => true] + $options); + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @throws UnexpectedValueException if the command response was malformed + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server): Iterator + { + $result = $this->listDatabases->execute($server); + + return new ArrayIterator(array_column($result, 'name')); + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/ListDatabases.php b/vendor/mongodb/mongodb/src/Operation/ListDatabases.php new file mode 100644 index 00000000..8aa31ac1 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/ListDatabases.php @@ -0,0 +1,82 @@ +listDatabases = new ListDatabasesCommand(['nameOnly' => false] + $options); + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return Iterator + * @throws UnexpectedValueException if the command response was malformed + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server) + { + return new DatabaseInfoLegacyIterator($this->listDatabases->execute($server)); + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/ListIndexes.php b/vendor/mongodb/mongodb/src/Operation/ListIndexes.php new file mode 100644 index 00000000..1116a25a --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/ListIndexes.php @@ -0,0 +1,145 @@ +options['maxTimeMS']) && ! is_integer($this->options['maxTimeMS'])) { + throw InvalidArgumentException::invalidType('"maxTimeMS" option', $this->options['maxTimeMS'], 'integer'); + } + + if (isset($this->options['session']) && ! $this->options['session'] instanceof Session) { + throw InvalidArgumentException::invalidType('"session" option', $this->options['session'], Session::class); + } + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return Iterator + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server) + { + return $this->executeCommand($server); + } + + /** + * Create options for executing the command. + * + * Note: read preference is intentionally omitted, as the spec requires that + * the command be executed on the primary. + * + * @see https://php.net/manual/en/mongodb-driver-server.executecommand.php + */ + private function createOptions(): array + { + $options = []; + + if (isset($this->options['session'])) { + $options['session'] = $this->options['session']; + } + + return $options; + } + + /** + * Returns information for all indexes for this collection using the + * listIndexes command. + * + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + private function executeCommand(Server $server): IndexInfoIteratorIterator + { + $cmd = ['listIndexes' => $this->collectionName]; + + foreach (['comment', 'maxTimeMS'] as $option) { + if (isset($this->options[$option])) { + $cmd[$option] = $this->options[$option]; + } + } + + try { + $cursor = $server->executeReadCommand($this->databaseName, new Command($cmd), $this->createOptions()); + } catch (CommandException $e) { + /* The server may return an error if the collection does not exist. + * Check for possible error codes (see: SERVER-20463) and return an + * empty iterator instead of throwing. + */ + if ($e->getCode() === self::ERROR_CODE_NAMESPACE_NOT_FOUND || $e->getCode() === self::ERROR_CODE_DATABASE_NOT_FOUND) { + return new IndexInfoIteratorIterator(new EmptyIterator()); + } + + throw $e; + } + + $cursor->setTypeMap(['root' => 'array', 'document' => 'array']); + + /** @var CachingIterator $iterator */ + $iterator = new CachingIterator($cursor); + + return new IndexInfoIteratorIterator($iterator, $this->databaseName . '.' . $this->collectionName); + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/ListSearchIndexes.php b/vendor/mongodb/mongodb/src/Operation/ListSearchIndexes.php new file mode 100644 index 00000000..5d59725e --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/ListSearchIndexes.php @@ -0,0 +1,93 @@ +listSearchIndexesOptions = array_intersect_key($options, ['name' => 1]); + $this->aggregateOptions = array_intersect_key($options, ['batchSize' => 1, 'codec' => 1, 'collation' => 1, 'comment' => 1, 'maxTimeMS' => 1, 'readConcern' => 1, 'readPreference' => 1, 'session' => 1, 'typeMap' => 1]); + + $this->aggregate = $this->createAggregate(); + } + + /** + * Execute the operation. + * + * @return Iterator&Countable + * @see Executable::execute() + * @throws UnexpectedValueException if the command response was malformed + * @throws UnsupportedException if collation or read concern is used and unsupported + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server): Iterator + { + $cursor = $this->aggregate->execute($server); + + return new CachingIterator($cursor); + } + + private function createAggregate(): Aggregate + { + $pipeline = [ + ['$listSearchIndexes' => (object) $this->listSearchIndexesOptions], + ]; + + return new Aggregate($this->databaseName, $this->collectionName, $pipeline, $this->aggregateOptions); + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/MapReduce.php b/vendor/mongodb/mongodb/src/Operation/MapReduce.php new file mode 100644 index 00000000..a62dd2f8 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/MapReduce.php @@ -0,0 +1,391 @@ +options['bypassDocumentValidation']) && ! is_bool($this->options['bypassDocumentValidation'])) { + throw InvalidArgumentException::invalidType('"bypassDocumentValidation" option', $this->options['bypassDocumentValidation'], 'boolean'); + } + + if (isset($this->options['collation']) && ! is_document($this->options['collation'])) { + throw InvalidArgumentException::expectedDocumentType('"collation" option', $this->options['collation']); + } + + if (isset($this->options['finalize']) && ! $this->options['finalize'] instanceof JavascriptInterface) { + throw InvalidArgumentException::invalidType('"finalize" option', $this->options['finalize'], JavascriptInterface::class); + } + + if (isset($this->options['jsMode']) && ! is_bool($this->options['jsMode'])) { + throw InvalidArgumentException::invalidType('"jsMode" option', $this->options['jsMode'], 'boolean'); + } + + if (isset($this->options['limit']) && ! is_integer($this->options['limit'])) { + throw InvalidArgumentException::invalidType('"limit" option', $this->options['limit'], 'integer'); + } + + if (isset($this->options['maxTimeMS']) && ! is_integer($this->options['maxTimeMS'])) { + throw InvalidArgumentException::invalidType('"maxTimeMS" option', $this->options['maxTimeMS'], 'integer'); + } + + if (isset($this->options['query']) && ! is_document($this->options['query'])) { + throw InvalidArgumentException::expectedDocumentType('"query" option', $this->options['query']); + } + + if (isset($this->options['readConcern']) && ! $this->options['readConcern'] instanceof ReadConcern) { + throw InvalidArgumentException::invalidType('"readConcern" option', $this->options['readConcern'], ReadConcern::class); + } + + if (isset($this->options['readPreference']) && ! $this->options['readPreference'] instanceof ReadPreference) { + throw InvalidArgumentException::invalidType('"readPreference" option', $this->options['readPreference'], ReadPreference::class); + } + + if (isset($this->options['scope']) && ! is_document($this->options['scope'])) { + throw InvalidArgumentException::expectedDocumentType('"scope" option', $this->options['scope']); + } + + if (isset($this->options['session']) && ! $this->options['session'] instanceof Session) { + throw InvalidArgumentException::invalidType('"session" option', $this->options['session'], Session::class); + } + + if (isset($this->options['sort']) && ! is_document($this->options['sort'])) { + throw InvalidArgumentException::expectedDocumentType('"sort" option', $this->options['sort']); + } + + if (isset($this->options['typeMap']) && ! is_array($this->options['typeMap'])) { + throw InvalidArgumentException::invalidType('"typeMap" option', $this->options['typeMap'], 'array'); + } + + if (isset($this->options['verbose']) && ! is_bool($this->options['verbose'])) { + throw InvalidArgumentException::invalidType('"verbose" option', $this->options['verbose'], 'boolean'); + } + + if (isset($this->options['writeConcern']) && ! $this->options['writeConcern'] instanceof WriteConcern) { + throw InvalidArgumentException::invalidType('"writeConcern" option', $this->options['writeConcern'], WriteConcern::class); + } + + if (isset($this->options['bypassDocumentValidation']) && ! $this->options['bypassDocumentValidation']) { + unset($this->options['bypassDocumentValidation']); + } + + if (isset($this->options['readConcern']) && $this->options['readConcern']->isDefault()) { + unset($this->options['readConcern']); + } + + if (isset($this->options['writeConcern']) && $this->options['writeConcern']->isDefault()) { + unset($this->options['writeConcern']); + } + + // Handle deprecation of CodeWScope + if ($map->getScope() !== null) { + @trigger_error('Use of Javascript with scope in "$map" argument for MapReduce is deprecated. Put all scope variables in the "scope" option of the MapReduce operation.', E_USER_DEPRECATED); + } + + if ($reduce->getScope() !== null) { + @trigger_error('Use of Javascript with scope in "$reduce" argument for MapReduce is deprecated. Put all scope variables in the "scope" option of the MapReduce operation.', E_USER_DEPRECATED); + } + + if (isset($this->options['finalize']) && $this->options['finalize']->getScope() !== null) { + @trigger_error('Use of Javascript with scope in "finalize" option for MapReduce is deprecated. Put all scope variables in the "scope" option of the MapReduce operation.', E_USER_DEPRECATED); + } + + $this->checkOutDeprecations($out); + + $this->out = $out; + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return MapReduceResult + * @throws UnexpectedValueException if the command response was malformed + * @throws UnsupportedException if read concern or write concern is used and unsupported + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server) + { + $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); + if ($inTransaction) { + if (isset($this->options['readConcern'])) { + throw UnsupportedException::readConcernNotSupportedInTransaction(); + } + + if (isset($this->options['writeConcern'])) { + throw UnsupportedException::writeConcernNotSupportedInTransaction(); + } + } + + $hasOutputCollection = ! is_mapreduce_output_inline($this->out); + + $command = $this->createCommand(); + $options = $this->createOptions($hasOutputCollection); + + /* If the mapReduce operation results in a write, use + * executeReadWriteCommand to ensure we're handling the writeConcern + * option. + * In other cases, we use executeCommand as this will prevent the + * mapReduce operation from being retried when retryReads is enabled. + * See https://github.com/mongodb/specifications/blob/master/source/retryable-reads/retryable-reads.rst#unsupported-read-operations. */ + $cursor = $hasOutputCollection + ? $server->executeReadWriteCommand($this->databaseName, $command, $options) + : $server->executeCommand($this->databaseName, $command, $options); + + if (isset($this->options['typeMap']) && ! $hasOutputCollection) { + $cursor->setTypeMap(create_field_path_type_map($this->options['typeMap'], 'results.$')); + } + + $result = current($cursor->toArray()); + assert($result instanceof stdClass); + + $getIterator = $this->createGetIteratorCallable($result, $server); + + return new MapReduceResult($getIterator, $result); + } + + private function checkOutDeprecations(string|array|object $out): void + { + if (is_string($out)) { + return; + } + + $out = document_to_array($out); + + if (isset($out['nonAtomic']) && ! $out['nonAtomic']) { + @trigger_error('Specifying false for "out.nonAtomic" is deprecated.', E_USER_DEPRECATED); + } + + if (isset($out['sharded']) && ! $out['sharded']) { + @trigger_error('Specifying false for "out.sharded" is deprecated.', E_USER_DEPRECATED); + } + } + + /** + * Create the mapReduce command. + */ + private function createCommand(): Command + { + $cmd = [ + 'mapReduce' => $this->collectionName, + 'map' => $this->map, + 'reduce' => $this->reduce, + 'out' => $this->out, + ]; + + foreach (['bypassDocumentValidation', 'comment', 'finalize', 'jsMode', 'limit', 'maxTimeMS', 'verbose'] as $option) { + if (isset($this->options[$option])) { + $cmd[$option] = $this->options[$option]; + } + } + + foreach (['collation', 'query', 'scope', 'sort'] as $option) { + if (isset($this->options[$option])) { + $cmd[$option] = (object) $this->options[$option]; + } + } + + return new Command($cmd); + } + + /** + * Creates a callable for MapReduceResult::getIterator(). + * + * @psalm-return MapReduceCallable + * @throws UnexpectedValueException if the command response was malformed + */ + private function createGetIteratorCallable(stdClass $result, Server $server): callable + { + // Inline results can be wrapped with an ArrayIterator + if (isset($result->results) && is_array($result->results)) { + $results = $result->results; + + return fn () => new ArrayIterator($results); + } + + if (isset($result->result) && (is_string($result->result) || is_object($result->result))) { + $options = isset($this->options['typeMap']) ? ['typeMap' => $this->options['typeMap']] : []; + + $find = is_string($result->result) + ? new Find($this->databaseName, $result->result, [], $options) + : new Find($result->result->db, $result->result->collection, [], $options); + + return fn () => $find->execute($server); + } + + throw new UnexpectedValueException('mapReduce command did not return inline results or an output collection'); + } + + /** + * Create options for executing the command. + * + * @see https://php.net/manual/en/mongodb-driver-server.executereadcommand.php + * @see https://php.net/manual/en/mongodb-driver-server.executereadwritecommand.php + */ + private function createOptions(bool $hasOutputCollection): array + { + $options = []; + + if (isset($this->options['readConcern'])) { + $options['readConcern'] = $this->options['readConcern']; + } + + if (! $hasOutputCollection && isset($this->options['readPreference'])) { + $options['readPreference'] = $this->options['readPreference']; + } + + if (isset($this->options['session'])) { + $options['session'] = $this->options['session']; + } + + if ($hasOutputCollection && isset($this->options['writeConcern'])) { + $options['writeConcern'] = $this->options['writeConcern']; + } + + return $options; + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/ModifyCollection.php b/vendor/mongodb/mongodb/src/Operation/ModifyCollection.php new file mode 100644 index 00000000..f8d0c721 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/ModifyCollection.php @@ -0,0 +1,133 @@ +options['session']) && ! $this->options['session'] instanceof Session) { + throw InvalidArgumentException::invalidType('"session" option', $this->options['session'], Session::class); + } + + if (isset($this->options['typeMap']) && ! is_array($this->options['typeMap'])) { + throw InvalidArgumentException::invalidType('"typeMap" option', $this->options['typeMap'], 'array'); + } + + if (isset($this->options['writeConcern']) && ! $this->options['writeConcern'] instanceof WriteConcern) { + throw InvalidArgumentException::invalidType('"writeConcern" option', $this->options['writeConcern'], WriteConcern::class); + } + + if (isset($this->options['writeConcern']) && $this->options['writeConcern']->isDefault()) { + unset($this->options['writeConcern']); + } + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return array|object Command result document + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server) + { + $cursor = $server->executeWriteCommand($this->databaseName, $this->createCommand(), $this->createOptions()); + + if (isset($this->options['typeMap'])) { + $cursor->setTypeMap($this->options['typeMap']); + } + + return current($cursor->toArray()); + } + + private function createCommand(): Command + { + $cmd = ['collMod' => $this->collectionName] + $this->collectionOptions; + + if (isset($this->options['comment'])) { + $cmd['comment'] = $this->options['comment']; + } + + return new Command($cmd); + } + + /** + * Create options for executing the command. + * + * @see https://php.net/manual/en/mongodb-driver-server.executewritecommand.php + */ + private function createOptions(): array + { + $options = []; + + if (isset($this->options['session'])) { + $options['session'] = $this->options['session']; + } + + if (isset($this->options['writeConcern'])) { + $options['writeConcern'] = $this->options['writeConcern']; + } + + return $options; + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/RenameCollection.php b/vendor/mongodb/mongodb/src/Operation/RenameCollection.php new file mode 100644 index 00000000..245231a1 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/RenameCollection.php @@ -0,0 +1,161 @@ +options['session']) && ! $this->options['session'] instanceof Session) { + throw InvalidArgumentException::invalidType('"session" option', $this->options['session'], Session::class); + } + + if (isset($this->options['typeMap']) && ! is_array($this->options['typeMap'])) { + throw InvalidArgumentException::invalidType('"typeMap" option', $this->options['typeMap'], 'array'); + } + + if (isset($this->options['writeConcern']) && ! $this->options['writeConcern'] instanceof WriteConcern) { + throw InvalidArgumentException::invalidType('"writeConcern" option', $this->options['writeConcern'], WriteConcern::class); + } + + if (isset($this->options['writeConcern']) && $this->options['writeConcern']->isDefault()) { + unset($this->options['writeConcern']); + } + + if (isset($this->options['dropTarget']) && ! is_bool($this->options['dropTarget'])) { + throw InvalidArgumentException::invalidType('"dropTarget" option', $this->options['dropTarget'], 'boolean'); + } + + $this->fromNamespace = $fromDatabaseName . '.' . $fromCollectionName; + $this->toNamespace = $toDatabaseName . '.' . $toCollectionName; + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return array|object Command result document + * @throws UnsupportedException if write concern is used and unsupported + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server) + { + $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); + if ($inTransaction && isset($this->options['writeConcern'])) { + throw UnsupportedException::writeConcernNotSupportedInTransaction(); + } + + $cursor = $server->executeWriteCommand('admin', $this->createCommand(), $this->createOptions()); + + if (isset($this->options['typeMap'])) { + $cursor->setTypeMap($this->options['typeMap']); + } + + return current($cursor->toArray()); + } + + /** + * Create the renameCollection command. + */ + private function createCommand(): Command + { + $cmd = [ + 'renameCollection' => $this->fromNamespace, + 'to' => $this->toNamespace, + ]; + + foreach (['comment', 'dropTarget'] as $option) { + if (isset($this->options[$option])) { + $cmd[$option] = $this->options[$option]; + } + } + + return new Command($cmd); + } + + /** + * Create options for executing the command. + * + * @see https://php.net/manual/en/mongodb-driver-server.executewritecommand.php + */ + private function createOptions(): array + { + $options = []; + + if (isset($this->options['session'])) { + $options['session'] = $this->options['session']; + } + + if (isset($this->options['writeConcern'])) { + $options['writeConcern'] = $this->options['writeConcern']; + } + + return $options; + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/ReplaceOne.php b/vendor/mongodb/mongodb/src/Operation/ReplaceOne.php new file mode 100644 index 00000000..84364092 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/ReplaceOne.php @@ -0,0 +1,150 @@ +update = new Update( + $databaseName, + $collectionName, + $filter, + $this->validateReplacement($replacement, $options['codec'] ?? null), + ['multi' => false] + $options, + ); + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return UpdateResult + * @throws UnsupportedException if collation is used and unsupported + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server) + { + return $this->update->execute($server); + } + + /** @return array|object */ + private function validateReplacement(array|object $replacement, ?DocumentCodec $codec) + { + if ($codec) { + $replacement = $codec->encode($replacement); + } + + if (! is_document($replacement)) { + throw InvalidArgumentException::expectedDocumentType('$replacement', $replacement); + } + + // Treat empty arrays as replacement documents for BC + if ($replacement === []) { + $replacement = (object) $replacement; + } + + if (is_first_key_operator($replacement)) { + throw new InvalidArgumentException('First key in $replacement is an update operator'); + } + + if (is_pipeline($replacement, true /* allowEmpty */)) { + throw new InvalidArgumentException('$replacement is an update pipeline'); + } + + return $replacement; + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/Update.php b/vendor/mongodb/mongodb/src/Operation/Update.php new file mode 100644 index 00000000..2016d89a --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/Update.php @@ -0,0 +1,289 @@ + false, + 'upsert' => false, + ]; + + if (isset($options['arrayFilters']) && ! is_array($options['arrayFilters'])) { + throw InvalidArgumentException::invalidType('"arrayFilters" option', $options['arrayFilters'], 'array'); + } + + if (isset($options['bypassDocumentValidation']) && ! is_bool($options['bypassDocumentValidation'])) { + throw InvalidArgumentException::invalidType('"bypassDocumentValidation" option', $options['bypassDocumentValidation'], 'boolean'); + } + + if (isset($options['collation']) && ! is_document($options['collation'])) { + throw InvalidArgumentException::expectedDocumentType('"collation" option', $options['collation']); + } + + if (isset($options['hint']) && ! is_string($options['hint']) && ! is_document($options['hint'])) { + throw InvalidArgumentException::expectedDocumentOrStringType('"hint" option', $options['hint']); + } + + if (! is_bool($options['multi'])) { + throw InvalidArgumentException::invalidType('"multi" option', $options['multi'], 'boolean'); + } + + if ($options['multi'] && ! is_first_key_operator($update) && ! is_pipeline($update)) { + throw new InvalidArgumentException('"multi" option cannot be true unless $update has update operator(s) or non-empty pipeline'); + } + + if (isset($options['session']) && ! $options['session'] instanceof Session) { + throw InvalidArgumentException::invalidType('"session" option', $options['session'], Session::class); + } + + if (! is_bool($options['upsert'])) { + throw InvalidArgumentException::invalidType('"upsert" option', $options['upsert'], 'boolean'); + } + + if (isset($options['writeConcern']) && ! $options['writeConcern'] instanceof WriteConcern) { + throw InvalidArgumentException::invalidType('"writeConcern" option', $options['writeConcern'], WriteConcern::class); + } + + if (isset($options['let']) && ! is_document($options['let'])) { + throw InvalidArgumentException::expectedDocumentType('"let" option', $options['let']); + } + + if (isset($options['sort']) && ! is_document($options['sort'])) { + throw InvalidArgumentException::expectedDocumentType('"sort" option', $options['sort']); + } + + if (isset($options['sort']) && $options['multi']) { + throw new InvalidArgumentException('"sort" option cannot be used with multi-document updates'); + } + + if (isset($options['bypassDocumentValidation']) && ! $options['bypassDocumentValidation']) { + unset($options['bypassDocumentValidation']); + } + + if (isset($options['writeConcern']) && $options['writeConcern']->isDefault()) { + unset($options['writeConcern']); + } + + $this->options = $options; + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return UpdateResult + * @throws UnsupportedException if hint or write concern is used and unsupported + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server) + { + /* CRUD spec requires a client-side error when using "hint" with an + * unacknowledged write concern on an unsupported server. */ + if ( + isset($this->options['writeConcern']) && ! is_write_concern_acknowledged($this->options['writeConcern']) && + isset($this->options['hint']) && ! server_supports_feature($server, self::WIRE_VERSION_FOR_HINT) + ) { + throw UnsupportedException::hintNotSupported(); + } + + $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); + if ($inTransaction && isset($this->options['writeConcern'])) { + throw UnsupportedException::writeConcernNotSupportedInTransaction(); + } + + $bulk = new Bulk($this->createBulkWriteOptions()); + $bulk->update($this->filter, $this->update, $this->createUpdateOptions()); + + $writeResult = $server->executeBulkWrite($this->databaseName . '.' . $this->collectionName, $bulk, $this->createExecuteOptions()); + + return new UpdateResult($writeResult); + } + + /** + * Returns the command document for this operation. + * + * @see Explainable::getCommandDocument() + * @return array + */ + public function getCommandDocument() + { + $cmd = ['update' => $this->collectionName, 'updates' => [['q' => $this->filter, 'u' => $this->update] + $this->createUpdateOptions()]]; + + if (isset($this->options['bypassDocumentValidation'])) { + $cmd['bypassDocumentValidation'] = $this->options['bypassDocumentValidation']; + } + + return $cmd; + } + + /** + * Create options for constructing the bulk write. + * + * @see https://php.net/manual/en/mongodb-driver-bulkwrite.construct.php + */ + private function createBulkWriteOptions(): array + { + $options = []; + + foreach (['bypassDocumentValidation', 'comment'] as $option) { + if (isset($this->options[$option])) { + $options[$option] = $this->options[$option]; + } + } + + if (isset($this->options['let'])) { + $options['let'] = (object) $this->options['let']; + } + + return $options; + } + + /** + * Create options for executing the bulk write. + * + * @see https://php.net/manual/en/mongodb-driver-server.executebulkwrite.php + */ + private function createExecuteOptions(): array + { + $options = []; + + if (isset($this->options['session'])) { + $options['session'] = $this->options['session']; + } + + if (isset($this->options['writeConcern'])) { + $options['writeConcern'] = $this->options['writeConcern']; + } + + return $options; + } + + /** + * Create options for the update command. + * + * Note that these options are different from the bulk write options, which + * are created in createExecuteOptions(). + */ + private function createUpdateOptions(): array + { + $updateOptions = [ + 'multi' => $this->options['multi'], + 'upsert' => $this->options['upsert'], + ]; + + foreach (['arrayFilters', 'hint'] as $option) { + if (isset($this->options[$option])) { + $updateOptions[$option] = $this->options[$option]; + } + } + + foreach (['collation', 'sort'] as $option) { + if (isset($this->options[$option])) { + $updateOptions[$option] = (object) $this->options[$option]; + } + } + + return $updateOptions; + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/UpdateMany.php b/vendor/mongodb/mongodb/src/Operation/UpdateMany.php new file mode 100644 index 00000000..f600d46e --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/UpdateMany.php @@ -0,0 +1,122 @@ +update = new Update( + $databaseName, + $collectionName, + $filter, + $update, + ['multi' => true] + $options, + ); + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return UpdateResult + * @throws UnsupportedException if collation is used and unsupported + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server) + { + return $this->update->execute($server); + } + + /** + * Returns the command document for this operation. + * + * @see Explainable::getCommandDocument() + * @return array + */ + public function getCommandDocument() + { + return $this->update->getCommandDocument(); + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/UpdateOne.php b/vendor/mongodb/mongodb/src/Operation/UpdateOne.php new file mode 100644 index 00000000..d7bbe57c --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/UpdateOne.php @@ -0,0 +1,128 @@ +update = new Update( + $databaseName, + $collectionName, + $filter, + $update, + ['multi' => false] + $options, + ); + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return UpdateResult + * @throws UnsupportedException if collation is used and unsupported + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server) + { + return $this->update->execute($server); + } + + /** + * Returns the command document for this operation. + * + * @see Explainable::getCommandDocument() + * @return array + */ + public function getCommandDocument() + { + return $this->update->getCommandDocument(); + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/UpdateSearchIndex.php b/vendor/mongodb/mongodb/src/Operation/UpdateSearchIndex.php new file mode 100644 index 00000000..effb4a94 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/UpdateSearchIndex.php @@ -0,0 +1,84 @@ +definition = (object) $definition; + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @throws UnsupportedException if write concern is used and unsupported + * @throws DriverRuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server): void + { + $cmd = [ + 'updateSearchIndex' => $this->collectionName, + 'name' => $this->name, + 'definition' => $this->definition, + ]; + + if (isset($this->options['comment'])) { + $cmd['comment'] = $this->options['comment']; + } + + $server->executeCommand($this->databaseName, new Command($cmd)); + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/Watch.php b/vendor/mongodb/mongodb/src/Operation/Watch.php new file mode 100644 index 00000000..7e192b29 --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/Watch.php @@ -0,0 +1,460 @@ + new ReadPreference(ReadPreference::PRIMARY), + ]; + + if (isset($options['codec']) && ! $options['codec'] instanceof DocumentCodec) { + throw InvalidArgumentException::invalidType('"codec" option', $options['codec'], DocumentCodec::class); + } + + if (isset($options['codec']) && isset($options['typeMap'])) { + throw InvalidArgumentException::cannotCombineCodecAndTypeMap(); + } + + if (array_key_exists('fullDocument', $options) && ! is_string($options['fullDocument'])) { + throw InvalidArgumentException::invalidType('"fullDocument" option', $options['fullDocument'], 'string'); + } + + if (isset($options['fullDocumentBeforeChange']) && ! is_string($options['fullDocumentBeforeChange'])) { + throw InvalidArgumentException::invalidType('"fullDocumentBeforeChange" option', $options['fullDocumentBeforeChange'], 'string'); + } + + if (! $options['readPreference'] instanceof ReadPreference) { + throw InvalidArgumentException::invalidType('"readPreference" option', $options['readPreference'], ReadPreference::class); + } + + if (isset($options['resumeAfter']) && ! is_document($options['resumeAfter'])) { + throw InvalidArgumentException::expectedDocumentType('"resumeAfter" option', $options['resumeAfter']); + } + + if (isset($options['startAfter']) && ! is_document($options['startAfter'])) { + throw InvalidArgumentException::expectedDocumentType('"startAfter" option', $options['startAfter']); + } + + if (isset($options['startAtOperationTime']) && ! $options['startAtOperationTime'] instanceof TimestampInterface) { + throw InvalidArgumentException::invalidType('"startAtOperationTime" option', $options['startAtOperationTime'], TimestampInterface::class); + } + + if (isset($options['showExpandedEvents']) && ! is_bool($options['showExpandedEvents'])) { + throw InvalidArgumentException::invalidType('"showExpandedEvents" option', $options['showExpandedEvents'], 'bool'); + } + + /* In the absence of an explicit session, create one to ensure that the + * initial aggregation and any resume attempts can use the same session + * ("implicit from the user's perspective" per PHPLIB-342). Since this + * is filling in for an implicit session, we default "causalConsistency" + * to false. */ + if (! isset($options['session'])) { + try { + $options['session'] = $manager->startSession(['causalConsistency' => false]); + } catch (RuntimeException) { + /* We can ignore the exception, as libmongoc likely cannot + * create its own session and there is no risk of a mismatch. */ + } + } + + $this->aggregateOptions = array_intersect_key($options, ['batchSize' => 1, 'collation' => 1, 'comment' => 1, 'maxAwaitTimeMS' => 1, 'readConcern' => 1, 'readPreference' => 1, 'session' => 1, 'typeMap' => 1]); + $this->changeStreamOptions = array_intersect_key($options, ['fullDocument' => 1, 'fullDocumentBeforeChange' => 1, 'resumeAfter' => 1, 'showExpandedEvents' => 1, 'startAfter' => 1, 'startAtOperationTime' => 1]); + + // Null database name implies a cluster-wide change stream + if ($databaseName === null) { + $databaseName = 'admin'; + $this->changeStreamOptions['allChangesForCluster'] = true; + } + + $this->databaseName = $databaseName; + $this->codec = $options['codec'] ?? null; + + $this->aggregate = $this->createAggregate(); + } + + /** + * Execute the operation. + * + * @see Executable::execute() + * @return ChangeStream + * @throws UnsupportedException if collation or read concern is used and unsupported + * @throws RuntimeException for other driver errors (e.g. connection errors) + */ + public function execute(Server $server) + { + return new ChangeStream( + $this->createChangeStreamIterator($server), + fn ($resumeToken, $hasAdvanced): ChangeStreamIterator => $this->resume($resumeToken, $hasAdvanced), + $this->codec, + ); + } + + /** @internal */ + final public function commandFailed(CommandFailedEvent $event): void + { + } + + /** @internal */ + final public function commandStarted(CommandStartedEvent $event): void + { + if ($event->getCommandName() !== 'aggregate') { + return; + } + + $this->firstBatchSize = 0; + $this->postBatchResumeToken = null; + } + + /** @internal */ + final public function commandSucceeded(CommandSucceededEvent $event): void + { + if ($event->getCommandName() !== 'aggregate') { + return; + } + + $reply = $event->getReply(); + + if (! isset($reply->cursor->firstBatch) || ! is_array($reply->cursor->firstBatch)) { + throw new UnexpectedValueException('aggregate command did not return a "cursor.firstBatch" array'); + } + + $this->firstBatchSize = count($reply->cursor->firstBatch); + + if (isset($reply->cursor->postBatchResumeToken) && is_object($reply->cursor->postBatchResumeToken)) { + $this->postBatchResumeToken = $reply->cursor->postBatchResumeToken; + } + + if ( + $this->shouldCaptureOperationTime() && + isset($reply->operationTime) && $reply->operationTime instanceof TimestampInterface + ) { + $this->operationTime = $reply->operationTime; + } + } + + /** + * Create the aggregate command for a change stream. + * + * This method is also used to recreate the aggregate command when resuming. + */ + private function createAggregate(): Aggregate + { + $pipeline = $this->pipeline; + array_unshift($pipeline, ['$changeStream' => (object) $this->changeStreamOptions]); + + return new Aggregate($this->databaseName, $this->collectionName, $pipeline, $this->aggregateOptions); + } + + /** + * Create a ChangeStreamIterator by executing the aggregate command. + */ + private function createChangeStreamIterator(Server $server): ChangeStreamIterator + { + return new ChangeStreamIterator( + $this->executeAggregate($server), + $this->firstBatchSize, + $this->getInitialResumeToken(), + $this->postBatchResumeToken, + ); + } + + /** + * Execute the aggregate command. + * + * The command will be executed using APM so that we can capture data from + * its response (e.g. firstBatch size, postBatchResumeToken). + * + * @return CursorInterface&Iterator + */ + private function executeAggregate(Server $server) + { + addSubscriber($this); + + try { + return $this->aggregate->execute($server); + } finally { + removeSubscriber($this); + } + } + + /** + * Return the initial resume token for creating the ChangeStreamIterator. + * + * @see https://github.com/mongodb/specifications/blob/master/source/change-streams/change-streams.rst#updating-the-cached-resume-token + * @return array|object|null + */ + private function getInitialResumeToken() + { + if ($this->firstBatchSize === 0 && isset($this->postBatchResumeToken)) { + return $this->postBatchResumeToken; + } + + if (isset($this->changeStreamOptions['startAfter'])) { + return $this->changeStreamOptions['startAfter']; + } + + if (isset($this->changeStreamOptions['resumeAfter'])) { + return $this->changeStreamOptions['resumeAfter']; + } + + return null; + } + + /** + * Resumes a change stream. + * + * @see https://github.com/mongodb/specifications/blob/master/source/change-streams/change-streams.rst#resume-process + * @throws InvalidArgumentException + */ + private function resume(array|object|null $resumeToken = null, bool $hasAdvanced = false): ChangeStreamIterator + { + $this->hasResumed = true; + + /* Select a new server using the original read preference. While watch + * is not usable within transactions, we still check if there is a + * pinned session. This is to avoid an ambiguous error message about + * running a command on the wrong server. */ + $server = select_server($this->manager, $this->aggregateOptions); + + $resumeOption = isset($this->changeStreamOptions['startAfter']) && ! $hasAdvanced ? 'startAfter' : 'resumeAfter'; + + unset($this->changeStreamOptions['resumeAfter']); + unset($this->changeStreamOptions['startAfter']); + unset($this->changeStreamOptions['startAtOperationTime']); + + if ($resumeToken !== null) { + $this->changeStreamOptions[$resumeOption] = $resumeToken; + } + + if ($resumeToken === null && $this->operationTime !== null) { + $this->changeStreamOptions['startAtOperationTime'] = $this->operationTime; + } + + // Recreate the aggregate command and return a new ChangeStreamIterator + $this->aggregate = $this->createAggregate(); + + return $this->createChangeStreamIterator($server); + } + + /** + * Determine whether to capture operation time from an aggregate response. + * + * @see https://github.com/mongodb/specifications/blob/master/source/change-streams/change-streams.rst#startatoperationtime + */ + private function shouldCaptureOperationTime(): bool + { + if ($this->hasResumed) { + return false; + } + + if ( + isset($this->changeStreamOptions['resumeAfter']) || + isset($this->changeStreamOptions['startAfter']) || + isset($this->changeStreamOptions['startAtOperationTime']) + ) { + return false; + } + + if ($this->firstBatchSize > 0) { + return false; + } + + if ($this->postBatchResumeToken !== null) { + return false; + } + + return true; + } +} diff --git a/vendor/mongodb/mongodb/src/Operation/WithTransaction.php b/vendor/mongodb/mongodb/src/Operation/WithTransaction.php new file mode 100644 index 00000000..f0b5b0ec --- /dev/null +++ b/vendor/mongodb/mongodb/src/Operation/WithTransaction.php @@ -0,0 +1,124 @@ +callback = $callback; + } + + /** + * Execute the operation in the given session + * + * This helper takes care of retrying the commit operation or the entire + * transaction if an error occurs. + * + * If the commit fails because of an UnknownTransactionCommitResult error, the + * commit is retried without re-invoking the callback. + * If the commit fails because of a TransientTransactionError, the entire + * transaction will be retried. In this case, the callback will be invoked + * again. It is important that the logic inside the callback is idempotent. + * + * In case of failures, the commit or transaction are retried until 120 seconds + * from the initial call have elapsed. After that, no retries will happen and + * the helper will throw the last exception received from the driver. + * + * @see Client::startSession + * + * @param Session $session A session object as retrieved by Client::startSession + * @throws RuntimeException for driver errors while committing the transaction + * @throws Exception for any other errors, including those thrown in the callback + */ + public function execute(Session $session): void + { + $startTime = time(); + + while (true) { + $session->startTransaction($this->transactionOptions); + + try { + call_user_func($this->callback, $session); + } catch (Throwable $e) { + if ($session->isInTransaction()) { + $session->abortTransaction(); + } + + if ( + $e instanceof RuntimeException && + $e->hasErrorLabel('TransientTransactionError') && + ! $this->isTransactionTimeLimitExceeded($startTime) + ) { + continue; + } + + throw $e; + } + + if (! $session->isInTransaction()) { + // Assume callback intentionally ended the transaction + return; + } + + while (true) { + try { + $session->commitTransaction(); + } catch (RuntimeException $e) { + if ( + $e->getCode() !== 50 /* MaxTimeMSExpired */ && + $e->hasErrorLabel('UnknownTransactionCommitResult') && + ! $this->isTransactionTimeLimitExceeded($startTime) + ) { + // Retry committing the transaction + continue; + } + + if ( + $e->hasErrorLabel('TransientTransactionError') && + ! $this->isTransactionTimeLimitExceeded($startTime) + ) { + // Restart the transaction, invoking the callback again + continue 2; + } + + throw $e; + } + + // Commit was successful + break; + } + + // Transaction was successful + break; + } + } + + /** + * Returns whether the time limit for retrying transactions in the convenient transaction API has passed + * + * @param int $startTime The time the transaction was started + */ + private function isTransactionTimeLimitExceeded(int $startTime): bool + { + return time() - $startTime >= 120; + } +} diff --git a/vendor/mongodb/mongodb/src/PsrLogAdapter.php b/vendor/mongodb/mongodb/src/PsrLogAdapter.php new file mode 100644 index 00000000..d042963d --- /dev/null +++ b/vendor/mongodb/mongodb/src/PsrLogAdapter.php @@ -0,0 +1,161 @@ + */ + private SplObjectStorage $loggers; + + private const SPEC_TO_PSR = [ + self::EMERGENCY => LogLevel::EMERGENCY, + self::ALERT => LogLevel::ALERT, + self::CRITICAL => LogLevel::CRITICAL, + self::ERROR => LogLevel::ERROR, + self::WARN => LogLevel::WARNING, + self::NOTICE => LogLevel::NOTICE, + self::INFO => LogLevel::INFO, + self::DEBUG => LogLevel::DEBUG, + // PSR does not define a "trace" level, so map it to "debug" + self::TRACE => LogLevel::DEBUG, + ]; + + private const MONGOC_TO_PSR = [ + LogSubscriber::LEVEL_ERROR => LogLevel::ERROR, + /* libmongoc considers "critical" less severe than "error" so map it to + * "error" in the PSR logger. */ + LogSubscriber::LEVEL_CRITICAL => LogLevel::ERROR, + LogSubscriber::LEVEL_WARNING => LogLevel::WARNING, + LogSubscriber::LEVEL_MESSAGE => LogLevel::NOTICE, + LogSubscriber::LEVEL_INFO => LogLevel::INFO, + LogSubscriber::LEVEL_DEBUG => LogLevel::DEBUG, + ]; + + public static function addLogger(LoggerInterface $logger): void + { + $instance = self::getInstance(); + + $instance->loggers->attach($logger); + + addSubscriber($instance); + } + + /** + * Forwards a log message from libmongoc/PHPC to all registered PSR loggers. + * + * @see LogSubscriber::log() + */ + public function log(int $level, string $domain, string $message): void + { + if (! isset(self::MONGOC_TO_PSR[$level])) { + throw new UnexpectedValueException(sprintf( + 'Expected level to be >= %d and <= %d, %d given for domain "%s" and message: %s', + LogSubscriber::LEVEL_ERROR, + LogSubscriber::LEVEL_DEBUG, + $level, + $domain, + $message, + )); + } + + $instance = self::getInstance(); + $psrLevel = self::MONGOC_TO_PSR[$level]; + $context = ['domain' => $domain]; + + foreach ($instance->loggers as $logger) { + $logger->log($psrLevel, $message, $context); + } + } + + public static function removeLogger(LoggerInterface $logger): void + { + $instance = self::getInstance(); + $instance->loggers->detach($logger); + + if ($instance->loggers->count() === 0) { + removeSubscriber($instance); + } + } + + /** + * Writes a log message to all registered PSR loggers. + * + * This function is intended for internal use within the library. + */ + public static function writeLog(int $specLevel, string $domain, string $message): void + { + if (! isset(self::SPEC_TO_PSR[$specLevel])) { + throw new UnexpectedValueException(sprintf( + 'Expected level to be >= %d and <= %d, %d given for domain "%s" and message: %s', + self::EMERGENCY, + self::TRACE, + $specLevel, + $domain, + $message, + )); + } + + $instance = self::getInstance(); + $psrLevel = self::SPEC_TO_PSR[$specLevel]; + $context = ['domain' => $domain]; + + foreach ($instance->loggers as $logger) { + $logger->log($psrLevel, $message, $context); + } + } + + private function __construct() + { + $this->loggers = new SplObjectStorage(); + } + + private static function getInstance(): self + { + return self::$instance ??= new self(); + } +} diff --git a/vendor/mongodb/mongodb/src/UpdateResult.php b/vendor/mongodb/mongodb/src/UpdateResult.php new file mode 100644 index 00000000..58a73a89 --- /dev/null +++ b/vendor/mongodb/mongodb/src/UpdateResult.php @@ -0,0 +1,133 @@ +isAcknowledged = $writeResult->isAcknowledged(); + } + + /** + * Return the number of documents that were matched by the filter. + * + * This method should only be called if the write was acknowledged. + * + * @see UpdateResult::isAcknowledged() + * @return integer|null + * @throws BadMethodCallException if the write result is unacknowledged + */ + public function getMatchedCount() + { + if ($this->isAcknowledged) { + return $this->writeResult->getMatchedCount(); + } + + throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__); + } + + /** + * Return the number of documents that were modified. + * + * This value is undefined (i.e. null) if the write executed as a legacy + * operation instead of command. + * + * This method should only be called if the write was acknowledged. + * + * @see UpdateResult::isAcknowledged() + * @return integer|null + * @throws BadMethodCallException if the write result is unacknowledged + */ + public function getModifiedCount() + { + if ($this->isAcknowledged) { + return $this->writeResult->getModifiedCount(); + } + + throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__); + } + + /** + * Return the number of documents that were upserted. + * + * This method should only be called if the write was acknowledged. + * + * @see UpdateResult::isAcknowledged() + * @return integer|null + * @throws BadMethodCallException if the write result is unacknowledged + */ + public function getUpsertedCount() + { + if ($this->isAcknowledged) { + return $this->writeResult->getUpsertedCount(); + } + + throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__); + } + + /** + * Return the ID of the document inserted by an upsert operation. + * + * If the document had an ID prior to upserting (i.e. the server did not + * need to generate an ID), this will contain its "_id". Any + * server-generated ID will be a MongoDB\BSON\ObjectId instance. + * + * This value is undefined (i.e. null) if an upsert did not take place. + * + * This method should only be called if the write was acknowledged. + * + * @see UpdateResult::isAcknowledged() + * @return mixed|null + * @throws BadMethodCallException if the write result is unacknowledged + */ + public function getUpsertedId() + { + if ($this->isAcknowledged) { + foreach ($this->writeResult->getUpsertedIds() as $id) { + return $id; + } + + return null; + } + + throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__); + } + + /** + * Return whether this update was acknowledged by the server. + * + * If the update was not acknowledged, other fields from the WriteResult + * (e.g. matchedCount) will be undefined and their getter methods should not + * be invoked. + * + * @return boolean + */ + public function isAcknowledged() + { + return $this->isAcknowledged; + } +} diff --git a/vendor/mongodb/mongodb/src/functions.php b/vendor/mongodb/mongodb/src/functions.php new file mode 100644 index 00000000..a445467b --- /dev/null +++ b/vendor/mongodb/mongodb/src/functions.php @@ -0,0 +1,695 @@ + 1, 'array.$' => 1 ] ) + * + * @psalm-suppress MoreSpecificReturnType + * @psalm-suppress LessSpecificReturnStatement + */ +function object(mixed ...$values): stdClass +{ + return (object) $values; +} + +/** + * Check whether all servers support executing a write stage on a secondary. + * + * @internal + * @param Server[] $servers + */ +function all_servers_support_write_stage_on_secondary(array $servers): bool +{ + /* Write stages on secondaries are technically supported by FCV 4.4, but the + * CRUD spec requires all 5.0+ servers since FCV is not tracked by SDAM. */ + static $wireVersionForWriteStageOnSecondary = 13; + + foreach ($servers as $server) { + // We can assume that load balancers only front 5.0+ servers + if ($server->getType() === Server::TYPE_LOAD_BALANCER) { + continue; + } + + if (! server_supports_feature($server, $wireVersionForWriteStageOnSecondary)) { + return false; + } + } + + return true; +} + +/** + * Applies a type map to a document. + * + * This function is used by operations where it is not possible to apply a type + * map to the cursor directly because the root document is a command response + * (e.g. findAndModify). + * + * @internal + * @param array|object $document Document to which the type map will be applied + * @param array $typeMap Type map for BSON deserialization. + * @return array|object + * @throws InvalidArgumentException + */ +function apply_type_map_to_document(array|object $document, array $typeMap) +{ + if (! is_document($document)) { + throw InvalidArgumentException::expectedDocumentType('$document', $document); + } + + return Document::fromPHP($document)->toPHP($typeMap); +} + +/** + * Converts a document parameter to an array. + * + * This is used to facilitate unified access to document fields. It also handles + * Document, PackedArray, and Serializable objects. + * + * This function is not used for type checking. Therefore, it does not reject + * PackedArray objects or Serializable::bsonSerialize() return values that would + * encode as BSON arrays. + * + * @internal + * @throws InvalidArgumentException if $document is not an array or object + */ +function document_to_array(array|object $document): array +{ + if ($document instanceof Document || $document instanceof PackedArray) { + /* Nested documents and arrays are intentionally left as BSON. We avoid + * iterator_to_array() since Document and PackedArray iteration returns + * all values as MongoDB\BSON\Value instances. */ + + /** @psalm-var array */ + return $document->toPHP([ + 'array' => 'bson', + 'document' => 'bson', + 'root' => 'array', + ]); + } elseif ($document instanceof Serializable) { + $document = $document->bsonSerialize(); + } + + if (is_object($document)) { + /* Note: this omits all uninitialized properties, whereas BSON encoding + * includes untyped, uninitialized properties. This is acceptable given + * document_to_array()'s use cases. */ + $document = get_object_vars($document); + } + + return $document; +} + +/** + * Return a collection's encryptedFields from the encryptedFieldsMap + * autoEncryption driver option (if available). + * + * @internal + * @see https://github.com/mongodb/specifications/blob/master/source/client-side-encryption/client-side-encryption.rst#collection-encryptedfields-lookup-getencryptedfields + * @see Collection::drop() + * @see Database::createCollection() + * @see Database::dropCollection() + * @return array|object|null + */ +function get_encrypted_fields_from_driver(string $databaseName, string $collectionName, Manager $manager) +{ + $encryptedFieldsMap = (array) $manager->getEncryptedFieldsMap(); + + return $encryptedFieldsMap[$databaseName . '.' . $collectionName] ?? null; +} + +/** + * Return a collection's encryptedFields option from the server (if any). + * + * @internal + * @see https://github.com/mongodb/specifications/blob/master/source/client-side-encryption/client-side-encryption.rst#collection-encryptedfields-lookup-getencryptedfields + * @see Collection::drop() + * @see Database::dropCollection() + * @return array|object|null + */ +function get_encrypted_fields_from_server(string $databaseName, string $collectionName, Manager $manager, Server $server) +{ + // No-op if the encryptedFieldsMap autoEncryption driver option was omitted + if ($manager->getEncryptedFieldsMap() === null) { + return null; + } + + $collectionInfoIterator = (new ListCollections($databaseName, ['filter' => ['name' => $collectionName]]))->execute($server); + + foreach ($collectionInfoIterator as $collectionInfo) { + /* Note: ListCollections applies a typeMap that converts BSON documents + * to PHP arrays. This should not be problematic as encryptedFields here + * is only used by drop helpers to obtain names of supporting encryption + * collections. */ + return $collectionInfo['options']['encryptedFields'] ?? null; + } + + return null; +} + +/** + * Returns whether a given value is a valid document. + * + * This method returns true for any array or object, but specifically excludes + * BSON PackedArray instances + * + * @internal + */ +function is_document(mixed $document): bool +{ + return is_array($document) || (is_object($document) && ! $document instanceof PackedArray); +} + +/** + * Return whether the first key in the document starts with a "$" character. + * + * This is used for validating aggregation pipeline stages and differentiating + * update and replacement documents. Since true and false return values may be + * expected in different contexts, this function intentionally throws if + * $document has an unexpected type instead of returning false. + * + * @internal + * @throws InvalidArgumentException if $document is not an array or object + */ +function is_first_key_operator(array|object $document): bool +{ + if ($document instanceof PackedArray) { + return false; + } + + $document = document_to_array($document); + + $firstKey = array_key_first($document); + + if (! is_string($firstKey)) { + return false; + } + + return '$' === ($firstKey[0] ?? null); +} + +/** + * Returns whether the argument is a valid aggregation or update pipeline. + * + * This is primarily used for validating arguments for update and replace + * operations, but can also be used for validating an aggregation pipeline. + * + * The $allowEmpty parameter can be used to control whether an empty array + * should be considered a valid pipeline. Empty arrays are generally valid for + * an aggregation pipeline, but the things are more complicated for update + * pipelines. + * + * Update operations must prohibit empty pipelines, since libmongoc may encode + * an empty pipeline array as an empty replacement document when writing an + * update command (arrays and documents have the same bson_t representation). + * For consistency, findOneAndUpdate should also prohibit empty pipelines. + * Replace operations (e.g. replaceOne, findOneAndReplace) should reject empty + * and non-empty pipelines alike, since neither is a replacement document. + * + * Note: this method may propagate an InvalidArgumentException from + * document_or_array() if a Serializable object within the pipeline array + * returns a non-array, non-object value from its bsonSerialize() method. + * + * @internal + * @throws InvalidArgumentException + */ +function is_pipeline(array|object $pipeline, bool $allowEmpty = false): bool +{ + if ($pipeline instanceof PackedArray) { + /* Nested documents and arrays are intentionally left as BSON. We avoid + * iterator_to_array() since PackedArray iteration returns all values as + * MongoDB\BSON\Value instances. */ + /** @psalm-var array */ + $pipeline = $pipeline->toPHP([ + 'array' => 'bson', + 'document' => 'bson', + 'root' => 'array', + ]); + } elseif ($pipeline instanceof Serializable) { + $pipeline = $pipeline->bsonSerialize(); + } + + if (! is_array($pipeline)) { + return false; + } + + if ($pipeline === []) { + return $allowEmpty; + } + + if (! array_is_list($pipeline)) { + return false; + } + + foreach ($pipeline as $stage) { + if (! is_document($stage)) { + return false; + } + + if (! is_first_key_operator($stage)) { + return false; + } + } + + return true; +} + +/** + * Returns whether the argument is a list that contains at least one + * {@see StageInterface} object. + * + * @internal + */ +function is_builder_pipeline(array $pipeline): bool +{ + if (! $pipeline || ! array_is_list($pipeline)) { + return false; + } + + foreach ($pipeline as $stage) { + if (is_object($stage) && $stage instanceof StageInterface) { + return true; + } + } + + return false; +} + +/** + * Returns whether we are currently in a transaction. + * + * @internal + * @param array $options Command options + */ +function is_in_transaction(array $options): bool +{ + if (isset($options['session']) && $options['session'] instanceof Session && $options['session']->isInTransaction()) { + return true; + } + + return false; +} + +/** + * Return whether the aggregation pipeline ends with an $out or $merge operator. + * + * This is used for determining whether the aggregation pipeline must be + * executed against a primary server. + * + * @internal + * @param array $pipeline Aggregation pipeline + */ +function is_last_pipeline_operator_write(array $pipeline): bool +{ + $lastOp = end($pipeline); + + if ($lastOp === false) { + return false; + } + + if (! is_array($lastOp) && ! is_object($lastOp)) { + return false; + } + + $key = array_key_first(document_to_array($lastOp)); + + return $key === '$merge' || $key === '$out'; +} + +/** + * Return whether the "out" option for a mapReduce operation is "inline". + * + * This is used to determine if a mapReduce command requires a primary. + * + * @internal + * @see https://mongodb.com/docs/manual/reference/command/mapReduce/#output-inline + * @param string|array|object $out Output specification + */ +function is_mapreduce_output_inline(string|array|object $out): bool +{ + if (! is_array($out) && ! is_object($out)) { + return false; + } + + return array_key_first(document_to_array($out)) === 'inline'; +} + +/** + * Return whether the write concern is acknowledged. + * + * This function is similar to mongoc_write_concern_is_acknowledged but does not + * check the fsync option since that was never supported in the PHP driver. + * + * @internal + * @see https://mongodb.com/docs/manual/reference/write-concern/ + */ +function is_write_concern_acknowledged(WriteConcern $writeConcern): bool +{ + /* Note: -1 corresponds to MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED, which is + * deprecated synonym of MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED and slated + * for removal in libmongoc 2.0. */ + return ($writeConcern->getW() !== 0 && $writeConcern->getW() !== -1) || $writeConcern->getJournal() === true; +} + +/** + * Return whether the server supports a particular feature. + * + * @internal + * @param Server $server Server to check + * @param integer $feature Feature constant (i.e. wire protocol version) + */ +function server_supports_feature(Server $server, int $feature): bool +{ + $info = $server->getInfo(); + $maxWireVersion = isset($info['maxWireVersion']) ? (integer) $info['maxWireVersion'] : 0; + $minWireVersion = isset($info['minWireVersion']) ? (integer) $info['minWireVersion'] : 0; + + return $minWireVersion <= $feature && $maxWireVersion >= $feature; +} + +/** + * Return whether the input is an array of strings. + * + * @internal + */ +function is_string_array(mixed $input): bool +{ + if (! is_array($input)) { + return false; + } + + foreach ($input as $item) { + if (! is_string($item)) { + return false; + } + } + + return true; +} + +/** + * Performs a deep copy of a value. + * + * This function will clone objects and recursively copy values within arrays. + * + * @internal + * @see https://bugs.php.net/bug.php?id=49664 + * @param mixed $element Value to be copied + * @return mixed + * @throws ReflectionException + */ +function recursive_copy(mixed $element) +{ + if (is_array($element)) { + foreach ($element as $key => $value) { + $element[$key] = recursive_copy($value); + } + + return $element; + } + + if (! is_object($element)) { + return $element; + } + + if (! (new ReflectionClass($element))->isCloneable()) { + return $element; + } + + return clone $element; +} + +/** + * Creates a type map to apply to a field type + * + * This is used in the Aggregate, Distinct, and FindAndModify operations to + * apply the root-level type map to the document that will be returned. It also + * replaces the root type with object for consistency within these operations + * + * An existing type map for the given field path will not be overwritten + * + * @internal + * @param array $typeMap The existing typeMap + * @param string $fieldPath The field path to apply the root type to + */ +function create_field_path_type_map(array $typeMap, string $fieldPath): array +{ + // If some field paths already exist, we prefix them with the field path we are assuming as the new root + if (isset($typeMap['fieldPaths']) && is_array($typeMap['fieldPaths'])) { + $fieldPaths = $typeMap['fieldPaths']; + + $typeMap['fieldPaths'] = []; + foreach ($fieldPaths as $existingFieldPath => $type) { + $typeMap['fieldPaths'][$fieldPath . '.' . $existingFieldPath] = $type; + } + } + + // If a root typemap was set, apply this to the field object + if (isset($typeMap['root'])) { + $typeMap['fieldPaths'][$fieldPath] = $typeMap['root']; + } + + /* Special case if we want to convert an array, in which case we need to + * ensure that the field containing the array is exposed as an array, + * instead of the type given in the type map's array key. */ + if (str_ends_with($fieldPath, '.$')) { + $typeMap['fieldPaths'][substr($fieldPath, 0, -2)] = 'array'; + } + + $typeMap['root'] = 'object'; + + return $typeMap; +} + +/** + * Execute a callback within a transaction in the given session + * + * This helper takes care of retrying the commit operation or the entire + * transaction if an error occurs. + * + * If the commit fails because of an UnknownTransactionCommitResult error, the + * commit is retried without re-invoking the callback. + * If the commit fails because of a TransientTransactionError, the entire + * transaction will be retried. In this case, the callback will be invoked + * again. It is important that the logic inside the callback is idempotent. + * + * In case of failures, the commit or transaction are retried until 120 seconds + * from the initial call have elapsed. After that, no retries will happen and + * the helper will throw the last exception received from the driver. + * + * @see Client::startSession() + * @see Session::startTransaction() for supported transaction options + * + * @param Session $session A session object as retrieved by Client::startSession + * @param callable $callback A callback that will be invoked within the transaction + * @param array $transactionOptions Additional options that are passed to Session::startTransaction + * @throws RuntimeException for driver errors while committing the transaction + * @throws Exception for any other errors, including those thrown in the callback + */ +function with_transaction(Session $session, callable $callback, array $transactionOptions = []): void +{ + $operation = new WithTransaction($callback, $transactionOptions); + $operation->execute($session); +} + +/** + * Returns the session option if it is set and valid. + * + * @internal + */ +function extract_session_from_options(array $options): ?Session +{ + if (isset($options['session']) && $options['session'] instanceof Session) { + return $options['session']; + } + + return null; +} + +/** + * Returns the readPreference option if it is set and valid. + * + * @internal + */ +function extract_read_preference_from_options(array $options): ?ReadPreference +{ + if (isset($options['readPreference']) && $options['readPreference'] instanceof ReadPreference) { + return $options['readPreference']; + } + + return null; +} + +/** + * Performs server selection, respecting the readPreference and session options. + * + * The pinned server for an active transaction takes priority, followed by an + * operation-level read preference, followed by an active transaction's read + * preference, followed by a primary read preference. + * + * @internal + */ +function select_server(Manager $manager, array $options): Server +{ + $session = extract_session_from_options($options); + $server = $session instanceof Session ? $session->getServer() : null; + + // Pinned server for an active transaction takes priority + if ($server !== null) { + return $server; + } + + // Operation read preference takes priority + $readPreference = extract_read_preference_from_options($options); + + // Read preference for an active transaction takes priority + if ($readPreference === null && $session instanceof Session && $session->isInTransaction()) { + /* Session::getTransactionOptions() should always return an array if the + * session is in a transaction, but we can be defensive. */ + $readPreference = extract_read_preference_from_options($session->getTransactionOptions() ?? []); + } + + // Manager::selectServer() defaults to a primary read preference + return $manager->selectServer($readPreference); +} + +/** + * Performs server selection for an aggregate operation with a write stage. The + * $options parameter may be modified by reference if a primary read preference + * must be forced due to the existence of pre-5.0 servers in the topology. + * + * @internal + * @see https://github.com/mongodb/specifications/blob/master/source/crud/crud.rst#aggregation-pipelines-with-write-stages + */ +function select_server_for_aggregate_write_stage(Manager $manager, array &$options): Server +{ + $readPreference = extract_read_preference_from_options($options); + + /* If there is either no read preference or a primary read preference, there + * is no special server selection logic to apply. + * + * Note: an alternative read preference could still be inherited from an + * active transaction's options, but we can rely on libmongoc to raise a + * "read preference in a transaction must be primary" error if necessary. */ + if ($readPreference === null || $readPreference->getModeString() === ReadPreference::PRIMARY) { + return select_server($manager, $options); + } + + $server = null; + $serverSelectionError = null; + + try { + $server = select_server($manager, $options); + } catch (DriverRuntimeException $serverSelectionError) { + } + + /* If any pre-5.0 servers exist in the topology, force a primary read + * preference and repeat server selection if it previously failed or + * selected a secondary. */ + if (! all_servers_support_write_stage_on_secondary($manager->getServers())) { + $options['readPreference'] = new ReadPreference(ReadPreference::PRIMARY); + + if ($server === null || $server->isSecondary()) { + return select_server($manager, $options); + } + } + + /* If the topology only contains 5.0+ servers, we should either return the + * previously selected server or propagate the server selection error. */ + if ($serverSelectionError !== null) { + throw $serverSelectionError; + } + + assert($server instanceof Server); + + return $server; +} + +/** + * Performs server selection for a write operation. + * + * The pinned server for an active transaction takes priority, followed by an + * operation-level read preference, followed by a primary read preference. This + * is similar to select_server() except that it ignores a read preference from + * an active transaction's options. + * + * @internal + */ +function select_server_for_write(Manager $manager, array $options): Server +{ + return select_server($manager, $options + ['readPreference' => new ReadPreference(ReadPreference::PRIMARY)]); +} diff --git a/vendor/services.php b/vendor/services.php index 0c06f807..d950393b 100644 --- a/vendor/services.php +++ b/vendor/services.php @@ -1,5 +1,5 @@ 'itinysun\\model\\helper\\Service',