From d468d69bc6c1cb11c71b9913328bbda46e8fa424 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20K=C3=B6hler?= Date: Tue, 11 Jul 2017 10:07:03 +0200 Subject: [PATCH 1/4] - added case insensitive contains comparison --- .../Expr/ClosureExpressionVisitor.php | 32 ++++++++++++------- .../Common/Collections/Expr/Comparison.php | 1 + .../Common/Collections/ExpressionBuilder.php | 11 +++++++ .../Collections/ExpressionBuilderTest.php | 8 +++++ 4 files changed, 40 insertions(+), 12 deletions(-) diff --git a/lib/Doctrine/Common/Collections/Expr/ClosureExpressionVisitor.php b/lib/Doctrine/Common/Collections/Expr/ClosureExpressionVisitor.php index 2d2610149..a87066c5f 100644 --- a/lib/Doctrine/Common/Collections/Expr/ClosureExpressionVisitor.php +++ b/lib/Doctrine/Common/Collections/Expr/ClosureExpressionVisitor.php @@ -36,7 +36,7 @@ class ClosureExpressionVisitor extends ExpressionVisitor * method, __get, __call). * * @param object|array $object - * @param string $field + * @param string $field * * @return mixed */ @@ -51,7 +51,7 @@ public static function getObjectFieldValue($object, $field) foreach ($accessors as $accessor) { $accessor .= $field; - if ( ! method_exists($object, $accessor)) { + if (!method_exists($object, $accessor)) { continue; } @@ -74,13 +74,17 @@ public static function getObjectFieldValue($object, $field) } // camelcase field name to support different variable naming conventions - $ccField = preg_replace_callback('/_(.?)/', function($matches) { return strtoupper($matches[1]); }, $field); + $ccField = preg_replace_callback( + '/_(.?)/', function ($matches) { + return strtoupper($matches[1]); + }, $field + ); foreach ($accessors as $accessor) { $accessor .= $ccField; - if ( ! method_exists($object, $accessor)) { + if (!method_exists($object, $accessor)) { continue; } @@ -93,16 +97,16 @@ public static function getObjectFieldValue($object, $field) /** * Helper for sorting arrays of objects based on multiple fields + orientations. * - * @param string $name - * @param int $orientation + * @param string $name + * @param int $orientation * @param \Closure $next * * @return \Closure */ public static function sortByField($name, $orientation = 1, \Closure $next = null) { - if ( ! $next) { - $next = function() : int { + if (!$next) { + $next = function () : int { return 0; }; } @@ -165,10 +169,11 @@ public function walkComparison(Comparison $comparison) case Comparison::NIN: return function ($object) use ($field, $value) : bool { - return ! in_array(ClosureExpressionVisitor::getObjectFieldValue($object, $field), $value); + return !in_array(ClosureExpressionVisitor::getObjectFieldValue($object, $field), $value); }; case Comparison::CONTAINS: + case Comparison::CONTAINS_CI: return function ($object) use ($field, $value) { return false !== strpos(ClosureExpressionVisitor::getObjectFieldValue($object, $field), $value); }; @@ -179,6 +184,7 @@ public function walkComparison(Comparison $comparison) if (!is_array($fieldValues)) { $fieldValues = iterator_to_array($fieldValues); } + return in_array($value, $fieldValues); }; @@ -189,7 +195,9 @@ public function walkComparison(Comparison $comparison) case Comparison::ENDS_WITH: return function ($object) use ($field, $value) : bool { - return $value === substr(ClosureExpressionVisitor::getObjectFieldValue($object, $field), -strlen($value)); + return $value === substr( + ClosureExpressionVisitor::getObjectFieldValue($object, $field), -strlen($value) + ); }; @@ -217,7 +225,7 @@ public function walkCompositeExpression(CompositeExpression $expr) $expressionList[] = $this->dispatch($child); } - switch($expr->getType()) { + switch ($expr->getType()) { case CompositeExpression::TYPE_AND: return $this->andExpressions($expressionList); @@ -238,7 +246,7 @@ private function andExpressions(array $expressions) : callable { return function ($object) use ($expressions) : bool { foreach ($expressions as $expression) { - if ( ! $expression($object)) { + if (!$expression($object)) { return false; } } diff --git a/lib/Doctrine/Common/Collections/Expr/Comparison.php b/lib/Doctrine/Common/Collections/Expr/Comparison.php index 72fa5eb75..cf6d77928 100644 --- a/lib/Doctrine/Common/Collections/Expr/Comparison.php +++ b/lib/Doctrine/Common/Collections/Expr/Comparison.php @@ -37,6 +37,7 @@ class Comparison implements Expression const IN = 'IN'; const NIN = 'NIN'; const CONTAINS = 'CONTAINS'; + const CONTAINS_CI = 'CONTAINS_CI'; const MEMBER_OF = 'MEMBER_OF'; const STARTS_WITH = 'STARTS_WITH'; const ENDS_WITH = 'ENDS_WITH'; diff --git a/lib/Doctrine/Common/Collections/ExpressionBuilder.php b/lib/Doctrine/Common/Collections/ExpressionBuilder.php index 1a44a7ba8..69944bea5 100644 --- a/lib/Doctrine/Common/Collections/ExpressionBuilder.php +++ b/lib/Doctrine/Common/Collections/ExpressionBuilder.php @@ -164,6 +164,17 @@ public function contains($field, $value) return new Comparison($field, Comparison::CONTAINS, new Value($value)); } + /** + * @param string $field + * @param mixed $value + * + * @return Comparison + */ + public function containsCi($field, $value) + { + return new Comparison($field, Comparison::CONTAINS_CI, new Value($value)); + } + /** * @param string $field * @param mixed $value diff --git a/tests/Doctrine/Tests/Common/Collections/ExpressionBuilderTest.php b/tests/Doctrine/Tests/Common/Collections/ExpressionBuilderTest.php index 4688cc0d4..974bcd72a 100644 --- a/tests/Doctrine/Tests/Common/Collections/ExpressionBuilderTest.php +++ b/tests/Doctrine/Tests/Common/Collections/ExpressionBuilderTest.php @@ -123,6 +123,14 @@ public function testContains() : void $this->assertEquals(Comparison::CONTAINS, $expr->getOperator()); } + public function testContainsCi() : void + { + $expr = $this->builder->containsCi("a", "b"); + + $this->assertInstanceOf(Comparison::class, $expr); + $this->assertEquals(Comparison::CONTAINS_CI, $expr->getOperator()); + } + public function testMemberOf() : void { $expr = $this->builder->memberOf("b", ["a"]); From 6de7e7ce5e3b0f5d50b5152366efbb9e721db212 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20K=C3=B6hler?= Date: Tue, 11 Jul 2017 15:36:05 +0200 Subject: [PATCH 2/4] - undo some auto formatting --- .../Expr/ClosureExpressionVisitor.php | 31 +++++++------------ 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/lib/Doctrine/Common/Collections/Expr/ClosureExpressionVisitor.php b/lib/Doctrine/Common/Collections/Expr/ClosureExpressionVisitor.php index a87066c5f..a9426368c 100644 --- a/lib/Doctrine/Common/Collections/Expr/ClosureExpressionVisitor.php +++ b/lib/Doctrine/Common/Collections/Expr/ClosureExpressionVisitor.php @@ -36,7 +36,7 @@ class ClosureExpressionVisitor extends ExpressionVisitor * method, __get, __call). * * @param object|array $object - * @param string $field + * @param string $field * * @return mixed */ @@ -51,7 +51,7 @@ public static function getObjectFieldValue($object, $field) foreach ($accessors as $accessor) { $accessor .= $field; - if (!method_exists($object, $accessor)) { + if ( ! method_exists($object, $accessor)) { continue; } @@ -74,17 +74,13 @@ public static function getObjectFieldValue($object, $field) } // camelcase field name to support different variable naming conventions - $ccField = preg_replace_callback( - '/_(.?)/', function ($matches) { - return strtoupper($matches[1]); - }, $field - ); + $ccField = preg_replace_callback('/_(.?)/', function($matches) { return strtoupper($matches[1]); }, $field); foreach ($accessors as $accessor) { $accessor .= $ccField; - if (!method_exists($object, $accessor)) { + if ( ! method_exists($object, $accessor)) { continue; } @@ -97,16 +93,16 @@ public static function getObjectFieldValue($object, $field) /** * Helper for sorting arrays of objects based on multiple fields + orientations. * - * @param string $name - * @param int $orientation + * @param string $name + * @param int $orientation * @param \Closure $next * * @return \Closure */ public static function sortByField($name, $orientation = 1, \Closure $next = null) { - if (!$next) { - $next = function () : int { + if ( ! $next) { + $next = function() : int { return 0; }; } @@ -169,7 +165,7 @@ public function walkComparison(Comparison $comparison) case Comparison::NIN: return function ($object) use ($field, $value) : bool { - return !in_array(ClosureExpressionVisitor::getObjectFieldValue($object, $field), $value); + return ! in_array(ClosureExpressionVisitor::getObjectFieldValue($object, $field), $value); }; case Comparison::CONTAINS: @@ -184,7 +180,6 @@ public function walkComparison(Comparison $comparison) if (!is_array($fieldValues)) { $fieldValues = iterator_to_array($fieldValues); } - return in_array($value, $fieldValues); }; @@ -195,9 +190,7 @@ public function walkComparison(Comparison $comparison) case Comparison::ENDS_WITH: return function ($object) use ($field, $value) : bool { - return $value === substr( - ClosureExpressionVisitor::getObjectFieldValue($object, $field), -strlen($value) - ); + return $value === substr(ClosureExpressionVisitor::getObjectFieldValue($object, $field), -strlen($value)); }; @@ -225,7 +218,7 @@ public function walkCompositeExpression(CompositeExpression $expr) $expressionList[] = $this->dispatch($child); } - switch ($expr->getType()) { + switch($expr->getType()) { case CompositeExpression::TYPE_AND: return $this->andExpressions($expressionList); @@ -246,7 +239,7 @@ private function andExpressions(array $expressions) : callable { return function ($object) use ($expressions) : bool { foreach ($expressions as $expression) { - if (!$expression($object)) { + if ( ! $expression($object)) { return false; } } From 91e8c960b367f5430fec9ec6bbe4239e10df67eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20K=C3=B6hler?= Date: Thu, 13 Jul 2017 09:31:03 +0200 Subject: [PATCH 3/4] - renamed function to iContains and const to ICONTAINS - fixed closure --- .../Common/Collections/Expr/ClosureExpressionVisitor.php | 6 +++++- lib/Doctrine/Common/Collections/Expr/Comparison.php | 2 +- lib/Doctrine/Common/Collections/ExpressionBuilder.php | 4 ++-- .../Tests/Common/Collections/ExpressionBuilderTest.php | 6 +++--- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/lib/Doctrine/Common/Collections/Expr/ClosureExpressionVisitor.php b/lib/Doctrine/Common/Collections/Expr/ClosureExpressionVisitor.php index a9426368c..b913e85a7 100644 --- a/lib/Doctrine/Common/Collections/Expr/ClosureExpressionVisitor.php +++ b/lib/Doctrine/Common/Collections/Expr/ClosureExpressionVisitor.php @@ -169,11 +169,15 @@ public function walkComparison(Comparison $comparison) }; case Comparison::CONTAINS: - case Comparison::CONTAINS_CI: return function ($object) use ($field, $value) { return false !== strpos(ClosureExpressionVisitor::getObjectFieldValue($object, $field), $value); }; + case Comparison::ICONTAINS: + return function ($object) use ($field, $value) { + return false !== strpos(mb_strtolower(ClosureExpressionVisitor::getObjectFieldValue($object, $field)), mb_strtolower($value)); + }; + case Comparison::MEMBER_OF: return function ($object) use ($field, $value) : bool { $fieldValues = ClosureExpressionVisitor::getObjectFieldValue($object, $field); diff --git a/lib/Doctrine/Common/Collections/Expr/Comparison.php b/lib/Doctrine/Common/Collections/Expr/Comparison.php index cf6d77928..6502b6969 100644 --- a/lib/Doctrine/Common/Collections/Expr/Comparison.php +++ b/lib/Doctrine/Common/Collections/Expr/Comparison.php @@ -37,7 +37,7 @@ class Comparison implements Expression const IN = 'IN'; const NIN = 'NIN'; const CONTAINS = 'CONTAINS'; - const CONTAINS_CI = 'CONTAINS_CI'; + const ICONTAINS = 'ICONTAINS'; const MEMBER_OF = 'MEMBER_OF'; const STARTS_WITH = 'STARTS_WITH'; const ENDS_WITH = 'ENDS_WITH'; diff --git a/lib/Doctrine/Common/Collections/ExpressionBuilder.php b/lib/Doctrine/Common/Collections/ExpressionBuilder.php index 69944bea5..78d262770 100644 --- a/lib/Doctrine/Common/Collections/ExpressionBuilder.php +++ b/lib/Doctrine/Common/Collections/ExpressionBuilder.php @@ -170,9 +170,9 @@ public function contains($field, $value) * * @return Comparison */ - public function containsCi($field, $value) + public function iContains($field, $value) { - return new Comparison($field, Comparison::CONTAINS_CI, new Value($value)); + return new Comparison($field, Comparison::ICONTAINS, new Value($value)); } /** diff --git a/tests/Doctrine/Tests/Common/Collections/ExpressionBuilderTest.php b/tests/Doctrine/Tests/Common/Collections/ExpressionBuilderTest.php index 974bcd72a..c1730509e 100644 --- a/tests/Doctrine/Tests/Common/Collections/ExpressionBuilderTest.php +++ b/tests/Doctrine/Tests/Common/Collections/ExpressionBuilderTest.php @@ -123,12 +123,12 @@ public function testContains() : void $this->assertEquals(Comparison::CONTAINS, $expr->getOperator()); } - public function testContainsCi() : void + public function testIContains() : void { - $expr = $this->builder->containsCi("a", "b"); + $expr = $this->builder->iContains("a", "b"); $this->assertInstanceOf(Comparison::class, $expr); - $this->assertEquals(Comparison::CONTAINS_CI, $expr->getOperator()); + $this->assertEquals(Comparison::ICONTAINS, $expr->getOperator()); } public function testMemberOf() : void From 3e8153c724b527827caf6e583519187756d4fcd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20K=C3=B6hler?= Date: Mon, 17 Jul 2017 09:06:43 +0200 Subject: [PATCH 4/4] - added ext-mbstring to suggest section --- composer.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/composer.json b/composer.json index b42dbb9b1..845db5505 100644 --- a/composer.json +++ b/composer.json @@ -31,5 +31,8 @@ "branch-alias": { "dev-master": "1.3.x-dev" } + }, + "suggest": { + "ext-mbstring": "Only required when ICONTAINS comparison is used" } }