Skip to content

Commit 96bba5a

Browse files
author
Tomasz Cyrankowski
committed
Added support for Document EmbedOne fields
1 parent 06ae939 commit 96bba5a

File tree

2 files changed

+90
-32
lines changed

2 files changed

+90
-32
lines changed

Grid/Source/Document.php

Lines changed: 70 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,16 @@ class Document extends Source
7373
*/
7474
protected $referencedMappings = [];
7575

76+
/**
77+
* @var array
78+
*/
79+
protected $embedColumns = [];
80+
81+
/**
82+
* @var array
83+
*/
84+
protected $embedMappings = [];
85+
7686
/**
7787
* @param string $documentName e.g. "Cms:Page"
7888
*/
@@ -197,8 +207,12 @@ public function execute($columns, $page = 0, $limit = 0, $maxResults = null, $gr
197207

198208
//checks if exists '.' notation on referenced columns and build query if it's filtered
199209
$subColumn = explode('.', $column->getId());
200-
if (count($subColumn) > 1 && isset($this->referencedMappings[$subColumn[0]])) {
201-
$this->addReferencedColumnn($subColumn, $column);
210+
if (count($subColumn) > 1) {
211+
if (isset($this->referencedMappings[$subColumn[0]])) {
212+
$this->addReferencedColumn($subColumn, $column);
213+
} elseif (isset($this->embedMappings[$subColumn[0]])) {
214+
$this->addEmbedColumn($subColumn, $column);
215+
}
202216

203217
continue;
204218
}
@@ -254,7 +268,6 @@ public function execute($columns, $page = 0, $limit = 0, $maxResults = null, $gr
254268
// I really don't know if Cursor is the right type returned (I mean, every single type).
255269
// As I didn't find out this information, I'm gonna test it with Cursor returned only.
256270
$cursor = $this->query->getQuery()->execute();
257-
258271
$this->count = $cursor->count();
259272

260273
foreach ($cursor as $resource) {
@@ -268,6 +281,7 @@ public function execute($columns, $page = 0, $limit = 0, $maxResults = null, $gr
268281
}
269282

270283
$this->addReferencedFields($row, $resource);
284+
$this->addEmbedFields($row, $resource);
271285

272286
//call overridden prepareRow or associated closure
273287
if (($modifiedRow = $this->prepareRow($row)) !== null) {
@@ -278,11 +292,7 @@ public function execute($columns, $page = 0, $limit = 0, $maxResults = null, $gr
278292
return $result;
279293
}
280294

281-
/**
282-
* @param array $subColumn
283-
* @param Column \APY\DataGridBundle\Grid\Column\Column
284-
*/
285-
protected function addReferencedColumnn(array $subColumn, Column $column)
295+
protected function addReferencedColumn(array $subColumn, Column $column)
286296
{
287297
$this->referencedColumns[$subColumn[0]][] = $subColumn[1];
288298

@@ -304,7 +314,7 @@ protected function addReferencedColumnn(array $subColumn, Column $column)
304314
$this->query->select($subColumn[0]);
305315
}
306316

307-
if ($cursor->count() == 1) {
317+
if ($cursor->count() === 1) {
308318
$this->query->field($subColumn[0])->references($resource);
309319
} else {
310320
$this->query->addOr($this->query->expr()->field($subColumn[0])->references($resource));
@@ -314,33 +324,63 @@ protected function addReferencedColumnn(array $subColumn, Column $column)
314324
}
315325
}
316326

327+
protected function addEmbedColumn(array $subColumn, Column $column)
328+
{
329+
$this->embedColumns[$subColumn[0]][] = $subColumn[1];
330+
331+
if ($column->isFiltered()) {
332+
$filters = $column->getFilters('document');
333+
foreach ($filters as $filter) {
334+
$operator = $this->normalizeOperator($filter->getOperator());
335+
$value = $this->normalizeValue($operator, $filter->getValue());
336+
if ($column->getDataJunction() === Column::DATA_DISJUNCTION) {
337+
$this->query->addOr($this->query->expr()->field($column->getField())->$operator($value));
338+
} else {
339+
$this->query->field($column->getField())->$operator($value);
340+
}
341+
}
342+
}
343+
344+
if ($column->isSorted()) {
345+
$this->query->sort($column->getField(), $column->getOrder());
346+
}
347+
}
348+
317349
/**
318-
* @param \APY\DataGridBundle\Grid\Row $row
319-
* @param Document $resource
350+
* @param Row $row
351+
* @param Document $resource
320352
*
321353
* @throws \Exception if getter for field does not exists
322-
*
323-
* @return \APY\DataGridBundle\Grid\Row $row with referenced fields
324354
*/
325355
protected function addReferencedFields(Row $row, $resource)
326356
{
327357
foreach ($this->referencedColumns as $parent => $subColumns) {
328-
$node = $this->getClassProperties($resource);
329-
if (isset($node[strtolower($parent)])) {
330-
$node = $node[strtolower($parent)];
331-
332-
foreach ($subColumns as $field) {
333-
$getter = 'get' . ucfirst($field);
334-
if (method_exists($node, $getter)) {
335-
$row->setField($parent . '.' . $field, $node->$getter());
336-
} else {
337-
throw new \Exception(sprintf('Method %s for Document %s not exists', $getter, $this->referencedMappings[$parent]));
338-
}
358+
$this->addSubfield($row, $resource, $parent, $subColumns);
359+
}
360+
}
361+
362+
protected function addEmbedFields(Row $row, $resource)
363+
{
364+
foreach ($this->embedColumns as $parent => $subColumns) {
365+
$this->addSubfield($row, $resource, $parent, $subColumns);
366+
}
367+
}
368+
369+
protected function addSubfield(Row $row, $resource, $parent, array $subColumns)
370+
{
371+
$node = $this->getClassProperties($resource);
372+
if (isset($node[strtolower($parent)])) {
373+
$node = $node[strtolower($parent)];
374+
375+
foreach ($subColumns as $field) {
376+
$getter = 'get' . ucfirst($field);
377+
if (method_exists($node, $getter)) {
378+
$row->setField($parent . '.' . $field, $node->$getter());
379+
} else {
380+
throw new \Exception(sprintf('Method %s for Document %s not exists', $getter, $this->referencedMappings[$parent]));
339381
}
340382
}
341383
}
342-
343-
return $row;
344384
}
345385

346386
public function getTotalCount($maxResults = null)
@@ -416,17 +456,17 @@ public function getFieldsMetadata($class, $group = 'default')
416456
$values['type'] = 'date';
417457
break;
418458
case 'collection':
459+
case 'many':
419460
$values['type'] = 'array';
420461
break;
421462
case 'one':
422463
$values['type'] = 'array';
423-
if (isset($mapping['reference']) && $mapping['reference'] === true) {
464+
if (isset($mapping['reference']) && true === $mapping['reference']) {
424465
$this->referencedMappings[$name] = $mapping['targetDocument'];
466+
} elseif (isset($mapping['embedded']) && true === $mapping['embedded']) {
467+
$this->embedMappings[$name] = $mapping['targetDocument'];
425468
}
426469
break;
427-
case 'many':
428-
$values['type'] = 'array';
429-
break;
430470
default:
431471
$values['type'] = 'text';
432472
}

Resources/doc/source/document_source.md

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,29 @@ And the template:
7070
{{ grid(grid) }}
7171
```
7272

73+
## Mapped fields (Referenced or embed) example
74+
75+
```php
76+
/**
77+
* @MongoDB\Document(collection="room")
78+
* @GRID\Source(columns="id, gameParameters, gameParameters.maxPlayers")
79+
*/
80+
class Room
81+
{
82+
/**
83+
* @var GameParameters
84+
* @MongoDB\EmbedOne(targetDocument=GameParameters::class)
85+
* @GRID\Column(field="gameParameters", visible=false)
86+
* @GRID\Column(field="gameParameters.maxPlayers", filterable=true, defaultOperator="eq", type="number")
87+
*/
88+
private $gameParameters;
89+
}
90+
```
91+
92+
7393
## Missing features
7494

75-
* Mapped fileds (Referenced or embed)
7695
* GroupBy attributes and aggregate DQL functions (If someone is skilled with the mapReduce feature, contact us)
77-
* Array column
7896
* Filter doesn't work with a ODM timestamp but it is show as a date and it can be sort
7997

8098
## Unsupported features

0 commit comments

Comments
 (0)