Skip to content

Commit 08dae54

Browse files
fix doctrine query builder
1 parent 781eca7 commit 08dae54

3 files changed

Lines changed: 71 additions & 9 deletions

File tree

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
/node_modules/
33
/.idea/
44

5-
yarn-error.log
5+
yarn-error.log
6+
composer.lock

README.md

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Highly inspired by [SgDatatablesBundle](https://github.com/stwe/DatatablesBundle
2020
5. [Configuration](#configuration)
2121
1. [Table Dataset Options](#table-dataset-options)
2222
2. [Table Options](#table-options)
23+
6. [Custom Doctrine Queries](#custom-doctrine-queries)
2324

2425
## Features
2526

@@ -253,6 +254,10 @@ Represents column with text. With formatter you can create complex columns.
253254
#### Example
254255

255256
```php
257+
//use statements for search and sort option
258+
use Doctrine\ORM\Query\Expr\Orx;
259+
use Doctrine\ORM\QueryBuilder;
260+
256261
->add('username', TextColumn::class, array(
257262
'title' => 'Username',
258263
'emptyData' => "No Username found.",
@@ -265,13 +270,29 @@ Represents column with text. With formatter you can create complex columns.
265270
'sort' => function (QueryBuilder $qb, $direction) { //execute if user sort this column
266271
$qb->addOrderBy('username', $direction);
267272
},
268-
'search' => function (QueryBuilder $qb, $search) { //execute if user use global search
269-
$qb->orWhere('user.username LIKE :username')
270-
->setParameter('username', $search . '%');
273+
'search' => function (Orx $orx, QueryBuilder $qb, $dql, $search, $key) {
274+
//first add condition to $orx
275+
//don't forget the '?' before $key
276+
$orx->add($qb->expr()->like($dql, '?' . $key));
277+
278+
//then bind search to query
279+
$qb->setParameter($key, '%' . $search . '%');
271280
}
272281
))
273282
```
274283

284+
**search** Option:
285+
286+
The search option seems a bit complicated at first, but it allows full control over the query in the column.
287+
288+
| Paramenter name | Description |
289+
| ------------------ | ------------------------------------------------------------ |
290+
| `Orx $orx` | All columns are connected to the SQL query or. With `$orx` more parts can be added to the query. |
291+
| `QueryBuilder $qb` | `$qb` holds the use QueryBuilder. It is the same instance as can be queried with `getQueryBuilder()` in the table class. |
292+
| `(string) $dql` | `$dql` represents the "path" to the variable in the query (e.g. `user.username` or in case of a JOIN `costCentre.name`) |
293+
| `$search` | The search in the type of a string. |
294+
| `$key` | The index of the columns already gone through. The index is used for parameter binding to the query. |
295+
275296

276297

277298
### BooleanColumn
@@ -576,6 +597,39 @@ hello_bootstrap_table:
576597

577598

578599

600+
## Custom Doctrine Queries
601+
602+
Sometimes you don't want to display all the data in a database table. For this you can "prefilter" the Doctrine query.
603+
604+
### Example
605+
606+
```php
607+
/**
608+
* @Route("/", name="default")
609+
*/
610+
public function index(Request $request, HelloBootstrapTableFactory $tableFactory)
611+
{
612+
//first create a instance of your table
613+
$table = $tableFactory->create(TestTable::class);
614+
615+
//then you can access the QueryBuilder from the table
616+
$table->getQueryBuilder()
617+
->andWhere('department.name = :departmentName')
618+
->setParameter('departmentName', 'IT');
619+
620+
$table->handleRequest($request);
621+
if ($table->isCallback()) {
622+
return $table->getResponse();
623+
}
624+
625+
return $this->render("index.html.twig", array(
626+
"table" => $table->createView()
627+
));
628+
}
629+
```
630+
631+
632+
579633
## ToDo's
580634
* Documentation
581635
* Cookie Extension

src/Query/DoctrineQueryBuilder.php

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
namespace HelloSebastian\HelloBootstrapTableBundle\Query;
55

6+
use Doctrine\Common\Collections\Criteria;
67
use Doctrine\ORM\EntityManagerInterface;
78
use Doctrine\Persistence\Mapping\ClassMetadata;
89
use HelloSebastian\HelloBootstrapTableBundle\Columns\ColumnBuilder;
@@ -100,8 +101,12 @@ public function fetchData($requestData)
100101
{
101102
$this->setupJoinFields();
102103

104+
$orExpr = $this->qb->expr()->orX();
105+
103106
if ($requestData['search']) {
104-
foreach ($this->columnBuilder->getColumns() as $column) {
107+
foreach ($this->columnBuilder->getColumns() as $key => $column) {
108+
++$key;
109+
105110
if ($column->getOutputOptions()['filterable']) {
106111

107112
if ($column->isAssociation()) {
@@ -110,17 +115,19 @@ public function fetchData($requestData)
110115
$path = $this->qb->getRootAliases()[0] . '.' . $column->getDql();
111116
}
112117

113-
114118
if ($searchCallback = $column->getSearchCallback()) {
115-
$searchCallback($this->qb, $requestData['search']);
119+
$searchCallback($orExpr, $this->qb, $path, $requestData['search'], $key);
120+
116121
} else {
117-
$this->qb->orWhere($path . ' LIKE :' . str_replace(".", "_", $path))
118-
->setParameter(str_replace(".", "_", $path), '%' . $requestData['search'] . '%');
122+
$orExpr->add($this->qb->expr()->like($path, '?' . $key));
123+
$this->qb->setParameter($key, '%' . $requestData['search'] . '%');
119124
}
120125
}
121126
}
122127
}
123128

129+
$this->qb->andWhere($orExpr);
130+
124131
if ($requestData["sort"]) {
125132
$column = $this->columnBuilder->getColumnByField($requestData["sort"]);
126133

0 commit comments

Comments
 (0)