Skip to content

Commit 5b77ddb

Browse files
authored
Merge pull request #3 from jenssegers/master
update fro, master fork to our build
2 parents a01e158 + 828e751 commit 5b77ddb

File tree

16 files changed

+456
-71
lines changed

16 files changed

+456
-71
lines changed

.github/FUNDING.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
github: jenssegers
2-
open_collective: laravel-mongodb
2+
tidelift: "packagist/jenssegers/mongodb"

.github/workflows/build-ci.yml

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
runs-on: ${{matrix.os}}
1212
strategy:
1313
matrix:
14-
php: ['7.1', '7.2', '7.3', '7.4']
14+
php: ['7.2', '7.3', '7.4']
1515
os: ['ubuntu-latest']
1616
mongodb: ['3.6', '4.0', '4.2']
1717
services:
@@ -30,9 +30,16 @@ jobs:
3030
name: PHP v${{ matrix.php }} with Mongo v${{ matrix.mongodb }}
3131

3232
steps:
33-
- uses: actions/checkout@v1
33+
- uses: actions/checkout@v2
34+
- name: "Installing php"
35+
uses: shivammathur/setup-php@v2
36+
with:
37+
php-version: ${{ matrix.php }}
38+
extensions: curl,mbstring,xdebug
39+
coverage: xdebug
40+
tools: composer
3441
- name: Show PHP version
35-
run: php${{ matrix.php }} -v && composer -V
42+
run: php -v && composer -V
3643
- name: Show Docker version
3744
run: if [[ "$DEBUG" == "true" ]]; then docker version && env; fi
3845
env:

LICENSE renamed to LICENSE.md

File renamed without changes.

README.md

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ This package adds functionalities to the Eloquent model and Query builder for Mo
2222
- [Extending the base model](#extending-the-base-model)
2323
- [Soft Deletes](#soft-deletes)
2424
- [Dates](#dates)
25+
- [Guarding attributes](#guarding-attributes)
2526
- [Basic Usage](#basic-usage)
2627
- [MongoDB-specific operators](#mongodb-specific-operators)
2728
- [MongoDB-specific Geo operations](#mongodb-specific-geo-operations)
@@ -42,6 +43,8 @@ This package adds functionalities to the Eloquent model and Query builder for Mo
4243
- [Cross-Database Relationships](#cross-database-relationships)
4344
- [Authentication](#authentication)
4445
- [Queues](#queues)
46+
- [Laravel specific](#laravel-specific)
47+
- [Lumen specific](#Lumen-specific)
4548
- [Upgrading](#upgrading)
4649
- [Upgrading from version 2 to 3](#upgrading-from-version-2-to-3)
4750

@@ -63,7 +66,7 @@ Make sure you have the MongoDB PHP driver installed. You can find installation i
6366
5.6.x | 3.4.x
6467
5.7.x | 3.4.x
6568
5.8.x | 3.5.x
66-
6.0.x | 3.6.x
69+
6.x | 3.6.x
6770

6871
Install the package via Composer:
6972

@@ -230,6 +233,18 @@ class Book extends Model
230233
}
231234
```
232235

236+
### Extending the Authenticable base model
237+
This package includes a MongoDB Authenticatable Eloquent class `Jenssegers\Mongodb\Auth\User` that you can use to replace the default Authenticatable class `Illuminate\Foundation\Auth\User` for your `User` model.
238+
239+
```php
240+
use Jenssegers\Mongodb\Auth\User as Authenticatable;
241+
242+
class User extends Authenticatable
243+
{
244+
245+
}
246+
```
247+
233248
### Soft Deletes
234249

235250
When soft deleting a model, it is not actually removed from your database. Instead, a deleted_at timestamp is set on the record.
@@ -249,6 +264,13 @@ class User extends Model
249264

250265
For more information check [Laravel Docs about Soft Deleting](http://laravel.com/docs/eloquent#soft-deleting).
251266

267+
### Guarding attributes
268+
269+
When choosing between guarding attributes or marking some as fillable, Taylor Otwell prefers the fillable route.
270+
This is in light of [recent security issues described here](https://blog.laravel.com/security-release-laravel-61835-7240).
271+
272+
Keep in mind guarding still works, but you may experience unexpected behavior.
273+
252274
### Dates
253275

254276
Eloquent allows you to work with Carbon or DateTime objects instead of MongoDate objects. Internally, these dates will be converted to MongoDate objects when saved to the database.
@@ -1067,6 +1089,8 @@ If you want to use MongoDB as your database backend, change the driver in `confi
10671089
'connections' => [
10681090
'database' => [
10691091
'driver' => 'mongodb',
1092+
// You can also specify your jobs specific database created on config/database.php
1093+
'connection' => 'mongodb-job',
10701094
'table' => 'jobs',
10711095
'queue' => 'default',
10721096
'expire' => 60,
@@ -1078,23 +1102,31 @@ If you want to use MongoDB to handle failed jobs, change the database in `config
10781102

10791103
```php
10801104
'failed' => [
1081-
'driver' => env('QUEUE_FAILED_DRIVER', 'database'),
1082-
'database' => env('DB_CONNECTION', 'mongodb'),
1105+
'driver' => 'mongodb',
1106+
// You can also specify your jobs specific database created on config/database.php
1107+
'database' => 'mongodb-job',
10831108
'table' => 'failed_jobs',
10841109
],
10851110
```
10861111

1087-
Or simply set your own `QUEUE_FAILED_DRIVER` environment variable to `mongodb`
1088-
```env
1089-
QUEUE_FAILED_DRIVER=mongodb
1090-
```
1112+
#### Laravel specific
10911113

1092-
Last, add the service provider in `config/app.php`:
1114+
Add the service provider in `config/app.php`:
10931115

10941116
```php
10951117
Jenssegers\Mongodb\MongodbQueueServiceProvider::class,
10961118
```
10971119

1120+
#### Lumen specific
1121+
1122+
With [Lumen](http://lumen.laravel.com), add the service provider in `bootstrap/app.php`. You must however ensure that you add the following **after** the `MongodbServiceProvider` registration.
1123+
1124+
```php
1125+
$app->make('queue');
1126+
1127+
$app->register(Jenssegers\Mongodb\MongodbQueueServiceProvider::class);
1128+
```
1129+
10981130
Upgrading
10991131
---------
11001132

@@ -1134,3 +1166,7 @@ Embedded relations now return an `Illuminate\Database\Eloquent\Collection` rathe
11341166
```php
11351167
$books = $user->books()->sortBy('title')->get();
11361168
```
1169+
1170+
## Security contact information
1171+
1172+
To report a security vulnerability, follow [these steps](https://tidelift.com/security).

src/Jenssegers/Mongodb/Collection.php

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -41,34 +41,32 @@ public function __call($method, $parameters)
4141
$start = microtime(true);
4242
$result = call_user_func_array([$this->collection, $method], $parameters);
4343

44-
if ($this->connection->logging()) {
45-
// Once we have run the query we will calculate the time that it took to run and
46-
// then log the query, bindings, and execution time so we will report them on
47-
// the event that the developer needs them. We'll log time in milliseconds.
48-
$time = $this->connection->getElapsedTime($start);
44+
// Once we have run the query we will calculate the time that it took to run and
45+
// then log the query, bindings, and execution time so we will report them on
46+
// the event that the developer needs them. We'll log time in milliseconds.
47+
$time = $this->connection->getElapsedTime($start);
4948

50-
$query = [];
49+
$query = [];
5150

52-
// Convert the query parameters to a json string.
53-
array_walk_recursive($parameters, function (&$item, $key) {
54-
if ($item instanceof ObjectID) {
55-
$item = (string) $item;
56-
}
57-
});
51+
// Convert the query parameters to a json string.
52+
array_walk_recursive($parameters, function (&$item, $key) {
53+
if ($item instanceof ObjectID) {
54+
$item = (string) $item;
55+
}
56+
});
5857

59-
// Convert the query parameters to a json string.
60-
foreach ($parameters as $parameter) {
61-
try {
62-
$query[] = json_encode($parameter);
63-
} catch (Exception $e) {
64-
$query[] = '{...}';
65-
}
58+
// Convert the query parameters to a json string.
59+
foreach ($parameters as $parameter) {
60+
try {
61+
$query[] = json_encode($parameter);
62+
} catch (Exception $e) {
63+
$query[] = '{...}';
6664
}
65+
}
6766

68-
$queryString = $this->collection->getCollectionName() . '.' . $method . '(' . implode(',', $query) . ')';
67+
$queryString = $this->collection->getCollectionName() . '.' . $method . '(' . implode(',', $query) . ')';
6968

70-
$this->connection->logQuery($queryString, [], $time);
71-
}
69+
$this->connection->logQuery($queryString, [], $time);
7270

7371
return $result;
7472
}

src/Jenssegers/Mongodb/Eloquent/Model.php

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,13 @@ protected function asDateTime($value)
9999
{
100100
// Convert UTCDateTime instances.
101101
if ($value instanceof UTCDateTime) {
102-
return Date::createFromTimestampMs($value->toDateTime()->format('Uv'));
102+
$date = $value->toDateTime();
103+
104+
$seconds = $date->format('U');
105+
$milliseconds = abs($date->format('v'));
106+
$timestampMs = sprintf('%d%03d', $seconds, $milliseconds);
107+
108+
return Date::createFromTimestampMs($timestampMs);
103109
}
104110

105111
return parent::asDateTime($value);
@@ -468,6 +474,17 @@ protected function getRelationsWithoutParent()
468474
return $relations;
469475
}
470476

477+
/**
478+
* Checks if column exists on a table. As this is a document model, just return true. This also
479+
* prevents calls to non-existent function Grammar::compileColumnListing()
480+
* @param string $key
481+
* @return bool
482+
*/
483+
protected function isGuardableColumn($key)
484+
{
485+
return true;
486+
}
487+
471488
/**
472489
* @inheritdoc
473490
*/

src/Jenssegers/Mongodb/Query/Builder.php

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,24 @@
88
use Illuminate\Database\Query\Expression;
99
use Illuminate\Support\Arr;
1010
use Illuminate\Support\Collection;
11+
use Illuminate\Support\LazyCollection;
1112
use Illuminate\Support\Str;
1213
use Jenssegers\Mongodb\Connection;
13-
use MongoCollection;
1414
use MongoDB\BSON\Binary;
1515
use MongoDB\BSON\ObjectID;
1616
use MongoDB\BSON\Regex;
1717
use MongoDB\BSON\UTCDateTime;
18+
use RuntimeException;
1819

20+
/**
21+
* Class Builder
22+
* @package Jenssegers\Mongodb\Query
23+
*/
1924
class Builder extends BaseBuilder
2025
{
2126
/**
2227
* The database collection.
23-
* @var MongoCollection
28+
* @var \MongoDB\Collection
2429
*/
2530
protected $collection;
2631

@@ -209,12 +214,25 @@ public function get($columns = [])
209214
return $this->getFresh($columns);
210215
}
211216

217+
/**
218+
* @inheritdoc
219+
*/
220+
public function cursor($columns = [])
221+
{
222+
$result = $this->getFresh($columns, true);
223+
if ($result instanceof LazyCollection) {
224+
return $result;
225+
}
226+
throw new RuntimeException("Query not compatible with cursor");
227+
}
228+
212229
/**
213230
* Execute the query as a fresh "select" statement.
214231
* @param array $columns
215-
* @return array|static[]|Collection
232+
* @param bool $returnLazy
233+
* @return array|static[]|Collection|LazyCollection
216234
*/
217-
public function getFresh($columns = [])
235+
public function getFresh($columns = [], $returnLazy = false)
218236
{
219237
// If no columns have been specified for the select statement, we will set them
220238
// here to either the passed columns, or the standard default of retrieving
@@ -402,6 +420,14 @@ public function getFresh($columns = [])
402420
// Execute query and get MongoCursor
403421
$cursor = $this->collection->find($wheres, $options);
404422

423+
if ($returnLazy) {
424+
return LazyCollection::make(function () use ($cursor) {
425+
foreach ($cursor as $item) {
426+
yield $item;
427+
}
428+
});
429+
}
430+
405431
// Return results as an array with numeric keys
406432
$results = iterator_to_array($cursor, false);
407433
return $this->useCollections ? new Collection($results) : $results;
@@ -698,15 +724,11 @@ public function from($collection, $as = null)
698724
/**
699725
* @inheritdoc
700726
*/
701-
public function truncate()
727+
public function truncate(): bool
702728
{
703-
$options = [
704-
'typeMap' => ['root' => 'object', 'document' => 'object'],
705-
];
706-
707-
$result = $this->collection->drop($options);
729+
$result = $this->collection->deleteMany([]);
708730

709-
return (1 == (int) $result->ok);
731+
return (1 === (int) $result->isAcknowledged());
710732
}
711733

712734
/**
@@ -993,6 +1015,7 @@ protected function compileWhereAll(array $where)
9931015
protected function compileWhereBasic(array $where)
9941016
{
9951017
extract($where);
1018+
$is_numeric = false;
9961019

9971020
// Replace like or not like with a Regex instance.
9981021
if (in_array($operator, ['like', 'not like'])) {
@@ -1004,15 +1027,21 @@ protected function compileWhereBasic(array $where)
10041027

10051028
// Convert to regular expression.
10061029
$regex = preg_replace('#(^|[^\\\])%#', '$1.*', preg_quote($value));
1030+
$plain_value = $value;
10071031

10081032
// Convert like to regular expression.
10091033
if (!Str::startsWith($value, '%')) {
10101034
$regex = '^' . $regex;
1035+
} else {
1036+
$plain_value = Str::replaceFirst('%', null, $plain_value);
10111037
}
10121038
if (!Str::endsWith($value, '%')) {
10131039
$regex .= '$';
1040+
} else {
1041+
$plain_value = Str::replaceLast('%', null, $plain_value);
10141042
}
10151043

1044+
$is_numeric = is_numeric($plain_value);
10161045
$value = new Regex($regex, 'i');
10171046
} // Manipulate regexp operations.
10181047
elseif (in_array($operator, ['regexp', 'not regexp', 'regex', 'not regex'])) {
@@ -1032,7 +1061,11 @@ protected function compileWhereBasic(array $where)
10321061
}
10331062

10341063
if (!isset($operator) || $operator == '=') {
1035-
$query = [$column => $value];
1064+
if ($is_numeric) {
1065+
$query = ['$where' => '/^'.$value->getPattern().'/.test(this.'.$column.')'];
1066+
} else {
1067+
$query = [$column => $value];
1068+
}
10361069
} elseif (array_key_exists($operator, $this->conversion)) {
10371070
$query = [$column => [$this->conversion[$operator] => $value]];
10381071
} else {

src/Jenssegers/Mongodb/Relations/BelongsToMany.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ protected function buildDictionary(Collection $results)
265265
/**
266266
* @inheritdoc
267267
*/
268-
protected function newPivotQuery()
268+
public function newPivotQuery()
269269
{
270270
return $this->newRelatedQuery();
271271
}

0 commit comments

Comments
 (0)