diff --git a/.travis.yml b/.travis.yml
index dcc88843..ed5670b8 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,7 +2,13 @@ language: php
php:
- 5.3
+ - 5.4
- 5.5
+ - 7.0
+
+matrix:
+ allow_failures:
+ - php: 7.0
env:
- SYMFONY_VERSION=origin/master
@@ -11,7 +17,8 @@ before_script:
- curl -s http://getcomposer.org/installer | php
- php composer.phar install
-script: phpunit
+script:
+ - phpunit
notifications:
email:
diff --git a/Grid/Column/Column.php b/Grid/Column/Column.php
index df97a0d4..1d1bf0fc 100755
--- a/Grid/Column/Column.php
+++ b/Grid/Column/Column.php
@@ -37,6 +37,11 @@ abstract class Column
const OPERATOR_NLIKE = 'nlike';
const OPERATOR_RLIKE = 'rlike';
const OPERATOR_LLIKE = 'llike';
+ const OPERATOR_SLIKE = 'slike'; //simple/strict LIKE
+ const OPERATOR_NSLIKE = 'nslike';
+ const OPERATOR_RSLIKE = 'rslike';
+ const OPERATOR_LSLIKE = 'lslike';
+
const OPERATOR_ISNULL = 'isNull';
const OPERATOR_ISNOTNULL = 'isNotNull';
@@ -91,6 +96,7 @@ abstract class Column
protected $class;
protected $isManualField;
protected $isAggregate;
+ protected $usePrefixTitle;
protected $dataJunction = self::DATA_CONJUNCTION;
@@ -128,7 +134,8 @@ public function __initialize(array $params)
$this->setOperatorsVisible($this->getParam('operatorsVisible', true));
$this->setIsManualField($this->getParam('isManualField', false));
$this->setIsAggregate($this->getParam('isAggregate', false));
-
+ $this->setUsePrefixTitle($this->getParam('usePrefixTitle', true));
+
// Order is important for the order display
$this->setOperators($this->getParam('operators', array(
self::OPERATOR_EQ,
@@ -143,6 +150,10 @@ public function __initialize(array $params)
self::OPERATOR_NLIKE,
self::OPERATOR_RLIKE,
self::OPERATOR_LLIKE,
+ self::OPERATOR_SLIKE,
+ self::OPERATOR_NSLIKE,
+ self::OPERATOR_RSLIKE,
+ self::OPERATOR_LSLIKE,
self::OPERATOR_ISNULL,
self::OPERATOR_ISNOTNULL,
)));
@@ -611,12 +622,16 @@ public function getFilters($source)
case self::OPERATOR_LIKE:
case self::OPERATOR_RLIKE:
case self::OPERATOR_LLIKE:
+ case self::OPERATOR_SLIKE:
+ case self::OPERATOR_RSLIKE:
+ case self::OPERATOR_LSLIKE:
if ($this->getSelectMulti()) {
$this->setDataJunction(self::DATA_DISJUNCTION);
}
case self::OPERATOR_EQ:
case self::OPERATOR_NEQ:
case self::OPERATOR_NLIKE:
+ case self::OPERATOR_NSLIKE:
foreach ((array) $this->data['from'] as $value) {
$filters[] = new Filter($this->data['operator'], $value);
}
@@ -898,4 +913,18 @@ public function getIsAggregate()
{
return $this->isAggregate;
}
+
+ public function getUsePrefixTitle()
+ {
+ return $this->usePrefixTitle;
+ }
+
+ public function setUsePrefixTitle($usePrefixTitle)
+ {
+ $this->usePrefixTitle = $usePrefixTitle;
+ return $this;
+ }
+
+
+
}
diff --git a/Grid/Grid.php b/Grid/Grid.php
index 298509bd..b2f1e8fc 100644
--- a/Grid/Grid.php
+++ b/Grid/Grid.php
@@ -267,6 +267,12 @@ class Grid
* @var string
*/
protected $defaultTweak;
+
+ /**
+ * Filters in session
+ * @var array
+ */
+ protected $sessionFilters;
// Lazy parameters
protected $lazyAddColumn = array();
@@ -2002,4 +2008,90 @@ public function getRawData($columnNames = null, $namedIndexes = true)
return $result;
}
+
+ /**
+ * Returns an array of the active filters of the grid stored in session
+ *
+ * @return Filter[]
+ * @throws \Exception
+ */
+ public function getFilters()
+ {
+ if ($this->hash === null) {
+ throw new \Exception('getFilters method is only available in the manipulate callback function or after the call of the method isRedirected of the grid.');
+ }
+
+ if ($this->sessionFilters === null) {
+ $this->sessionFilters = array();
+ $session = $this->sessionData;
+
+ $requestQueries = array(
+ self::REQUEST_QUERY_MASS_ACTION_ALL_KEYS_SELECTED,
+ self::REQUEST_QUERY_MASS_ACTION,
+ self::REQUEST_QUERY_EXPORT,
+ self::REQUEST_QUERY_PAGE,
+ self::REQUEST_QUERY_LIMIT,
+ self::REQUEST_QUERY_ORDER,
+ self::REQUEST_QUERY_TEMPLATE,
+ self::REQUEST_QUERY_RESET
+ );
+
+ foreach ($requestQueries as $request_query) {
+ unset($session[$request_query]);
+ }
+
+ foreach ($session as $columnId => $sessionFilter) {
+ if (isset($sessionFilter['operator'])) {
+ $operator = $sessionFilter['operator'];
+ unset($sessionFilter['operator']);
+ } else {
+ $operator = $this->getColumn($columnId)->getDefaultOperator();
+ }
+
+ if (! isset($sessionFilter['to'])) {
+ $sessionFilter = $sessionFilter['from'];
+ }
+
+ $this->sessionFilters[$columnId] = new Filter($operator, $sessionFilter);
+ }
+ }
+
+ return $this->sessionFilters;
+ }
+
+ /**
+ * Returns the filter of a column stored in session
+ *
+ * @param string $columnId
+ * Id of the column
+ * @return Filter
+ * @throws \Exception
+ */
+ public function getFilter($columnId)
+ {
+ if ($this->hash === null) {
+ throw new \Exception('getFilters method is only available in the manipulate callback function or after the call of the method isRedirected of the grid.');
+ }
+
+ $sessionFilters = $this->getFilters();
+
+ return isset($sessionFilters[$columnId]) ? $sessionFilters[$columnId] : null;
+ }
+
+ /**
+ * A filter of the column is stored in session ?
+ *
+ * @param string $columnId
+ * Id of the column
+ * @return boolean
+ * @throws \Exception
+ */
+ public function hasFilter($columnId)
+ {
+ if ($this->hash === null) {
+ throw new \Exception('hasFilters method is only available in the manipulate callback function or after the call of the method isRedirected of the grid.');
+ }
+
+ return getFilter($columnId) !== null;
+ }
}
diff --git a/Grid/Source/Document.php b/Grid/Source/Document.php
index c9a73e67..bc6ed134 100644
--- a/Grid/Source/Document.php
+++ b/Grid/Source/Document.php
@@ -100,6 +100,10 @@ protected function normalizeOperator($operator)
case Column::OPERATOR_NLIKE:
case Column::OPERATOR_RLIKE:
case Column::OPERATOR_LLIKE:
+ case Column::OPERATOR_SLIKE:
+ case Column::OPERATOR_NSLIKE:
+ case Column::OPERATOR_RSLIKE:
+ case Column::OPERATOR_LSLIKE:
case Column::OPERATOR_NEQ:
return 'equals';
case Column::OPERATOR_ISNULL:
@@ -125,6 +129,14 @@ protected function normalizeValue($operator, $value)
return new \MongoRegex('/^'.$value.'/i');
case Column::OPERATOR_LLIKE:
return new \MongoRegex('/'.$value.'$/i');
+ case Column::OPERATOR_SLIKE:
+ return new \MongoRegex('/'.$value.'/');
+ case Column::OPERATOR_SLIKE:
+ return new \MongoRegex('/^((?!'.$value.').)*$/');
+ case Column::OPERATOR_RSLIKE:
+ return new \MongoRegex('/^'.$value.'/');
+ case Column::OPERATOR_LSLIKE:
+ return new \MongoRegex('/'.$value.'$/');
case Column::OPERATOR_ISNULL:
return false;
case Column::OPERATOR_ISNOTNULL:
@@ -249,6 +261,7 @@ public function getFieldsMetadata($class, $group = 'default')
if (isset($mapping['fieldName'])) {
$values['field'] = $mapping['fieldName'];
+ $values['id'] = $mapping['fieldName'];
}
if (isset($mapping['id']) && $mapping['id'] == 'id') {
@@ -281,6 +294,15 @@ public function getFieldsMetadata($class, $group = 'default')
case 'timestamp':
$values['type'] = 'date';
break;
+ case 'collection':
+ $values['type'] = 'array';
+ break;
+ case 'one':
+ $values['type'] = 'array';
+ break;
+ case 'many':
+ $values['type'] = 'array';
+ break;
default:
$values['type'] = 'text';
}
@@ -310,7 +332,7 @@ public function populateSelectFilters($columns, $loop = false)
// For negative operators, show all values
if ($selectFrom === 'query') {
foreach ($column->getFilters('document') as $filter) {
- if (in_array($filter->getOperator(), array(Column::OPERATOR_NEQ, Column::OPERATOR_NLIKE))) {
+ if (in_array($filter->getOperator(), array(Column::OPERATOR_NEQ, Column::OPERATOR_NLIKE,Column::OPERATOR_NSLIKE))) {
$selectFrom = 'source';
break;
}
diff --git a/Grid/Source/Entity.php b/Grid/Source/Entity.php
index 2f0258e0..ec1ad141 100644
--- a/Grid/Source/Entity.php
+++ b/Grid/Source/Entity.php
@@ -254,7 +254,11 @@ protected function normalizeOperator($operator)
case Column::OPERATOR_LLIKE:
case Column::OPERATOR_RLIKE:
case Column::OPERATOR_NLIKE:
- return 'like';
+ case Column::OPERATOR_SLIKE:
+ case Column::OPERATOR_LSLIKE:
+ case Column::OPERATOR_RSLIKE:
+ case Column::OPERATOR_NSLIKE:
+ return 'like';
default:
return $operator;
}
@@ -266,10 +270,14 @@ protected function normalizeValue($operator, $value)
//case Column::OPERATOR_REGEXP:
case Column::OPERATOR_LIKE:
case Column::OPERATOR_NLIKE:
+ case Column::OPERATOR_SLIKE:
+ case Column::OPERATOR_NSLIKE:
return "%$value%";
case Column::OPERATOR_LLIKE:
+ case Column::OPERATOR_LSLIKE:
return "%$value";
case Column::OPERATOR_RLIKE:
+ case Column::OPERATOR_RSLIKE:
return "$value%";
default:
return $value;
@@ -363,9 +371,16 @@ public function execute($columns, $page = 0, $limit = 0, $maxResults = null, $gr
$columnForFilter = ($column->getType() !== 'join') ? $column : $columnsById[$filter->getColumnName()];
- $q = $this->query->expr()->$operator($this->getFieldName($columnForFilter, false), "?$bindIndex");
+ $fieldName = $this->getFieldName($columnForFilter, false);
+ $bindIndexPlaceholder = "?$bindIndex";
+ if( in_array($filter->getOperator(), array(Column::OPERATOR_LIKE,Column::OPERATOR_RLIKE,Column::OPERATOR_LLIKE,Column::OPERATOR_NLIKE,))){
+ $fieldName = "LOWER($fieldName)";
+ $bindIndexPlaceholder = "LOWER($bindIndexPlaceholder)";
+ }
+
+ $q = $this->query->expr()->$operator($fieldName, $bindIndexPlaceholder);
- if ($filter->getOperator() == Column::OPERATOR_NLIKE) {
+ if ($filter->getOperator() == Column::OPERATOR_NLIKE || $filter->getOperator() == Column::OPERATOR_NSLIKE) {
$q = $this->query->expr()->not($q);
}
@@ -595,7 +610,7 @@ public function populateSelectFilters($columns, $loop = false)
// For negative operators, show all values
if ($selectFrom === 'query') {
foreach ($column->getFilters('entity') as $filter) {
- if (in_array($filter->getOperator(), array(Column::OPERATOR_NEQ, Column::OPERATOR_NLIKE))) {
+ if (in_array($filter->getOperator(), array(Column::OPERATOR_NEQ, Column::OPERATOR_NLIKE,Column::OPERATOR_NSLIKE))) {
$selectFrom = 'source';
break;
}
diff --git a/Grid/Source/Source.php b/Grid/Source/Source.php
index 7634bf79..56921bbb 100755
--- a/Grid/Source/Source.php
+++ b/Grid/Source/Source.php
@@ -288,6 +288,18 @@ public function executeFromData($columns, $page = 0, $limit = 0, $maxResults = n
case Column\Column::OPERATOR_RLIKE:
$value = '/^'.preg_quote($value, '/').'/i';
break;
+ case Column\Column::OPERATOR_SLIKE:
+ $value = '/'.preg_quote($value, '/').'/';
+ break;
+ case Column\Column::OPERATOR_NSLIKE:
+ $value = '/^((?!'.preg_quote($value, '/').').)*$/';
+ break;
+ case Column\Column::OPERATOR_LSLIKE:
+ $value = '/'.preg_quote($value, '/').'$/';
+ break;
+ case Column\Column::OPERATOR_RSLIKE:
+ $value = '/^'.preg_quote($value, '/').'/';
+ break;
}
}
@@ -307,6 +319,10 @@ public function executeFromData($columns, $page = 0, $limit = 0, $maxResults = n
case Column\Column::OPERATOR_NLIKE:
case Column\Column::OPERATOR_LLIKE:
case Column\Column::OPERATOR_RLIKE:
+ case Column\Column::OPERATOR_SLIKE:
+ case Column\Column::OPERATOR_NSLIKE:
+ case Column\Column::OPERATOR_LSLIKE:
+ case Column\Column::OPERATOR_RSLIKE:
$fieldValue = $this->prepareStringForLikeCompare($fieldValue, $column->getType());
$found = preg_match($value, $fieldValue);
@@ -455,7 +471,7 @@ public function populateSelectFiltersFromData($columns, $loop = false)
// For negative operators, show all values
if ($selectFrom === 'query') {
foreach ($column->getFilters('vector') as $filter) {
- if (in_array($filter->getOperator(), array(Column\Column::OPERATOR_NEQ, Column\Column::OPERATOR_NLIKE))) {
+ if (in_array($filter->getOperator(), array(Column\Column::OPERATOR_NEQ, Column\Column::OPERATOR_NLIKE,Column\Column::OPERATOR_NSLIKE))) {
$selectFrom = 'source';
break;
}
diff --git a/Resources/doc/columns_configuration/annotations/column_annotation_property.md b/Resources/doc/columns_configuration/annotations/column_annotation_property.md
index 4c369794..dd853bb3 100644
--- a/Resources/doc/columns_configuration/annotations/column_annotation_property.md
+++ b/Resources/doc/columns_configuration/annotations/column_annotation_property.md
@@ -64,7 +64,7 @@ class Product
|values|array|_none_||For select filters or replace values in the grid|
|searchOnClick|boolean|false|true or false|Sets the possibility to perform a search on the clicked cell (filterable has to be true)|
|safe|string or false|html|false
or
see [Escape filters](http://twig.sensiolabs.org/doc/filters/escape.html)|Sets the escape filter|
-
+|usePrefixTitle|boolean|true|true or false|Use the prefixTitle of the grid to render title|
**Note 1**: Every attribute has a setter and a getter method.
**Note 2**: With the `values` attributes, if `type1` is found, the grid displays the value `Type 1`.
**Note 3**: If operators are not visible, filtering is performed with the default operator.
diff --git a/Resources/doc/columns_configuration/filters/create_filter.md b/Resources/doc/columns_configuration/filters/create_filter.md
index f0865729..199c940e 100644
--- a/Resources/doc/columns_configuration/filters/create_filter.md
+++ b/Resources/doc/columns_configuration/filters/create_filter.md
@@ -4,6 +4,8 @@ Create a filter
If you want another filter than the input and the select filters you can create your own filter.
You just have to create your template for your filter and call it in the `filter` attribute of a column.
+**Note**: The name of your filter is converted to lowercase.
+
## Example with another input filter:
#### Create the template
@@ -56,4 +58,4 @@ $grid->setSource($source);
$grid->getColumn('description')->setFilterType('input2');
...
-```
\ No newline at end of file
+```
diff --git a/Resources/doc/columns_configuration/types/join_column.md b/Resources/doc/columns_configuration/types/join_column.md
index f2b2510c..ef74702a 100644
--- a/Resources/doc/columns_configuration/types/join_column.md
+++ b/Resources/doc/columns_configuration/types/join_column.md
@@ -63,10 +63,14 @@ Everything.
|lte|Lower than or equal to|
|gt|Greater than|
|gte|Greater than or equal to|
-|like|Contains|
-|nlike|Not contain|
-|rlike|Starts with|
-|llike|Ends with|
+|like|Contains (case insensitive)|
+|nlike|Not contain (case insensitive)|
+|rlike|Starts with (case insensitive)|
+|llike|Ends with (case insensitive)|
+|slike|Contains|
+|nslike|Not contain|
+|rslike|Starts with|
+|lslike|Ends with|
|btw|Between exclusive|
|btwe|Between inclusive|
|isNull|Is not defined|
diff --git a/Resources/doc/columns_configuration/types/text_column.md b/Resources/doc/columns_configuration/types/text_column.md
index 458e252e..f7091de7 100644
--- a/Resources/doc/columns_configuration/types/text_column.md
+++ b/Resources/doc/columns_configuration/types/text_column.md
@@ -27,10 +27,14 @@ Everything.
|lte|Lower than or equal to|
|gt|Greater than|
|gte|Greater than or equal to|
-|like|Contains|
-|nlike|Not contain|
-|rlike|Starts with|
-|llike|Ends with|
+|like|Contains (case insensitive)|
+|nlike|Not contain (case insensitive)|
+|rlike|Starts with (case insensitive)|
+|llike|Ends with (case insensitive)|
+|slike|Contains|
+|nslike|Not contain|
+|rslike|Starts with|
+|lslike|Ends with|
|btw|Between exclusive|
|btwe|Between inclusive|
|isNull|Is not defined|
diff --git a/Resources/doc/grid_configuration/set_columns_order.md b/Resources/doc/grid_configuration/set_columns_order.md
index ab3cff0c..fe598d67 100644
--- a/Resources/doc/grid_configuration/set_columns_order.md
+++ b/Resources/doc/grid_configuration/set_columns_order.md
@@ -31,7 +31,7 @@ The new order will be : Column2, Column5, Column1, Column3, Column4
```php
$userColumns = array('Column2', 'Column5', 'Column1');
-$grid->setColumnsOrder(userColumns, false);
+$grid->setColumnsOrder($userColumns, false);
```
The new order will be : Column2, Column5, Column1
diff --git a/Resources/doc/grid_configuration/set_default_filters.md b/Resources/doc/grid_configuration/set_default_filters.md
index 8319f0b1..d30823de 100644
--- a/Resources/doc/grid_configuration/set_default_filters.md
+++ b/Resources/doc/grid_configuration/set_default_filters.md
@@ -42,15 +42,23 @@ $grid->setDefaultFilters($filters);
|lte|Lower than or equal to|
|gt|Greater than|
|gte|Greater than or equal to|
-|like|Contains|
-|nlike|Not contain|
-|rlike|Starts with|
-|llike|Ends with|
+|like|Contains (case insensitive)|
+|nlike|Not contain (case insensitive)|
+|rlike|Starts with (case insensitive)|
+|llike|Ends with (case insensitive)|
+|slike|Contains|
+|nslike|Not contain|
+|rslike|Starts with|
+|lslike|Ends with|
|btw|Between exclusive|
|btwe|Between inclusive|
|isNull|Is not defined|
|isNotNull|Is defined|
+**Note**: LIKE filter is case insensitive by default, the resulting SQL query will look like `LOWER(column) LIKE LOWER(:criteria)`.
+
+SLIKE filter does not mean "case sensitive like", it is strict/simple LIKE so case sensitivity will depend of your RDBSM (collation, etc.).
+
## Example
```php
diff --git a/Resources/doc/grid_configuration/set_permanent_filters.md b/Resources/doc/grid_configuration/set_permanent_filters.md
index 2da80c0c..da1c0c9b 100644
--- a/Resources/doc/grid_configuration/set_permanent_filters.md
+++ b/Resources/doc/grid_configuration/set_permanent_filters.md
@@ -42,10 +42,14 @@ $grid->setPermanentFilters($filters);
|lte|Lower than or equal to|
|gt|Greater than|
|gte|Greater than or equal to|
-|like|Contains|
-|nlike|Not contain|
-|rlike|Starts with|
-|llike|Ends with|
+|like|Contains (case insensitive)|
+|nlike|Not contain (case insensitive)|
+|rlike|Starts with (case insensitive)|
+|llike|Ends with (case insensitive)|
+|slike|Contains|
+|nslike|Not contain|
+|rslike|Starts with|
+|lslike|Ends with|
|btw|Between exclusive|
|btwe|Between inclusive|
|isNull|Is not defined|
diff --git a/Resources/translations/messages.en.xliff b/Resources/translations/messages.en.xliff
index 3bc95ab6..11ba3946 100644
--- a/Resources/translations/messages.en.xliff
+++ b/Resources/translations/messages.en.xliff
@@ -67,6 +67,7 @@
%count% Result, |%count% Results,
+
+
+
+
+ Contains
+
+
+
+ Not contains
+
+
+
+ Starts with
+
+
+
+ Ends with
+