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, + + + + slike + Contains + + + nslike + Not contains + + + rslike + Starts with + + + lslike + Ends with + \ No newline at end of file diff --git a/Resources/translations/messages.fr.xliff b/Resources/translations/messages.fr.xliff index 7a525cf2..3412fce7 100644 --- a/Resources/translations/messages.fr.xliff +++ b/Resources/translations/messages.fr.xliff @@ -125,7 +125,23 @@ Order by Trier par - + + + slike + Contient + + + nslike + Ne contient pas + + + rslike + Commence par + + + lslike + Finit par + diff --git a/Resources/translations/messages.nl.xliff b/Resources/translations/messages.nl.xliff index 09c86853..eca168ba 100644 --- a/Resources/translations/messages.nl.xliff +++ b/Resources/translations/messages.nl.xliff @@ -2,6 +2,54 @@ + + Page + Pagina + + + , Display + , Toon + + + of %count% + van %count% + + + Items per page + Items per pagina + + + Select visible + Selecteer zichtbare + + + Select all + Selecteer alle + + + Deselect visible + Wis zichtbare + + + Deselect all + Wis alle + + + Action + Actie + + + Submit Action + Actie toepassen + + + From: + Van: + + + To: + Tot: + eq Gelijk aan diff --git a/Resources/translations/messages.pl.xliff b/Resources/translations/messages.pl.xliff index 35549a23..2be9d822 100644 --- a/Resources/translations/messages.pl.xliff +++ b/Resources/translations/messages.pl.xliff @@ -2,6 +2,71 @@ + + eq + Równe + + + neq + Różne niż + + + lt + Mniejsze niż + + + lte + Mniejsze lub równe + + + gt + Większe niż + + + gte + Większe lub równe + + + req + Wyrażenie regularne + + + like + Stała + + + nlike + Zmienna + + + rlike + Zaczynające się + + + llike + Kończące się + + + btw + Pomiędzy bez + + + btwe + Pomiędzy z + + + isNull + Puste + + + isNotNull + Niepuste + + + %count% Results, + %count% Wynik, |%count% Wyników, + + Page Strona @@ -52,4 +117,4 @@ - \ No newline at end of file + diff --git a/Resources/views/blocks.html.twig b/Resources/views/blocks.html.twig index 5d38ba2f..e9230061 100644 --- a/Resources/views/blocks.html.twig +++ b/Resources/views/blocks.html.twig @@ -64,10 +64,14 @@ {%- spaceless %} {% if column.type == 'massaction' %} - {% else %} - {% set columnTitle = grid.prefixTitle ~ column.title ~ '__abbr' %} - {% if columnTitle|trans == columnTitle %} - {% set columnTitle = grid.prefixTitle ~ column.title %} + {% else %} + {% if column.usePrefixTitle == true %} + {% set columnTitle = grid.prefixTitle ~ column.title ~ '__abbr' %} + {% if columnTitle|trans == columnTitle %} + {% set columnTitle = grid.prefixTitle ~ column.title %} + {% endif %} + {% else %} + {% set columnTitle = column.title %} {% endif %} {% if (column.sortable) %} {{ columnTitle|trans }} @@ -103,7 +107,11 @@