From d1ee7f4353a8db0b3af0df3e463b4fc17e0fc01a Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 12 Sep 2018 18:17:17 +0200 Subject: [PATCH] =?UTF-8?q?N=C2=B0931:=20TagSet=20search=20(manage=20undef?= =?UTF-8?q?ined=20values)=20unit=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/oql/expression.class.inc.php | 23 +++++++++------- js/search/search_form_criteria_tag_set.js | 5 ++++ .../criteriontooql.class.inc.php | 22 ++++++++++++--- .../criteriontosearchform.class.inc.php | 27 +++++++++++++++++-- .../search/CriterionConversionTest.php | 11 +++++++- 5 files changed, 73 insertions(+), 15 deletions(-) diff --git a/core/oql/expression.class.inc.php b/core/oql/expression.class.inc.php index aff3bd7b3..acd2d233f 100644 --- a/core/oql/expression.class.inc.php +++ b/core/oql/expression.class.inc.php @@ -578,6 +578,7 @@ class BinaryExpression extends Expression * @param null $oAttDef * * @return array + * @throws \MissingQueryArgument */ public function GetCriterion($oSearch, &$aArgs = null, $bRetrofitParams = false, $oAttDef = null) { @@ -676,6 +677,10 @@ class BinaryExpression extends Expression } } } + if (isset($aCriteriaLeft['widget']) && isset($aCriteriaRight['widget']) && ($aCriteriaLeft['widget'] == AttributeDefinition::SEARCH_WIDGET_TYPE_TAG_SET) && ($aCriteriaRight['widget'] == AttributeDefinition::SEARCH_WIDGET_TYPE_TAG_SET)) + { + $aCriteriaOverride['operator'] = 'MATCHES'; + } } return array_merge($aCriteriaLeft, $aCriteriaRight, $aCriteriaOverride); @@ -886,20 +891,20 @@ class ScalarExpression extends UnaryExpression public function GetCriterion($oSearch, &$aArgs = null, $bRetrofitParams = false, $oAttDef = null) { - $aCriteria = array(); + $aCriterion = array(); switch ((string)($this->m_value)) { case '%Y-%m-%d': - $aCriteria['unit'] = 'DAY'; + $aCriterion['unit'] = 'DAY'; break; case '%Y-%m': - $aCriteria['unit'] = 'MONTH'; + $aCriterion['unit'] = 'MONTH'; break; case '%w': - $aCriteria['unit'] = 'WEEKDAY'; + $aCriterion['unit'] = 'WEEKDAY'; break; case '%H': - $aCriteria['unit'] = 'HOUR'; + $aCriterion['unit'] = 'HOUR'; break; default: $aValue = array(); @@ -938,7 +943,7 @@ class ScalarExpression extends UnaryExpression } else { - $aValue['label'] = Dict::S('Enum:Undefined'); + $aCriterion['has_undefined'] = true; } } catch (Exception $e) @@ -981,12 +986,12 @@ class ScalarExpression extends UnaryExpression { // only if a label is found $aValue['value'] = $this->GetValue(); - $aCriteria['values'] = array($aValue); + $aCriterion['values'] = array($aValue); } break; } - $aCriteria['oql'] = $this->RenderExpression(false, $aArgs, $bRetrofitParams); - return $aCriteria; + $aCriterion['oql'] = $this->RenderExpression(false, $aArgs, $bRetrofitParams); + return $aCriterion; } } diff --git a/js/search/search_form_criteria_tag_set.js b/js/search/search_form_criteria_tag_set.js index 999108ff8..0e77f7c3b 100644 --- a/js/search/search_form_criteria_tag_set.js +++ b/js/search/search_form_criteria_tag_set.js @@ -23,6 +23,11 @@ $(function() 'empty': null, // Remove as it will be handle by the "null" value in the "MATCHES" operator 'not_empty': null, // Remove as it will be handle by the "null" value in the "MATCHES" operator }, + // Null value + 'null_value': { + 'code': '', + 'label': Dict.S('Enum:Undefined'), + }, }, diff --git a/sources/application/search/criterionconversion/criteriontooql.class.inc.php b/sources/application/search/criterionconversion/criteriontooql.class.inc.php index 53c0bc90c..a97d8d2be 100644 --- a/sources/application/search/criterionconversion/criteriontooql.class.inc.php +++ b/sources/application/search/criterionconversion/criteriontooql.class.inc.php @@ -157,8 +157,7 @@ class CriterionToOQL extends CriterionConversionAbstract { $aValues = self::GetValues($aCriteria); $sValue = self::GetValue($aValues, 0); - - if (empty($sValue)) + if (empty($sValue) && (!(isset($aCriteria['has_undefined'])) || !($aCriteria['has_undefined']))) { return "1"; } @@ -183,17 +182,34 @@ class CriterionToOQL extends CriterionConversionAbstract { $aValues = self::GetValues($aCriteria); $aRawValues = array(); + $bHasUnDefined = isset($aCriteria['has_undefined']) ? $aCriteria['has_undefined'] : false; for($i = 0; $i < count($aValues); $i++) { - $aRawValues[] = self::GetValue($aValues, $i); + $sRawValue = self::GetValue($aValues, $i); + if (strlen($sRawValue) == 0) + { + $bHasUnDefined = true; + } + else + { + $aRawValues[] = $sRawValue; + } } $sValue = implode(' ', $aRawValues); if (empty($sValue)) { + if ($bHasUnDefined) + { + return "({$sRef} = '')"; + } return "1"; } + if ($bHasUnDefined) + { + return "((({$sRef} MATCHES '{$sValue}') OR ({$sRef} = '')) AND 1)"; + } return "({$sRef} MATCHES '{$sValue}')"; } diff --git a/sources/application/search/criterionconversion/criteriontosearchform.class.inc.php b/sources/application/search/criterionconversion/criteriontosearchform.class.inc.php index 484a99daa..5cdb07d95 100644 --- a/sources/application/search/criterionconversion/criteriontosearchform.class.inc.php +++ b/sources/application/search/criterionconversion/criteriontosearchform.class.inc.php @@ -674,8 +674,18 @@ class CriterionToSearchForm extends CriterionConversionAbstract { case 'MATCHES': // Nothing special to do + if (isset($aCriteria['has_undefined']) && $aCriteria['has_undefined']) + { + if (!isset($aCriteria['values'])) + { + $aCriteria['values'] = array(); + } + // Convention for 'undefined' tag set + $aCriteria['values'][] = array('value' => '', 'label' => Dict::S('Enum:Undefined')); + } break; + case 'OR': case 'ISNULL': $aCriteria['operator'] = CriterionConversionAbstract::OP_EQUALS; if (isset($aCriteria['has_undefined']) && $aCriteria['has_undefined']) @@ -684,8 +694,21 @@ class CriterionToSearchForm extends CriterionConversionAbstract { $aCriteria['values'] = array(); } - // Convention for 'undefined' enums - $aCriteria['values'][] = array('value' => 'null', 'label' => Dict::S('Enum:Undefined')); + // Convention for 'undefined' tag set + $aCriteria['values'][] = array('value' => '', 'label' => Dict::S('Enum:Undefined')); + } + break; + + case '=': + $aCriteria['operator'] = CriterionConversionAbstract::OP_EQUALS; + if (isset($aCriteria['has_undefined']) && $aCriteria['has_undefined']) + { + if (!isset($aCriteria['values'])) + { + $aCriteria['values'] = array(); + } + // Convention for 'undefined' tag set + $aCriteria['values'][] = array('value' => '', 'label' => Dict::S('Enum:Undefined')); } break; diff --git a/test/application/search/CriterionConversionTest.php b/test/application/search/CriterionConversionTest.php index 033714061..c041901f9 100644 --- a/test/application/search/CriterionConversionTest.php +++ b/test/application/search/CriterionConversionTest.php @@ -468,7 +468,16 @@ class CriterionConversionTest extends ItopDataTestCase 'ExpectedOQL' => "SELECT `UserRequest` FROM UserRequest AS `UserRequest` WHERE `UserRequest`.`tagfield` MATCHES 'tag1 tag2'", 'ExpectedCriterion' => array(array('widget' => 'tag_set')), ), - + 'TagSet Undefined' => array( + 'OQL' => "SELECT UserRequest WHERE tagfield = ''", + 'ExpectedOQL' => "SELECT `UserRequest` FROM UserRequest AS `UserRequest` WHERE (`UserRequest`.`tagfield` = '')", + 'ExpectedCriterion' => array(array('widget' => 'tag_set')), + ), + 'TagSet Undefined and tag' => array( + 'OQL' => "SELECT UserRequest WHERE (((tagfield MATCHES 'tag1 tag2') OR (tagfield = '')) AND 1)", + 'ExpectedOQL' => "SELECT `UserRequest` FROM UserRequest AS `UserRequest` WHERE ((`UserRequest`.`tagfield` MATCHES 'tag1 tag2' OR (`UserRequest`.`tagfield` = '')) AND 1)", + 'ExpectedCriterion' => array(array('widget' => 'tag_set')), + ), ); }