From 155034092f99b28e29fd753a024eb61a1f9bc280 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20Espi=C3=A9?= Date: Thu, 29 Mar 2018 08:45:46 +0000 Subject: [PATCH] Advanced Search: remove the conversion IN <=> NOT IN for external keys SVN:b1162[5564] --- .../criteriontooql.class.inc.php | 58 ++++++++++--------- .../criteriontosearchform.class.inc.php | 28 ++++++++- .../search/CriterionConversionTest.php | 2 +- 3 files changed, 57 insertions(+), 31 deletions(-) diff --git a/sources/application/search/criterionconversion/criteriontooql.class.inc.php b/sources/application/search/criterionconversion/criteriontooql.class.inc.php index 4171538d6..6c237df07 100644 --- a/sources/application/search/criterionconversion/criteriontooql.class.inc.php +++ b/sources/application/search/criterionconversion/criteriontooql.class.inc.php @@ -26,6 +26,7 @@ namespace Combodo\iTop\Application\Search\CriterionConversion; use AttributeDate; use AttributeDateTime; use AttributeDefinition; +use AttributeEnum; use Combodo\iTop\Application\Search\AjaxSearchException; use Combodo\iTop\Application\Search\CriterionConversionAbstract; use Combodo\iTop\Application\Search\SearchForm; @@ -155,42 +156,45 @@ class CriterionToOQL extends CriterionConversionAbstract if (array_key_exists($sAttCode, $aAttributeDefs)) { $oAttDef = $aAttributeDefs[$sAttCode]; - $aAllowedValues = SearchForm::GetFieldAllowedValues($oAttDef); - if (array_key_exists('values', $aAllowedValues)) + if ($oAttDef instanceof AttributeEnum) { - // Can't invert the test if NULL is allowed - if (!$oAttDef->IsNullAllowed()) + $aAllowedValues = SearchForm::GetFieldAllowedValues($oAttDef); + if (array_key_exists('values', $aAllowedValues)) { - $aAllowedValues = $aAllowedValues['values']; - if (count($aValues) == count($aAllowedValues)) + // Can't invert the test if NULL is allowed + if (!$oAttDef->IsNullAllowed()) { - // All entries are selected - return "1"; - } - // more selected values than remaining so use NOT IN - else - { - if (count($aValues) > (count($aAllowedValues) / 2)) + $aAllowedValues = $aAllowedValues['values']; + if (count($aValues) == count($aAllowedValues)) { - foreach($aValues as $aValue) + // All entries are selected + return "1"; + } + // more selected values than remaining so use NOT IN + else + { + if (count($aValues) > (count($aAllowedValues) / 2)) { - unset($aAllowedValues[$aValue['value']]); - } - $sInList = implode("','", array_keys($aAllowedValues)); + foreach($aValues as $aValue) + { + unset($aAllowedValues[$aValue['value']]); + } + $sInList = implode("','", array_keys($aAllowedValues)); - return "({$sRef} NOT IN ('$sInList'))"; + return "({$sRef} NOT IN ('$sInList'))"; + } } } - } - // search for "undefined" - for ($i = 0; $i < count($aValues); $i++) - { - $aValue = $aValues[$i]; - if (isset($aValue['value']) && ($aValue['value'] === 'null')) + // search for "undefined" + for($i = 0; $i < count($aValues); $i++) { - $bFilterOnUndefined = true; - unset($aValues[$i]); - break; + $aValue = $aValues[$i]; + if (isset($aValue['value']) && ($aValue['value'] === 'null')) + { + $bFilterOnUndefined = true; + unset($aValues[$i]); + break; + } } } } diff --git a/sources/application/search/criterionconversion/criteriontosearchform.class.inc.php b/sources/application/search/criterionconversion/criteriontosearchform.class.inc.php index 88779f228..666538b28 100644 --- a/sources/application/search/criterionconversion/criteriontosearchform.class.inc.php +++ b/sources/application/search/criterionconversion/criteriontosearchform.class.inc.php @@ -68,7 +68,7 @@ class CriterionToSearchForm extends CriterionConversionAbstract AttributeDefinition::SEARCH_WIDGET_TYPE_NUMERIC => 'NumericToSearchForm', AttributeDefinition::SEARCH_WIDGET_TYPE_EXTERNAL_KEY => 'ExternalKeyToSearchForm', AttributeDefinition::SEARCH_WIDGET_TYPE_HIERARCHICAL_KEY => 'ExternalKeyToSearchForm', - AttributeDefinition::SEARCH_WIDGET_TYPE_ENUM => 'ExternalKeyToSearchForm', + AttributeDefinition::SEARCH_WIDGET_TYPE_ENUM => 'EnumToSearchForm', ); foreach($aAndCriterionRaw as $aCriteria) @@ -93,6 +93,7 @@ class CriterionToSearchForm extends CriterionConversionAbstract // Check criteria validity if (!isset($aCriteria['ref']) || !isset($aAllFields[$aCriteria['ref']])) { + $aCriteria['widget'] = AttributeDefinition::SEARCH_WIDGET_TYPE_RAW; $aCriteria['label'] = Dict::S('UI:Search:Criteria:Raw:Filtered'); if (isset($aCriteria['ref'])) { @@ -492,8 +493,7 @@ class CriterionToSearchForm extends CriterionConversionAbstract return $aCriteria; } - - protected static function ExternalKeyToSearchForm($aCriteria, $aFields) + protected static function EnumToSearchForm($aCriteria, $aFields) { $sOperator = $aCriteria['operator']; switch ($sOperator) @@ -503,6 +503,7 @@ class CriterionToSearchForm extends CriterionConversionAbstract $aCriteria['operator'] = CriterionConversionAbstract::OP_IN; break; case 'NOT IN': + case 'NOTIN': case '!=': // Same as NOT IN $aCriteria = self::RevertValues($aCriteria, $aFields); @@ -533,6 +534,27 @@ class CriterionToSearchForm extends CriterionConversionAbstract return $aCriteria; } + protected static function ExternalKeyToSearchForm($aCriteria, $aFields) + { + $sOperator = $aCriteria['operator']; + switch ($sOperator) + { + case '=': + // Same as IN + $aCriteria['operator'] = CriterionConversionAbstract::OP_IN; + break; + case 'IN': + // Nothing special to do + break; + default: + // Unknown operator + $aCriteria['widget'] = AttributeDefinition::SEARCH_WIDGET_TYPE_RAW; + break; + } + + return $aCriteria; + } + /** * @param $aCriteria * @param $aFields diff --git a/test/application/search/CriterionConversionTest.php b/test/application/search/CriterionConversionTest.php index dcdf33e7f..777f3e2f9 100644 --- a/test/application/search/CriterionConversionTest.php +++ b/test/application/search/CriterionConversionTest.php @@ -431,7 +431,7 @@ class CriterionConversionTest extends ItopDataTestCase 'key NOT IN' => array( 'OQL' => "SELECT Contact WHERE org_id NOT IN ('1')", 'ExpectedOQL' => "SELECT `Contact` FROM Contact AS `Contact` WHERE (`Contact`.`org_id` NOT IN ('1'))", - 'ExpectedCriterion' => array(array('widget' => 'hierarchical_key', 'operator' => 'IN')), + 'ExpectedCriterion' => array(array('widget' => 'raw', 'operator' => 'NOT IN')), ), 'key IN' => array( 'OQL' => "SELECT Contact WHERE org_id IN ('1')",