diff --git a/core/oql/expression.class.inc.php b/core/oql/expression.class.inc.php index 63f806382..98510a594 100644 --- a/core/oql/expression.class.inc.php +++ b/core/oql/expression.class.inc.php @@ -59,6 +59,11 @@ abstract class Expression return $this->Render($aArgs); } + public function GetAttDef($aClasses = array()) + { + return null; + } + /** * Recursively browse the expression tree * @param Closure $callback @@ -384,6 +389,14 @@ class BinaryExpression extends Expression $this->GetRightExpr()->CollectUsedParents($aTable); } + public function GetAttDef($aClasses = array()) + { + $oAttDef = $this->GetLeftExpr()->GetAttDef($aClasses); + if (!is_null($oAttDef)) return $oAttDef; + + return $this->GetRightExpr()->GetAttDef($aClasses); + } + /** * List all constant expression of the form = or = : * Could be extended to support = @@ -502,11 +515,10 @@ class BinaryExpression extends Expression // Default criterion (Field OPE Field) is not supported return parent::GetCriterion($oSearch, $aArgs, $bRetrofitParams, $oAttDef); } - if ($oLeftExpr instanceof FieldExpression) - { - $oAttDef = $oLeftExpr->GetAttDef($oSearch->GetJoinedClasses()); - } - if ($oRightExpr instanceof FieldExpression) + + $oAttDef = $oLeftExpr->GetAttDef($oSearch->GetJoinedClasses()); + + if (is_null($oAttDef)) { $oAttDef = $oRightExpr->GetAttDef($oSearch->GetJoinedClasses()); $bReverseOperator = true; @@ -649,6 +661,11 @@ class ScalarExpression extends UnaryExpression */ public function Display($oSearch, &$aArgs = null, $oAttDef = null) { + if (strpos($this->m_value, '%') === 0) + { + return ''; + } + if (!is_null($oAttDef)) { if ($oAttDef->IsExternalKey()) @@ -668,11 +685,6 @@ class ScalarExpression extends UnaryExpression return $oAttDef->GetAsPlainText($this->m_value); } - if (strpos($this->m_value, '%') === 0) - { - return ''; - } - return $this->Render($aArgs); } @@ -697,43 +709,44 @@ class ScalarExpression extends UnaryExpression public function GetCriterion($oSearch, &$aArgs = null, $bRetrofitParams = false, $oAttDef = null) { - $aValue = array('value' => $this->GetValue()); - if (!is_null($oAttDef)) - { - switch (true) - { - case $oAttDef->IsExternalKey(): - try - { - /** @var AttributeExternalKey $oAttDef */ - $sTarget = $oAttDef->GetTargetClass(); - $oObj = MetaModel::GetObject($sTarget, $this->GetValue()); - - $aValue['label'] = $oObj->Get("friendlyname"); - - } catch (Exception $e) - { - IssueLog::Error($e->getMessage()); - } - break; - default: - $aValue['label'] = $oAttDef->GetAsPlainText($this->GetValue()); - break; - } - } $aCriteria = array(); switch ((string)($this->m_value)) { case '%Y-%m-%d': - $aCriteria['date'] = 'd'; + $aCriteria['date_type'] = 'd'; break; case '%Y-%m': - $aCriteria['date'] = 'm'; + $aCriteria['date_type'] = 'm'; break; case '%w': - $aCriteria['date'] = 'w'; + $aCriteria['date_type'] = 'w'; break; default: + $aValue = array('value' => $this->GetValue()); + if (!is_null($oAttDef)) + { + switch (true) + { + case $oAttDef->IsExternalKey(): + try + { + /** @var AttributeExternalKey $oAttDef */ + $sTarget = $oAttDef->GetTargetClass(); + $oObj = MetaModel::GetObject($sTarget, $this->GetValue()); + + $aValue['label'] = $oObj->Get("friendlyname"); + + } + catch (Exception $e) + { + IssueLog::Error($e->getMessage()); + } + break; + default: + $aValue['label'] = $oAttDef->GetAsPlainText($this->GetValue()); + break; + } + } $aCriteria['values'] = array($aValue); break; } @@ -1313,6 +1326,17 @@ class ListExpression extends Expression } } + public function GetAttDef($aClasses = array()) + { + foreach($this->m_aExpressions as $oExpression) + { + $oAttDef = $oExpression->GetAttDef($aClasses); + if (!is_null($oAttDef)) return $oAttDef; + } + + return null; + } + public function GetCriterion($oSearch, &$aArgs = null, $bRetrofitParams = false, $oAttDef = null) { $aValues = array(); @@ -1456,6 +1480,17 @@ class FunctionExpression extends Expression } } + public function GetAttDef($aClasses = array()) + { + foreach($this->m_aArgs as $oExpression) + { + $oAttDef = $oExpression->GetAttDef($aClasses); + if (!is_null($oAttDef)) return $oAttDef; + } + + return null; + } + /** * Make the most relevant label, given the value of the expression * @@ -1577,6 +1612,7 @@ class FunctionExpression extends Expression case 'DATE_ADD': case 'DATE_SUB': + case 'DATE_FORMAT': $aCriteria = array('widget' => 'date_time'); foreach($this->m_aArgs as $oExpression) { diff --git a/sources/application/search/criterionconversion/criteriontooql.class.inc.php b/sources/application/search/criterionconversion/criteriontooql.class.inc.php index 36c946030..b116904e1 100644 --- a/sources/application/search/criterionconversion/criteriontooql.class.inc.php +++ b/sources/application/search/criterionconversion/criteriontooql.class.inc.php @@ -30,7 +30,6 @@ use AttributeExternalKey; use Combodo\iTop\Application\Search\AjaxSearchException; use Combodo\iTop\Application\Search\CriterionConversionAbstract; use Combodo\iTop\Application\Search\SearchForm; -use DateInterval; class CriterionToOQL extends CriterionConversionAbstract { @@ -273,9 +272,8 @@ class CriterionToOQL extends CriterionConversionAbstract if (!empty($sEndDate)) { $oDate = $oFormat->parse($sEndDate); - $oDate->add(DateInterval::createFromDateString('1 second')); $sEndDate = $oDate->format($sAttributeClass::GetSQLFormat()); - $aOQL[] = "({$sRef} < '$sEndDate')"; + $aOQL[] = "({$sRef} <= '$sEndDate')"; } $sOQL = implode(' AND ', $aOQL); diff --git a/sources/application/search/criterionconversion/criteriontosearchform.class.inc.php b/sources/application/search/criterionconversion/criteriontosearchform.class.inc.php index d86fbd18a..34a003e64 100644 --- a/sources/application/search/criterionconversion/criteriontosearchform.class.inc.php +++ b/sources/application/search/criterionconversion/criteriontosearchform.class.inc.php @@ -25,6 +25,7 @@ namespace Combodo\iTop\Application\Search\CriterionConversion; +use AttributeDate; use AttributeDateTime; use AttributeDefinition; use Combodo\iTop\Application\Search\CriterionConversionAbstract; @@ -169,14 +170,14 @@ class CriterionToSearchForm extends CriterionConversionAbstract // Merge into 'between' operation. // The ends of the interval are included $aCurrCriterion['operator'] = 'between_dates'; - $sFormat = AttributeDateTime::GetFormat()->ToMomentJS(); + $oFormat = AttributeDate::GetFormat(); $sLastDate = $aPrevCriterion['values'][0]['value']; if ($sPrevOperator == '<') { // previous day to include ends $oDate = new DateTime($sLastDate); $oDate->sub(DateInterval::createFromDateString('1 day')); - $sLastDate = $oDate->format($sFormat); + $sLastDate = $oFormat->format($oDate); } $sFirstDate = $aCurrCriterion['values'][0]['value']; @@ -185,7 +186,7 @@ class CriterionToSearchForm extends CriterionConversionAbstract // next day to include ends $oDate = new DateTime($sFirstDate); $oDate->add(DateInterval::createFromDateString('1 day')); - $sFirstDate = $oDate->format($sFormat); + $sFirstDate = $oFormat->format($oDate); } $aCurrCriterion['values'] = array(); @@ -338,13 +339,36 @@ class CriterionToSearchForm extends CriterionConversionAbstract protected static function DateToSearchForm($aCriteria, $aFields) { - return DateTimeToSearchForm($aCriteria, $aFields); + return self::DateTimeToSearchForm($aCriteria, $aFields); } protected static function DateTimeToSearchForm($aCriteria, $aFields) { if (!array_key_exists('is_relative', $aCriteria) || !$aCriteria['is_relative']) { + // Convert '=' in 'between' + if (isset($aCriteria['operator']) && ($aCriteria['operator'] === '=')) + { + $aCriteria['operator'] = CriterionConversionAbstract::OP_BETWEEN_DATES; + $sWidget = $aCriteria['widget']; + if ($sWidget == AttributeDefinition::SEARCH_WIDGET_TYPE_DATE) + { + $aCriteria['values'][1] = $aCriteria['values'][0]; + } + else + { + $sDate = $aCriteria['values'][0]['value']; + $oDate = new DateTime($sDate); + + $oDate->add(DateInterval::createFromDateString('1 day')); + $oDate->sub(DateInterval::createFromDateString('1 second')); + + $sLastDate = $oDate->format(AttributeDateTime::GetSQLFormat()); + $sLastDate = AttributeDateTime::GetFormat()->Format($sLastDate); + $aCriteria['values'][1] = array('value' => $sLastDate, 'label' => $sLastDate); + } + } + return $aCriteria; } diff --git a/test/application/search/CriterionConversionTest.php b/test/application/search/CriterionConversionTest.php index 65439e78b..38cf022d0 100644 --- a/test/application/search/CriterionConversionTest.php +++ b/test/application/search/CriterionConversionTest.php @@ -297,6 +297,9 @@ class CriterionConversionTest extends ItopDataTestCase /** * @dataProvider OqlProvider + * + * @param $sOQL + * * @throws \OQLException */ function testOqlToForSearchToOql($sOQL)