mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-21 09:38:48 +02:00
Advanced Search: Field List
SVN:b1162[5417]
This commit is contained in:
@@ -24,6 +24,7 @@ namespace Combodo\iTop\Application\Search\CriterionConversion;
|
||||
|
||||
|
||||
use Combodo\iTop\Application\Search\CriterionConversionAbstract;
|
||||
use Combodo\iTop\Application\Search\SearchForm;
|
||||
|
||||
class CriterionToOQL extends CriterionConversionAbstract
|
||||
{
|
||||
@@ -50,6 +51,7 @@ class CriterionToOQL extends CriterionConversionAbstract
|
||||
self::OP_ENDS_WITH => 'EndsWithToOql',
|
||||
self::OP_EMPTY => 'EmptyToOql',
|
||||
self::OP_NOT_EMPTY => 'NotEmptyToOql',
|
||||
self::OP_IN => 'InToOql',
|
||||
self::OP_ALL => 'AllToOql',
|
||||
);
|
||||
|
||||
@@ -57,7 +59,7 @@ class CriterionToOQL extends CriterionConversionAbstract
|
||||
{
|
||||
$sFct = $aMappedOperators[$sOperator];
|
||||
|
||||
return self::$sFct($sRef, $sOperator, self::GetValues($aCriteria));
|
||||
return self::$sFct($sRef, $sOperator, $aCriteria);
|
||||
}
|
||||
|
||||
$sValue = self::GetValue(self::GetValues($aCriteria), 0);
|
||||
@@ -87,38 +89,72 @@ class CriterionToOQL extends CriterionConversionAbstract
|
||||
return $aValues[$iIndex]['value'];
|
||||
}
|
||||
|
||||
protected static function ContainsToOql($sRef, $sOperator, $aValues)
|
||||
protected static function ContainsToOql($sRef, $sOperator, $aCriteria)
|
||||
{
|
||||
$aValues = self::GetValues($aCriteria);
|
||||
$sValue = self::GetValue($aValues, 0);
|
||||
|
||||
return "({$sRef} LIKE '%{$sValue}%')";
|
||||
}
|
||||
|
||||
protected static function StartsWithToOql($sRef, $sOperator, $aValues)
|
||||
protected static function StartsWithToOql($sRef, $sOperator, $aCriteria)
|
||||
{
|
||||
$aValues = self::GetValues($aCriteria);
|
||||
$sValue = self::GetValue($aValues, 0);
|
||||
|
||||
return "({$sRef} LIKE '{$sValue}%')";
|
||||
}
|
||||
|
||||
protected static function EndsWithToOql($sRef, $sOperator, $aValues)
|
||||
protected static function EndsWithToOql($sRef, $sOperator, $aCriteria)
|
||||
{
|
||||
$aValues = self::GetValues($aCriteria);
|
||||
$sValue = self::GetValue($aValues, 0);
|
||||
|
||||
return "({$sRef} LIKE '%{$sValue}')";
|
||||
}
|
||||
|
||||
protected static function EmptyToOql($sRef, $sOperator, $aValues)
|
||||
protected static function EmptyToOql($sRef, $sOperator, $aCriteria)
|
||||
{
|
||||
return "({$sRef} = '')";
|
||||
}
|
||||
|
||||
protected static function NotEmptyToOql($sRef, $sOperator, $aValues)
|
||||
protected static function NotEmptyToOql($sRef, $sOperator, $aCriteria)
|
||||
{
|
||||
return "({$sRef} != '')";
|
||||
}
|
||||
|
||||
protected static function AllToOql($sRef, $sOperator, $aValues)
|
||||
protected static function InToOql($sRef, $sOperator, $aCriteria)
|
||||
{
|
||||
$sAttCode = $aCriteria['code'];
|
||||
$sClass = $aCriteria['class'];
|
||||
$aValues = $aCriteria['values'];
|
||||
|
||||
$aAttributeDefs = MetaModel::ListAttributeDefs($sClass);
|
||||
if (array_key_exists($sAttCode, $aAttributeDefs))
|
||||
{
|
||||
$oAttDef = $aAttributeDefs[$sAttCode];
|
||||
$aAllowedValues = SearchForm::GetFieldAllowedValues($oAttDef);
|
||||
if (array_key_exists('values', $aAllowedValues))
|
||||
{
|
||||
$aAllowedValues = $aAllowedValues['values'];
|
||||
// more selected values than remaining so use NOT IN
|
||||
if (count($aValues) > (count($aAllowedValues) / 2))
|
||||
{
|
||||
foreach($aValues as $aValue)
|
||||
{
|
||||
unset($aAllowedValues[$aValue['value']]);
|
||||
}
|
||||
$sOQL = "({$sRef} NOT IN (";
|
||||
$s .= implode(',', array_keys($aAllowedValues));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "({$sRef} != '')";
|
||||
}
|
||||
|
||||
protected static function AllToOql($sRef, $sOperator, $aCriteria)
|
||||
{
|
||||
return "1";
|
||||
}
|
||||
|
||||
@@ -20,22 +20,33 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Convert OQL expressions into structure for the search form
|
||||
* Convert structures from OQL expressions into structure for the search form
|
||||
*/
|
||||
namespace Combodo\iTop\Application\Search\CriterionConversion;
|
||||
|
||||
|
||||
use AttributeString;
|
||||
use AttributeDefinition;
|
||||
use Combodo\iTop\Application\Search\CriterionConversionAbstract;
|
||||
|
||||
class CriterionToSearchForm extends CriterionConversionAbstract
|
||||
{
|
||||
|
||||
public static function Convert($aAndCriterionRaw)
|
||||
public static function Convert($aAndCriterionRaw, $aFieldsByCategory)
|
||||
{
|
||||
$aAllFields = array();
|
||||
foreach($aFieldsByCategory as $aFields)
|
||||
{
|
||||
foreach($aFields as $aField)
|
||||
{
|
||||
$sAlias = $aField['class_alias'];
|
||||
$sCode = $aField['code'];
|
||||
$aAllFields["$sAlias.$sCode"] = $aField;
|
||||
}
|
||||
}
|
||||
$aAndCriterion = array();
|
||||
$aMappingOperatorToFunction = array(
|
||||
AttributeString::SEARCH_WIDGET_TYPE => 'TextToSearchForm',
|
||||
AttributeDefinition::SEARCH_WIDGET_TYPE_STRING => 'TextToSearchForm',
|
||||
AttributeDefinition::SEARCH_WIDGET_TYPE_ENUM => 'EnumToSearchForm',
|
||||
);
|
||||
|
||||
foreach($aAndCriterionRaw as $aCriteria)
|
||||
@@ -45,7 +56,7 @@ class CriterionToSearchForm extends CriterionConversionAbstract
|
||||
if (array_key_exists($aCriteria['widget'], $aMappingOperatorToFunction))
|
||||
{
|
||||
$sFct = $aMappingOperatorToFunction[$aCriteria['widget']];
|
||||
$aAndCriterion[] = self::$sFct($aCriteria);
|
||||
$aAndCriterion[] = self::$sFct($aCriteria, $aAllFields);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -62,7 +73,7 @@ class CriterionToSearchForm extends CriterionConversionAbstract
|
||||
return $aAndCriterion;
|
||||
}
|
||||
|
||||
protected static function TextToSearchForm($aCriteria)
|
||||
protected static function TextToSearchForm($aCriteria, $aFields)
|
||||
{
|
||||
$sOperator = $aCriteria['operator'];
|
||||
$sValue = $aCriteria['values'][0]['value'];
|
||||
@@ -100,4 +111,43 @@ class CriterionToSearchForm extends CriterionConversionAbstract
|
||||
|
||||
return $aCriteria;
|
||||
}
|
||||
|
||||
protected static function EnumToSearchForm($aCriteria, $aFields)
|
||||
{
|
||||
$sOperator = $aCriteria['operator'];
|
||||
$sRef = $aCriteria['ref'];
|
||||
$aValues = $aCriteria['values'];
|
||||
if (array_key_exists($sRef, $aFields))
|
||||
{
|
||||
$aField = $aFields[$sRef];
|
||||
if (array_key_exists('allowed_values', $aField) && array_key_exists('values', $aField['allowed_values']))
|
||||
{
|
||||
$aAllowedValues = $aField['allowed_values']['values'];
|
||||
}
|
||||
}
|
||||
|
||||
switch (true)
|
||||
{
|
||||
case ($sOperator == 'NOT IN'):
|
||||
if (isset($aAllowedValues))
|
||||
{
|
||||
foreach($aValues as $aValue)
|
||||
{
|
||||
$sValue = $aValue['value'];
|
||||
unset($aAllowedValues[$sValue]);
|
||||
}
|
||||
$aCriteria['values'] = array();
|
||||
|
||||
foreach($aAllowedValues as $sValue => $sLabel)
|
||||
{
|
||||
$aValue = array('value' => $sValue, 'label' => $sLabel);
|
||||
$aCriteria['values'][] = $aValue;
|
||||
}
|
||||
$aCriteria['operator'] = 'IN';
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return $aCriteria;
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,7 @@ abstract class CriterionConversionAbstract
|
||||
const OP_ENDS_WITH = 'ends_with';
|
||||
const OP_EMPTY = 'empty';
|
||||
const OP_NOT_EMPTY = 'not_empty';
|
||||
const OP_IN = 'IN';
|
||||
const OP_ALL = 'all';
|
||||
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ class SearchForm
|
||||
|
||||
$aFields = $this->GetFields($oSet);
|
||||
$oSearch = $oSet->GetFilter();
|
||||
$aCriterion = $this->GetCriterion($oSearch);
|
||||
$aCriterion = $this->GetCriterion($oSearch, $aFields);
|
||||
|
||||
$oBaseSearch = $oSearch->DeepClone();
|
||||
$oBaseSearch->ResetCondition();
|
||||
@@ -173,7 +173,7 @@ class SearchForm
|
||||
$aAuthorizedClasses = array();
|
||||
foreach($aSelectedClasses as $sAlias => $sClassName)
|
||||
{
|
||||
if (\UserRights::IsActionAllowed($sClassName, UR_ACTION_BULK_READ, $oSet) != UR_ALLOWED_NO)
|
||||
if (\UserRights::IsActionAllowed($sClassName, UR_ACTION_READ, $oSet) != UR_ALLOWED_NO)
|
||||
{
|
||||
$aAuthorizedClasses[$sAlias] = $sClassName;
|
||||
}
|
||||
@@ -195,7 +195,7 @@ class SearchForm
|
||||
unset($aAttributeDefs[$sAttCode]);
|
||||
}
|
||||
}
|
||||
usort($aZList, function ($aItem1, $aItem2) {
|
||||
uasort($aZList, function ($aItem1, $aItem2) {
|
||||
return strcmp($aItem1['label'], $aItem2['label']);
|
||||
});
|
||||
$aAllFields['zlist'] = $aZList;
|
||||
@@ -207,7 +207,7 @@ class SearchForm
|
||||
|
||||
$aOthers = $this->AppendField($sClass, $sAlias, $sAttCode, $oAttDef, $aOthers);
|
||||
}
|
||||
usort($aOthers, function ($aItem1, $aItem2) {
|
||||
uasort($aOthers, function ($aItem1, $aItem2) {
|
||||
return strcmp($aItem1['label'], $aItem2['label']);
|
||||
});
|
||||
|
||||
@@ -231,7 +231,7 @@ class SearchForm
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetFieldAllowedValues($oAttrDef)
|
||||
public static function GetFieldAllowedValues($oAttrDef)
|
||||
{
|
||||
if ($oAttrDef->IsExternalKey(EXTKEY_ABSOLUTE))
|
||||
{
|
||||
@@ -269,8 +269,11 @@ class SearchForm
|
||||
|
||||
/**
|
||||
* @param \DBSearch $oSearch
|
||||
* @param array $aFields
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetCriterion($oSearch)
|
||||
public function GetCriterion($oSearch, $aFields)
|
||||
{
|
||||
$oExpression = $oSearch->GetCriteria();
|
||||
|
||||
@@ -288,7 +291,7 @@ class SearchForm
|
||||
}
|
||||
$aAndCriterion[] = $oAndSubExpr->GetCriterion($oSearch);
|
||||
}
|
||||
$aAndCriterion = CriterionToSearchForm::Convert($aAndCriterion);
|
||||
$aAndCriterion = CriterionToSearchForm::Convert($aAndCriterion, $aFields);
|
||||
$aOrCriterion[] = array('and' => $aAndCriterion);
|
||||
}
|
||||
|
||||
@@ -317,7 +320,7 @@ class SearchForm
|
||||
$aField['class_alias'] = $sClassAlias;
|
||||
$aField['label'] = $sLabel;
|
||||
$aField['widget'] = $oAttrDef->GetSearchType();
|
||||
$aField['allowed_values'] = $this->GetFieldAllowedValues($oAttrDef);
|
||||
$aField['allowed_values'] = self::GetFieldAllowedValues($oAttrDef);
|
||||
$aFields[$sClassAlias.'.'.$sFilterCode] = $aField;
|
||||
$this->aLabels[$sLabel] = true;
|
||||
}
|
||||
|
||||
@@ -45,13 +45,16 @@ class SearchFormTest extends ItopDataTestCase
|
||||
public function testGetFields()
|
||||
{
|
||||
$oSearchForm = new SearchForm();
|
||||
$aFields = $oSearchForm->GetFields('Contact', 'Contact');
|
||||
$oSearch = \DBSearch::FromOQL("SELECT Contact");
|
||||
$aFields = $oSearchForm->GetFields(new \DBObjectSet($oSearch));
|
||||
$this->debug(json_encode($aFields, JSON_PRETTY_PRINT));
|
||||
$this->assertCount(7, $aFields['zlist']);
|
||||
|
||||
$oSearchForm = new SearchForm();
|
||||
$oSearch = \DBSearch::FromOQL("SELECT Contact AS C WHERE C.status = 'active'");
|
||||
$aFields = $oSearchForm->GetFields($oSearch->GetClass(), $oSearch->GetClassAlias());
|
||||
$aFields = $oSearchForm->GetFields(new \DBObjectSet($oSearch));
|
||||
$this->debug(json_encode($aFields, JSON_PRETTY_PRINT));
|
||||
$this->assertCount(4, $aFields['others']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,7 +69,9 @@ class SearchFormTest extends ItopDataTestCase
|
||||
$oSearchForm = new SearchForm();
|
||||
try
|
||||
{
|
||||
$aCriterion = $oSearchForm->GetCriterion(\DBSearch::FromOQL($sOQL));
|
||||
$oSearch = \DBSearch::FromOQL($sOQL);
|
||||
$aFields = $oSearchForm->GetFields(new \DBObjectSet($oSearch));
|
||||
$aCriterion = $oSearchForm->GetCriterion($oSearch, $aFields);
|
||||
} catch (\OQLException $e)
|
||||
{
|
||||
$this->assertTrue(false);
|
||||
@@ -89,6 +94,8 @@ class SearchFormTest extends ItopDataTestCase
|
||||
array('OQL' => "SELECT Contact WHERE status = 'active' AND name LIKE 'toto%'", 1),
|
||||
array('OQL' => "SELECT Contact WHERE status = 'active' AND org_id = 3", 1),
|
||||
array('OQL' => "SELECT Contact WHERE status IN ('active', 'inactive')", 1),
|
||||
array('OQL' => "SELECT Contact WHERE status NOT IN ('active')", 1),
|
||||
array('OQL' => "SELECT Contact WHERE status NOT IN ('active', 'inactive')", 1),
|
||||
array('OQL' => "SELECT Contact WHERE status = 'active' OR name LIKE 'toto%'", 2),
|
||||
array('OQL' => "SELECT UserRequest WHERE DATE_SUB(NOW(), INTERVAL 14 DAY) < start_date", 1),
|
||||
array('OQL' => "SELECT UserRequest WHERE start_date > '2017-01-01' AND '2018-01-01' >= start_date", 1),
|
||||
|
||||
Reference in New Issue
Block a user