diff --git a/core/oql/expression.class.inc.php b/core/oql/expression.class.inc.php index b4b0b827b9..c302998a86 100644 --- a/core/oql/expression.class.inc.php +++ b/core/oql/expression.class.inc.php @@ -510,11 +510,6 @@ class BinaryExpression extends Expression $bReverseOperator = false; $oLeftExpr = $this->GetLeftExpr(); $oRightExpr = $this->GetRightExpr(); - if ($oLeftExpr instanceof FieldExpression && $oRightExpr instanceof FieldExpression) - { - // Default criterion (Field OPE Field) is not supported - return parent::GetCriterion($oSearch, $aArgs, $bRetrofitParams, $oAttDef); - } $oAttDef = $oLeftExpr->GetAttDef($oSearch->GetJoinedClasses()); @@ -532,7 +527,6 @@ class BinaryExpression extends Expression $aCriteriaLeft = $oLeftExpr->GetCriterion($oSearch, $aArgs, $bRetrofitParams, $oAttDef); $aCriteriaRight = $oRightExpr->GetCriterion($oSearch, $aArgs, $bRetrofitParams, $oAttDef); - if ($bReverseOperator) { $aCriteria = array_merge($aCriteriaRight, $aCriteriaLeft); @@ -565,6 +559,12 @@ class BinaryExpression extends Expression $aCriteria['oql'] = $this->Render($aArgs, $bRetrofitParams); $aCriteria['label'] = $this->Display($oSearch, $aArgs, $oAttDef); + if (isset($aCriteriaLeft['ref']) && isset($aCriteriaRight['ref']) && ($aCriteriaLeft['ref'] != $aCriteriaRight['ref'])) + { + // Only one Field is supported in the expressions + $aCriteria['widget'] = AttributeDefinition::SEARCH_WIDGET_TYPE_RAW; + } + return $aCriteria; } } diff --git a/sources/application/search/searchform.class.inc.php b/sources/application/search/searchform.class.inc.php index 631f82ea79..12ec3b9732 100644 --- a/sources/application/search/searchform.class.inc.php +++ b/sources/application/search/searchform.class.inc.php @@ -294,6 +294,11 @@ class SearchForm */ public static function GetFieldAllowedValues($oAttrDef) { + // better than MetaModel::GetConfig()->Get('max_combo_length') + // changing this value can introduce weird behaviour + static $iMaxComboLength = 50; + $aValues = array(); + if ($oAttrDef->IsExternalKey(EXTKEY_ABSOLUTE)) { $sTargetClass = $oAttrDef->GetTargetClass(); @@ -308,26 +313,34 @@ class SearchForm } $oSearch->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', true); $oSet = new DBObjectSet($oSearch); - if ($oSet->Count() > MetaModel::GetConfig()->Get('max_combo_length')) + if ($oSet->Count() > $iMaxComboLength) { return array('autocomplete' => true); } + if ($oSet->Count() > MetaModel::GetConfig()->Get('max_combo_length')) + { + $aValues['autocomplete'] = true; + } } else { if (method_exists($oAttrDef, 'GetAllowedValuesAsObjectSet')) { $oSet = $oAttrDef->GetAllowedValuesAsObjectSet(); - if ($oSet->Count() > MetaModel::GetConfig()->Get('max_combo_length')) + if ($oSet->Count() > $iMaxComboLength) { return array('autocomplete' => true); } + if ($oSet->Count() > MetaModel::GetConfig()->Get('max_combo_length')) + { + $aValues['autocomplete'] = true; + } } } - $aAllowedValues = $oAttrDef->GetAllowedValues(); + $aValues['values'] = $oAttrDef->GetAllowedValues(); - return array('values' => $aAllowedValues); + return $aValues; } /** diff --git a/test/application/search/CriterionConversionTest.php b/test/application/search/CriterionConversionTest.php index 0112ee318f..dcdf33e7f5 100644 --- a/test/application/search/CriterionConversionTest.php +++ b/test/application/search/CriterionConversionTest.php @@ -300,14 +300,19 @@ class CriterionConversionTest extends ItopDataTestCase * * @param $sOQL * + * @param $sExpectedOQL + * + * @param $aExpectedCriterion + * * @throws \OQLException */ - function testOqlToForSearchToOql($sOQL) + function testOqlToForSearchToOql($sOQL, $sExpectedOQL, $aExpectedCriterion) { $this->debug($sOQL); $oSearchForm = new SearchForm(); $oSearch = \DBSearch::FromOQL($sOQL); $aFields = $oSearchForm->GetFields(new \DBObjectSet($oSearch)); + /** @var \DBObjectSearch $oSearch */ $aCriterion = $oSearchForm->GetCriterion($oSearch, $aFields); $aAndCriterion = $aCriterion['or'][0]['and']; @@ -337,53 +342,229 @@ class CriterionConversionTest extends ItopDataTestCase } $this->debug($aNewCriterion); + $this->assertFalse($this->array_diff_assoc_recursive($aExpectedCriterion, $aNewCriterion)); + $aCriterion['or'][0]['and'] = $aNewCriterion; $oSearch->ResetCondition(); $oFilter = CriterionParser::Parse($oSearch->ToOQL(), $aCriterion); - $this->debug($oFilter->ToOQL()); + $sResultOQL = $oFilter->ToOQL(); + $this->debug($sResultOQL); - $this->assertTrue(true); + $this->assertEquals($sExpectedOQL, $sResultOQL); } function OqlProvider() { return array( - 'no criteria' => array('OQL' => 'SELECT WebApplication'), - 'string starts' => array('OQL' => "SELECT Contact WHERE name LIKE 'toto%'"), - 'string ends' => array('OQL' => "SELECT Contact WHERE name LIKE '%toto'"), - 'string contains 1' => array('OQL' => "SELECT Contact WHERE name LIKE '%toto%'"), - 'string contains 2' => array('OQL' => "SELECT Person AS B WHERE B.name LIKE '%A%'"), - 'string regexp' => array('OQL' => "SELECT Server WHERE name REGEXP '^dbserver[0-9]+\\\\\\\\..+\\\\\\\\.[a-z]{2,3}$'"), - 'enum + key =' => array('OQL' => "SELECT Contact WHERE status = 'active' AND org_id = 3"), - 'enum =' => array('OQL' => "SELECT Contact WHERE status = 'active'"), - 'enum IN' => array('OQL' => "SELECT Contact WHERE status IN ('active', 'inactive')"), - 'enum NOT IN 1' => array('OQL' => "SELECT Contact WHERE status NOT IN ('active')"), - 'enum NOT IN 2' => array('OQL' => "SELECT Person AS p JOIN UserRequest AS u ON u.agent_id = p.id WHERE u.status != 'closed'"), - 'enum undefined 1' => array('OQL' => "SELECT FunctionalCI WHERE ((business_criticity = 'high') OR ISNULL(business_criticity)) AND 1"), - 'enum undefined 2' => array('OQL' => "SELECT FunctionalCI WHERE ((business_criticity IN ('high', 'medium')) OR ISNULL(business_criticity)) AND 1"), - 'enum undefined 3' => array('OQL' => "SELECT FunctionalCI WHERE ISNULL(business_criticity)"), - 'key NOT IN' => array('OQL' => "SELECT Contact WHERE org_id NOT IN ('1')"), - 'key IN' => array('OQL' => "SELECT Contact WHERE org_id IN ('1')"), - 'key empty' => array('OQL' => "SELECT Person WHERE location_id = '0'"), - 'Date relative 1' => array('OQL' => "SELECT UserRequest WHERE DATE_SUB(NOW(), INTERVAL 14 DAY) < start_date"), - 'Date relative 2' => array('OQL' => "SELECT Contract AS c WHERE c.end_date > NOW() AND c.end_date < DATE_ADD(NOW(), INTERVAL 30 DAY)"), - 'Date relative 3' => array('OQL' => "SELECT UserRequest AS u WHERE u.close_date > DATE_ADD(u.start_date, INTERVAL 8 HOUR)"), - 'Date relative 4' => array('OQL' => "SELECT UserRequest AS u WHERE u.start_date < DATE_SUB(NOW(), INTERVAL 60 MINUTE) AND u.status = 'new'"), - 'Date between 1' => array('OQL' => "SELECT UserRequest WHERE start_date > '2017-01-01 00:00:00' AND '2018-01-01 00:00:00' >= start_date"), - 'Date between 2' => array('OQL' => "SELECT UserRequest WHERE start_date > '2017-01-01 00:00:00' AND status = 'active' AND org_id = 3 AND '2018-01-01 00:00:00' >= start_date"), - 'Date between 3' => array('OQL' => "SELECT UserRequest WHERE start_date >= '2017-01-01 00:00:00' AND '2017-01-01 00:00:00' >= start_date"), - 'Date between 4' => array('OQL' => "SELECT UserRequest WHERE start_date >= '2017-01-01 00:00:00' AND '2017-01-01 01:00:00' > start_date"), - 'Date between 5' => array('OQL' => "SELECT UserRequest WHERE start_date >= '2017-01-01 00:00:00' AND '2017-01-02 00:00:00' > start_date"), - 'Date between 6' => array('OQL' => "SELECT UserRequest WHERE start_date >= '2017-01-01' AND '2017-01-02' >= start_date"), - 'Date between 7' => array('OQL' => "SELECT CustomerContract WHERE ((start_date >= '2018-03-01') AND (start_date < '2018-04-01'))"), - 'Date =' => array('OQL' => "SELECT CustomerContract WHERE (start_date = '2018-03-01')"), - 'Date =2' => array('OQL' => "SELECT UserRequest WHERE (DATE_FORMAT(start_date, '%Y-%m-%d') = '2018-03-21')"), - 'Num between 1' => array('OQL' => "SELECT Server WHERE nb_u >= 0 AND 1 >= nb_u"), - 'Num ISNULL' => array('OQL' => "SELECT Server WHERE ISNULL(nb_u)"), - 'Hierarchical below' => array('OQL' => "SELECT Person AS P JOIN Organization AS Node ON P.org_id = Node.id JOIN Organization AS Root ON Node.parent_id BELOW Root.id WHERE Root.id=1"), - 'IP range' => array('OQL' => "SELECT DatacenterDevice AS dev WHERE INET_ATON(dev.managementip) > INET_ATON('10.22.32.224') AND INET_ATON(dev.managementip) < INET_ATON('10.22.32.255')"), + 'no criteria' => array( + 'OQL' => 'SELECT WebApplication', + 'ExpectedOQL' => "SELECT `WebApplication` FROM WebApplication AS `WebApplication` WHERE 1", + 'ExpectedCriterion' => array(), + ), + 'string starts' => array( + 'OQL' => "SELECT Contact WHERE name LIKE 'toto%'", + 'ExpectedOQL' => "SELECT `Contact` FROM Contact AS `Contact` WHERE (`Contact`.`name` LIKE 'toto%')", + 'ExpectedCriterion' => array(array('widget' => 'string', 'operator' => 'starts_with', 'values' => array(array('value' => 'toto')))), + ), + 'string ends' => array( + 'OQL' => "SELECT Contact WHERE name LIKE '%toto'", + 'ExpectedOQL' => "SELECT `Contact` FROM Contact AS `Contact` WHERE (`Contact`.`name` LIKE '%toto')", + 'ExpectedCriterion' => array(array('widget' => 'string', 'operator' => 'ends_with', 'values' => array(array('value' => 'toto')))), + ), + 'string contains 1' => array( + 'OQL' => "SELECT Contact WHERE name LIKE '%toto%'", + 'ExpectedOQL' => "SELECT `Contact` FROM Contact AS `Contact` WHERE (`Contact`.`name` LIKE '%toto%')", + 'ExpectedCriterion' => array(array('widget' => 'string', 'operator' => 'contains', 'values' => array(array('value' => 'toto')))), + ), + 'string contains 2' => array( + 'OQL' => "SELECT Person AS B WHERE B.name LIKE '%A%'", + 'ExpectedOQL' => "SELECT `B` FROM Person AS `B` WHERE (`B`.`name` LIKE '%A%')", + 'ExpectedCriterion' => array(array('widget' => 'string', 'operator' => 'contains', 'values' => array(array('value' => 'A')))), + ), + 'string regexp' => array( + 'OQL' => "SELECT Server WHERE name REGEXP '^dbserver[0-9]+\\\\\\\\..+\\\\\\\\.[a-z]{2,3}$'", + 'ExpectedOQL' => "SELECT `Server` FROM Server AS `Server` WHERE (`Server`.`name` REGEXP '^dbserver[0-9]+\\\\..+\\\\.[a-z]{2,3}$')", + 'ExpectedCriterion' => array(array('widget' => 'string', 'operator' => 'REGEXP')), + ), + 'enum + key =' => array( + 'OQL' => "SELECT Contact WHERE status = 'active' AND org_id = 3", + 'ExpectedOQL' => "SELECT `Contact` FROM Contact AS `Contact` WHERE ((`Contact`.`org_id` = '3') AND (`Contact`.`status` = 'active'))", + 'ExpectedCriterion' => array(array('widget' => 'hierarchical_key', 'operator' => 'IN'), array('widget' => 'enum', 'operator' => 'IN')), + ), + 'enum =' => array( + 'OQL' => "SELECT Contact WHERE status = 'active'", + 'ExpectedOQL' => "SELECT `Contact` FROM Contact AS `Contact` WHERE (`Contact`.`status` = 'active')", + 'ExpectedCriterion' => array(array('widget' => 'enum', 'operator' => 'IN', 'values' => array(array('value' => 'active')))), + ), + 'enum IN' => array( + 'OQL' => "SELECT Contact WHERE status IN ('active', 'inactive')", + 'ExpectedOQL' => "SELECT `Contact` FROM Contact AS `Contact` WHERE 1", + 'ExpectedCriterion' => array(array('widget' => 'enum', 'operator' => 'IN', 'values' => array(array('value' => 'active'), array('value' => 'inactive')))), + ), + 'enum NOT IN 1' => array( + 'OQL' => "SELECT Contact WHERE status NOT IN ('active')", + 'ExpectedOQL' => "SELECT `Contact` FROM Contact AS `Contact` WHERE (`Contact`.`status` = 'inactive')", + 'ExpectedCriterion' => array(array('widget' => 'enum', 'operator' => 'IN', 'values' => array(array('value' => 'inactive')))), + ), + 'enum NOT IN 2' => array( + 'OQL' => "SELECT Person AS p JOIN UserRequest AS u ON u.agent_id = p.id WHERE u.status != 'closed'", + 'ExpectedOQL' => "SELECT `p` FROM Person AS `p` JOIN UserRequest AS `u` ON `u`.agent_id = `p`.id WHERE (`u`.`status` != 'closed')", + 'ExpectedCriterion' => array(array('widget' => 'raw')), + ), + 'enum undefined 1' => array( + 'OQL' => "SELECT FunctionalCI WHERE ((business_criticity = 'high') OR ISNULL(business_criticity)) AND 1", + 'ExpectedOQL' => "SELECT `FunctionalCI` FROM FunctionalCI AS `FunctionalCI` WHERE (((`FunctionalCI`.`business_criticity` = 'high') OR ISNULL(`FunctionalCI`.`business_criticity`)) AND 1)", + 'ExpectedCriterion' => array(array('widget' => 'enum', 'has_undefined' => true, 'operator' => 'IN', 'values' => array(array('value' => 'high'), array('value' => 'null')))), + ), + 'enum undefined 2' => array( + 'OQL' => "SELECT FunctionalCI WHERE ((business_criticity IN ('high', 'medium')) OR ISNULL(business_criticity)) AND 1", + 'ExpectedOQL' => "SELECT `FunctionalCI` FROM FunctionalCI AS `FunctionalCI` WHERE (((`FunctionalCI`.`business_criticity` IN ('high', 'medium')) OR ISNULL(`FunctionalCI`.`business_criticity`)) AND 1)", + 'ExpectedCriterion' => array(array('widget' => 'enum', 'has_undefined' => true, 'operator' => 'IN', 'values' => array(array('value' => 'high'), array('value' => 'medium'), array('value' => 'null')))), + ), + 'enum undefined 3' => array( + 'OQL' => "SELECT FunctionalCI WHERE ISNULL(business_criticity)", + 'ExpectedOQL' => "SELECT `FunctionalCI` FROM FunctionalCI AS `FunctionalCI` WHERE ISNULL(`FunctionalCI`.`business_criticity`)", + 'ExpectedCriterion' => array(array('widget' => 'enum', 'has_undefined' => true, 'operator' => 'IN', 'values' => array(array('value' => 'null')))), + ), + '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')), + ), + 'key IN' => array( + 'OQL' => "SELECT Contact WHERE org_id IN ('1')", + 'ExpectedOQL' => "SELECT `Contact` FROM Contact AS `Contact` WHERE (`Contact`.`org_id` = '1')", + 'ExpectedCriterion' => array(array('widget' => 'hierarchical_key', 'operator' => 'IN')), + ), + 'key empty' => array( + 'OQL' => "SELECT Person WHERE location_id = '0'", + 'ExpectedOQL' => "SELECT `Person` FROM Person AS `Person` WHERE (`Person`.`location_id` = '0')", + 'ExpectedCriterion' => array(array('widget' => 'external_key', 'operator' => 'IN', 'values' => array(array('value' => '0')))), + ), + 'Double field' => array( + 'OQL' => "SELECT UserRequest AS u WHERE u.close_date > u.start_date", + 'ExpectedOQL' => "SELECT `u` FROM UserRequest AS `u` WHERE (`u`.`close_date` > `u`.`start_date`)", + 'ExpectedCriterion' => array(array('widget' => 'raw')), + ), + 'Date relative 1' => array( + 'OQL' => "SELECT UserRequest WHERE DATE_SUB(NOW(), INTERVAL 14 DAY) < start_date", + 'ExpectedOQL' => "SELECT `UserRequest` FROM UserRequest AS `UserRequest` WHERE (DATE_SUB(NOW(), INTERVAL 14 DAY) < `UserRequest`.`start_date`)", + 'ExpectedCriterion' => array(array('widget' => 'raw')), + ), + 'Date relative 2' => array( + 'OQL' => "SELECT Contract AS c WHERE c.end_date > NOW() AND c.end_date < DATE_ADD(NOW(), INTERVAL 30 DAY)", + 'ExpectedOQL' => "SELECT `c` FROM Contract AS `c` WHERE ((`c`.`end_date` < DATE_ADD(NOW(), INTERVAL 30 DAY)) AND (`c`.`end_date` > NOW()))", + 'ExpectedCriterion' => array(array('widget' => 'raw'), array('widget' => 'raw')), + ), + 'Date relative 3' => array( + 'OQL' => "SELECT UserRequest AS u WHERE u.close_date > DATE_ADD(u.start_date, INTERVAL 8 HOUR)", + 'ExpectedOQL' => "SELECT `u` FROM UserRequest AS `u` WHERE (`u`.`close_date` > DATE_ADD(`u`.`start_date`, INTERVAL 8 HOUR))", + 'ExpectedCriterion' => array(), + ), + 'Date relative 4' => array( + 'OQL' => "SELECT UserRequest AS u WHERE u.start_date < DATE_SUB(NOW(), INTERVAL 60 MINUTE) AND u.status = 'new'", + 'ExpectedOQL' => "SELECT `u` FROM UserRequest AS `u` WHERE ((`u`.`start_date` < DATE_SUB(NOW(), INTERVAL 60 MINUTE)) AND (`u`.`status` = 'new'))", + 'ExpectedCriterion' => array(array('widget' => 'raw')), + ), + 'Date between 1' => array( + 'OQL' => "SELECT UserRequest WHERE start_date > '2017-01-01 00:00:00' AND '2018-01-01 00:00:00' >= start_date", + 'ExpectedOQL' => "SELECT `UserRequest` FROM UserRequest AS `UserRequest` WHERE ((`UserRequest`.`start_date` >= '2017-01-01 00:00:01') AND (`UserRequest`.`start_date` <= '2018-01-01 00:00:00'))", + 'ExpectedCriterion' => array(array('widget' => 'date_time', 'operator' => 'between_dates')), + ), + 'Date between 2' => array( + 'OQL' => "SELECT UserRequest WHERE start_date > '2017-01-01 00:00:00' AND status = 'active' AND org_id = 3 AND '2018-01-01 00:00:00' >= start_date", + 'ExpectedOQL' => "SELECT `UserRequest` FROM UserRequest AS `UserRequest` WHERE ((((`UserRequest`.`org_id` = '3') AND (`UserRequest`.`start_date` >= '2017-01-01 00:00:01')) AND (`UserRequest`.`start_date` <= '2018-01-01 00:00:00')) AND (`UserRequest`.`status` = 'active'))", + 'ExpectedCriterion' => array(array('widget' => 'hierarchical_key', 'operator' => 'IN'), array('widget' => 'date_time', 'operator' => 'between_dates'), array('widget' => 'enum', 'operator' => 'IN')), + ), + 'Date between 3' => array( + 'OQL' => "SELECT UserRequest WHERE start_date >= '2017-01-01 00:00:00' AND '2017-01-01 00:00:00' >= start_date", + 'ExpectedOQL' => "SELECT `UserRequest` FROM UserRequest AS `UserRequest` WHERE ((`UserRequest`.`start_date` >= '2017-01-01 00:00:00') AND (`UserRequest`.`start_date` <= '2017-01-01 00:00:00'))", + 'ExpectedCriterion' => array(array('widget' => 'date_time', 'operator' => 'between_dates')), + ), + 'Date between 4' => array( + 'OQL' => "SELECT UserRequest WHERE start_date >= '2017-01-01 00:00:00' AND '2017-01-01 01:00:00' > start_date", + 'ExpectedOQL' => "SELECT `UserRequest` FROM UserRequest AS `UserRequest` WHERE ((`UserRequest`.`start_date` >= '2017-01-01 00:00:00') AND (`UserRequest`.`start_date` <= '2017-01-01 00:59:59'))", + 'ExpectedCriterion' => array(array('widget' => 'date_time', 'operator' => 'between_dates')), + ), + 'Date between 5' => array( + 'OQL' => "SELECT UserRequest WHERE start_date >= '2017-01-01 00:00:00' AND '2017-01-02 00:00:00' > start_date", + 'ExpectedOQL' => "SELECT `UserRequest` FROM UserRequest AS `UserRequest` WHERE ((`UserRequest`.`start_date` >= '2017-01-01 00:00:00') AND (`UserRequest`.`start_date` <= '2017-01-01 23:59:59'))", + 'ExpectedCriterion' => array(array('widget' => 'date_time', 'operator' => 'between_dates')), + ), + 'Date between 6' => array( + 'OQL' => "SELECT UserRequest WHERE start_date >= '2017-01-01' AND '2017-01-02' >= start_date", + 'ExpectedOQL' => "SELECT `UserRequest` FROM UserRequest AS `UserRequest` WHERE ((`UserRequest`.`start_date` >= '2017-01-01 00:00:00') AND (`UserRequest`.`start_date` <= '2017-01-02 00:00:00'))", + 'ExpectedCriterion' => array(array('widget' => 'date_time', 'operator' => 'between_dates')), + ), + 'Date between 7' => array( + 'OQL' => "SELECT CustomerContract WHERE ((start_date >= '2018-03-01') AND (start_date < '2018-04-01'))", + 'ExpectedOQL' => "SELECT `CustomerContract` FROM CustomerContract AS `CustomerContract` WHERE ((`CustomerContract`.`start_date` >= '2018-03-01') AND (`CustomerContract`.`start_date` <= '2018-03-31'))", + 'ExpectedCriterion' => array(array('widget' => 'date', 'operator' => 'between_dates')), + ), + 'Date =' => array( + 'OQL' => "SELECT CustomerContract WHERE (start_date = '2018-03-01')", + 'ExpectedOQL' => "SELECT `CustomerContract` FROM CustomerContract AS `CustomerContract` WHERE ((`CustomerContract`.`start_date` >= '2018-03-01') AND (`CustomerContract`.`start_date` <= '2018-03-01'))", + 'ExpectedCriterion' => array(array('widget' => 'date', 'operator' => 'between_dates')), + ), + 'Date =2' => array( + 'OQL' => "SELECT UserRequest WHERE (DATE_FORMAT(start_date, '%Y-%m-%d') = '2018-03-21')", + 'ExpectedOQL' => "SELECT `UserRequest` FROM UserRequest AS `UserRequest` WHERE ((`UserRequest`.`start_date` >= '2018-03-21 00:00:00') AND (`UserRequest`.`start_date` <= '2018-03-21 23:59:59'))", + 'ExpectedCriterion' => array(array('widget' => 'date_time', 'operator' => 'between_dates')), + ), + 'Num between 1' => array( + 'OQL' => "SELECT Server WHERE nb_u >= 0 AND 1 >= nb_u", + 'ExpectedOQL' => "SELECT `Server` FROM Server AS `Server` WHERE ((`Server`.`nb_u` >= '0') AND (`Server`.`nb_u` <= '1'))", + 'ExpectedCriterion' => array(array('widget' => 'numeric', 'operator' => 'between')), + ), + 'Num ISNULL' => array( + 'OQL' => "SELECT Server WHERE ISNULL(nb_u)", + 'ExpectedOQL' => "SELECT `Server` FROM Server AS `Server` WHERE ISNULL(`Server`.`nb_u`)", + 'ExpectedCriterion' => array(array('widget' => 'numeric', 'operator' => 'empty')), + ), + 'Hierarchical below' => array( + 'OQL' => "SELECT Person AS P JOIN Organization AS Node ON P.org_id = Node.id JOIN Organization AS Root ON Node.parent_id BELOW Root.id WHERE Root.id=1", + 'ExpectedOQL' => "SELECT `P` FROM Person AS `P` JOIN Organization AS `Node` ON `P`.org_id = `Node`.id JOIN Organization AS `Root` ON `Node`.parent_id BELOW `Root`.id WHERE (`Root`.`id` = 1)", + 'ExpectedCriterion' => array(array('widget' => 'raw')), + ), + 'IP range' => array( + 'OQL' => "SELECT DatacenterDevice AS dev WHERE INET_ATON(dev.managementip) > INET_ATON('10.22.32.224') AND INET_ATON(dev.managementip) < INET_ATON('10.22.32.255')", + 'ExpectedOQL' => "SELECT `dev` FROM DatacenterDevice AS `dev` WHERE ((INET_ATON(`dev`.`managementip`) < INET_ATON('10.22.32.255')) AND (INET_ATON(`dev`.`managementip`) > INET_ATON('10.22.32.224')))", + 'ExpectedCriterion' => array(array('widget' => 'raw')), + ), ); } + + function array_diff_assoc_recursive($array1, $array2) + { + foreach($array1 as $key => $value) + { + if (is_array($value)) + { + if (!isset($array2[$key])) + { + $difference[$key] = $value; + } + elseif (!is_array($array2[$key])) + { + $difference[$key] = $value; + } + else + { + $new_diff = $this->array_diff_assoc_recursive($value, $array2[$key]); + if ($new_diff !== false) + { + $difference[$key] = $new_diff; + } + } + } + elseif (!array_key_exists($key, $array2) || $array2[$key] != $value) + { + $difference[$key] = $value; + } + } + + return !isset($difference) ? false : $difference; + } }