diff --git a/src/Operation/FindAndModify.php b/src/Operation/FindAndModify.php index ce6689b38..9e1e5949d 100644 --- a/src/Operation/FindAndModify.php +++ b/src/Operation/FindAndModify.php @@ -55,6 +55,9 @@ class FindAndModify implements Executable, Explainable /** @var integer */ private static $wireVersionForDocumentLevelValidation = 4; + /** @var integer */ + private static $wireVersionForHint = 9; + /** @var integer */ private static $wireVersionForHintServerSideError = 8; @@ -245,7 +248,7 @@ public function execute(Server $server) * options (SERVER-40005), but the CRUD spec requires client-side errors * for server versions < 4.2. For later versions, we'll rely on the * server to either utilize the option or report its own error. */ - if (isset($this->options['hint']) && ! server_supports_feature($server, self::$wireVersionForHintServerSideError)) { + if (isset($this->options['hint']) && ! $this->isHintSupported($server)) { throw UnsupportedException::hintNotSupported(); } @@ -338,4 +341,20 @@ private function createOptions() return $options; } + + private function isAcknowledgedWriteConcern() : bool + { + if (! isset($this->options['writeConcern'])) { + return true; + } + + return $this->options['writeConcern']->getW() > 1 || $this->options['writeConcern']->getJournal(); + } + + private function isHintSupported(Server $server) : bool + { + $requiredWireVersion = $this->isAcknowledgedWriteConcern() ? self::$wireVersionForHintServerSideError : self::$wireVersionForHint; + + return server_supports_feature($server, $requiredWireVersion); + } }