public function isValid(array $data, Filter $filter) { $logicalValidationSum = 0; $lastLogicalOperator = null; foreach ($filter->getOperators() as $operator) { if ($operator instanceof ComparisonOperatorInterface) { $handler = $this->handlerFactory->getHandler($operator); /** * This is based on the idea that boolean will be cast to integer (TRUE -> 1 and FALSE -> 0) * and that the operator 'AND' represents the mathematical '*' and 'OR' represents '+'. * This will happen for example: (TRUE and FALSE or TRUE and TRUE) -> (1 * 0 + 1 * 1) = 1 */ $currentValidation = (int) $handler->doesMatch($this->getValue($operator->getField(), $data)); if ($lastLogicalOperator === Names::LOGICAL_OR) { $logicalValidationSum = $logicalValidationSum + $currentValidation; } elseif ($lastLogicalOperator === Names::LOGICAL_AND) { $logicalValidationSum = $logicalValidationSum * $currentValidation; } elseif ($lastLogicalOperator === null) { $logicalValidationSum = $currentValidation; } } if ($operator instanceof AbstractLogicalOperator) { $lastLogicalOperator = $operator->getName(); } if ($lastLogicalOperator === Names::LOGICAL_OR && $logicalValidationSum >= 1) { return true; } } return $logicalValidationSum >= 1 || count($filter->getOperators()) === 0; }
/** * @expectedException ABK\QueryBundle\Filter\Exceptions\InvalidArgumentException */ public function testGetHandlerThrowsExceptionWithNotRegisteredHandlers() { $this->operatorMock = $this->getMockBuilder('ABK\\QueryBundle\\Filter\\Operators\\OperatorInterface')->disableOriginalConstructor()->getMock(); $this->operatorMock->expects($this->any())->method('getName')->will($this->returnValue('FALSE_NAME')); $this->operatorMock->expects($this->any())->method('getType')->will($this->returnValue('FALSE_TYPE')); $this->subject->getHandler($this->operatorMock); }