bsonSerialize(); } if (is_object($document)) { $document = get_object_vars($document); } if ( ! is_array($document)) { throw InvalidArgumentException::invalidType('$document', $document, 'array or object'); } $name = ''; foreach ($document as $field => $type) { $name .= ($name != '' ? '_' : '') . $field . '_' . $type; } return $name; } /** * Return whether the first key in the document starts with a "$" character. * * This is used for differentiating update and replacement documents. * * @internal * @param array|object $document Update or replacement document * @return boolean * @throws InvalidArgumentException */ function is_first_key_operator($document) { if ($document instanceof Serializable) { $document = $document->bsonSerialize(); } if (is_object($document)) { $document = get_object_vars($document); } if ( ! is_array($document)) { throw InvalidArgumentException::invalidType('$document', $document, 'array or object'); } reset($document); $firstKey = (string) key($document); return (isset($firstKey[0]) && $firstKey[0] === '$'); } /** * Return whether the aggregation pipeline ends with an $out operator. * * This is used for determining whether the aggregation pipeline must be * executed against a primary server. * * @internal * @param array $pipeline List of pipeline operations * @return boolean */ function is_last_pipeline_operator_out(array $pipeline) { $lastOp = end($pipeline); if ($lastOp === false) { return false; } $lastOp = (array) $lastOp; return key($lastOp) === '$out'; } /** * Return whether the "out" option for a mapReduce operation is "inline". * * This is used to determine if a mapReduce command requires a primary. * * @internal * @see https://docs.mongodb.com/manual/reference/command/mapReduce/#output-inline * @param string|array|object $out Output specification * @return boolean * @throws InvalidArgumentException */ function is_mapreduce_output_inline($out) { if ( ! is_array($out) && ! is_object($out)) { return false; } if ($out instanceof Serializable) { $out = $out->bsonSerialize(); } if (is_object($out)) { $out = get_object_vars($out); } if ( ! is_array($out)) { throw InvalidArgumentException::invalidType('$out', $out, 'array or object'); } reset($out); return key($out) === 'inline'; } /** * Return whether the server supports a particular feature. * * @internal * @param Server $server Server to check * @param integer $feature Feature constant (i.e. wire protocol version) * @return boolean */ function server_supports_feature(Server $server, $feature) { $info = $server->getInfo(); $maxWireVersion = isset($info['maxWireVersion']) ? (integer) $info['maxWireVersion'] : 0; $minWireVersion = isset($info['minWireVersion']) ? (integer) $info['minWireVersion'] : 0; return ($minWireVersion <= $feature && $maxWireVersion >= $feature); } function is_string_array($input) { if (!is_array($input)){ return false; } foreach($input as $item) { if (!is_string($item)) { return false; } } return true; } /** * Performs a deep copy of a value. * * This function will clone objects and recursively copy values within arrays. * * @internal * @see https://bugs.php.net/bug.php?id=49664 * @param mixed $element Value to be copied * @return mixed */ function recursive_copy($element) { if (is_array($element)) { foreach ($element as $key => $value) { $element[$key] = recursive_copy($value); } return $element; } if ( ! is_object($element)) { return $element; } if ( ! (new ReflectionClass($element))->isCloneable()) { return $element; } return clone $element; }