From c485286114efc2c7151edfaabf415c0077c2f5eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20Espi=C3=A9?= Date: Mon, 16 Apr 2018 16:35:20 +0000 Subject: [PATCH] Advanced Search: External keys to hierarchical class selects sub-classes as in previous version SVN:trunk[5675] --- core/attributedef.class.inc.php | 6 +- core/dbobjectsearch.class.php | 2 +- core/oql/check_oql.php | 14 +-- core/oql/expression.class.inc.php | 76 +++++++++++-- .../criteriontooql.class.inc.php | 105 +++++++++++++----- .../criteriontosearchform.class.inc.php | 28 +++-- .../search/criterionparser.class.inc.php | 28 ++--- .../search/searchform.class.inc.php | 13 ++- test/ItopTestCase.php | 3 +- .../search/CriterionConversionTest.php | 23 +++- test/application/search/SearchFormTest.php | 16 +-- test/core/apcEmulationTest.php | 2 +- test/core/dictTest.php | 2 +- ...cEmulation.php => mockApcEmulation.incphp} | 0 test/core/{mockDict.php => mockDict.incphp} | 0 15 files changed, 232 insertions(+), 86 deletions(-) rename test/core/{mockApcEmulation.php => mockApcEmulation.incphp} (100%) rename test/core/{mockDict.php => mockDict.incphp} (100%) diff --git a/core/attributedef.class.inc.php b/core/attributedef.class.inc.php index 03179137d..dd63d310b 100644 --- a/core/attributedef.class.inc.php +++ b/core/attributedef.class.inc.php @@ -238,8 +238,11 @@ abstract class AttributeDefinition /** * Check the validity of the given value + * * @param DBObject $oHostObject * @param string An error if any, null otherwise + * + * @return bool */ public function CheckValue(DBObject $oHostObject, $value) { @@ -252,7 +255,8 @@ abstract class AttributeDefinition { return ""; // e.g: return array("Site", "infrid", "name"); - } + } + public function GetFinalAttDef() { return $this; diff --git a/core/dbobjectsearch.class.php b/core/dbobjectsearch.class.php index dbd40e605..b5adfe74a 100644 --- a/core/dbobjectsearch.class.php +++ b/core/dbobjectsearch.class.php @@ -1005,7 +1005,7 @@ class DBObjectSearch extends DBSearch public function GetCriteria() {return $this->m_oSearchCondition;} public function GetCriteria_FullText() {throw new Exception("Removed GetCriteria_FullText");} - protected function GetCriteria_PointingTo($sKeyAttCode = "") + public function GetCriteria_PointingTo($sKeyAttCode = "") { if (empty($sKeyAttCode)) { diff --git a/core/oql/check_oql.php b/core/oql/check_oql.php index 08960aec0..ed90b09cb 100644 --- a/core/oql/check_oql.php +++ b/core/oql/check_oql.php @@ -20,13 +20,13 @@ * echo "Ok, '$sOQL' is a valid query"; * } */ -if (!class_exists('CoreException', false)) -{ - class CoreException extends Exception - { - - } -} +//if (!class_exists('CoreException', false)) +//{ +// class CoreException extends Exception +// { +// +// } +//} require_once(__DIR__.'/expression.class.inc.php'); require_once(__DIR__.'/oqlquery.class.inc.php'); diff --git a/core/oql/expression.class.inc.php b/core/oql/expression.class.inc.php index bb490313f..3bafdd37c 100644 --- a/core/oql/expression.class.inc.php +++ b/core/oql/expression.class.inc.php @@ -530,11 +530,14 @@ class BinaryExpression extends Expression return parent::GetCriterion($oSearch, $aArgs, $bRetrofitParams, $oAttDef); } - $aCriteriaLeft = $oLeftExpr->GetCriterion($oSearch, $aArgs, $bRetrofitParams, $oAttDef); - $aCriteriaRight = $oRightExpr->GetCriterion($oSearch, $aArgs, $bRetrofitParams, $oAttDef); if ($bReverseOperator) { + $aCriteriaRight = $oRightExpr->GetCriterion($oSearch, $aArgs, $bRetrofitParams, $oAttDef); + // $oAttDef can be different now + $oAttDef = $oRightExpr->GetAttDef($oSearch->GetJoinedClasses()); + $aCriteriaLeft = $oLeftExpr->GetCriterion($oSearch, $aArgs, $bRetrofitParams, $oAttDef); + $aCriteria = array_merge($aCriteriaRight, $aCriteriaLeft); // switch left and right expressions so reverse the operator // Note that the operation is the same so < becomes > and not >= @@ -559,6 +562,11 @@ class BinaryExpression extends Expression } else { + $aCriteriaLeft = $oLeftExpr->GetCriterion($oSearch, $aArgs, $bRetrofitParams, $oAttDef); + // $oAttDef can be different now + $oAttDef = $oLeftExpr->GetAttDef($oSearch->GetJoinedClasses()); + $aCriteriaRight = $oRightExpr->GetCriterion($oSearch, $aArgs, $bRetrofitParams, $oAttDef); + $aCriteria = array_merge($aCriteriaLeft, $aCriteriaRight); $aCriteria['operator'] = $this->GetOperator(); } @@ -1056,9 +1064,28 @@ class FieldExpression extends UnaryExpression } } + private function GetJoinedFilters($oSearch, $iOperatorCodeTarget) + { + $aFilters = array(); + $aPointingToByKey = $oSearch->GetCriteria_PointingTo(); + foreach ($aPointingToByKey as $sExtKey => $aPointingTo) + { + foreach($aPointingTo as $iOperatorCode => $aFilter) + { + if ($iOperatorCode == $iOperatorCodeTarget) + { + foreach($aFilter as $oExtFilter) + { + $aFilters[$sExtKey] = $oExtFilter; + } + } + } + } + return $aFilters; + } /** - * @param $oSearch + * @param DBObjectSearch $oSearch * @param null $aArgs * @param bool $bRetrofitParams * @param AttributeDefinition $oAttDef @@ -1067,6 +1094,38 @@ class FieldExpression extends UnaryExpression */ public function GetCriterion($oSearch, &$aArgs = null, $bRetrofitParams = false, $oAttDef = null) { + $aCriteria = array(); + $aCriteria['is_hierarchical'] = false; + // Replace BELOW joins by the corresponding external key for the search + // Try to detect hierarchical links + if ($this->m_sName == 'id') + { + if (method_exists($oSearch, 'GetCriteria_PointingTo')) + { + $aFilters = $this->GetJoinedFilters($oSearch, TREE_OPERATOR_EQUALS); + if (!empty($aFilters)) + { + foreach($aFilters as $sExtKey => $oFilter) + { + $aSubFilters = $this->GetJoinedFilters($oFilter, TREE_OPERATOR_BELOW); + foreach($aSubFilters as $oSubFilter) + { + /** @var \DBObjectSearch $oSubFilter */ + $sClassAlias = $oSubFilter->GetClassAlias(); + if ($sClassAlias == $this->m_sParent) + { + // Hierarchical link detected + // replace current field with the corresponding external key + $this->m_sName = $sExtKey; + $this->m_sParent = $oSearch->GetClassAlias(); + $aCriteria['is_hierarchical'] = true; + } + } + } + } + } + } + if (method_exists($oSearch, 'GetJoinedClasses')) { $oAttDef = $this->GetAttDef($oSearch->GetJoinedClasses()); @@ -1096,11 +1155,12 @@ class FieldExpression extends UnaryExpression { $sSearchType = AttributeDefinition::SEARCH_WIDGET_TYPE; } - return array( - 'widget' => $sSearchType, - 'ref' => $this->GetParent().'.'.$this->GetName(), - 'class_alias' => $this->GetParent(), - ); + + $aCriteria['widget'] = $sSearchType; + $aCriteria['ref'] = $this->GetParent().'.'.$this->GetName(); + $aCriteria['class_alias'] = $this->GetParent(); + + return $aCriteria; } } diff --git a/sources/application/search/criterionconversion/criteriontooql.class.inc.php b/sources/application/search/criterionconversion/criteriontooql.class.inc.php index bcf1f7c2f..9f2159638 100644 --- a/sources/application/search/criterionconversion/criteriontooql.class.inc.php +++ b/sources/application/search/criterionconversion/criteriontooql.class.inc.php @@ -27,16 +27,19 @@ use AttributeDate; use AttributeDateTime; use AttributeDefinition; use AttributeEnum; +use AttributeExternalKey; use Combodo\iTop\Application\Search\AjaxSearchException; use Combodo\iTop\Application\Search\CriterionConversionAbstract; use Combodo\iTop\Application\Search\SearchForm; +use DBObjectSearch; use Exception; +use Expression; use MetaModel; class CriterionToOQL extends CriterionConversionAbstract { - public static function Convert($aCriteria) + public static function Convert($oSearch, $aCriteria) { if (!empty($aCriteria['oql'])) { @@ -44,6 +47,7 @@ class CriterionToOQL extends CriterionConversionAbstract } $aRef = explode('.', $aCriteria['ref']); + $aCriteria['code'] = $aRef[1]; for($i = 0; $i < count($aRef); $i++) { $aRef[$i] = '`'.$aRef[$i].'`'; @@ -77,7 +81,7 @@ class CriterionToOQL extends CriterionConversionAbstract { $sFct = $aMappedOperators[$sOperator]; - return self::$sFct($sRef, $aCriteria); + return self::$sFct($oSearch, $sRef, $aCriteria); } $sValue = self::GetValue(self::GetValues($aCriteria), 0); @@ -109,7 +113,7 @@ class CriterionToOQL extends CriterionConversionAbstract return $aValues[$iIndex]['value']; } - protected static function ContainsToOql($sRef, $aCriteria) + protected static function ContainsToOql($oSearch, $sRef, $aCriteria) { $aValues = self::GetValues($aCriteria); $sValue = self::GetValue($aValues, 0); @@ -119,7 +123,7 @@ class CriterionToOQL extends CriterionConversionAbstract return "({$sRef} LIKE '%{$sValue}%')"; } - protected static function StartsWithToOql($sRef, $aCriteria) + protected static function StartsWithToOql($oSearch, $sRef, $aCriteria) { $aValues = self::GetValues($aCriteria); $sValue = self::GetValue($aValues, 0); @@ -129,7 +133,7 @@ class CriterionToOQL extends CriterionConversionAbstract return "({$sRef} LIKE '{$sValue}%')"; } - protected static function EndsWithToOql($sRef, $aCriteria) + protected static function EndsWithToOql($oSearch, $sRef, $aCriteria) { $aValues = self::GetValues($aCriteria); $sValue = self::GetValue($aValues, 0); @@ -139,7 +143,7 @@ class CriterionToOQL extends CriterionConversionAbstract return "({$sRef} LIKE '%{$sValue}')"; } - protected static function EqualsToOql($sRef, $aCriteria) + protected static function EqualsToOql($oSearch, $sRef, $aCriteria) { $aValues = self::GetValues($aCriteria); $sValue = self::GetValue($aValues, 0); @@ -149,7 +153,7 @@ class CriterionToOQL extends CriterionConversionAbstract return "({$sRef} = '{$sValue}')"; } - protected static function RegexpToOql($sRef, $aCriteria) + protected static function RegexpToOql($oSearch, $sRef, $aCriteria) { $aValues = self::GetValues($aCriteria); $sValue = self::GetValue($aValues, 0); @@ -159,7 +163,7 @@ class CriterionToOQL extends CriterionConversionAbstract return "({$sRef} REGEXP '{$sValue}')"; } - protected static function EmptyToOql($sRef, $aCriteria) + protected static function EmptyToOql($oSearch, $sRef, $aCriteria) { if (isset($aCriteria['widget'])) { @@ -176,7 +180,7 @@ class CriterionToOQL extends CriterionConversionAbstract return "({$sRef} = '')"; } - protected static function NotEmptyToOql($sRef, $aCriteria) + protected static function NotEmptyToOql($oSearch, $sRef, $aCriteria) { if (isset($aCriteria['widget'])) { @@ -193,7 +197,14 @@ class CriterionToOQL extends CriterionConversionAbstract return "({$sRef} != '')"; } - protected static function InToOql($sRef, $aCriteria) + /** + * @param DBObjectSearch $oSearch + * @param $sRef + * @param $aCriteria + * + * @return mixed|string + */ + protected static function InToOql($oSearch, $sRef, $aCriteria) { $sAttCode = $aCriteria['code']; $sClass = $aCriteria['class']; @@ -255,7 +266,7 @@ class CriterionToOQL extends CriterionConversionAbstract } } } - } catch (\CoreException $e) + } catch (Exception $e) { } @@ -271,28 +282,69 @@ class CriterionToOQL extends CriterionConversionAbstract $sFilterOnUndefined = "ISNULL({$sRef})"; if (count($aValues) === 0) { - return $sFilterOnUndefined; + $sCondition = $sFilterOnUndefined; } - - if (count($aInValues) == 1) + elseif (count($aInValues) == 1) { // Add 'AND 1' to group the 'OR' inside an AND list for OQL parsing - return "((({$sRef} = '$sInList') OR {$sFilterOnUndefined}) AND 1)"; + $sCondition = "((({$sRef} = '$sInList') OR {$sFilterOnUndefined}) AND 1)"; + } + else + { + // Add 'AND 1' to group the 'OR' inside an AND list for OQL parsing + $sCondition = "(({$sRef} IN ('$sInList') OR {$sFilterOnUndefined}) AND 1)"; + } + } + elseif (count($aInValues) == 1) + { + $sCondition = "({$sRef} = '$sInList')"; + } + else + { + $sCondition = "({$sRef} IN ('$sInList'))"; + } + + // Hierarchical keys + if (isset($oAttDef) && $oAttDef->IsExternalKey() && (!isset($aCriteria['is_hierarchical']) || ($aCriteria['is_hierarchical'] !== false))) + { + if ($oAttDef instanceof AttributeExternalKey) + { + $sTargetClass = $oAttDef->GetTargetClass(); + } + else + { + /** @var AttributeExternalKey $oFinalAttDef */ + $oFinalAttDef = $oAttDef->GetFinalAttDef(); + $sTargetClass = $oFinalAttDef->GetTargetClass(); } - // Add 'AND 1' to group the 'OR' inside an AND list for OQL parsing - return "(({$sRef} IN ('$sInList') OR {$sFilterOnUndefined}) AND 1)"; + try + { + $sHierarchicalKeyCode = MetaModel::IsHierarchicalClass($sTargetClass); + if ($sHierarchicalKeyCode !== false) + { + $oFilter = new DBObjectSearch($sTargetClass); + $sFilterAlias = $oFilter->GetClassAlias(); + $sCondition = str_replace("$sRef", $sFilterAlias.'.id', $sCondition); + $oCondition = Expression::FromOQL($sCondition); + $oFilter->AddConditionExpression($oCondition); + + $oHKFilter = new DBObjectSearch($sTargetClass); + + $oHKFilter->AddCondition_PointingTo($oFilter, $sHierarchicalKeyCode, TREE_OPERATOR_BELOW); + // Use the 'below' operator by default + $oSearch->AddCondition_PointingTo($oHKFilter, $sAttCode); + $sCondition = '1'; + } + } catch (Exception $e) + { + } } - if (count($aInValues) == 1) - { - return "({$sRef} = '$sInList')"; - } - - return "({$sRef} IN ('$sInList'))"; + return $sCondition; } - protected static function BetweenDatesToOql($sRef, $aCriteria) + protected static function BetweenDatesToOql($oSearch, $sRef, $aCriteria) { $aOQL = array(); @@ -352,13 +404,14 @@ class CriterionToOQL extends CriterionConversionAbstract } /** + * @param DBObjectSearch $oSearch * @param $sRef * @param $aCriteria * * @return string * @throws \Combodo\iTop\Application\Search\AjaxSearchException */ - protected static function BetweenToOql($sRef, $aCriteria) + protected static function BetweenToOql($oSearch, $sRef, $aCriteria) { $aOQL = array(); @@ -411,7 +464,7 @@ class CriterionToOQL extends CriterionConversionAbstract } - protected static function AllToOql($sRef, $aCriteria) + protected static function AllToOql($oSearch, $sRef, $aCriteria) { return "1"; } diff --git a/sources/application/search/criterionconversion/criteriontosearchform.class.inc.php b/sources/application/search/criterionconversion/criteriontosearchform.class.inc.php index 0dfc9b2e8..22f9886a0 100644 --- a/sources/application/search/criterionconversion/criteriontosearchform.class.inc.php +++ b/sources/application/search/criterionconversion/criteriontosearchform.class.inc.php @@ -240,7 +240,7 @@ class CriterionToSearchForm extends CriterionConversionAbstract * @param $aCurrCriterion * @param $aMergedCriterion * - * @return Current criteria or null if merged + * @return array Current criteria or null if merged * @throws \Exception */ protected static function MergeDate($aPrevCriterion, $aCurrCriterion, &$aMergedCriterion) @@ -295,7 +295,7 @@ class CriterionToSearchForm extends CriterionConversionAbstract * @param $aCurrCriterion * @param $aMergedCriterion * - * @return Current criteria or null if merged + * @return array Current criteria or null if merged * @throws \Exception */ protected static function MergeDateTime($aPrevCriterion, $aCurrCriterion, &$aMergedCriterion) @@ -352,7 +352,7 @@ class CriterionToSearchForm extends CriterionConversionAbstract * @param $aCurrCriterion * @param $aMergedCriterion * - * @return Current criteria or null if merged + * @return array Current criteria or null if merged * @throws \Exception */ protected static function MergeNumeric($aPrevCriterion, $aCurrCriterion, &$aMergedCriterion) @@ -514,16 +514,27 @@ class CriterionToSearchForm extends CriterionConversionAbstract $oDate = new DateTime($sDate); $sFirstDateValue = $oDate->format(AttributeDateTime::GetSQLFormat()); - $sFirstDateLabel = AttributeDateTime::GetFormat()->Format($sFirstDateValue); - $aCriteria['values'][0] = array('value' => $sFirstDateValue, 'label' => "$sFirstDateLabel"); - + try + { + $sFirstDateLabel = AttributeDateTime::GetFormat()->Format($sFirstDateValue); + $aCriteria['values'][0] = array('value' => $sFirstDateValue, 'label' => "$sFirstDateLabel"); + } + catch (Exception $e) + { + } $oDate->add(DateInterval::createFromDateString('1 day')); $oDate->sub(DateInterval::createFromDateString('1 second')); $sLastDateValue = $oDate->format(AttributeDateTime::GetSQLFormat()); - $sLastDateLabel = AttributeDateTime::GetFormat()->Format($sLastDateValue); - $aCriteria['values'][1] = array('value' => $sLastDateValue, 'label' => "$sLastDateLabel"); + try + { + $sLastDateLabel = AttributeDateTime::GetFormat()->Format($sLastDateValue); + $aCriteria['values'][1] = array('value' => $sLastDateValue, 'label' => "$sLastDateLabel"); + } + catch (Exception $e) + { + } } } break; @@ -634,6 +645,7 @@ class CriterionToSearchForm extends CriterionConversionAbstract case '=': // Same as IN $aCriteria['operator'] = CriterionConversionAbstract::OP_IN; + unset($aCriteria['oql']); break; case 'IN': // Nothing special to do diff --git a/sources/application/search/criterionparser.class.inc.php b/sources/application/search/criterionparser.class.inc.php index 097e02b5c..36c4b6671 100644 --- a/sources/application/search/criterionparser.class.inc.php +++ b/sources/application/search/criterionparser.class.inc.php @@ -47,22 +47,22 @@ class CriterionParser */ public static function Parse($sBaseOql, $aCriterion, $sHiddenCriteria = null) { - $aExpression = array(); - $aOr = $aCriterion['or']; - foreach($aOr as $aAndList) - { - - $sExpression = self::ParseAndList($aAndList['and']); - if (!empty($sExpression)) - { - $aExpression[] = $sExpression; - } - } - try { $oSearch = DBObjectSearch::FromOQL($sBaseOql); + $aExpression = array(); + $aOr = $aCriterion['or']; + foreach($aOr as $aAndList) + { + + $sExpression = self::ParseAndList($oSearch, $aAndList['and']); + if (!empty($sExpression)) + { + $aExpression[] = $sExpression; + } + } + if (!empty($sHiddenCriteria)) { $oHiddenCriteriaExpression = Expression::FromOQL($sHiddenCriteria); @@ -85,13 +85,13 @@ class CriterionParser return null; } - private static function ParseAndList($aAnd) + private static function ParseAndList($oSearch, $aAnd) { $aExpression = array(); foreach($aAnd as $aCriteria) { - $sExpression = CriterionToOQL::Convert($aCriteria); + $sExpression = CriterionToOQL::Convert($oSearch, $aCriteria); if ($sExpression !== '1') { $aExpression[] = $sExpression; diff --git a/sources/application/search/searchform.class.inc.php b/sources/application/search/searchform.class.inc.php index 49932e35c..0a07147f4 100644 --- a/sources/application/search/searchform.class.inc.php +++ b/sources/application/search/searchform.class.inc.php @@ -26,6 +26,8 @@ namespace Combodo\iTop\Application\Search; use ApplicationContext; use AttributeDefinition; use AttributeExternalField; +use AttributeFriendlyName; +use AttributeSubItem; use CMDBObjectSet; use Combodo\iTop\Application\Search\CriterionConversion\CriterionToSearchForm; use CoreException; @@ -39,7 +41,6 @@ use IssueLog; use MetaModel; use TrueExpression; use utils; -use ValueSetObjects; use WebPage; class SearchForm @@ -395,7 +396,7 @@ class SearchForm } /** - * @param $oAttrDef + * @param \AttributeDefinition $oAttrDef * * @return array */ @@ -409,6 +410,7 @@ class SearchForm } else { + /** @var \AttributeExternalKey $oAttrDef */ $sTargetClass = $oAttrDef->GetTargetClass(); } try @@ -441,6 +443,7 @@ class SearchForm { if (method_exists($oAttrDef, 'GetAllowedValuesAsObjectSet')) { + /** @var DBObjectSet $oSet */ $oSet = $oAttrDef->GetAllowedValuesAsObjectSet(); $iCount = $oSet->Count(); if ($iCount > MetaModel::GetConfig()->Get('max_combo_length')) @@ -489,6 +492,7 @@ class SearchForm $aAndExpressions = Expression::Split($oORSubExpr, 'AND'); foreach($aAndExpressions as $oAndSubExpr) { + /** @var Expression $oAndSubExpr */ if (($oAndSubExpr instanceof TrueExpression) || ($oAndSubExpr->Render() == 1)) { continue; @@ -535,7 +539,7 @@ class SearchForm * @param $sClass * @param $sClassAlias * @param $sAttCode - * @param $oAttDef + * @param AttributeDefinition $oAttDef * @param $aFields * @param bool $bHasIndex * @@ -619,7 +623,7 @@ class SearchForm } /** - * @param $oSearch + * @param DBObjectSearch $oSearch * @return array */ protected function GetDefaultCriterion($oSearch) @@ -653,5 +657,4 @@ class SearchForm return $aOrCriterion; } - } \ No newline at end of file diff --git a/test/ItopTestCase.php b/test/ItopTestCase.php index 83341d55d..a5f834d9e 100644 --- a/test/ItopTestCase.php +++ b/test/ItopTestCase.php @@ -35,7 +35,8 @@ class ItopTestCase extends TestCase { @include_once '../approot.inc.php'; @include_once '../../approot.inc.php'; - @include_once '../../../approot.inc.php'; + @include_once '../../../approot.inc.php'; + @include_once '../../../../approot.inc.php'; $this->debug("\n----------\n---------- ".$this->getName()."\n----------\n"); } diff --git a/test/application/search/CriterionConversionTest.php b/test/application/search/CriterionConversionTest.php index fe766cef3..4b88b836a 100644 --- a/test/application/search/CriterionConversionTest.php +++ b/test/application/search/CriterionConversionTest.php @@ -33,6 +33,8 @@ use Combodo\iTop\Application\Search\CriterionConversion\CriterionToSearchForm; use Combodo\iTop\Application\Search\CriterionParser; use Combodo\iTop\Application\Search\SearchForm; use Combodo\iTop\Test\UnitTest\ItopDataTestCase; +use DBObjectSearch; +use DBSearch; class CriterionConversionTest extends ItopDataTestCase { @@ -49,13 +51,17 @@ class CriterionConversionTest extends ItopDataTestCase /** * @dataProvider ToOqlProvider * + * @param $sClass * @param $sJSONCriterion * @param $sExpectedOQL + * + * @throws \Exception */ - public function testToOql($sJSONCriterion, $sExpectedOQL) + public function testToOql($sClass, $sJSONCriterion, $sExpectedOQL) { + $oSearch = new DBObjectSearch($sClass); $sOql = CriterionToOQL::Convert( - json_decode($sJSONCriterion, true) + $oSearch, json_decode($sJSONCriterion, true) ); $this->debug($sOql); @@ -66,6 +72,7 @@ class CriterionConversionTest extends ItopDataTestCase { return array( '>' => array( + 'UserRequest', '{ "ref": "UserRequest.start_date", "values": [ @@ -80,6 +87,7 @@ class CriterionConversionTest extends ItopDataTestCase "(`UserRequest`.`start_date` > '2017-01-01')" ), 'contains' => array( + 'Contact', '{ "ref": "Contact.name", "values": [ @@ -94,6 +102,7 @@ class CriterionConversionTest extends ItopDataTestCase "(`Contact`.`name` LIKE '%toto%')" ), 'starts_with' => array( + 'Contact', '{ "ref": "Contact.name", "values": [ @@ -108,6 +117,7 @@ class CriterionConversionTest extends ItopDataTestCase "(`Contact`.`name` LIKE 'toto%')" ), 'ends_with' => array( + 'Contact', '{ "ref": "Contact.name", "values": [ @@ -122,6 +132,7 @@ class CriterionConversionTest extends ItopDataTestCase "(`Contact`.`name` LIKE '%toto')" ), 'empty' => array( + 'Contact', '{ "ref": "Contact.name", "values": [ @@ -136,6 +147,7 @@ class CriterionConversionTest extends ItopDataTestCase "(`Contact`.`name` = '')" ), 'not_empty' => array( + 'Contact', '{ "ref": "Contact.name", "values": [ @@ -163,7 +175,8 @@ class CriterionConversionTest extends ItopDataTestCase function testToSearchForm($aCriterion, $sExpectedOperator) { $oSearchForm = new SearchForm(); - $oSearch = \DBSearch::FromOQL("SELECT Contact"); + /** @var \DBObjectSearch $oSearch */ + $oSearch = DBSearch::FromOQL("SELECT Contact"); $aFields = $oSearchForm->GetFields(new \DBObjectSet($oSearch)); $aRes = CriterionToSearchForm::Convert($aCriterion, $aFields, $oSearch->GetJoinedClasses()); $this->debug($aRes); @@ -530,8 +543,8 @@ class CriterionConversionTest extends ItopDataTestCase ), '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')), + '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' => 'hierarchical_key')), ), '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')", diff --git a/test/application/search/SearchFormTest.php b/test/application/search/SearchFormTest.php index bbbd06659..f2806a346 100644 --- a/test/application/search/SearchFormTest.php +++ b/test/application/search/SearchFormTest.php @@ -24,6 +24,7 @@ namespace Combodo\iTop\Test\UnitTest\Application\Search; use Combodo\iTop\Application\Search\SearchForm; use Combodo\iTop\Test\UnitTest\ItopDataTestCase; +use DBObjectSearch; use Exception; class SearchFormTest extends ItopDataTestCase @@ -43,27 +44,25 @@ class SearchFormTest extends ItopDataTestCase * @dataProvider GetFieldsProvider * @throws \OQLException */ - public function testGetFields($sOQL, $iNum, $sList) + public function testGetFields($sOQL) { $oSearchForm = new SearchForm(); $oSearch = \DBSearch::FromOQL($sOQL); $aFields = $oSearchForm->GetFields(new \DBObjectSet($oSearch)); $this->debug($sOQL); $this->debug(json_encode($aFields, JSON_PRETTY_PRINT)); - $this->assertCount($iNum, $aFields[$sList]); - + $this->assertTrue(count($aFields['zlist']) > 0); + $this->assertTrue(count($aFields['others']) > 0); } public function GetFieldsProvider() { return array( - array("SELECT Contact", 8, 'zlist'), - array("SELECT Contact AS C WHERE C.status = 'active'", 3, 'others'), - array("SELECT Person", 12, 'zlist'), + array("SELECT Contact"), + array("SELECT Contact AS C WHERE C.status = 'active'"), + array("SELECT Person"), array( "SELECT Person AS p JOIN UserRequest AS u ON u.agent_id = p.id WHERE u.status != 'closed'", - 12, - 'zlist' ), ); } @@ -83,6 +82,7 @@ class SearchFormTest extends ItopDataTestCase { $oSearch = \DBSearch::FromOQL($sOQL); $aFields = $oSearchForm->GetFields(new \DBObjectSet($oSearch)); + /** @var DBObjectSearch $oSearch */ $aCriterion = $oSearchForm->GetCriterion($oSearch, $aFields); } catch (\OQLException $e) { diff --git a/test/core/apcEmulationTest.php b/test/core/apcEmulationTest.php index 25923f9dd..2da1647ea 100644 --- a/test/core/apcEmulationTest.php +++ b/test/core/apcEmulationTest.php @@ -44,7 +44,7 @@ class apcEmulationTest extends ItopTestCase { parent::setUp(); require_once(APPROOT.'core/apc-emulation.php'); - require_once 'mockApcEmulation.php'; + require_once 'mockApcEmulation.incphp'; apc_clear_cache(); } diff --git a/test/core/dictTest.php b/test/core/dictTest.php index 02d39e9af..3d4de9cb4 100644 --- a/test/core/dictTest.php +++ b/test/core/dictTest.php @@ -44,7 +44,7 @@ class dictTest extends ItopTestCase parent::setUp(); require_once (APPROOT.'core/coreexception.class.inc.php'); require_once (APPROOT.'core/dict.class.inc.php'); - require_once 'mockDict.php'; + require_once 'mockDict.incphp'; } /** diff --git a/test/core/mockApcEmulation.php b/test/core/mockApcEmulation.incphp similarity index 100% rename from test/core/mockApcEmulation.php rename to test/core/mockApcEmulation.incphp diff --git a/test/core/mockDict.php b/test/core/mockDict.incphp similarity index 100% rename from test/core/mockDict.php rename to test/core/mockDict.incphp