diff --git a/.evergreen/config/generated/build/build-extension.yml b/.evergreen/config/generated/build/build-extension.yml index c16586063..02033b002 100644 --- a/.evergreen/config/generated/build/build-extension.yml +++ b/.evergreen/config/generated/build/build-extension.yml @@ -7,11 +7,11 @@ tasks: vars: PHP_VERSION: "8.3" - func: "compile extension" - # TODO: remove once 1.20.0 is released + # TODO: remove once 2.0.0 is released vars: - EXTENSION_BRANCH: "v1.20" + EXTENSION_BRANCH: "v2.x" - func: "upload extension" - # TODO: re-enable once 1.20.0 is released + # TODO: re-enable once 2.0.0 is released # - name: "build-php-8.3-lowest" # tags: ["build", "php8.3", "lowest", "pr", "tag"] # commands: @@ -20,7 +20,7 @@ tasks: # PHP_VERSION: "8.3" # - func: "compile extension" # vars: -# EXTENSION_VERSION: "1.20.0" +# EXTENSION_VERSION: "2.0.0" # - func: "upload extension" # - name: "build-php-8.3-next-stable" # tags: ["build", "php8.3", "next-stable", "pr", "tag"] @@ -30,7 +30,7 @@ tasks: # PHP_VERSION: "8.3" # - func: "compile extension" # vars: -# EXTENSION_BRANCH: "v1.20.0" +# EXTENSION_BRANCH: "v2.0" # - func: "upload extension" # - name: "build-php-8.3-next-minor" # tags: ["build", "php8.3", "next-minor"] @@ -40,7 +40,7 @@ tasks: # PHP_VERSION: "8.3" # - func: "compile extension" # vars: -# EXTENSION_BRANCH: "master" +# EXTENSION_BRANCH: "v2.x" # - func: "upload extension" - name: "build-php-8.2" tags: ["build", "php8.2", "stable", "pr", "tag"] @@ -49,11 +49,11 @@ tasks: vars: PHP_VERSION: "8.2" - func: "compile extension" - # TODO: remove once 1.20.0 is released + # TODO: remove once 2.0.0 is released vars: - EXTENSION_BRANCH: "v1.20" + EXTENSION_BRANCH: "v2.x" - func: "upload extension" - # TODO: re-enable once 1.20.0 is released + # TODO: re-enable once 2.0.0 is released # - name: "build-php-8.2-lowest" # tags: ["build", "php8.2", "lowest", "pr", "tag"] # commands: @@ -62,7 +62,7 @@ tasks: # PHP_VERSION: "8.2" # - func: "compile extension" # vars: -# EXTENSION_VERSION: "1.20.0" +# EXTENSION_VERSION: "2.0.0" # - func: "upload extension" # - name: "build-php-8.2-next-stable" # tags: ["build", "php8.2", "next-stable", "pr", "tag"] @@ -72,7 +72,7 @@ tasks: # PHP_VERSION: "8.2" # - func: "compile extension" # vars: -# EXTENSION_BRANCH: "v1.20.0" +# EXTENSION_BRANCH: "v2.0" # - func: "upload extension" # - name: "build-php-8.2-next-minor" # tags: ["build", "php8.2", "next-minor"] @@ -82,7 +82,7 @@ tasks: # PHP_VERSION: "8.2" # - func: "compile extension" # vars: -# EXTENSION_BRANCH: "master" +# EXTENSION_BRANCH: "v2.x" # - func: "upload extension" - name: "build-php-8.1" tags: ["build", "php8.1", "stable", "pr", "tag"] @@ -91,11 +91,11 @@ tasks: vars: PHP_VERSION: "8.1" - func: "compile extension" - # TODO: remove once 1.20.0 is released + # TODO: remove once 2.0.0 is released vars: - EXTENSION_BRANCH: "v1.20" + EXTENSION_BRANCH: "v2.x" - func: "upload extension" - # TODO: re-enable once 1.20.0 is released + # TODO: re-enable once 2.0.0 is released # - name: "build-php-8.1-lowest" # tags: ["build", "php8.1", "lowest", "pr", "tag"] # commands: @@ -104,7 +104,7 @@ tasks: # PHP_VERSION: "8.1" # - func: "compile extension" # vars: -# EXTENSION_VERSION: "1.20.0" +# EXTENSION_VERSION: "2.0.0" # - func: "upload extension" # - name: "build-php-8.1-next-stable" # tags: ["build", "php8.1", "next-stable", "pr", "tag"] @@ -114,7 +114,7 @@ tasks: # PHP_VERSION: "8.1" # - func: "compile extension" # vars: -# EXTENSION_BRANCH: "v1.20.0" +# EXTENSION_BRANCH: "v2.0" # - func: "upload extension" # - name: "build-php-8.1-next-minor" # tags: ["build", "php8.1", "next-minor"] @@ -124,5 +124,5 @@ tasks: # PHP_VERSION: "8.1" # - func: "compile extension" # vars: -# EXTENSION_BRANCH: "master" +# EXTENSION_BRANCH: "v2.x" # - func: "upload extension" diff --git a/.evergreen/config/templates/build/build-extension.yml b/.evergreen/config/templates/build/build-extension.yml index ecd1fffdd..1599967ab 100644 --- a/.evergreen/config/templates/build/build-extension.yml +++ b/.evergreen/config/templates/build/build-extension.yml @@ -5,11 +5,11 @@ vars: PHP_VERSION: "%phpVersion%" - func: "compile extension" - # TODO: remove once 1.20.0 is released + # TODO: remove once 2.0.0 is released vars: - EXTENSION_BRANCH: "v1.20" + EXTENSION_BRANCH: "v2.x" - func: "upload extension" - # TODO: re-enable once 1.20.0 is released + # TODO: re-enable once 2.0.0 is released # - name: "build-php-%phpVersion%-lowest" # tags: ["build", "php%phpVersion%", "lowest", "pr", "tag"] # commands: @@ -18,7 +18,7 @@ # PHP_VERSION: "%phpVersion%" # - func: "compile extension" # vars: -# EXTENSION_VERSION: "1.20.0" +# EXTENSION_VERSION: "2.0.0" # - func: "upload extension" # - name: "build-php-%phpVersion%-next-stable" # tags: ["build", "php%phpVersion%", "next-stable", "pr", "tag"] @@ -28,7 +28,7 @@ # PHP_VERSION: "%phpVersion%" # - func: "compile extension" # vars: -# EXTENSION_BRANCH: "v1.20.0" +# EXTENSION_BRANCH: "v2.0" # - func: "upload extension" # - name: "build-php-%phpVersion%-next-minor" # tags: ["build", "php%phpVersion%", "next-minor"] @@ -38,5 +38,5 @@ # PHP_VERSION: "%phpVersion%" # - func: "compile extension" # vars: -# EXTENSION_BRANCH: "master" +# EXTENSION_BRANCH: "v2.x" # - func: "upload extension" diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index 5dbb7dd71..b03f7779f 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -13,9 +13,9 @@ on: env: PHP_VERSION: "8.2" - # TODO: change to "stable" once 1.20.0 is released + # TODO: change to "stable" once 2.0.0 is released # DRIVER_VERSION: "stable" - DRIVER_VERSION: "mongodb/mongo-php-driver@v1.20" + DRIVER_VERSION: "mongodb/mongo-php-driver@v2.x" jobs: phpcs: diff --git a/.github/workflows/generator.yml b/.github/workflows/generator.yml index 2427a41eb..711befabd 100644 --- a/.github/workflows/generator.yml +++ b/.github/workflows/generator.yml @@ -13,9 +13,9 @@ on: env: PHP_VERSION: "8.2" - # TODO: change to "stable" once 1.20.0 is released + # TODO: change to "stable" once 2.0.0 is released # DRIVER_VERSION: "stable" - DRIVER_VERSION: "mongodb/mongo-php-driver@v1.20" + DRIVER_VERSION: "mongodb/mongo-php-driver@v2.x" jobs: psalm: diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index ebb60cabf..82919098f 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -19,9 +19,9 @@ on: env: PHP_VERSION: "8.2" - # TODO: change to "stable" once 1.20.0 is released + # TODO: change to "stable" once 2.0.0 is released # DRIVER_VERSION: "stable" - DRIVER_VERSION: "mongodb/mongo-php-driver@v1.20" + DRIVER_VERSION: "mongodb/mongo-php-driver@v2.x" jobs: psalm: diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 803eb476d..29d36194f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -12,9 +12,9 @@ on: - "feature/*" env: - # TODO: change to "stable" once 1.20.0 is released + # TODO: change to "stable" once 2.0.0 is released # DRIVER_VERSION: "stable" - DRIVER_VERSION: "mongodb/mongo-php-driver@v1.20" + DRIVER_VERSION: "mongodb/mongo-php-driver@v2.x" jobs: phpunit: diff --git a/UPGRADE-2.0.md b/UPGRADE-2.0.md index 2c131e24c..8dabbdd59 100644 --- a/UPGRADE-2.0.md +++ b/UPGRADE-2.0.md @@ -2,6 +2,7 @@ UPGRADE FROM 1.x to 2.0 ======================== * Classes in the namespace `MongoDB\Operation\` are `final`. + * All methods in interfaces and classes now define a return type. GridFS ------ diff --git a/composer.json b/composer.json index d9d0516b4..95b96ddb8 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ "require": { "php": "^8.1", "ext-json": "*", - "ext-mongodb": "^1.20.0", + "ext-mongodb": "^2.0", "composer-runtime-api": "^2.0", "psr/log": "^1.1.4|^2|^3", "symfony/polyfill-php80": "^1.27", diff --git a/phpcs.xml.dist b/phpcs.xml.dist index de542ac64..3c2b9441b 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -133,14 +133,6 @@ - - - - - src - - - diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 039b43007..5ea414eb3 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -5,11 +5,7 @@ name]]> - - - - @@ -23,6 +19,9 @@ + + + @@ -184,11 +183,14 @@ - - - + + + + + ]]> + @@ -196,6 +198,9 @@ + + ]]> + @@ -227,10 +232,19 @@ + + + + + ]]> + + + ]]> + @@ -257,10 +271,19 @@ + + + + + ]]> + + + ]]> + @@ -324,6 +347,7 @@ getArrayCopy()]]> + getArrayCopy()]]> @@ -331,6 +355,7 @@ + @@ -339,6 +364,15 @@ + + + + + ]]> + + + ]]> + cursor->nextBatch]]> @@ -354,11 +388,6 @@ current()]]> - - - - - @@ -724,18 +753,6 @@ value ?? null) : null]]> - - - - - - - - - - - - @@ -786,14 +803,26 @@ - - listCollections->execute($server), $this->databaseName)]]> - + + + + + ]]> + + + ]]> + - - listDatabases->execute($server))]]> - + + + + + ]]> + + + ]]> + @@ -801,10 +830,19 @@ databaseName . '.' . $this->collectionName)]]> + + + + + ]]> + + + ]]> + diff --git a/psalm.xml.dist b/psalm.xml.dist index 83d825d51..d9640583b 100644 --- a/psalm.xml.dist +++ b/psalm.xml.dist @@ -21,6 +21,8 @@ + + diff --git a/src/BulkWriteResult.php b/src/BulkWriteResult.php index 4fb556e0b..548acc9a7 100644 --- a/src/BulkWriteResult.php +++ b/src/BulkWriteResult.php @@ -38,10 +38,9 @@ public function __construct(private WriteResult $writeResult, private array $ins * 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() + public function getDeletedCount(): ?int { if ($this->isAcknowledged) { return $this->writeResult->getDeletedCount(); @@ -56,10 +55,9 @@ public function getDeletedCount() * 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() + public function getInsertedCount(): ?int { if ($this->isAcknowledged) { return $this->writeResult->getInsertedCount(); @@ -76,10 +74,8 @@ public function getInsertedCount() * 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() + public function getInsertedIds(): array { return $this->insertedIds; } @@ -90,10 +86,9 @@ public function getInsertedIds() * 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() + public function getMatchedCount(): ?int { if ($this->isAcknowledged) { return $this->writeResult->getMatchedCount(); @@ -111,10 +106,9 @@ public function getMatchedCount() * 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() + public function getModifiedCount(): ?int { if ($this->isAcknowledged) { return $this->writeResult->getModifiedCount(); @@ -129,10 +123,9 @@ public function getModifiedCount() * 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() + public function getUpsertedCount(): ?int { if ($this->isAcknowledged) { return $this->writeResult->getUpsertedCount(); @@ -152,10 +145,9 @@ public function getUpsertedCount() * 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() + public function getUpsertedIds(): array { if ($this->isAcknowledged) { return $this->writeResult->getUpsertedIds(); @@ -169,10 +161,8 @@ public function getUpsertedIds() * * If the update was not acknowledged, other fields from the WriteResult * (e.g. matchedCount) will be undefined. - * - * @return boolean */ - public function isAcknowledged() + public function isAcknowledged(): bool { return $this->isAcknowledged; } diff --git a/src/ChangeStream.php b/src/ChangeStream.php index 55f25b031..a1a732666 100644 --- a/src/ChangeStream.php +++ b/src/ChangeStream.php @@ -21,22 +21,16 @@ use MongoDB\BSON\Document; use MongoDB\BSON\Int64; use MongoDB\Codec\DocumentCodec; -use MongoDB\Driver\CursorId; use MongoDB\Driver\Exception\ConnectionException; use MongoDB\Driver\Exception\RuntimeException; use MongoDB\Driver\Exception\ServerException; use MongoDB\Exception\BadMethodCallException; use MongoDB\Exception\ResumeTokenException; use MongoDB\Model\ChangeStreamIterator; -use ReturnTypeWillChange; use function assert; use function call_user_func; use function in_array; -use function sprintf; -use function trigger_error; - -use const E_USER_DEPRECATED; /** * Iterator for a change stream. @@ -88,12 +82,8 @@ class ChangeStream implements Iterator */ private bool $hasAdvanced = false; - /** - * @see https://php.net/iterator.current - * @return array|object|null - */ - #[ReturnTypeWillChange] - public function current() + /** @see https://php.net/iterator.current */ + public function current(): array|object|null { $value = $this->iterator->current(); @@ -106,26 +96,9 @@ public function current() return $this->codec->decode($value); } - /** - * @return CursorId|Int64 - * @psalm-return ($asInt64 is true ? Int64 : CursorId) - */ - #[ReturnTypeWillChange] - public function getCursorId(bool $asInt64 = false) + public function getCursorId(): Int64 { - 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); + return $this->iterator->getInnerIterator()->getId(); } /** @@ -134,20 +107,14 @@ public function getCursorId(bool $asInt64 = false) * 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() + public function getResumeToken(): array|object|null { return $this->iterator->getResumeToken(); } - /** - * @see https://php.net/iterator.key - * @return int|null - */ - #[ReturnTypeWillChange] - public function key() + /** @see https://php.net/iterator.key */ + public function key(): ?int { if ($this->valid()) { return $this->key; @@ -158,11 +125,9 @@ public function key() /** * @see https://php.net/iterator.next - * @return void * @throws ResumeTokenException */ - #[ReturnTypeWillChange] - public function next() + public function next(): void { try { $this->iterator->next(); @@ -174,11 +139,9 @@ public function next() /** * @see https://php.net/iterator.rewind - * @return void * @throws ResumeTokenException */ - #[ReturnTypeWillChange] - public function rewind() + public function rewind(): void { try { $this->iterator->rewind(); @@ -191,12 +154,8 @@ public function rewind() } } - /** - * @see https://php.net/iterator.valid - * @return boolean - */ - #[ReturnTypeWillChange] - public function valid() + /** @see https://php.net/iterator.valid */ + public function valid(): bool { return $this->iterator->valid(); } @@ -255,7 +214,8 @@ private function onIteration(bool $incrementKey): void * 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') { + // Use a type-unsafe comparison to compare with Int64 instances + if ($this->getCursorId() == 0) { $this->resumeCallable = null; } diff --git a/src/Client.php b/src/Client.php index 5ed76a0e0..00a1a6ed3 100644 --- a/src/Client.php +++ b/src/Client.php @@ -39,6 +39,7 @@ use MongoDB\Model\BSONArray; use MongoDB\Model\BSONDocument; use MongoDB\Model\DatabaseInfo; +use MongoDB\Model\DatabaseInfoIterator; use MongoDB\Operation\DropDatabase; use MongoDB\Operation\ListDatabaseNames; use MongoDB\Operation\ListDatabases; @@ -143,9 +144,8 @@ public function __construct(?string $uri = null, array $uriOptions = [], array $ * 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() + public function __debugInfo(): array { return [ 'manager' => $this->manager, @@ -166,19 +166,16 @@ public function __debugInfo() * @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) + public function __get(string $databaseName): Database { return $this->selectDatabase($databaseName); } /** * Return the connection string (i.e. URI). - * - * @return string */ - public function __toString() + public function __toString(): string { return $this->uri; } @@ -197,10 +194,8 @@ final public function addSubscriber(Subscriber $subscriber): void * Returns a ClientEncryption instance for explicit encryption and decryption * * @param array $options Encryption options - * - * @return ClientEncryption */ - public function createClientEncryption(array $options) + public function createClientEncryption(array $options): ClientEncryption { if (isset($options['keyVaultClient'])) { if ($options['keyVaultClient'] instanceof self) { @@ -224,7 +219,7 @@ public function createClientEncryption(array $options) * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function dropDatabase(string $databaseName, array $options = []) + public function dropDatabase(string $databaseName, array $options = []): array|object { if (! isset($options['typeMap'])) { $options['typeMap'] = $this->typeMap; @@ -243,10 +238,8 @@ public function dropDatabase(string $databaseName, array $options = []) /** * Return the Manager. - * - * @return Manager */ - public function getManager() + public function getManager(): Manager { return $this->manager; } @@ -255,29 +248,24 @@ public function getManager() * Return the read concern for this client. * * @see https://php.net/manual/en/mongodb-driver-readconcern.isdefault.php - * @return ReadConcern */ - public function getReadConcern() + public function getReadConcern(): ReadConcern { return $this->readConcern; } /** * Return the read preference for this client. - * - * @return ReadPreference */ - public function getReadPreference() + public function getReadPreference(): ReadPreference { return $this->readPreference; } /** * Return the type map for this client. - * - * @return array */ - public function getTypeMap() + public function getTypeMap(): array { return $this->typeMap; } @@ -286,9 +274,8 @@ public function getTypeMap() * Return the write concern for this client. * * @see https://php.net/manual/en/mongodb-driver-writeconcern.isdefault.php - * @return WriteConcern */ - public function getWriteConcern() + public function getWriteConcern(): WriteConcern { return $this->writeConcern; } @@ -318,7 +305,7 @@ public function listDatabaseNames(array $options = []): Iterator * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function listDatabases(array $options = []) + public function listDatabases(array $options = []): DatabaseInfoIterator { $operation = new ListDatabases($options); $server = select_server($this->manager, $options); @@ -343,10 +330,9 @@ final public function removeSubscriber(Subscriber $subscriber): void * @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 = []) + public function selectCollection(string $databaseName, string $collectionName, array $options = []): Collection { $options += ['typeMap' => $this->typeMap, 'builderEncoder' => $this->builderEncoder]; @@ -359,10 +345,9 @@ public function selectCollection(string $databaseName, string $collectionName, a * @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 = []) + public function selectDatabase(string $databaseName, array $options = []): Database { $options += ['typeMap' => $this->typeMap, 'builderEncoder' => $this->builderEncoder]; @@ -374,9 +359,8 @@ public function selectDatabase(string $databaseName, array $options = []) * * @see https://php.net/manual/en/mongodb-driver-manager.startsession.php * @param array $options Session options - * @return Session */ - public function startSession(array $options = []) + public function startSession(array $options = []): Session { return $this->manager->startSession($options); } @@ -387,10 +371,9 @@ public function startSession(array $options = []) * @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 = []) + public function watch(array $pipeline = [], array $options = []): ChangeStream { if (is_builder_pipeline($pipeline)) { $pipeline = new Pipeline(...$pipeline); diff --git a/src/Codec/DecodeIfSupported.php b/src/Codec/DecodeIfSupported.php index 7fd768011..ea8dde15c 100644 --- a/src/Codec/DecodeIfSupported.php +++ b/src/Codec/DecodeIfSupported.php @@ -30,17 +30,13 @@ abstract public function canDecode(mixed $value): bool; /** * @psalm-param BSONType $value - * @return mixed * @psalm-return NativeType * @throws UnsupportedValueException if the decoder does not support the value */ - abstract public function decode(mixed $value); + abstract public function decode(mixed $value): mixed; - /** - * @return mixed - * @psalm-return ($value is BSONType ? NativeType : $value) - */ - public function decodeIfSupported(mixed $value) + /** @psalm-return ($value is BSONType ? NativeType : $value) */ + public function decodeIfSupported(mixed $value): mixed { return $this->canDecode($value) ? $this->decode($value) : $value; } diff --git a/src/Codec/Decoder.php b/src/Codec/Decoder.php index 432fb2dd7..37ff9b263 100644 --- a/src/Codec/Decoder.php +++ b/src/Codec/Decoder.php @@ -37,11 +37,10 @@ public function canDecode(mixed $value): bool; * should throw an exception. * * @psalm-param BSONType $value - * @return mixed * @psalm-return NativeType * @throws UnsupportedValueException if the decoder does not support the value */ - public function decode(mixed $value); + public function decode(mixed $value): mixed; /** * Decodes a given value if supported, otherwise returns the value as-is. @@ -49,8 +48,7 @@ public function decode(mixed $value); * The DecodeIfSupported trait provides a default implementation of this * method. * - * @return mixed * @psalm-return ($value is BSONType ? NativeType : $value) */ - public function decodeIfSupported(mixed $value); + public function decodeIfSupported(mixed $value): mixed; } diff --git a/src/Codec/EncodeIfSupported.php b/src/Codec/EncodeIfSupported.php index 33823cfd6..2ce1fcf53 100644 --- a/src/Codec/EncodeIfSupported.php +++ b/src/Codec/EncodeIfSupported.php @@ -30,17 +30,13 @@ abstract public function canEncode(mixed $value): bool; /** * @psalm-param NativeType $value - * @return mixed * @psalm-return BSONType * @throws UnsupportedValueException if the encoder does not support the value */ - abstract public function encode(mixed $value); + abstract public function encode(mixed $value): mixed; - /** - * @return mixed - * @psalm-return ($value is NativeType ? BSONType : $value) - */ - public function encodeIfSupported(mixed $value) + /** @psalm-return ($value is NativeType ? BSONType : $value) */ + public function encodeIfSupported(mixed $value): mixed { return $this->canEncode($value) ? $this->encode($value) : $value; } diff --git a/src/Codec/Encoder.php b/src/Codec/Encoder.php index 0cd0d58cb..c8ee0917b 100644 --- a/src/Codec/Encoder.php +++ b/src/Codec/Encoder.php @@ -37,11 +37,10 @@ public function canEncode(mixed $value): bool; * should throw an exception. * * @psalm-param NativeType $value - * @return mixed * @psalm-return BSONType * @throws UnsupportedValueException if the encoder does not support the value */ - public function encode(mixed $value); + public function encode(mixed $value): mixed; /** * Encodes a given value if supported, otherwise returns the value as-is. @@ -49,8 +48,7 @@ public function encode(mixed $value); * The EncodeIfSupported trait provides a default implementation of this * method. * - * @return mixed * @psalm-return ($value is NativeType ? BSONType : $value) */ - public function encodeIfSupported(mixed $value); + public function encodeIfSupported(mixed $value): mixed; } diff --git a/src/Collection.php b/src/Collection.php index ab82cca5d..2c659f5db 100644 --- a/src/Collection.php +++ b/src/Collection.php @@ -38,6 +38,7 @@ use MongoDB\Model\BSONArray; use MongoDB\Model\BSONDocument; use MongoDB\Model\IndexInfo; +use MongoDB\Model\IndexInfoIterator; use MongoDB\Operation\Aggregate; use MongoDB\Operation\BulkWrite; use MongoDB\Operation\Count; @@ -181,9 +182,8 @@ public function __construct(private Manager $manager, private string $databaseNa * 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() + public function __debugInfo(): array { return [ 'builderEncoder' => $this->builderEncoder, @@ -202,9 +202,8 @@ public function __debugInfo() * Return the collection namespace (e.g. "db.collection"). * * @see https://mongodb.com/docs/manual/core/databases-and-collections/ - * @return string */ - public function __toString() + public function __toString(): string { return $this->databaseName . '.' . $this->collectionName; } @@ -215,13 +214,12 @@ public function __toString() * @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 = []) + public function aggregate(array $pipeline, array $options = []): CursorInterface { if (is_builder_pipeline($pipeline)) { $pipeline = new Pipeline(...$pipeline); @@ -261,12 +259,11 @@ public function aggregate(array $pipeline, array $options = []) * @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 = []) + public function bulkWrite(array $operations, array $options = []): BulkWriteResult { $options = $this->inheritBuilderEncoder($options); $options = $this->inheritWriteOptions($options); @@ -283,7 +280,6 @@ public function bulkWrite(array $operations, array $options = []) * @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 @@ -291,7 +287,7 @@ public function bulkWrite(array $operations, array $options = []) * * @deprecated 1.4 */ - public function count(array|object $filter = [], array $options = []) + public function count(array|object $filter = [], array $options = []): int { $filter = $this->builderEncoder->encodeIfSupported($filter); $options = $this->inheritReadOptions($options); @@ -307,13 +303,12 @@ public function count(array|object $filter = [], array $options = []) * @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 = []) + public function countDocuments(array|object $filter = [], array $options = []): int { $filter = $this->builderEncoder->encodeIfSupported($filter); $options = $this->inheritReadOptions($options); @@ -336,7 +331,7 @@ public function countDocuments(array|object $filter = [], array $options = []) * @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 = []) + public function createIndex(array|object $key, array $options = []): string { $operationOptionKeys = ['comment' => 1, 'commitQuorum' => 1, 'maxTimeMS' => 1, 'session' => 1, 'writeConcern' => 1]; $indexOptions = array_diff_key($options, $operationOptionKeys); @@ -372,7 +367,7 @@ public function createIndex(array|object $key, array $options = []) * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function createIndexes(array $indexes, array $options = []) + public function createIndexes(array $indexes, array $options = []): array { $options = $this->inheritWriteOptions($options); @@ -446,12 +441,11 @@ public function createSearchIndexes(array $indexes, array $options = []): array * @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 = []) + public function deleteMany(array|object $filter, array $options = []): DeleteResult { $filter = $this->builderEncoder->encodeIfSupported($filter); $options = $this->inheritWriteOptions($options); @@ -468,12 +462,11 @@ public function deleteMany(array|object $filter, array $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 = []) + public function deleteOne(array|object $filter, array $options = []): DeleteResult { $filter = $this->builderEncoder->encodeIfSupported($filter); $options = $this->inheritWriteOptions($options); @@ -490,13 +483,12 @@ public function deleteOne(array|object $filter, array $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 = []) + public function distinct(string $fieldName, array|object $filter = [], array $options = []): array { $filter = $this->builderEncoder->encodeIfSupported($filter); $options = $this->inheritReadOptions($options); @@ -517,7 +509,7 @@ public function distinct(string $fieldName, array|object $filter = [], array $op * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function drop(array $options = []) + public function drop(array $options = []): array|object { $options = $this->inheritWriteOptions($options); $options = $this->inheritTypeMap($options); @@ -547,7 +539,7 @@ public function drop(array $options = []) * @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 = []) + public function dropIndex(string|IndexInfo $indexName, array $options = []): array|object { $indexName = (string) $indexName; @@ -573,7 +565,7 @@ public function dropIndex(string|IndexInfo $indexName, array $options = []) * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function dropIndexes(array $options = []) + public function dropIndexes(array $options = []): array|object { $options = $this->inheritWriteOptions($options); $options = $this->inheritTypeMap($options); @@ -606,13 +598,12 @@ public function dropSearchIndex(string $name, array $options = []): void * * @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 = []) + public function estimatedDocumentCount(array $options = []): int { $options = $this->inheritReadOptions($options); @@ -628,12 +619,11 @@ public function estimatedDocumentCount(array $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 = []) + public function explain(Explainable $explainable, array $options = []): array|object { $options = $this->inheritReadPreference($options); $options = $this->inheritTypeMap($options); @@ -650,12 +640,11 @@ public function explain(Explainable $explainable, array $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 = []) + public function find(array|object $filter = [], array $options = []): CursorInterface { $filter = $this->builderEncoder->encodeIfSupported($filter); $options = $this->inheritReadOptions($options); @@ -673,12 +662,11 @@ public function find(array|object $filter = [], array $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 = []) + public function findOne(array|object $filter = [], array $options = []): array|object|null { $filter = $this->builderEncoder->encodeIfSupported($filter); $options = $this->inheritReadOptions($options); @@ -698,13 +686,12 @@ public function findOne(array|object $filter = [], array $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 = []) + public function findOneAndDelete(array|object $filter, array $options = []): array|object|null { $filter = $this->builderEncoder->encodeIfSupported($filter); $options = $this->inheritWriteOptions($options); @@ -729,13 +716,12 @@ public function findOneAndDelete(array|object $filter, array $options = []) * @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 = []) + public function findOneAndReplace(array|object $filter, array|object $replacement, array $options = []): array|object|null { $filter = $this->builderEncoder->encodeIfSupported($filter); $options = $this->inheritWriteOptions($options); @@ -760,13 +746,12 @@ public function findOneAndReplace(array|object $filter, array|object $replacemen * @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 = []) + public function findOneAndUpdate(array|object $filter, array|object $update, array $options = []): array|object|null { $filter = $this->builderEncoder->encodeIfSupported($filter); $options = $this->inheritWriteOptions($options); @@ -779,30 +764,24 @@ public function findOneAndUpdate(array|object $filter, array|object $update, arr /** * Return the collection name. - * - * @return string */ - public function getCollectionName() + public function getCollectionName(): string { return $this->collectionName; } /** * Return the database name. - * - * @return string */ - public function getDatabaseName() + public function getDatabaseName(): string { return $this->databaseName; } /** * Return the Manager. - * - * @return Manager */ - public function getManager() + public function getManager(): Manager { return $this->manager; } @@ -811,9 +790,8 @@ public function getManager() * Return the collection namespace. * * @see https://mongodb.com/docs/manual/reference/glossary/#term-namespace - * @return string */ - public function getNamespace() + public function getNamespace(): string { return $this->databaseName . '.' . $this->collectionName; } @@ -822,29 +800,24 @@ public function getNamespace() * Return the read concern for this collection. * * @see https://php.net/manual/en/mongodb-driver-readconcern.isdefault.php - * @return ReadConcern */ - public function getReadConcern() + public function getReadConcern(): ReadConcern { return $this->readConcern; } /** * Return the read preference for this collection. - * - * @return ReadPreference */ - public function getReadPreference() + public function getReadPreference(): ReadPreference { return $this->readPreference; } /** * Return the type map for this collection. - * - * @return array */ - public function getTypeMap() + public function getTypeMap(): array { return $this->typeMap; } @@ -853,9 +826,8 @@ public function getTypeMap() * Return the write concern for this collection. * * @see https://php.net/manual/en/mongodb-driver-writeconcern.isdefault.php - * @return WriteConcern */ - public function getWriteConcern() + public function getWriteConcern(): WriteConcern { return $this->writeConcern; } @@ -867,11 +839,10 @@ public function getWriteConcern() * @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 = []) + public function insertMany(array $documents, array $options = []): InsertManyResult { $options = $this->inheritWriteOptions($options); $options = $this->inheritCodec($options); @@ -888,11 +859,10 @@ public function insertMany(array $documents, array $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 = []) + public function insertOne(array|object $document, array $options = []): InsertOneResult { $options = $this->inheritWriteOptions($options); $options = $this->inheritCodec($options); @@ -910,7 +880,7 @@ public function insertOne(array|object $document, array $options = []) * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function listIndexes(array $options = []) + public function listIndexes(array $options = []): IndexInfoIterator { $operation = new ListIndexes($this->databaseName, $this->collectionName, $options); @@ -944,13 +914,12 @@ public function listSearchIndexes(array $options = []): Iterator * @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 = []) + public function mapReduce(JavascriptInterface $map, JavascriptInterface $reduce, string|array|object $out, array $options = []): MapReduceResult { $hasOutputCollection = ! is_mapreduce_output_inline($out); @@ -988,7 +957,7 @@ public function mapReduce(JavascriptInterface $map, JavascriptInterface $reduce, * @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 = []) + public function rename(string $toCollectionName, ?string $toDatabaseName = null, array $options = []): array|object { if (! isset($toDatabaseName)) { $toDatabaseName = $this->databaseName; @@ -1010,12 +979,11 @@ public function rename(string $toCollectionName, ?string $toDatabaseName = null, * @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 = []) + public function replaceOne(array|object $filter, array|object $replacement, array $options = []): UpdateResult { $filter = $this->builderEncoder->encodeIfSupported($filter); $options = $this->inheritWriteOptions($options); @@ -1034,12 +1002,11 @@ public function replaceOne(array|object $filter, array|object $replacement, arra * @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 = []) + public function updateMany(array|object $filter, array|object $update, array $options = []): UpdateResult { $filter = $this->builderEncoder->encodeIfSupported($filter); $update = $this->builderEncoder->encodeIfSupported($update); @@ -1058,12 +1025,11 @@ public function updateMany(array|object $filter, array|object $update, array $op * @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 = []) + public function updateOne(array|object $filter, array|object $update, array $options = []): UpdateResult { $filter = $this->builderEncoder->encodeIfSupported($filter); $update = $this->builderEncoder->encodeIfSupported($update); @@ -1099,10 +1065,9 @@ public function updateSearchIndex(string $name, array|object $definition, array * @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 = []) + public function watch(array $pipeline = [], array $options = []): ChangeStream { if (is_builder_pipeline($pipeline)) { $pipeline = new Pipeline(...$pipeline); @@ -1123,10 +1088,9 @@ public function watch(array $pipeline = [], array $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 = []) + public function withOptions(array $options = []): Collection { $options += [ 'builderEncoder' => $this->builderEncoder, diff --git a/src/Database.php b/src/Database.php index 4d15637a4..e8e256c49 100644 --- a/src/Database.php +++ b/src/Database.php @@ -24,7 +24,7 @@ use MongoDB\Builder\Pipeline; use MongoDB\Codec\Encoder; use MongoDB\Driver\ClientEncryption; -use MongoDB\Driver\Cursor; +use MongoDB\Driver\CursorInterface; use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException; use MongoDB\Driver\Manager; use MongoDB\Driver\ReadConcern; @@ -38,6 +38,7 @@ use MongoDB\Model\BSONArray; use MongoDB\Model\BSONDocument; use MongoDB\Model\CollectionInfo; +use MongoDB\Model\CollectionInfoIterator; use MongoDB\Operation\Aggregate; use MongoDB\Operation\CreateCollection; use MongoDB\Operation\CreateEncryptedCollection; @@ -52,7 +53,6 @@ use MongoDB\Operation\Watch; use stdClass; use Throwable; -use Traversable; use function is_array; use function strlen; @@ -145,9 +145,8 @@ public function __construct(private Manager $manager, private string $databaseNa * 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() + public function __debugInfo(): array { return [ 'builderEncoder' => $this->builderEncoder, @@ -170,19 +169,16 @@ public function __debugInfo() * @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) + public function __get(string $collectionName): Collection { return $this->selectCollection($collectionName); } /** * Return the database name. - * - * @return string */ - public function __toString() + public function __toString(): string { return $this->databaseName; } @@ -195,13 +191,12 @@ public function __toString() * @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 = []) + public function aggregate(array $pipeline, array $options = []): CursorInterface { if (is_builder_pipeline($pipeline)) { $pipeline = new Pipeline(...$pipeline); @@ -251,11 +246,10 @@ public function aggregate(array $pipeline, array $options = []) * @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 = []) + public function command(array|object $command, array $options = []): CursorInterface { if (! isset($options['typeMap'])) { $options['typeMap'] = $this->typeMap; @@ -282,7 +276,7 @@ public function command(array|object $command, array $options = []) * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function createCollection(string $collectionName, array $options = []) + public function createCollection(string $collectionName, array $options = []): array|object { if (! isset($options['typeMap'])) { $options['typeMap'] = $this->typeMap; @@ -358,7 +352,7 @@ public function createEncryptedCollection(string $collectionName, ClientEncrypti * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function drop(array $options = []) + public function drop(array $options = []): array|object { if (! isset($options['typeMap'])) { $options['typeMap'] = $this->typeMap; @@ -386,7 +380,7 @@ public function drop(array $options = []) * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function dropCollection(string $collectionName, array $options = []) + public function dropCollection(string $collectionName, array $options = []): array|object { if (! isset($options['typeMap'])) { $options['typeMap'] = $this->typeMap; @@ -412,20 +406,16 @@ public function dropCollection(string $collectionName, array $options = []) /** * Returns the database name. - * - * @return string */ - public function getDatabaseName() + public function getDatabaseName(): string { return $this->databaseName; } /** * Return the Manager. - * - * @return Manager */ - public function getManager() + public function getManager(): Manager { return $this->manager; } @@ -434,29 +424,24 @@ public function getManager() * Return the read concern for this database. * * @see https://php.net/manual/en/mongodb-driver-readconcern.isdefault.php - * @return ReadConcern */ - public function getReadConcern() + public function getReadConcern(): ReadConcern { return $this->readConcern; } /** * Return the read preference for this database. - * - * @return ReadPreference */ - public function getReadPreference() + public function getReadPreference(): ReadPreference { return $this->readPreference; } /** * Return the type map for this database. - * - * @return array */ - public function getTypeMap() + public function getTypeMap(): array { return $this->typeMap; } @@ -465,9 +450,8 @@ public function getTypeMap() * Return the write concern for this database. * * @see https://php.net/manual/en/mongodb-driver-writeconcern.isdefault.php - * @return WriteConcern */ - public function getWriteConcern() + public function getWriteConcern(): WriteConcern { return $this->writeConcern; } @@ -495,7 +479,7 @@ public function listCollectionNames(array $options = []): Iterator * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function listCollections(array $options = []) + public function listCollections(array $options = []): CollectionInfoIterator { $operation = new ListCollections($this->databaseName, $options); $server = select_server($this->manager, $options); @@ -510,11 +494,10 @@ public function listCollections(array $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 = []) + public function modifyCollection(string $collectionName, array $collectionOptions, array $options = []): array|object { if (! isset($options['typeMap'])) { $options['typeMap'] = $this->typeMap; @@ -544,7 +527,7 @@ public function modifyCollection(string $collectionName, array $collectionOption * @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 = []) + public function renameCollection(string $fromCollectionName, string $toCollectionName, ?string $toDatabaseName = null, array $options = []): array|object { if (! isset($toDatabaseName)) { $toDatabaseName = $this->databaseName; @@ -571,10 +554,9 @@ public function renameCollection(string $fromCollectionName, string $toCollectio * @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 = []) + public function selectCollection(string $collectionName, array $options = []): Collection { $options += [ 'builderEncoder' => $this->builderEncoder, @@ -592,10 +574,9 @@ public function selectCollection(string $collectionName, array $options = []) * * @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 = []) + public function selectGridFSBucket(array $options = []): Bucket { $options += [ 'readConcern' => $this->readConcern, @@ -613,10 +594,9 @@ public function selectGridFSBucket(array $options = []) * @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 = []) + public function watch(array $pipeline = [], array $options = []): ChangeStream { if (is_builder_pipeline($pipeline)) { $pipeline = new Pipeline(...$pipeline); @@ -648,10 +628,9 @@ public function watch(array $pipeline = [], array $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 = []) + public function withOptions(array $options = []): Database { $options += [ 'readConcern' => $this->readConcern, diff --git a/src/DeleteResult.php b/src/DeleteResult.php index 56f3f072d..b58d3650d 100644 --- a/src/DeleteResult.php +++ b/src/DeleteResult.php @@ -38,10 +38,9 @@ public function __construct(private WriteResult $writeResult) * 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() + public function getDeletedCount(): ?int { if ($this->isAcknowledged) { return $this->writeResult->getDeletedCount(); @@ -55,10 +54,8 @@ public function getDeletedCount() * * If the delete was not acknowledged, other fields from the WriteResult * (e.g. deletedCount) will be undefined. - * - * @return boolean */ - public function isAcknowledged() + public function isAcknowledged(): bool { return $this->isAcknowledged; } diff --git a/src/Exception/BadMethodCallException.php b/src/Exception/BadMethodCallException.php index 4595bb9d1..e165b95ac 100644 --- a/src/Exception/BadMethodCallException.php +++ b/src/Exception/BadMethodCallException.php @@ -27,10 +27,9 @@ class BadMethodCallException extends BaseBadMethodCallException implements Excep * Thrown when a mutable method is invoked on an immutable object. * * @param string $class Class name - * @return self * @internal */ - public static function classIsImmutable(string $class) + public static function classIsImmutable(string $class): self { return new self(sprintf('%s is immutable', $class)); } @@ -39,10 +38,9 @@ public static function classIsImmutable(string $class) * Thrown when accessing a result field on an unacknowledged write result. * * @param string $method Method name - * @return self * @internal */ - public static function unacknowledgedWriteResultAccess(string $method) + public static function unacknowledgedWriteResultAccess(string $method): self { return new self(sprintf('%s should not be called for an unacknowledged write result', $method)); } diff --git a/src/Exception/InvalidArgumentException.php b/src/Exception/InvalidArgumentException.php index 8a1b81ec2..2a9bc30b9 100644 --- a/src/Exception/InvalidArgumentException.php +++ b/src/Exception/InvalidArgumentException.php @@ -53,10 +53,9 @@ public static function expectedDocumentType(string $name, mixed $value): self * @param string $name Name of the argument or option * @param mixed $value Actual value (used to derive the type) * @param string|list $expectedType Expected type as a string or an array containing one or more strings - * @return self * @internal */ - public static function invalidType(string $name, mixed $value, string|array $expectedType) + public static function invalidType(string $name, mixed $value, string|array $expectedType): self { if (is_array($expectedType)) { $expectedType = self::expectedTypesToString($expectedType); diff --git a/src/Exception/ResumeTokenException.php b/src/Exception/ResumeTokenException.php index a73249cf9..9117f700d 100644 --- a/src/Exception/ResumeTokenException.php +++ b/src/Exception/ResumeTokenException.php @@ -26,10 +26,9 @@ class ResumeTokenException extends RuntimeException * Thrown when a resume token has an invalid type. * * @param mixed $value Actual value (used to derive the type) - * @return self * @internal */ - public static function invalidType(mixed $value) + public static function invalidType(mixed $value): self { return new self(sprintf('Expected resume token to have type "array or object" but found "%s"', get_debug_type($value))); } @@ -37,10 +36,9 @@ public static function invalidType(mixed $value) /** * Thrown when a resume token is not found in a change document. * - * @return self * @internal */ - public static function notFound() + public static function notFound(): self { return new self('Resume token not found in change document'); } diff --git a/src/Exception/UnsupportedException.php b/src/Exception/UnsupportedException.php index 2ad501051..1a5273715 100644 --- a/src/Exception/UnsupportedException.php +++ b/src/Exception/UnsupportedException.php @@ -23,10 +23,9 @@ class UnsupportedException extends RuntimeException * Thrown when the commitQuorum option for createIndexes is not supported * by a server. * - * @return self * @internal */ - public static function commitQuorumNotSupported() + public static function commitQuorumNotSupported(): self { return new self('The "commitQuorum" option is not supported by the server executing this operation'); } @@ -34,10 +33,9 @@ public static function commitQuorumNotSupported() /** * Thrown when a command's hint option is not supported by a server. * - * @return self * @internal */ - public static function hintNotSupported() + public static function hintNotSupported(): self { return new self('Hint is not supported by the server executing this operation'); } @@ -45,10 +43,9 @@ public static function hintNotSupported() /** * Thrown when a readConcern is used with a read operation in a transaction. * - * @return self * @internal */ - public static function readConcernNotSupportedInTransaction() + public static function readConcernNotSupportedInTransaction(): self { return new self('The "readConcern" option cannot be specified within a transaction. Instead, specify it when starting the transaction.'); } @@ -56,10 +53,9 @@ public static function readConcernNotSupportedInTransaction() /** * Thrown when a writeConcern is used with a write operation in a transaction. * - * @return self * @internal */ - public static function writeConcernNotSupportedInTransaction() + public static function writeConcernNotSupportedInTransaction(): self { return new self('The "writeConcern" option cannot be specified within a transaction. Instead, specify it when starting the transaction.'); } diff --git a/src/Exception/UnsupportedValueException.php b/src/Exception/UnsupportedValueException.php index d744baa13..62e089e5e 100644 --- a/src/Exception/UnsupportedValueException.php +++ b/src/Exception/UnsupportedValueException.php @@ -24,8 +24,7 @@ class UnsupportedValueException extends InvalidArgumentException implements Exception { - /** @return mixed */ - public function getValue() + public function getValue(): mixed { return $this->value; } diff --git a/src/GridFS/Bucket.php b/src/GridFS/Bucket.php index 04324df09..e054450cf 100644 --- a/src/GridFS/Bucket.php +++ b/src/GridFS/Bucket.php @@ -17,7 +17,6 @@ namespace MongoDB\GridFS; -use Iterator; use MongoDB\BSON\Document; use MongoDB\Codec\DocumentCodec; use MongoDB\Collection; @@ -184,9 +183,8 @@ public function __construct(private Manager $manager, private string $databaseNa * 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() + public function __debugInfo(): array { return [ 'bucketName' => $this->bucketName, @@ -208,11 +206,10 @@ public function __debugInfo() * 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) + public function delete(mixed $id): void { $file = $this->collectionWrapper->findFileById($id); $this->collectionWrapper->deleteFileAndChunksById($id); @@ -227,13 +224,12 @@ public function delete(mixed $id) * * @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) + public function downloadToStream(mixed $id, $destination): void { if (! is_resource($destination) || get_resource_type($destination) != 'stream') { throw InvalidArgumentException::invalidType('$destination', $destination, 'resource'); @@ -267,13 +263,12 @@ public function downloadToStream(mixed $id, $destination) * @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 = []) + public function downloadToStreamByName(string $filename, $destination, array $options = []): void { if (! is_resource($destination) || get_resource_type($destination) != 'stream') { throw InvalidArgumentException::invalidType('$destination', $destination, 'resource'); @@ -289,10 +284,9 @@ public function downloadToStreamByName(string $filename, $destination, array $op * 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() + public function drop(): void { $this->collectionWrapper->dropCollections(); } @@ -304,12 +298,11 @@ public function drop() * @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 = []) + public function find(array|object $filter = [], array $options = []): CursorInterface { if ($this->codec && ! array_key_exists('codec', $options)) { $options['codec'] = $this->codec; @@ -325,12 +318,11 @@ public function find(array|object $filter = [], array $options = []) * @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 = []) + public function findOne(array|object $filter = [], array $options = []): array|object|null { if ($this->codec && ! array_key_exists('codec', $options)) { $options['codec'] = $this->codec; @@ -341,40 +333,32 @@ public function findOne(array|object $filter = [], array $options = []) /** * Return the bucket name. - * - * @return string */ - public function getBucketName() + public function getBucketName(): string { return $this->bucketName; } /** * Return the chunks collection. - * - * @return Collection */ - public function getChunksCollection() + public function getChunksCollection(): Collection { return $this->collectionWrapper->getChunksCollection(); } /** * Return the chunk size in bytes. - * - * @return integer */ - public function getChunkSizeBytes() + public function getChunkSizeBytes(): int { return $this->chunkSizeBytes; } /** * Return the database name. - * - * @return string */ - public function getDatabaseName() + public function getDatabaseName(): string { return $this->databaseName; } @@ -383,11 +367,10 @@ public function getDatabaseName() * 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) + public function getFileDocumentForStream($stream): array|object { $file = $this->getRawFileDocumentForStream($stream); @@ -403,12 +386,11 @@ public function getFileDocumentForStream($stream) * 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) + public function getFileIdForStream($stream): mixed { $file = $this->getRawFileDocumentForStream($stream); @@ -428,10 +410,8 @@ public function getFileIdForStream($stream) /** * Return the files collection. - * - * @return Collection */ - public function getFilesCollection() + public function getFilesCollection(): Collection { return $this->collectionWrapper->getFilesCollection(); } @@ -440,29 +420,24 @@ public function 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() + public function getReadConcern(): ReadConcern { return $this->readConcern; } /** * Return the read preference for this GridFS bucket. - * - * @return ReadPreference */ - public function getReadPreference() + public function getReadPreference(): ReadPreference { return $this->readPreference; } /** * Return the type map for this GridFS bucket. - * - * @return array */ - public function getTypeMap() + public function getTypeMap(): array { return $this->typeMap; } @@ -471,9 +446,8 @@ public function getTypeMap() * Return the write concern for this GridFS bucket. * * @see https://php.net/manual/en/mongodb-driver-writeconcern.isdefault.php - * @return WriteConcern */ - public function getWriteConcern() + public function getWriteConcern(): WriteConcern { return $this->writeConcern; } @@ -598,11 +572,10 @@ public function registerGlobalStreamWrapperAlias(string $alias): void * * @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) + public function rename(mixed $id, string $newFilename): void { $updateResult = $this->collectionWrapper->updateFilenameForId($id, $newFilename); @@ -645,7 +618,7 @@ public function rename(mixed $id, string $newFilename) * @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 = []) + public function uploadFromStream(string $filename, $source, array $options = []): mixed { if (! is_resource($source) || get_resource_type($source) != 'stream') { throw InvalidArgumentException::invalidType('$source', $source, 'resource'); diff --git a/src/GridFS/CollectionWrapper.php b/src/GridFS/CollectionWrapper.php index a28185cb0..30923ccde 100644 --- a/src/GridFS/CollectionWrapper.php +++ b/src/GridFS/CollectionWrapper.php @@ -18,7 +18,6 @@ namespace MongoDB\GridFS; use ArrayIterator; -use Iterator; use MongoDB\Collection; use MongoDB\Driver\CursorInterface; use MongoDB\Driver\Manager; @@ -117,9 +116,8 @@ public function dropCollections(): void * * @param mixed $id File ID * @param integer $fromChunk Starting chunk (inclusive) - * @return CursorInterface&Iterator */ - public function findChunksByFileId(mixed $id, int $fromChunk = 0) + public function findChunksByFileId(mixed $id, int $fromChunk = 0): CursorInterface { return $this->chunksCollection->find( [ @@ -194,9 +192,8 @@ public function findFileById(mixed $id): ?object * @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 = []) + public function findFiles(array|object $filter, array $options = []): CursorInterface { return $this->filesCollection->find($filter, $options); } @@ -206,9 +203,8 @@ public function findFiles(array|object $filter, array $options = []) * * @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 = []) + public function findOneFile(array|object $filter, array $options = []): array|object|null { return $this->filesCollection->findOne($filter, $options); } diff --git a/src/GridFS/Exception/CorruptFileException.php b/src/GridFS/Exception/CorruptFileException.php index 34f89a6c0..b9feef87d 100644 --- a/src/GridFS/Exception/CorruptFileException.php +++ b/src/GridFS/Exception/CorruptFileException.php @@ -37,10 +37,9 @@ public static function invalidChunkData(int $chunkIndex): self * Thrown when a chunk is not found for an expected index. * * @param integer $expectedIndex Expected index number - * @return self * @internal */ - public static function missingChunk(int $expectedIndex) + public static function missingChunk(int $expectedIndex): self { return new self(sprintf('Chunk not found for index "%d"', $expectedIndex)); } @@ -50,10 +49,9 @@ public static function missingChunk(int $expectedIndex) * * @param integer $index Actual index number (i.e. "n" field) * @param integer $expectedIndex Expected index number - * @return self * @internal */ - public static function unexpectedIndex(int $index, int $expectedIndex) + public static function unexpectedIndex(int $index, int $expectedIndex): self { return new self(sprintf('Expected chunk to have index "%d" but found "%d"', $expectedIndex, $index)); } @@ -63,10 +61,9 @@ public static function unexpectedIndex(int $index, int $expectedIndex) * * @param integer $size Actual size (i.e. "data" field length) * @param integer $expectedSize Expected size - * @return self * @internal */ - public static function unexpectedSize(int $size, int $expectedSize) + public static function unexpectedSize(int $size, int $expectedSize): self { return new self(sprintf('Expected chunk to have size "%d" but found "%d"', $expectedSize, $size)); } diff --git a/src/GridFS/Exception/FileNotFoundException.php b/src/GridFS/Exception/FileNotFoundException.php index 21b8871ca..4cf153c08 100644 --- a/src/GridFS/Exception/FileNotFoundException.php +++ b/src/GridFS/Exception/FileNotFoundException.php @@ -28,10 +28,9 @@ class FileNotFoundException extends RuntimeException * Thrown when a file cannot be found by its filename. * * @param string $filename Filename - * @return self * @internal */ - public static function byFilename(string $filename) + public static function byFilename(string $filename): self { return new self(sprintf('File with name "%s" not found', $filename)); } @@ -42,10 +41,9 @@ public static function byFilename(string $filename) * @param string $filename Filename * @param integer $revision Revision * @param string $namespace Namespace for the files collection - * @return self * @internal */ - public static function byFilenameAndRevision(string $filename, int $revision, string $namespace) + public static function byFilenameAndRevision(string $filename, int $revision, string $namespace): self { return new self(sprintf('File with name "%s" and revision "%d" not found in "%s"', $filename, $revision, $namespace)); } @@ -55,10 +53,9 @@ public static function byFilenameAndRevision(string $filename, int $revision, st * * @param mixed $id File ID * @param string $namespace Namespace for the files collection - * @return self * @internal */ - public static function byId(mixed $id, string $namespace) + public static function byId(mixed $id, string $namespace): self { $json = Document::fromPHP(['_id' => $id])->toRelaxedExtendedJSON(); diff --git a/src/GridFS/ReadableStream.php b/src/GridFS/ReadableStream.php index c8441d18c..4e9b1ec72 100644 --- a/src/GridFS/ReadableStream.php +++ b/src/GridFS/ReadableStream.php @@ -17,7 +17,6 @@ namespace MongoDB\GridFS; -use Iterator; use MongoDB\BSON\Binary; use MongoDB\Driver\CursorInterface; use MongoDB\Exception\InvalidArgumentException; @@ -48,8 +47,7 @@ final class ReadableStream private int $chunkOffset = 0; - /** @var (CursorInterface&Iterator)|null */ - private ?Iterator $chunksIterator = null; + private ?CursorInterface $chunksIterator = null; private int $expectedLastChunkSize = 0; diff --git a/src/GridFS/StreamWrapper.php b/src/GridFS/StreamWrapper.php index 302a63385..e4f57fa85 100644 --- a/src/GridFS/StreamWrapper.php +++ b/src/GridFS/StreamWrapper.php @@ -315,8 +315,7 @@ public function unlink(string $path): bool return true; } - /** @return false|array */ - public function url_stat(string $path, int $flags) + public function url_stat(string $path, int $flags): false|array { assert($this->stream === null); diff --git a/src/InsertManyResult.php b/src/InsertManyResult.php index 6ad2a9595..3d2176e58 100644 --- a/src/InsertManyResult.php +++ b/src/InsertManyResult.php @@ -38,10 +38,9 @@ public function __construct(private WriteResult $writeResult, private array $ins * 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() + public function getInsertedCount(): ?int { if ($this->isAcknowledged) { return $this->writeResult->getInsertedCount(); @@ -58,10 +57,8 @@ public function getInsertedCount() * 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() + public function getInsertedIds(): array { return $this->insertedIds; } @@ -71,10 +68,8 @@ public function getInsertedIds() * * If the insert was not acknowledged, other fields from the WriteResult * (e.g. insertedCount) will be undefined. - * - * @return boolean */ - public function isAcknowledged() + public function isAcknowledged(): bool { return $this->writeResult->isAcknowledged(); } diff --git a/src/InsertOneResult.php b/src/InsertOneResult.php index 9c72775c8..8e3d4b3ab 100644 --- a/src/InsertOneResult.php +++ b/src/InsertOneResult.php @@ -38,10 +38,9 @@ public function __construct(private WriteResult $writeResult, private mixed $ins * 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() + public function getInsertedCount(): ?int { if ($this->isAcknowledged) { return $this->writeResult->getInsertedCount(); @@ -56,10 +55,8 @@ public function getInsertedCount() * 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() + public function getInsertedId(): mixed { return $this->insertedId; } @@ -73,10 +70,8 @@ public function getInsertedId() * 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() + public function isAcknowledged(): bool { return $this->writeResult->isAcknowledged(); } diff --git a/src/MapReduceResult.php b/src/MapReduceResult.php index 00a75116a..dbe0e1dda 100644 --- a/src/MapReduceResult.php +++ b/src/MapReduceResult.php @@ -18,7 +18,6 @@ namespace MongoDB; use IteratorAggregate; -use ReturnTypeWillChange; use stdClass; use Traversable; @@ -52,20 +51,16 @@ class MapReduceResult implements IteratorAggregate /** * Returns various count statistics from the mapReduce command. - * - * @return array */ - public function getCounts() + public function getCounts(): array { return $this->counts; } /** * Return the command execution time in milliseconds. - * - * @return integer */ - public function getExecutionTimeMS() + public function getExecutionTimeMS(): int { return $this->executionTimeMS; } @@ -76,8 +71,7 @@ public function getExecutionTimeMS() * @see https://php.net/iteratoraggregate.getiterator * @return Traversable */ - #[ReturnTypeWillChange] - public function getIterator() + public function getIterator(): Traversable { return call_user_func($this->getIterator); } @@ -87,10 +81,8 @@ public function getIterator() * * 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() + public function getTiming(): array { return $this->timing; } diff --git a/src/Model/BSONArray.php b/src/Model/BSONArray.php index f055f4cb7..040350ce4 100644 --- a/src/Model/BSONArray.php +++ b/src/Model/BSONArray.php @@ -21,7 +21,6 @@ use JsonSerializable; use MongoDB\BSON\Serializable; use MongoDB\BSON\Unserializable; -use ReturnTypeWillChange; use function array_values; use function MongoDB\recursive_copy; @@ -51,9 +50,8 @@ public function __clone() * * @see https://php.net/oop5.magic#object.set-state * @see https://php.net/var-export - * @return self */ - public static function __set_state(array $properties) + public static function __set_state(array $properties): self { $array = new self(); $array->exchangeArray($properties); @@ -68,10 +66,8 @@ public static function __set_state(array $properties) * as a BSON array. * * @see https://php.net/mongodb-bson-serializable.bsonserialize - * @return array */ - #[ReturnTypeWillChange] - public function bsonSerialize() + public function bsonSerialize(): array { return array_values($this->getArrayCopy()); } @@ -82,8 +78,7 @@ public function bsonSerialize() * @see https://php.net/mongodb-bson-unserializable.bsonunserialize * @param array $data Array data */ - #[ReturnTypeWillChange] - public function bsonUnserialize(array $data) + public function bsonUnserialize(array $data): void { parent::__construct($data); } @@ -95,10 +90,8 @@ public function bsonUnserialize(array $data) * as a JSON array. * * @see https://php.net/jsonserializable.jsonserialize - * @return array */ - #[ReturnTypeWillChange] - public function jsonSerialize() + public function jsonSerialize(): array { return array_values($this->getArrayCopy()); } diff --git a/src/Model/BSONDocument.php b/src/Model/BSONDocument.php index b9a9c0d80..5df92c0be 100644 --- a/src/Model/BSONDocument.php +++ b/src/Model/BSONDocument.php @@ -22,7 +22,6 @@ use JsonSerializable; use MongoDB\BSON\Serializable; use MongoDB\BSON\Unserializable; -use ReturnTypeWillChange; use stdClass; use function MongoDB\recursive_copy; @@ -65,9 +64,8 @@ public function __construct(array $input = [], int $flags = ArrayObject::ARRAY_A * * @see https://php.net/oop5.magic#object.set-state * @see https://php.net/var-export - * @return self */ - public static function __set_state(array $properties) + public static function __set_state(array $properties): self { $document = new self(); $document->exchangeArray($properties); @@ -79,10 +77,8 @@ public static function __set_state(array $properties) * Serialize the document to BSON. * * @see https://php.net/mongodb-bson-serializable.bsonserialize - * @return stdClass */ - #[ReturnTypeWillChange] - public function bsonSerialize() + public function bsonSerialize(): stdClass { return (object) $this->getArrayCopy(); } @@ -93,8 +89,7 @@ public function bsonSerialize() * @see https://php.net/mongodb-bson-unserializable.bsonunserialize * @param array $data Array data */ - #[ReturnTypeWillChange] - public function bsonUnserialize(array $data) + public function bsonUnserialize(array $data): void { parent::__construct($data, ArrayObject::ARRAY_AS_PROPS); } @@ -103,10 +98,8 @@ public function bsonUnserialize(array $data) * Serialize the array to JSON. * * @see https://php.net/jsonserializable.jsonserialize - * @return object */ - #[ReturnTypeWillChange] - public function jsonSerialize() + public function jsonSerialize(): stdClass { return (object) $this->getArrayCopy(); } diff --git a/src/Model/BSONIterator.php b/src/Model/BSONIterator.php index 2ca257c7f..e90901173 100644 --- a/src/Model/BSONIterator.php +++ b/src/Model/BSONIterator.php @@ -21,7 +21,6 @@ use MongoDB\BSON\Document; use MongoDB\Exception\InvalidArgumentException; use MongoDB\Exception\UnexpectedValueException; -use ReturnTypeWillChange; use function assert; use function is_array; @@ -50,44 +49,28 @@ class BSONIterator implements Iterator private int $position = 0; - /** - * @see https://php.net/iterator.current - * @return mixed - */ - #[ReturnTypeWillChange] - public function current() + /** @see https://php.net/iterator.current */ + public function current(): mixed { return $this->current; } - /** - * @see https://php.net/iterator.key - * @return int - */ - #[ReturnTypeWillChange] - public function key() + /** @see https://php.net/iterator.key */ + public function key(): int { return $this->key; } - /** - * @see https://php.net/iterator.next - * @return void - */ - #[ReturnTypeWillChange] - public function next() + /** @see https://php.net/iterator.next */ + public function next(): void { $this->key++; $this->current = null; $this->advance(); } - /** - * @see https://php.net/iterator.rewind - * @return void - */ - #[ReturnTypeWillChange] - public function rewind() + /** @see https://php.net/iterator.rewind */ + public function rewind(): void { $this->key = 0; $this->position = 0; @@ -96,7 +79,6 @@ public function rewind() } /** @see https://php.net/iterator.valid */ - #[ReturnTypeWillChange] public function valid(): bool { return $this->current !== null; diff --git a/src/Model/CachingIterator.php b/src/Model/CachingIterator.php index 2f4fcb29f..64c61708f 100644 --- a/src/Model/CachingIterator.php +++ b/src/Model/CachingIterator.php @@ -20,7 +20,6 @@ use Countable; use Iterator; use IteratorIterator; -use ReturnTypeWillChange; use Traversable; use function count; @@ -79,12 +78,8 @@ public function count(): int return count($this->items); } - /** - * @see https://php.net/iterator.current - * @return mixed - */ - #[ReturnTypeWillChange] - public function current() + /** @see https://php.net/iterator.current */ + public function current(): mixed { $currentItem = current($this->items); @@ -93,11 +88,9 @@ public function current() /** * @see https://php.net/iterator.key - * @return mixed * @psalm-return TKey|null */ - #[ReturnTypeWillChange] - public function key() + public function key(): mixed { $currentItem = current($this->items); diff --git a/src/Model/CallbackIterator.php b/src/Model/CallbackIterator.php index cf7e60fa5..161224925 100644 --- a/src/Model/CallbackIterator.php +++ b/src/Model/CallbackIterator.php @@ -19,7 +19,6 @@ use Iterator; use IteratorIterator; -use ReturnTypeWillChange; use Traversable; use function call_user_func; @@ -56,8 +55,7 @@ public function __construct(Traversable $traversable, callable $callback) * @see https://php.net/iterator.current * @return TCallbackValue */ - #[ReturnTypeWillChange] - public function current() + public function current(): mixed { return call_user_func($this->callback, $this->iterator->current(), $this->iterator->key()); } @@ -66,8 +64,7 @@ public function current() * @see https://php.net/iterator.key * @return TKey */ - #[ReturnTypeWillChange] - public function key() + public function key(): mixed { return $this->iterator->key(); } diff --git a/src/Model/ChangeStreamIterator.php b/src/Model/ChangeStreamIterator.php index 721c59734..4a4f36b51 100644 --- a/src/Model/ChangeStreamIterator.php +++ b/src/Model/ChangeStreamIterator.php @@ -17,7 +17,6 @@ namespace MongoDB\Model; -use Iterator; use IteratorIterator; use MongoDB\BSON\Document; use MongoDB\BSON\Serializable; @@ -30,7 +29,6 @@ use MongoDB\Exception\InvalidArgumentException; use MongoDB\Exception\ResumeTokenException; use MongoDB\Exception\UnexpectedValueException; -use ReturnTypeWillChange; use function assert; use function count; @@ -49,7 +47,7 @@ * * @internal * @template TValue of array|object - * @template-extends IteratorIterator&Iterator> + * @template-extends IteratorIterator> */ final class ChangeStreamIterator extends IteratorIterator implements CommandSubscriber { @@ -67,28 +65,25 @@ final class ChangeStreamIterator extends IteratorIterator implements CommandSubs /** * @see https://php.net/iteratoriterator.current - * @return array|object|null * @psalm-return TValue|null */ - #[ReturnTypeWillChange] - public function current() + public function current(): array|object|null { 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. + * This method is necessary as psalm does not properly set the return type + * of IteratorIterator::getInnerIterator to the templated iterator * - * @return CursorInterface&Iterator + * @see https://github.com/vimeo/psalm/pull/11100. + * + * @return CursorInterface */ - final public function getInnerIterator(): Iterator + public function getInnerIterator(): CursorInterface { $cursor = parent::getInnerIterator(); assert($cursor instanceof CursorInterface); - assert($cursor instanceof Iterator); return $cursor; } @@ -99,10 +94,8 @@ final public function getInnerIterator(): Iterator * 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() + public function getResumeToken(): array|object|null { return $this->resumeToken; } @@ -115,12 +108,8 @@ public function getServer(): Server return $this->server; } - /** - * @see https://php.net/iteratoriterator.key - * @return int|null - */ - #[ReturnTypeWillChange] - public function key() + /** @see https://php.net/iteratoriterator.key */ + public function key(): ?int { return $this->valid() ? parent::key() : null; } @@ -173,18 +162,10 @@ public function valid(): bool /** * @internal - * @psalm-param CursorInterface&Iterator $cursor + * @psalm-param CursorInterface $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); } @@ -238,11 +219,10 @@ final public function commandSucceeded(CommandSucceededEvent $event): void * 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) + private function extractResumeToken(array|object $document): array|object { if (! is_document($document)) { throw InvalidArgumentException::expectedDocumentType('$document', $document); diff --git a/src/Model/CodecCursor.php b/src/Model/CodecCursor.php index 642f3c3c1..d7a3776b2 100644 --- a/src/Model/CodecCursor.php +++ b/src/Model/CodecCursor.php @@ -17,30 +17,24 @@ namespace MongoDB\Model; -use Iterator; use MongoDB\BSON\Document; use MongoDB\BSON\Int64; use MongoDB\Codec\DocumentCodec; -use MongoDB\Driver\Cursor; -use MongoDB\Driver\CursorId; use MongoDB\Driver\CursorInterface; use MongoDB\Driver\Server; -use ReturnTypeWillChange; use function assert; use function iterator_to_array; use function sprintf; use function trigger_error; -use const E_USER_DEPRECATED; use const E_USER_WARNING; /** * @template TValue of object - * @template-implements CursorInterface - * @template-implements Iterator + * @template-implements CursorInterface */ -class CodecCursor implements CursorInterface, Iterator +class CodecCursor implements CursorInterface { private const TYPEMAP = ['root' => 'bson']; @@ -64,33 +58,16 @@ public function current(): ?object * @param DocumentCodec $codec * @return self */ - public static function fromCursor(Cursor $cursor, DocumentCodec $codec): self + public static function fromCursor(CursorInterface $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) + public function getId(): Int64 { - 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); + return $this->cursor->getId(); } public function getServer(): Server @@ -138,7 +115,7 @@ public function valid(): bool } /** @param DocumentCodec $codec */ - private function __construct(private Cursor $cursor, private DocumentCodec $codec) + private function __construct(private CursorInterface $cursor, private DocumentCodec $codec) { } } diff --git a/src/Model/CollectionInfo.php b/src/Model/CollectionInfo.php index 2850a4be4..717e19d84 100644 --- a/src/Model/CollectionInfo.php +++ b/src/Model/CollectionInfo.php @@ -19,7 +19,6 @@ use ArrayAccess; use MongoDB\Exception\BadMethodCallException; -use ReturnTypeWillChange; use function array_key_exists; @@ -45,9 +44,8 @@ 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() + public function __debugInfo(): array { return $this->info; } @@ -56,10 +54,8 @@ public function __debugInfo() * 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() + public function getCappedMax(): ?int { /* The MongoDB server might return this number as an integer or float */ return isset($this->info['options']['max']) ? (integer) $this->info['options']['max'] : null; @@ -69,10 +65,8 @@ public function getCappedMax() * 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() + public function getCappedSize(): ?int { /* The MongoDB server might return this number as an integer or float */ return isset($this->info['options']['size']) ? (integer) $this->info['options']['size'] : null; @@ -100,9 +94,8 @@ public function getInfo(): array * Return the collection name. * * @see https://mongodb.com/docs/manual/reference/command/listCollections/#output - * @return string */ - public function getName() + public function getName(): string { return (string) $this->info['name']; } @@ -111,9 +104,8 @@ public function getName() * Return the collection options. * * @see https://mongodb.com/docs/manual/reference/command/listCollections/#output - * @return array */ - public function getOptions() + public function getOptions(): array { return (array) ($this->info['options'] ?? []); } @@ -132,10 +124,8 @@ public function getType(): string * Return whether the collection is a capped collection. * * @deprecated 1.0 Deprecated in favor of using getOptions - * - * @return boolean */ - public function isCapped() + public function isCapped(): bool { return ! empty($this->info['options']['capped']); } @@ -144,11 +134,9 @@ public function isCapped() * 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) + public function offsetExists(mixed $offset): bool { return array_key_exists($offset, $this->info); } @@ -157,11 +145,9 @@ public function offsetExists(mixed $offset) * 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) + public function offsetGet(mixed $offset): mixed { return $this->info[$offset]; } @@ -171,10 +157,8 @@ public function offsetGet(mixed $offset) * * @see https://php.net/arrayaccess.offsetset * @throws BadMethodCallException - * @return void */ - #[ReturnTypeWillChange] - public function offsetSet(mixed $offset, mixed $value) + public function offsetSet(mixed $offset, mixed $value): void { throw BadMethodCallException::classIsImmutable(self::class); } @@ -184,10 +168,8 @@ public function offsetSet(mixed $offset, mixed $value) * * @see https://php.net/arrayaccess.offsetunset * @throws BadMethodCallException - * @return void */ - #[ReturnTypeWillChange] - public function offsetUnset(mixed $offset) + public function offsetUnset(mixed $offset): void { throw BadMethodCallException::classIsImmutable(self::class); } diff --git a/src/Model/CollectionInfoIterator.php b/src/Model/CollectionInfoIterator.php index e7ebf4984..6ce22c551 100644 --- a/src/Model/CollectionInfoIterator.php +++ b/src/Model/CollectionInfoIterator.php @@ -18,7 +18,6 @@ namespace MongoDB\Model; use Iterator; -use ReturnTypeWillChange; /** * CollectionInfoIterator interface. @@ -33,9 +32,6 @@ interface CollectionInfoIterator extends Iterator { /** * Return the current element as a CollectionInfo instance. - * - * @return CollectionInfo */ - #[ReturnTypeWillChange] - public function current(); + public function current(): CollectionInfo; } diff --git a/src/Model/DatabaseInfo.php b/src/Model/DatabaseInfo.php index 2803532f8..2a9d01204 100644 --- a/src/Model/DatabaseInfo.php +++ b/src/Model/DatabaseInfo.php @@ -19,7 +19,6 @@ use ArrayAccess; use MongoDB\Exception\BadMethodCallException; -use ReturnTypeWillChange; use function array_key_exists; @@ -44,29 +43,24 @@ 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() + public function __debugInfo(): array { return $this->info; } /** * Return the database name. - * - * @return string */ - public function getName() + public function getName(): string { return (string) $this->info['name']; } /** * Return the databases size on disk (in bytes). - * - * @return integer */ - public function getSizeOnDisk() + public function getSizeOnDisk(): int { /* The MongoDB server might return this number as an integer or float */ return (integer) $this->info['sizeOnDisk']; @@ -74,10 +68,8 @@ public function getSizeOnDisk() /** * Return whether the database is empty. - * - * @return boolean */ - public function isEmpty() + public function isEmpty(): bool { return (boolean) $this->info['empty']; } @@ -86,11 +78,9 @@ public function isEmpty() * 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) + public function offsetExists(mixed $offset): bool { return array_key_exists($offset, $this->info); } @@ -99,11 +89,9 @@ public function offsetExists(mixed $offset) * 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) + public function offsetGet(mixed $offset): mixed { return $this->info[$offset]; } @@ -113,10 +101,8 @@ public function offsetGet(mixed $offset) * * @see https://php.net/arrayaccess.offsetset * @throws BadMethodCallException - * @return void */ - #[ReturnTypeWillChange] - public function offsetSet(mixed $offset, mixed $value) + public function offsetSet(mixed $offset, mixed $value): void { throw BadMethodCallException::classIsImmutable(self::class); } @@ -126,10 +112,8 @@ public function offsetSet(mixed $offset, mixed $value) * * @see https://php.net/arrayaccess.offsetunset * @throws BadMethodCallException - * @return void */ - #[ReturnTypeWillChange] - public function offsetUnset(mixed $offset) + public function offsetUnset(mixed $offset): void { throw BadMethodCallException::classIsImmutable(self::class); } diff --git a/src/Model/DatabaseInfoIterator.php b/src/Model/DatabaseInfoIterator.php index 72199bd32..fc00fb79b 100644 --- a/src/Model/DatabaseInfoIterator.php +++ b/src/Model/DatabaseInfoIterator.php @@ -18,7 +18,6 @@ namespace MongoDB\Model; use Iterator; -use ReturnTypeWillChange; /** * DatabaseInfoIterator interface. @@ -33,9 +32,6 @@ interface DatabaseInfoIterator extends Iterator { /** * Return the current element as a DatabaseInfo instance. - * - * @return DatabaseInfo */ - #[ReturnTypeWillChange] - public function current(); + public function current(): DatabaseInfo; } diff --git a/src/Model/IndexInfo.php b/src/Model/IndexInfo.php index 53b7b63f0..360b27327 100644 --- a/src/Model/IndexInfo.php +++ b/src/Model/IndexInfo.php @@ -19,7 +19,6 @@ use ArrayAccess; use MongoDB\Exception\BadMethodCallException; -use ReturnTypeWillChange; use function array_key_exists; use function array_search; @@ -53,39 +52,32 @@ 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() + public function __debugInfo(): array { return $this->info; } /** * Return the index name to allow casting IndexInfo to string. - * - * @return string */ - public function __toString() + public function __toString(): string { return $this->getName(); } /** * Return the index key. - * - * @return array */ - public function getKey() + public function getKey(): array { return (array) $this->info['key']; } /** * Return the index name. - * - * @return string */ - public function getName() + public function getName(): string { return (string) $this->info['name']; } @@ -94,10 +86,8 @@ public function getName() * Return the index namespace (e.g. "db.collection"). * * @deprecated - * - * @return string */ - public function getNamespace() + public function getNamespace(): string { @trigger_error('MongoDB 4.4 drops support for the namespace in indexes, the method "IndexInfo::getNamespace()" will be removed in a future release', E_USER_DEPRECATED); @@ -106,20 +96,16 @@ public function getNamespace() /** * Return the index version. - * - * @return integer */ - public function getVersion() + public function getVersion(): int { return (integer) $this->info['v']; } /** * Return whether or not this index is of type 2dsphere. - * - * @return boolean */ - public function is2dSphere() + public function is2dSphere(): bool { return array_search('2dsphere', $this->getKey(), true) !== false; } @@ -127,10 +113,9 @@ public function is2dSphere() /** * 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() + public function isGeoHaystack(): bool { @trigger_error('MongoDB 5.0 removes support for "geoHaystack" indexes, the method "IndexInfo::isGeoHaystack()" will be removed in a future release', E_USER_DEPRECATED); @@ -141,19 +126,16 @@ public function isGeoHaystack() * Return whether this is a sparse index. * * @see https://mongodb.com/docs/manual/core/index-sparse/ - * @return boolean */ - public function isSparse() + public function isSparse(): bool { return ! empty($this->info['sparse']); } /** * Return whether or not this index is of type text. - * - * @return boolean */ - public function isText() + public function isText(): bool { return array_search('text', $this->getKey(), true) !== false; } @@ -162,9 +144,8 @@ public function isText() * Return whether this is a TTL index. * * @see https://mongodb.com/docs/manual/core/index-ttl/ - * @return boolean */ - public function isTtl() + public function isTtl(): bool { return array_key_exists('expireAfterSeconds', $this->info); } @@ -173,9 +154,8 @@ public function isTtl() * Return whether this is a unique index. * * @see https://mongodb.com/docs/manual/core/index-unique/ - * @return boolean */ - public function isUnique() + public function isUnique(): bool { return ! empty($this->info['unique']); } @@ -184,11 +164,9 @@ public function isUnique() * 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) + public function offsetExists(mixed $offset): bool { return array_key_exists($offset, $this->info); } @@ -202,11 +180,9 @@ public function offsetExists(mixed $offset) * * @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) + public function offsetGet(mixed $offset): mixed { return $this->info[$offset]; } @@ -216,10 +192,8 @@ public function offsetGet(mixed $offset) * * @see https://php.net/arrayaccess.offsetset * @throws BadMethodCallException - * @return void */ - #[ReturnTypeWillChange] - public function offsetSet(mixed $offset, mixed $value) + public function offsetSet(mixed $offset, mixed $value): void { throw BadMethodCallException::classIsImmutable(self::class); } @@ -229,10 +203,8 @@ public function offsetSet(mixed $offset, mixed $value) * * @see https://php.net/arrayaccess.offsetunset * @throws BadMethodCallException - * @return void */ - #[ReturnTypeWillChange] - public function offsetUnset(mixed $offset) + public function offsetUnset(mixed $offset): void { throw BadMethodCallException::classIsImmutable(self::class); } diff --git a/src/Model/IndexInfoIterator.php b/src/Model/IndexInfoIterator.php index b7929c20f..f52e8dbfa 100644 --- a/src/Model/IndexInfoIterator.php +++ b/src/Model/IndexInfoIterator.php @@ -18,7 +18,6 @@ namespace MongoDB\Model; use Iterator; -use ReturnTypeWillChange; /** * IndexInfoIterator interface. @@ -33,9 +32,6 @@ interface IndexInfoIterator extends Iterator { /** * Return the current element as a IndexInfo instance. - * - * @return IndexInfo */ - #[ReturnTypeWillChange] - public function current(); + public function current(): IndexInfo; } diff --git a/src/Operation/Aggregate.php b/src/Operation/Aggregate.php index 495d741a9..b7f109589 100644 --- a/src/Operation/Aggregate.php +++ b/src/Operation/Aggregate.php @@ -17,10 +17,8 @@ namespace MongoDB\Operation; -use Iterator; use MongoDB\Codec\DocumentCodec; use MongoDB\Driver\Command; -use MongoDB\Driver\Cursor; use MongoDB\Driver\CursorInterface; use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException; use MongoDB\Driver\ReadConcern; @@ -215,12 +213,11 @@ public function __construct(private string $databaseName, private ?string $colle * 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) + public function execute(Server $server): CursorInterface { $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); if ($inTransaction) { @@ -255,9 +252,8 @@ public function execute(Server $server) * Returns the command document for this operation. * * @see Explainable::getCommandDocument() - * @return array */ - public function getCommandDocument() + public function getCommandDocument(): array { $cmd = $this->createCommandDocument(); @@ -320,7 +316,7 @@ private function createCommandOptions(): array * @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 + private function executeCommand(Server $server, Command $command): CursorInterface { $options = []; diff --git a/src/Operation/BulkWrite.php b/src/Operation/BulkWrite.php index d9eb43376..178ff1847 100644 --- a/src/Operation/BulkWrite.php +++ b/src/Operation/BulkWrite.php @@ -186,11 +186,10 @@ public function __construct(private string $databaseName, private string $collec * 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) + public function execute(Server $server): BulkWriteResult { $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); if ($inTransaction && isset($this->options['writeConcern'])) { diff --git a/src/Operation/Count.php b/src/Operation/Count.php index 6a42a5c15..df91214bd 100644 --- a/src/Operation/Count.php +++ b/src/Operation/Count.php @@ -125,12 +125,11 @@ public function __construct(private string $databaseName, private string $collec * 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) + public function execute(Server $server): int { $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); if ($inTransaction && isset($this->options['readConcern'])) { @@ -152,9 +151,8 @@ public function execute(Server $server) * Returns the command document for this operation. * * @see Explainable::getCommandDocument() - * @return array */ - public function getCommandDocument() + public function getCommandDocument(): array { $cmd = $this->createCommandDocument(); diff --git a/src/Operation/CountDocuments.php b/src/Operation/CountDocuments.php index 449399a5a..4badaaf3b 100644 --- a/src/Operation/CountDocuments.php +++ b/src/Operation/CountDocuments.php @@ -104,12 +104,11 @@ public function __construct(private string $databaseName, private string $collec * 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) + public function execute(Server $server): int { $cursor = $this->aggregate->execute($server); diff --git a/src/Operation/CreateCollection.php b/src/Operation/CreateCollection.php index e5406315e..2182aec58 100644 --- a/src/Operation/CreateCollection.php +++ b/src/Operation/CreateCollection.php @@ -243,7 +243,7 @@ public function __construct(private string $databaseName, private string $collec * @return array|object Command result document * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): array|object { $cursor = $server->executeWriteCommand($this->databaseName, $this->createCommand(), $this->createOptions()); diff --git a/src/Operation/CreateEncryptedCollection.php b/src/Operation/CreateEncryptedCollection.php index 9c7d120d8..fec5f2d18 100644 --- a/src/Operation/CreateEncryptedCollection.php +++ b/src/Operation/CreateEncryptedCollection.php @@ -160,7 +160,7 @@ public function createDataKeys(ClientEncryption $clientEncryption, string $kmsPr * @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) + public function execute(Server $server): array|object { 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.'); diff --git a/src/Operation/CreateIndexes.php b/src/Operation/CreateIndexes.php index 637e99cbd..0b164c48c 100644 --- a/src/Operation/CreateIndexes.php +++ b/src/Operation/CreateIndexes.php @@ -121,7 +121,7 @@ public function __construct(private string $databaseName, private string $collec * @throws UnsupportedException if write concern is used and unsupported * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): array { $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); if ($inTransaction && isset($this->options['writeConcern'])) { diff --git a/src/Operation/DatabaseCommand.php b/src/Operation/DatabaseCommand.php index bf02a6430..97cb7a500 100644 --- a/src/Operation/DatabaseCommand.php +++ b/src/Operation/DatabaseCommand.php @@ -18,7 +18,7 @@ namespace MongoDB\Operation; use MongoDB\Driver\Command; -use MongoDB\Driver\Cursor; +use MongoDB\Driver\CursorInterface; use MongoDB\Driver\ReadPreference; use MongoDB\Driver\Server; use MongoDB\Driver\Session; @@ -82,9 +82,8 @@ public function __construct(private string $databaseName, array|object $command, * Execute the operation. * * @see Executable::execute() - * @return Cursor */ - public function execute(Server $server) + public function execute(Server $server): CursorInterface { $cursor = $server->executeCommand($this->databaseName, $this->command, $this->createOptions()); diff --git a/src/Operation/Delete.php b/src/Operation/Delete.php index 09e39a922..ae2a46306 100644 --- a/src/Operation/Delete.php +++ b/src/Operation/Delete.php @@ -121,11 +121,10 @@ public function __construct(private string $databaseName, private string $collec * 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) + public function execute(Server $server): DeleteResult { /* CRUD spec requires a client-side error when using "hint" with an * unacknowledged write concern on an unsupported server. */ @@ -153,9 +152,8 @@ public function execute(Server $server) * Returns the command document for this operation. * * @see Explainable::getCommandDocument() - * @return array */ - public function getCommandDocument() + public function getCommandDocument(): array { $cmd = ['delete' => $this->collectionName, 'deletes' => [['q' => $this->filter] + $this->createDeleteOptions()]]; diff --git a/src/Operation/DeleteMany.php b/src/Operation/DeleteMany.php index 2d85727a8..78090c464 100644 --- a/src/Operation/DeleteMany.php +++ b/src/Operation/DeleteMany.php @@ -75,11 +75,10 @@ public function __construct(string $databaseName, string $collectionName, array| * 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) + public function execute(Server $server): DeleteResult { return $this->delete->execute($server); } @@ -88,9 +87,8 @@ public function execute(Server $server) * Returns the command document for this operation. * * @see Explainable::getCommandDocument() - * @return array */ - public function getCommandDocument() + public function getCommandDocument(): array { return $this->delete->getCommandDocument(); } diff --git a/src/Operation/DeleteOne.php b/src/Operation/DeleteOne.php index c9460a916..157bb748a 100644 --- a/src/Operation/DeleteOne.php +++ b/src/Operation/DeleteOne.php @@ -75,11 +75,10 @@ public function __construct(string $databaseName, string $collectionName, array| * 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) + public function execute(Server $server): DeleteResult { return $this->delete->execute($server); } @@ -88,9 +87,8 @@ public function execute(Server $server) * Returns the command document for this operation. * * @see Explainable::getCommandDocument() - * @return array */ - public function getCommandDocument() + public function getCommandDocument(): array { return $this->delete->getCommandDocument(); } diff --git a/src/Operation/Distinct.php b/src/Operation/Distinct.php index e69adabac..1f06c0ff2 100644 --- a/src/Operation/Distinct.php +++ b/src/Operation/Distinct.php @@ -110,12 +110,11 @@ public function __construct(private string $databaseName, private string $collec * 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) + public function execute(Server $server): array { $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); if ($inTransaction && isset($this->options['readConcern'])) { @@ -141,9 +140,8 @@ public function execute(Server $server) * Returns the command document for this operation. * * @see Explainable::getCommandDocument() - * @return array */ - public function getCommandDocument() + public function getCommandDocument(): array { $cmd = $this->createCommandDocument(); diff --git a/src/Operation/DropCollection.php b/src/Operation/DropCollection.php index 3384bd998..d1a0b65a8 100644 --- a/src/Operation/DropCollection.php +++ b/src/Operation/DropCollection.php @@ -88,7 +88,7 @@ public function __construct(private string $databaseName, private string $collec * @throws UnsupportedException if write concern is used and unsupported * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): array|object { $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); if ($inTransaction && isset($this->options['writeConcern'])) { diff --git a/src/Operation/DropDatabase.php b/src/Operation/DropDatabase.php index cb1563612..c60015e5c 100644 --- a/src/Operation/DropDatabase.php +++ b/src/Operation/DropDatabase.php @@ -82,7 +82,7 @@ public function __construct(private string $databaseName, private array $options * @return array|object Command result document * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): array|object { $cursor = $server->executeWriteCommand($this->databaseName, $this->createCommand(), $this->createOptions()); diff --git a/src/Operation/DropEncryptedCollection.php b/src/Operation/DropEncryptedCollection.php index 1d90f89f4..32f143ee5 100644 --- a/src/Operation/DropEncryptedCollection.php +++ b/src/Operation/DropEncryptedCollection.php @@ -89,7 +89,7 @@ public function __construct(string $databaseName, string $collectionName, array * @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) + public function execute(Server $server): array|object { foreach ($this->dropMetadataCollections as $dropMetadataCollection) { $dropMetadataCollection->execute($server); diff --git a/src/Operation/DropIndexes.php b/src/Operation/DropIndexes.php index 69cc8ce4c..d6b1beb59 100644 --- a/src/Operation/DropIndexes.php +++ b/src/Operation/DropIndexes.php @@ -97,7 +97,7 @@ public function __construct(private string $databaseName, private string $collec * @throws UnsupportedException if write concern is used and unsupported * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): array|object { $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); if ($inTransaction && isset($this->options['writeConcern'])) { diff --git a/src/Operation/EstimatedDocumentCount.php b/src/Operation/EstimatedDocumentCount.php index 3a6ce256b..2a5aada61 100644 --- a/src/Operation/EstimatedDocumentCount.php +++ b/src/Operation/EstimatedDocumentCount.php @@ -88,12 +88,11 @@ public function __construct(private string $databaseName, private string $collec * 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) + public function execute(Server $server): int { return $this->createCount()->execute($server); } @@ -102,9 +101,8 @@ public function execute(Server $server) * Returns the command document for this operation. * * @see Explainable::getCommandDocument() - * @return array */ - public function getCommandDocument() + public function getCommandDocument(): array { return $this->createCount()->getCommandDocument(); } diff --git a/src/Operation/Executable.php b/src/Operation/Executable.php index 5bd8c68b3..2c8dbc9f2 100644 --- a/src/Operation/Executable.php +++ b/src/Operation/Executable.php @@ -32,7 +32,8 @@ interface Executable /** * Execute the operation. * - * @return mixed + * @phpcsSuppress SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingNativeTypeHint + * @return mixed|void */ public function execute(Server $server); } diff --git a/src/Operation/Explain.php b/src/Operation/Explain.php index a6e14303f..0c3f5e5e3 100644 --- a/src/Operation/Explain.php +++ b/src/Operation/Explain.php @@ -87,11 +87,10 @@ public function __construct(private string $databaseName, private Explainable $e * 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) + public function execute(Server $server): array|object { $cursor = $server->executeCommand($this->databaseName, $this->createCommand(), $this->createOptions()); diff --git a/src/Operation/Explainable.php b/src/Operation/Explainable.php index f380e1c32..372d4cb29 100644 --- a/src/Operation/Explainable.php +++ b/src/Operation/Explainable.php @@ -27,8 +27,6 @@ interface Explainable extends Executable { /** * Returns the command document for this operation. - * - * @return array */ - public function getCommandDocument(); + public function getCommandDocument(): array; } diff --git a/src/Operation/Find.php b/src/Operation/Find.php index f391faea5..43838d479 100644 --- a/src/Operation/Find.php +++ b/src/Operation/Find.php @@ -17,7 +17,6 @@ namespace MongoDB\Operation; -use Iterator; use MongoDB\Codec\DocumentCodec; use MongoDB\Driver\CursorInterface; use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException; @@ -300,11 +299,10 @@ public function __construct(private string $databaseName, private string $collec * 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) + public function execute(Server $server): CursorInterface { $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); if ($inTransaction && isset($this->options['readConcern'])) { @@ -328,9 +326,8 @@ public function execute(Server $server) * Returns the command document for this operation. * * @see Explainable::getCommandDocument() - * @return array */ - public function getCommandDocument() + public function getCommandDocument(): array { $cmd = ['find' => $this->collectionName, 'filter' => (object) $this->filter]; diff --git a/src/Operation/FindAndModify.php b/src/Operation/FindAndModify.php index 07abfe80e..8b1f14f2e 100644 --- a/src/Operation/FindAndModify.php +++ b/src/Operation/FindAndModify.php @@ -222,12 +222,11 @@ public function __construct(private string $databaseName, private string $collec * 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) + public function execute(Server $server): array|object|null { /* Server versions >= 4.2.0 raise errors for unsupported update options. * For previous versions, the CRUD spec requires a client-side error. */ @@ -274,9 +273,8 @@ public function execute(Server $server) * Returns the command document for this operation. * * @see Explainable::getCommandDocument() - * @return array */ - public function getCommandDocument() + public function getCommandDocument(): array { return $this->createCommandDocument(); } diff --git a/src/Operation/FindOne.php b/src/Operation/FindOne.php index 0670d97c6..0290356ee 100644 --- a/src/Operation/FindOne.php +++ b/src/Operation/FindOne.php @@ -118,11 +118,10 @@ public function __construct(string $databaseName, string $collectionName, array| * 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) + public function execute(Server $server): array|object|null { $cursor = $this->find->execute($server); $document = current($cursor->toArray()); @@ -134,9 +133,8 @@ public function execute(Server $server) * Returns the command document for this operation. * * @see Explainable::getCommandDocument() - * @return array */ - public function getCommandDocument() + public function getCommandDocument(): array { return $this->find->getCommandDocument(); } diff --git a/src/Operation/FindOneAndDelete.php b/src/Operation/FindOneAndDelete.php index 68be63e23..bf70bfc4a 100644 --- a/src/Operation/FindOneAndDelete.php +++ b/src/Operation/FindOneAndDelete.php @@ -108,11 +108,10 @@ public function __construct(string $databaseName, string $collectionName, array| * 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) + public function execute(Server $server): array|object|null { return $this->findAndModify->execute($server); } @@ -121,9 +120,8 @@ public function execute(Server $server) * Returns the command document for this operation. * * @see Explainable::getCommandDocument() - * @return array */ - public function getCommandDocument() + public function getCommandDocument(): array { return $this->findAndModify->getCommandDocument(); } diff --git a/src/Operation/FindOneAndReplace.php b/src/Operation/FindOneAndReplace.php index 21a34fc77..b9a5bdf7d 100644 --- a/src/Operation/FindOneAndReplace.php +++ b/src/Operation/FindOneAndReplace.php @@ -151,11 +151,10 @@ public function __construct(string $databaseName, string $collectionName, array| * 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) + public function execute(Server $server): array|object|null { return $this->findAndModify->execute($server); } @@ -164,15 +163,13 @@ public function execute(Server $server) * Returns the command document for this operation. * * @see Explainable::getCommandDocument() - * @return array */ - public function getCommandDocument() + public function getCommandDocument(): array { return $this->findAndModify->getCommandDocument(); } - /** @return array|object */ - private function validateReplacement(array|object $replacement, ?DocumentCodec $codec) + private function validateReplacement(array|object $replacement, ?DocumentCodec $codec): array|object { if (isset($codec)) { $replacement = $codec->encode($replacement); diff --git a/src/Operation/FindOneAndUpdate.php b/src/Operation/FindOneAndUpdate.php index f44cc4421..56db8cb8e 100644 --- a/src/Operation/FindOneAndUpdate.php +++ b/src/Operation/FindOneAndUpdate.php @@ -151,11 +151,10 @@ public function __construct(string $databaseName, string $collectionName, array| * 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) + public function execute(Server $server): array|object|null { return $this->findAndModify->execute($server); } @@ -164,9 +163,8 @@ public function execute(Server $server) * Returns the command document for this operation. * * @see Explainable::getCommandDocument() - * @return array */ - public function getCommandDocument() + public function getCommandDocument(): array { return $this->findAndModify->getCommandDocument(); } diff --git a/src/Operation/InsertMany.php b/src/Operation/InsertMany.php index 8f99fc771..9de46a1f0 100644 --- a/src/Operation/InsertMany.php +++ b/src/Operation/InsertMany.php @@ -115,11 +115,10 @@ public function __construct(private string $databaseName, private string $collec * 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) + public function execute(Server $server): InsertManyResult { $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); if ($inTransaction && isset($this->options['writeConcern'])) { diff --git a/src/Operation/InsertOne.php b/src/Operation/InsertOne.php index 95d49c129..2c08d8db2 100644 --- a/src/Operation/InsertOne.php +++ b/src/Operation/InsertOne.php @@ -98,11 +98,10 @@ public function __construct(private string $databaseName, private string $collec * 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) + public function execute(Server $server): InsertOneResult { $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); if (isset($this->options['writeConcern']) && $inTransaction) { @@ -156,8 +155,7 @@ private function createExecuteOptions(): array return $options; } - /** @return array|object */ - private function validateDocument(array|object $document, ?DocumentCodec $codec) + private function validateDocument(array|object $document, ?DocumentCodec $codec): array|object { if ($codec) { $document = $codec->encode($document); diff --git a/src/Operation/ListCollections.php b/src/Operation/ListCollections.php index dfdf203e4..efce4da48 100644 --- a/src/Operation/ListCollections.php +++ b/src/Operation/ListCollections.php @@ -24,6 +24,7 @@ use MongoDB\Exception\InvalidArgumentException; use MongoDB\Model\CollectionInfo; use MongoDB\Model\CollectionInfoCommandIterator; +use MongoDB\Model\CollectionInfoIterator; /** * Operation for the listCollections command. @@ -72,7 +73,7 @@ public function __construct(private string $databaseName, array $options = []) * @return Iterator * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): CollectionInfoIterator { return new CollectionInfoCommandIterator($this->listCollections->execute($server), $this->databaseName); } diff --git a/src/Operation/ListDatabases.php b/src/Operation/ListDatabases.php index 06703f622..1e67daafd 100644 --- a/src/Operation/ListDatabases.php +++ b/src/Operation/ListDatabases.php @@ -24,6 +24,7 @@ use MongoDB\Exception\InvalidArgumentException; use MongoDB\Exception\UnexpectedValueException; use MongoDB\Model\DatabaseInfo; +use MongoDB\Model\DatabaseInfoIterator; use MongoDB\Model\DatabaseInfoLegacyIterator; /** @@ -73,7 +74,7 @@ public function __construct(array $options = []) * @throws UnexpectedValueException if the command response was malformed * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): DatabaseInfoIterator { return new DatabaseInfoLegacyIterator($this->listDatabases->execute($server)); } diff --git a/src/Operation/ListIndexes.php b/src/Operation/ListIndexes.php index 57140a63c..a32b96b97 100644 --- a/src/Operation/ListIndexes.php +++ b/src/Operation/ListIndexes.php @@ -27,6 +27,7 @@ use MongoDB\Exception\InvalidArgumentException; use MongoDB\Model\CachingIterator; use MongoDB\Model\IndexInfo; +use MongoDB\Model\IndexInfoIterator; use MongoDB\Model\IndexInfoIteratorIterator; use function is_integer; @@ -79,7 +80,7 @@ public function __construct(private string $databaseName, private string $collec * @return Iterator * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): IndexInfoIterator { return $this->executeCommand($server); } diff --git a/src/Operation/MapReduce.php b/src/Operation/MapReduce.php index dcb1be4c6..197f340fa 100644 --- a/src/Operation/MapReduce.php +++ b/src/Operation/MapReduce.php @@ -241,12 +241,11 @@ public function __construct(private string $databaseName, private string $collec * 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) + public function execute(Server $server): MapReduceResult { $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); if ($inTransaction) { diff --git a/src/Operation/ModifyCollection.php b/src/Operation/ModifyCollection.php index dd707cd2d..45a5f1c4b 100644 --- a/src/Operation/ModifyCollection.php +++ b/src/Operation/ModifyCollection.php @@ -87,7 +87,7 @@ public function __construct(private string $databaseName, private string $collec * @return array|object Command result document * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): array|object { $cursor = $server->executeWriteCommand($this->databaseName, $this->createCommand(), $this->createOptions()); diff --git a/src/Operation/RenameCollection.php b/src/Operation/RenameCollection.php index d90c9815b..078bf487f 100644 --- a/src/Operation/RenameCollection.php +++ b/src/Operation/RenameCollection.php @@ -102,7 +102,7 @@ public function __construct(string $fromDatabaseName, string $fromCollectionName * @throws UnsupportedException if write concern is used and unsupported * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): array|object { $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); if ($inTransaction && isset($this->options['writeConcern'])) { diff --git a/src/Operation/ReplaceOne.php b/src/Operation/ReplaceOne.php index 47277e058..ab4944b27 100644 --- a/src/Operation/ReplaceOne.php +++ b/src/Operation/ReplaceOne.php @@ -104,17 +104,15 @@ public function __construct(string $databaseName, string $collectionName, array| * 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) + public function execute(Server $server): UpdateResult { return $this->update->execute($server); } - /** @return array|object */ - private function validateReplacement(array|object $replacement, ?DocumentCodec $codec) + private function validateReplacement(array|object $replacement, ?DocumentCodec $codec): array|object { if ($codec) { $replacement = $codec->encode($replacement); diff --git a/src/Operation/Update.php b/src/Operation/Update.php index 1eb0bc9da..79f64fecb 100644 --- a/src/Operation/Update.php +++ b/src/Operation/Update.php @@ -165,11 +165,10 @@ public function __construct(private string $databaseName, private string $collec * 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) + public function execute(Server $server): UpdateResult { /* CRUD spec requires a client-side error when using "hint" with an * unacknowledged write concern on an unsupported server. */ @@ -197,9 +196,8 @@ public function execute(Server $server) * Returns the command document for this operation. * * @see Explainable::getCommandDocument() - * @return array */ - public function getCommandDocument() + public function getCommandDocument(): array { $cmd = ['update' => $this->collectionName, 'updates' => [['q' => $this->filter, 'u' => $this->update] + $this->createUpdateOptions()]]; diff --git a/src/Operation/UpdateMany.php b/src/Operation/UpdateMany.php index a0f204837..ac1f932a7 100644 --- a/src/Operation/UpdateMany.php +++ b/src/Operation/UpdateMany.php @@ -98,11 +98,10 @@ public function __construct(string $databaseName, string $collectionName, array| * 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) + public function execute(Server $server): UpdateResult { return $this->update->execute($server); } @@ -111,9 +110,8 @@ public function execute(Server $server) * Returns the command document for this operation. * * @see Explainable::getCommandDocument() - * @return array */ - public function getCommandDocument() + public function getCommandDocument(): array { return $this->update->getCommandDocument(); } diff --git a/src/Operation/UpdateOne.php b/src/Operation/UpdateOne.php index ac0f20720..d1026e65f 100644 --- a/src/Operation/UpdateOne.php +++ b/src/Operation/UpdateOne.php @@ -98,11 +98,10 @@ public function __construct(string $databaseName, string $collectionName, array| * 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) + public function execute(Server $server): UpdateResult { return $this->update->execute($server); } @@ -111,9 +110,8 @@ public function execute(Server $server) * Returns the command document for this operation. * * @see Explainable::getCommandDocument() - * @return array */ - public function getCommandDocument() + public function getCommandDocument(): array { return $this->update->getCommandDocument(); } diff --git a/src/Operation/Watch.php b/src/Operation/Watch.php index ea93d1937..45074b2ca 100644 --- a/src/Operation/Watch.php +++ b/src/Operation/Watch.php @@ -17,7 +17,6 @@ namespace MongoDB\Operation; -use Iterator; use MongoDB\BSON\TimestampInterface; use MongoDB\ChangeStream; use MongoDB\Codec\DocumentCodec; @@ -266,11 +265,10 @@ public function __construct(private Manager $manager, ?string $databaseName, pri * 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) + public function execute(Server $server): ChangeStream { return new ChangeStream( $this->createChangeStreamIterator($server), @@ -353,10 +351,8 @@ private function createChangeStreamIterator(Server $server): ChangeStreamIterato * * 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) + private function executeAggregate(Server $server): CursorInterface { addSubscriber($this); @@ -371,9 +367,8 @@ private function executeAggregate(Server $server) * 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() + private function getInitialResumeToken(): array|object|null { if ($this->firstBatchSize === 0 && isset($this->postBatchResumeToken)) { return $this->postBatchResumeToken; diff --git a/src/UpdateResult.php b/src/UpdateResult.php index 58a73a890..9e8ef487f 100644 --- a/src/UpdateResult.php +++ b/src/UpdateResult.php @@ -38,10 +38,9 @@ public function __construct(private WriteResult $writeResult) * 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() + public function getMatchedCount(): ?int { if ($this->isAcknowledged) { return $this->writeResult->getMatchedCount(); @@ -59,10 +58,9 @@ public function getMatchedCount() * 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() + public function getModifiedCount(): ?int { if ($this->isAcknowledged) { return $this->writeResult->getModifiedCount(); @@ -77,10 +75,9 @@ public function getModifiedCount() * 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() + public function getUpsertedCount(): ?int { if ($this->isAcknowledged) { return $this->writeResult->getUpsertedCount(); @@ -101,10 +98,9 @@ public function getUpsertedCount() * 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() + public function getUpsertedId(): mixed { if ($this->isAcknowledged) { foreach ($this->writeResult->getUpsertedIds() as $id) { @@ -123,10 +119,8 @@ public function getUpsertedId() * 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() + public function isAcknowledged(): bool { return $this->isAcknowledged; } diff --git a/src/functions.php b/src/functions.php index a445467ba..5d66bd13a 100644 --- a/src/functions.php +++ b/src/functions.php @@ -122,10 +122,9 @@ function all_servers_support_write_stage_on_secondary(array $servers): bool * @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) +function apply_type_map_to_document(array|object $document, array $typeMap): array|object { if (! is_document($document)) { throw InvalidArgumentException::expectedDocumentType('$document', $document); @@ -183,9 +182,8 @@ function document_to_array(array|object $document): array * @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) +function get_encrypted_fields_from_driver(string $databaseName, string $collectionName, Manager $manager): array|object|null { $encryptedFieldsMap = (array) $manager->getEncryptedFieldsMap(); @@ -199,9 +197,8 @@ function get_encrypted_fields_from_driver(string $databaseName, string $collecti * @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) +function get_encrypted_fields_from_server(string $databaseName, string $collectionName, Manager $manager, Server $server): array|object|null { // No-op if the encryptedFieldsMap autoEncryption driver option was omitted if ($manager->getEncryptedFieldsMap() === null) { @@ -469,10 +466,9 @@ function is_string_array(mixed $input): bool * @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) +function recursive_copy(mixed $element): mixed { if (is_array($element)) { foreach ($element as $key => $value) { diff --git a/stubs/Driver/Cursor.stub.php b/stubs/Driver/Cursor.stub.php new file mode 100644 index 000000000..2ee403832 --- /dev/null +++ b/stubs/Driver/Cursor.stub.php @@ -0,0 +1,59 @@ + + */ +final class Cursor implements CursorInterface +{ + /** + * @return TValue|null + * @psalm-ignore-nullable-return + */ + public function current(): array|object|null + { + } + + public function next(): void + { + } + + /** @psalm-ignore-nullable-return */ + public function key(): ?int + { + } + + public function valid(): bool + { + } + + public function rewind(): void + { + } + + /** @return array */ + public function toArray(): array + { + } + + public function getId(): Int64 + { + } + + public function getServer(): Server + { + } + + public function isDead(): bool + { + } + + public function setTypeMap(array $typemap): void + { + } +} diff --git a/stubs/Driver/CursorInterface.stub.php b/stubs/Driver/CursorInterface.stub.php new file mode 100644 index 000000000..d2a89737a --- /dev/null +++ b/stubs/Driver/CursorInterface.stub.php @@ -0,0 +1,33 @@ + + */ +interface CursorInterface extends Iterator +{ + /** + * @return TValue|null + * @psalm-ignore-nullable-return + */ + public function current(): array|object|null; + + public function getId(): Int64; + + public function getServer(): Server; + + public function isDead(): bool; + + /** @psalm-ignore-nullable-return */ + public function key(): ?int; + + public function setTypeMap(array $typemap): void; + + /** @return array */ + public function toArray(): array; +} diff --git a/tests/Model/CodecCursorFunctionalTest.php b/tests/Model/CodecCursorFunctionalTest.php index 432d71732..0fb2b35c6 100644 --- a/tests/Model/CodecCursorFunctionalTest.php +++ b/tests/Model/CodecCursorFunctionalTest.php @@ -4,16 +4,9 @@ use MongoDB\BSON\Int64; use MongoDB\Codec\DocumentCodec; -use MongoDB\Driver\CursorId; use MongoDB\Model\CodecCursor; use MongoDB\Tests\FunctionalTestCase; -use function restore_error_handler; -use function set_error_handler; - -use const E_DEPRECATED; -use const E_USER_DEPRECATED; - class CodecCursorFunctionalTest extends FunctionalTestCase { public function setUp(): void @@ -36,44 +29,6 @@ public function testSetTypeMap(): void $codecCursor->setTypeMap(['root' => 'array']); } - public function testGetIdReturnTypeWithoutArgument(): void - { - $collection = self::createTestClient()->selectCollection($this->getDatabaseName(), $this->getCollectionName()); - $cursor = $collection->find(); - - $codecCursor = CodecCursor::fromCursor($cursor, $this->createMock(DocumentCodec::class)); - - $deprecations = []; - - try { - $previousErrorHandler = set_error_handler( - function (...$args) use (&$previousErrorHandler, &$deprecations) { - $deprecations[] = $args; - - return true; - }, - E_USER_DEPRECATED | E_DEPRECATED, - ); - - $cursorId = $codecCursor->getId(); - } finally { - restore_error_handler(); - } - - self::assertInstanceOf(CursorId::class, $cursorId); - - // Expect 2 deprecations: 1 from CodecCursor, one from Cursor - self::assertCount(2, $deprecations); - self::assertSame( - 'The method "MongoDB\Model\CodecCursor::getId" will no longer return a "MongoDB\Driver\CursorId" instance in the future. Pass "true" as argument to change to the new behavior and receive a "MongoDB\BSON\Int64" instance instead.', - $deprecations[0][1], - ); - self::assertSame( - 'MongoDB\Driver\Cursor::getId(): The method "MongoDB\Driver\Cursor::getId" will no longer return a "MongoDB\Driver\CursorId" instance in the future. Pass "true" as argument to change to the new behavior and receive a "MongoDB\BSON\Int64" instance instead.', - $deprecations[1][1], - ); - } - public function testGetIdReturnTypeWithArgument(): void { $collection = self::createTestClient()->selectCollection($this->getDatabaseName(), $this->getCollectionName()); @@ -81,24 +36,6 @@ public function testGetIdReturnTypeWithArgument(): void $codecCursor = CodecCursor::fromCursor($cursor, $this->createMock(DocumentCodec::class)); - $deprecations = []; - - try { - $previousErrorHandler = set_error_handler( - function (...$args) use (&$previousErrorHandler, &$deprecations) { - $deprecations[] = $args; - - return true; - }, - E_USER_DEPRECATED | E_DEPRECATED, - ); - - $cursorId = $codecCursor->getId(true); - } finally { - restore_error_handler(); - } - - self::assertInstanceOf(Int64::class, $cursorId); - self::assertCount(0, $deprecations); + self::assertInstanceOf(Int64::class, $codecCursor->getId()); } } diff --git a/tests/Operation/WatchFunctionalTest.php b/tests/Operation/WatchFunctionalTest.php index cc6690b0f..eed98fa88 100644 --- a/tests/Operation/WatchFunctionalTest.php +++ b/tests/Operation/WatchFunctionalTest.php @@ -721,7 +721,7 @@ public function testInitialCursorIsNotClosed(): void * reports the cursor as alive. While the cursor ID is accessed through * ChangeStream, we'll need to use reflection to access the internal * Cursor and call isDead(). */ - $this->assertNotEquals('0', (string) $changeStream->getCursorId(true)); + $this->assertNotEquals(0, $changeStream->getCursorId()); $rc = new ReflectionClass(ChangeStream::class); $rp = $rc->getProperty('iterator'); @@ -1371,11 +1371,11 @@ public function testOriginalReadPreferenceIsPreservedOnResume(): void } $changeStream = $operation->execute($secondary); - $previousCursorId = $changeStream->getCursorId(true); + $previousCursorId = $changeStream->getCursorId(); $this->forceChangeStreamResume($secondary); $changeStream->next(); - $this->assertNotEquals($previousCursorId, $changeStream->getCursorId(true)); + $this->assertNotEquals($previousCursorId, $changeStream->getCursorId()); $getCursor = Closure::bind( fn () => $this->iterator->getInnerIterator(),