From aba8f50d6ce39ad7471c562adfad279413deffd1 Mon Sep 17 00:00:00 2001 From: IT-Talents Date: Wed, 19 Sep 2018 13:43:57 +0200 Subject: [PATCH 1/3] add support for 'join with' --- Datatable/Column/AbstractColumn.php | 34 +++++++++++++++++++++++++++++ Resources/doc/columns.md | 1 + Response/DatatableQueryBuilder.php | 21 ++++++++++++++---- 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/Datatable/Column/AbstractColumn.php b/Datatable/Column/AbstractColumn.php index 7da35c1c..fe5be778 100644 --- a/Datatable/Column/AbstractColumn.php +++ b/Datatable/Column/AbstractColumn.php @@ -199,6 +199,14 @@ abstract class AbstractColumn implements ColumnInterface */ protected $joinType; + /** + * With expression, if the column represents an association. + * Default: null + * + * @var null|string + */ + protected $withExpr; + /** * The data type of the column. * Is set automatically in ColumnBuilder when 'null'. @@ -321,6 +329,7 @@ public function configureOptions(OptionsResolver $resolver) 'width' => null, 'add_if' => null, 'join_type' => 'leftJoin', + 'with_expr' => null, 'type_of_field' => null, 'responsive_priority' => null, )); @@ -341,6 +350,7 @@ public function configureOptions(OptionsResolver $resolver) $resolver->setAllowedTypes('width', array('null', 'string')); $resolver->setAllowedTypes('add_if', array('null', 'Closure')); $resolver->setAllowedTypes('join_type', 'string'); + $resolver->setAllowedTypes('with_expr', array('null', 'string')); $resolver->setAllowedTypes('type_of_field', array('null', 'string')); $resolver->setAllowedTypes('responsive_priority', array('null', 'int')); @@ -817,6 +827,30 @@ public function setJoinType($joinType) return $this; } + /** + * Get WITH expression. + * + * @return string + */ + public function getWithExpr() + { + return $this->withExpr; + } + + /** + * Set WITH expression. + * + * @param string $withExpr + * + * @return $this + */ + public function setWithExpr($withExpr = null) + { + $this->withExpr = $withExpr; + + return $this; + } + /** * Get type of field. * diff --git a/Resources/doc/columns.md b/Resources/doc/columns.md index 10578300..db429430 100644 --- a/Resources/doc/columns.md +++ b/Resources/doc/columns.md @@ -43,6 +43,7 @@ With 'null' initialized options uses the default value of the DataTables plugin. | width | null or string | null | | Column width assignment. | | add_if | null or Closure | null | | Add column only if conditions are TRUE. | | join_type | string | 'leftJoin' | | Join type (default: 'leftJoin'), if the column represents an association. | +| with_expr | null or string | null | | WITH expression for join, if the column represents an association. | | type_of_field | null or string | null (autodetect) | | Set the data type itself for ordering (example: integer instead string). | | responsive_priority | null or int | null | | Set column's visibility priority. Requires the Responsive extension. | | filter | array | TextFilter | | A Filter instance for individual filtering. | diff --git a/Response/DatatableQueryBuilder.php b/Response/DatatableQueryBuilder.php index ee2c5fca..908462c2 100644 --- a/Response/DatatableQueryBuilder.php +++ b/Response/DatatableQueryBuilder.php @@ -255,6 +255,7 @@ private function initColumnArrays() $this->addSearchColumn($column, null, $searchDql); } elseif (true === $this->accessor->getValue($column, 'selectColumn')) { $parts = explode('.', $dql); + $withExpr = $this->accessor->getValue($column, 'withExpr'); while (count($parts) > 1) { $previousPart = $currentPart; @@ -263,8 +264,14 @@ private function initColumnArrays() $currentPart = array_shift($parts); $currentAlias = ($previousPart === $this->entityShortName ? '' : $previousPart.'_').$currentPart; - if (!array_key_exists($previousAlias.'.'.$currentPart, $this->joins)) { - $this->addJoin($previousAlias.'.'.$currentPart, $currentAlias, $this->accessor->getValue($column, 'joinType')); + $columnTableName = $previousAlias.'.'.$currentPart; + if (!array_key_exists($columnTableName, $this->joins)) { + $this->addJoin($columnTableName, $currentAlias, $this->accessor->getValue($column, 'joinType')); + } + // for the last dql part join using WITH, if expression is given for column + if (count($parts) === 1 && array_key_exists($columnTableName, $this->joins) && null !== $withExpr) { + $with = str_replace($currentPart . '.', $currentAlias . '.', $withExpr); + $this->addJoin($columnTableName, $currentAlias, $this->accessor->getValue($column, 'joinType'), $with); } $metadata = $this->setIdentifierFromAssociation($currentAlias, $currentPart, $metadata); @@ -395,7 +402,11 @@ private function setSelectFrom(QueryBuilder $qb) private function setJoins(QueryBuilder $qb) { foreach ($this->joins as $key => $value) { - $qb->{$value['type']}($key, $value['alias']); + if (\array_key_exists('with', $value) && null !== $value['with']) { + $qb->{$value['type']}($key, $value['alias'], Query\Expr\Join::WITH, $value['with']); + } else { + $qb->{$value['type']}($key, $value['alias']); + } } return $this; @@ -723,14 +734,16 @@ private function addSearchOrderColumn($column, $columnTableName, $data) * @param string $columnTableName * @param string $alias * @param string $type + * @param string $with * * @return $this */ - private function addJoin($columnTableName, $alias, $type) + private function addJoin($columnTableName, $alias, $type, $with = null) { $this->joins[$columnTableName] = array( 'alias' => $alias, 'type' => $type, + 'with' => $with, ); return $this; From 4a119af9b3fd2fa950a3e802c6777326600bea67 Mon Sep 17 00:00:00 2001 From: IT-Talents Date: Wed, 19 Sep 2018 15:16:19 +0200 Subject: [PATCH 2/3] rename column property --- Datatable/Column/AbstractColumn.php | 22 +++++++++++----------- Resources/doc/columns.md | 2 +- Response/DatatableQueryBuilder.php | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Datatable/Column/AbstractColumn.php b/Datatable/Column/AbstractColumn.php index fe5be778..e7e081d4 100644 --- a/Datatable/Column/AbstractColumn.php +++ b/Datatable/Column/AbstractColumn.php @@ -200,12 +200,12 @@ abstract class AbstractColumn implements ColumnInterface protected $joinType; /** - * With expression, if the column represents an association. + * Join conditions, if the column represents an association. * Default: null * * @var null|string */ - protected $withExpr; + protected $joinConditions; /** * The data type of the column. @@ -329,7 +329,7 @@ public function configureOptions(OptionsResolver $resolver) 'width' => null, 'add_if' => null, 'join_type' => 'leftJoin', - 'with_expr' => null, + 'join_conditions' => null, 'type_of_field' => null, 'responsive_priority' => null, )); @@ -350,7 +350,7 @@ public function configureOptions(OptionsResolver $resolver) $resolver->setAllowedTypes('width', array('null', 'string')); $resolver->setAllowedTypes('add_if', array('null', 'Closure')); $resolver->setAllowedTypes('join_type', 'string'); - $resolver->setAllowedTypes('with_expr', array('null', 'string')); + $resolver->setAllowedTypes('join_conditions', array('null', 'string')); $resolver->setAllowedTypes('type_of_field', array('null', 'string')); $resolver->setAllowedTypes('responsive_priority', array('null', 'int')); @@ -828,25 +828,25 @@ public function setJoinType($joinType) } /** - * Get WITH expression. + * Get join conditions. * * @return string */ - public function getWithExpr() + public function getJoinConditions() { - return $this->withExpr; + return $this->joinConditions; } /** - * Set WITH expression. + * Set join conditions. * - * @param string $withExpr + * @param string $joinConditions * * @return $this */ - public function setWithExpr($withExpr = null) + public function setJoinConditions($joinConditions = null) { - $this->withExpr = $withExpr; + $this->joinConditions = $joinConditions; return $this; } diff --git a/Resources/doc/columns.md b/Resources/doc/columns.md index db429430..d75cfeb0 100644 --- a/Resources/doc/columns.md +++ b/Resources/doc/columns.md @@ -43,7 +43,7 @@ With 'null' initialized options uses the default value of the DataTables plugin. | width | null or string | null | | Column width assignment. | | add_if | null or Closure | null | | Add column only if conditions are TRUE. | | join_type | string | 'leftJoin' | | Join type (default: 'leftJoin'), if the column represents an association. | -| with_expr | null or string | null | | WITH expression for join, if the column represents an association. | +| join_conditions | null or string | null | | Join conditions (using WITH), if the column represents an association. | | type_of_field | null or string | null (autodetect) | | Set the data type itself for ordering (example: integer instead string). | | responsive_priority | null or int | null | | Set column's visibility priority. Requires the Responsive extension. | | filter | array | TextFilter | | A Filter instance for individual filtering. | diff --git a/Response/DatatableQueryBuilder.php b/Response/DatatableQueryBuilder.php index 908462c2..1c9f38a9 100644 --- a/Response/DatatableQueryBuilder.php +++ b/Response/DatatableQueryBuilder.php @@ -255,7 +255,7 @@ private function initColumnArrays() $this->addSearchColumn($column, null, $searchDql); } elseif (true === $this->accessor->getValue($column, 'selectColumn')) { $parts = explode('.', $dql); - $withExpr = $this->accessor->getValue($column, 'withExpr'); + $withExpr = $this->accessor->getValue($column, 'joinConditions'); while (count($parts) > 1) { $previousPart = $currentPart; From 090889134e378d06d96029fd5bfa373f26317441 Mon Sep 17 00:00:00 2001 From: IT-Talents Date: Wed, 19 Sep 2018 15:19:59 +0200 Subject: [PATCH 3/3] add example --- Resources/doc/columns.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Resources/doc/columns.md b/Resources/doc/columns.md index d75cfeb0..ee415052 100644 --- a/Resources/doc/columns.md +++ b/Resources/doc/columns.md @@ -118,6 +118,7 @@ $this->columnBuilder 'data' => 'comments[,].title', 'searchable' => true, 'orderable' => true, + 'join_conditions' => 'comments.reviewed = 1', )) ; ```