diff --git a/core/valuesetdef.class.inc.php b/core/valuesetdef.class.inc.php index 99911c3de..8fc98e703 100644 --- a/core/valuesetdef.class.inc.php +++ b/core/valuesetdef.class.inc.php @@ -225,108 +225,106 @@ class ValueSetObjects extends ValueSetDefinition $this->m_aValues = array(); - if ($this->m_bAllowAllData) - { - $oFilter = DBObjectSearch::FromOQL_AllData($this->m_sFilterExpr); + $oFilter = $this->GetFilter($sOperation, $sContains); + + $oObjects = new DBObjectSet($oFilter, $this->m_aOrderBy, $aArgs, null, $this->m_iLimit, 0, $this->m_bSort); + if (empty($this->m_sValueAttCode)) { + $aAttToLoad = array($oFilter->GetClassAlias() => array('friendlyname')); + } else { + $aAttToLoad = array($oFilter->GetClassAlias() => array($this->m_sValueAttCode)); } - else - { + $oObjects->OptimizeColumnLoad($aAttToLoad); + while ($oObject = $oObjects->Fetch()) { + if (empty($this->m_sValueAttCode)) { + $this->m_aValues[$oObject->GetKey()] = $oObject->GetName(); + } else { + $this->m_aValues[$oObject->GetKey()] = $oObject->Get($this->m_sValueAttCode); + } + } + + return true; + } + + + /** + * Get filter for functions LoadValues and LoadValuesForAutocomplete + * + * @param $sOperation + * @param $sContains + * + * @return \DBObjectSearch|\DBSearch|\DBUnionSearch|false|mixed + * @throws \CoreException + * @throws \OQLException + * @since 3.0.3 3.1.0 + */ + protected function GetFilter($sOperation, $sContains) + { + $this->m_sContains = $sContains; + $this->m_sOperation = $sOperation; + + if ($this->m_bAllowAllData) { + $oFilter = DBObjectSearch::FromOQL_AllData($this->m_sFilterExpr); + } else { $oFilter = DBObjectSearch::FromOQL($this->m_sFilterExpr); $oFilter->SetShowObsoleteData(utils::ShowObsoleteData()); } - if (!$oFilter) return false; - if (!is_null($this->m_oExtraCondition)) - { + if (!$oFilter) { + return false; + } + if (!is_null($this->m_oExtraCondition)) { $oFilter = $oFilter->Intersect($this->m_oExtraCondition); } - foreach($this->m_aModifierProperties as $sPluginClass => $aProperties) - { - foreach ($aProperties as $sProperty => $value) - { + foreach ($this->m_aModifierProperties as $sPluginClass => $aProperties) { + foreach ($aProperties as $sProperty => $value) { $oFilter->SetModifierProperty($sPluginClass, $sProperty, $value); } } - $oExpression = DBObjectSearch::GetPolymorphicExpression($oFilter->GetClass(), 'friendlyname'); - $aFields = $oExpression->ListRequiredFields(); $sClass = $oFilter->GetClass(); - /*foreach($aFields as $sField) - { - $aFieldItems = explode('.', $sField); - if ($aFieldItems[0] != $sClass) - { - $sOperation = 'contains'; - break; - } - }*/ - switch ($sOperation) - { + switch ($this->m_sOperation) { case 'equals': - $aAttributes = MetaModel::GetFriendlyNameAttributeCodeList($sClass); - $sClassAlias = $oFilter->GetClassAlias(); - $aFilters = array(); - $oValueExpr = new ScalarExpression($sContains); - foreach($aAttributes as $sAttribute) - { - $oNewFilter = $oFilter->DeepClone(); - $oNameExpr = new FieldExpression($sAttribute, $sClassAlias); - $oCondition = new BinaryExpression($oNameExpr, '=', $oValueExpr); - $oNewFilter->AddConditionExpression($oCondition); - $aFilters[] = $oNewFilter; + case 'start_with': + if ($this->m_sOperation === 'start_with') { + $this->m_sContains .= '%'; + $sOperator = 'LIKE'; + } else { + $sOperator = '='; + } + + $aAttributes = MetaModel::GetFriendlyNameAttributeCodeList($sClass); + if (count($aAttributes) > 0) { + $sClassAlias = $oFilter->GetClassAlias(); + $aFilters = array(); + $oValueExpr = new ScalarExpression($this->m_sContains); + foreach ($aAttributes as $sAttribute) { + $oNewFilter = $oFilter->DeepClone(); + $oNameExpr = new FieldExpression($sAttribute, $sClassAlias); + $oCondition = new BinaryExpression($oNameExpr, $sOperator, $oValueExpr); + $oNewFilter->AddConditionExpression($oCondition); + $aFilters[] = $oNewFilter; + } + // Unions are much faster than OR conditions + $oFilter = new DBUnionSearch($aFilters); + } else { + $oValueExpr = new ScalarExpression($this->m_sContains); + $oNameExpr = new FieldExpression('friendlyname', $oFilter->GetClassAlias()); + $oNewCondition = new BinaryExpression($oNameExpr, $sOperator, $oValueExpr); + $oFilter->AddConditionExpression($oNewCondition); } - // Unions are much faster than OR conditions - $oFilter = new DBUnionSearch($aFilters); break; - case 'start_with': - $aAttributes = MetaModel::GetFriendlyNameAttributeCodeList($sClass); - $sClassAlias = $oFilter->GetClassAlias(); - $aFilters = array(); - $oValueExpr = new ScalarExpression($sContains.'%'); - foreach($aAttributes as $sAttribute) - { - $oNewFilter = $oFilter->DeepClone(); - $oNameExpr = new FieldExpression($sAttribute, $sClassAlias); - $oCondition = new BinaryExpression($oNameExpr, 'LIKE', $oValueExpr); - $oNewFilter->AddConditionExpression($oCondition); - $aFilters[] = $oNewFilter; - } - // Unions are much faster than OR conditions - $oFilter = new DBUnionSearch($aFilters); - break; default: - $oValueExpr = new ScalarExpression('%'.$sContains.'%'); + $oValueExpr = new ScalarExpression('%'.$this->m_sContains.'%'); $oNameExpr = new FieldExpression('friendlyname', $oFilter->GetClassAlias()); $oNewCondition = new BinaryExpression($oNameExpr, 'LIKE', $oValueExpr); $oFilter->AddConditionExpression($oNewCondition); break; } - $oObjects = new DBObjectSet($oFilter, $this->m_aOrderBy, $aArgs, null, $this->m_iLimit, 0, $this->m_bSort); - if (empty($this->m_sValueAttCode)) - { - $aAttToLoad = array($oFilter->GetClassAlias() => array('friendlyname')); - } - else - { - $aAttToLoad = array($oFilter->GetClassAlias() => array($this->m_sValueAttCode)); - } - $oObjects->OptimizeColumnLoad($aAttToLoad); - while ($oObject = $oObjects->Fetch()) - { - if (empty($this->m_sValueAttCode)) - { - $this->m_aValues[$oObject->GetKey()] = $oObject->GetName(); - } - else - { - $this->m_aValues[$oObject->GetKey()] = $oObject->Get($this->m_sValueAttCode); - } - } - return true; + return $oFilter; } - + public function GetValuesDescription() { return 'Filter: '.$this->m_sFilterExpr; @@ -376,73 +374,12 @@ class ValueSetObjects extends ValueSetDefinition */ protected function LoadValuesForAutocomplete($aArgs, $sContains = '', $sOperation = 'contains') { - $this->m_sContains = $sContains; - $this->m_sOperation = $sOperation; - $this->m_aValues = array(); - if ($this->m_bAllowAllData) { - $oFilter = DBObjectSearch::FromOQL_AllData($this->m_sFilterExpr); - } else { - $oFilter = DBObjectSearch::FromOQL($this->m_sFilterExpr); - $oFilter->SetShowObsoleteData(utils::ShowObsoleteData()); - } - - if (!$oFilter) { - return false; - } - if (!is_null($this->m_oExtraCondition)) { - $oFilter = $oFilter->Intersect($this->m_oExtraCondition); - } - foreach ($this->m_aModifierProperties as $sPluginClass => $aProperties) { - foreach ($aProperties as $sProperty => $value) { - $oFilter->SetModifierProperty($sPluginClass, $sProperty, $value); - } - } - - //$oExpression = DBObjectSearch::GetPolymorphicExpression($oFilter->GetClass(), 'friendlyname'); + $oFilter = $this->GetFilter($sOperation, $sContains); $sClass = $oFilter->GetClass(); $sClassAlias = $oFilter->GetClassAlias(); - switch ($sOperation) { - case 'equals': - $aAttributes = MetaModel::GetFriendlyNameAttributeCodeList($sClass); - $aFilters = array(); - $oValueExpr = new ScalarExpression($sContains); - foreach ($aAttributes as $sAttribute) { - $oNewFilter = $oFilter->DeepClone(); - $oNameExpr = new FieldExpression($sAttribute, $sClassAlias); - $oCondition = new BinaryExpression($oNameExpr, '=', $oValueExpr); - $oNewFilter->AddConditionExpression($oCondition); - $aFilters[] = $oNewFilter; - } - // Unions are much faster than OR conditions - $oFilter = new DBUnionSearch($aFilters); - break; - case 'start_with': - $aAttributes = MetaModel::GetFriendlyNameAttributeCodeList($sClass); - $aFilters = array(); - $oValueExpr = new ScalarExpression($sContains.'%'); - foreach($aAttributes as $sAttribute) - { - $oNewFilter = $oFilter->DeepClone(); - $oNameExpr = new FieldExpression($sAttribute, $sClassAlias); - $oCondition = new BinaryExpression($oNameExpr, 'LIKE', $oValueExpr); - $oNewFilter->AddConditionExpression($oCondition); - $aFilters[] = $oNewFilter; - } - // Unions are much faster than OR conditions - $oFilter = new DBUnionSearch($aFilters); - break; - - default: - $oValueExpr = new ScalarExpression('%'.$sContains.'%'); - $oNameExpr = new FieldExpression('friendlyname', $sClassAlias); - $oNewCondition = new BinaryExpression($oNameExpr, 'LIKE', $oValueExpr); - $oFilter->AddConditionExpression($oNewCondition); - break; - } - $oObjects = new DBObjectSet($oFilter, $this->m_aOrderBy, $aArgs, null, $this->m_iLimit, 0, $this->m_bSort); if (empty($this->m_sValueAttCode)) { $aAttToLoad = ['friendlyname']; diff --git a/tests/php-unit-tests/unitary-tests/core/MockValueSetObjects.php b/tests/php-unit-tests/unitary-tests/core/MockValueSetObjects.php new file mode 100644 index 000000000..7db46cea8 --- /dev/null +++ b/tests/php-unit-tests/unitary-tests/core/MockValueSetObjects.php @@ -0,0 +1,17 @@ +GetFilter($sOperation, $sContains)->ToOQL(); + + } +} diff --git a/tests/php-unit-tests/unitary-tests/core/ValueSetObjectsTest.php b/tests/php-unit-tests/unitary-tests/core/ValueSetObjectsTest.php new file mode 100644 index 000000000..9f7089f3f --- /dev/null +++ b/tests/php-unit-tests/unitary-tests/core/ValueSetObjectsTest.php @@ -0,0 +1,64 @@ +RequireOnceItopFile('core/valuesetdef.class.inc.php'); + $this->RequireOnceItopFile('application/startup.inc.php'); + $this->RequireOnceUnitTestFile('./MockValueSetObjects.php'); + } + + /** + * @return array + */ + public function GetGetFilterProvider() + { + return array( + 'Ticket contains bla' => array("Ticket", "bla", "contains", "SELECT `Ticket` FROM Ticket AS `Ticket` WHERE (`Ticket`.`friendlyname` LIKE '%bla%')"), + 'Ticket equals bla' => array("Ticket", "bla", "equals", "SELECT `Ticket` FROM Ticket AS `Ticket` WHERE (`Ticket`.`ref` = 'bla')"), + 'Ticket start_with bla' => array("Ticket", "bla", "start_with", "SELECT `Ticket` FROM Ticket AS `Ticket` WHERE (`Ticket`.`ref` LIKE 'bla%')"), + 'UserRequest contains bla' => array("UserRequest", "bla", "contains", "SELECT `UserRequest` FROM UserRequest AS `UserRequest` WHERE (`UserRequest`.`friendlyname` LIKE '%bla%')"), + 'UserRequest equals bla' => array("UserRequest", "bla", "equals", "SELECT `UserRequest` FROM UserRequest AS `UserRequest` WHERE (`UserRequest`.`ref` = 'bla')"), + 'UserRequest start_with bla' => array("UserRequest", "bla", "start_with", "SELECT `UserRequest` FROM UserRequest AS `UserRequest` WHERE (`UserRequest`.`ref` LIKE 'bla%')"), + ); + } + + + /** + * @param $Class + * @param $sContains + * @param $sOperation + * @param $sExpectedOQL + * + * @dataProvider GetGetFilterProvider + * @return void + */ + public function testGetFiler($Class, $sContains, $sOperation, $sExpectedOQL) + { + $sFilterExp = 'SELECT '.$Class; + $oValueSetObject = new MockValueSetObjects($sFilterExp); + $sFilter = $oValueSetObject->GetFilterOQL($sOperation, $sContains); + + $this->assertEquals($sExpectedOQL, $sFilter); + + } +} \ No newline at end of file