Advanced Search: remove the conversion IN <=> NOT IN for external keys

SVN:b1162[5564]
This commit is contained in:
Eric Espié
2018-03-29 08:45:46 +00:00
parent 11af11b3be
commit 155034092f
3 changed files with 57 additions and 31 deletions

View File

@@ -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;
}
}
}
}

View File

@@ -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

View File

@@ -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')",