public function find($p, $cb)
{
if (!isset($p['offset'])) {
$p['offset'] = 0;
}
if (!isset($p['limit'])) {
$p['limit'] = 0;
}
if (!isset($p['opts'])) {
$p['opts'] = '0';
}
if (isset($p['tailable']) && $p['tailable']) {
$p['opts'] = '01000' . (isset($p['await']) && $p['await'] ? '1' : '0') . '00';
}
if (!isset($p['where'])) {
$p['where'] = [];
}
$this->_params($p);
$o = [];
$s = false;
foreach ($p as $k => $v) {
if ($k === 'sort' || $k === 'hint' || $k === 'explain' || $k === 'snapshot') {
if (!$s) {
$s = true;
}
if ($k === 'sort') {
$o['orderby'] = $v;
} elseif ($k === 'parse_oplog') {
} elseif ($k === 'rp') {
$o['$readPreference'] = $v;
} else {
$o[$k] = $v;
}
}
}
if ($s) {
$o['query'] = $p['where'];
} else {
$o = $p['where'];
}
if (empty($o['orderby'])) {
unset($o['orderby']);
}
if ($this->safeMode) {
static::safeModeEnc($o);
}
try {
$bson = bson_encode($o);
if (isset($p['parse_oplog'])) {
$bson = str_replace("\$gt", "\t\$gt", $bson);
}
$cb = CallbackWrapper::wrap($cb);
$this->request(self::OP_QUERY, chr(bindec(strrev($p['opts']))) . "" . $p['col'] . "" . pack('VV', $p['offset'], $p['limit']) . $bson . (isset($p['fields']) ? bson_encode($p['fields']) : ''), true, null, function ($conn, $reqId = null) use($p, $cb) {
if (!$conn) {
!$cb || $cb(['$err' => 'Connection error.']);
return;
}
$conn->requests[$reqId] = [$p['col'], $cb, false, isset($p['parse_oplog']), isset($p['tailable'])];
});
} catch (\MongoException $e) {
Daemon::log('MongoClient exception: ' . $e->getMessage() . ': ' . $e->getTraceAsString());
if ($cb !== null) {
$cb(['$err' => $e->getMessage(), '$query' => $o, '$fields' => isset($p['fields']) ? $p['fields'] : null]);
}
}
}