N°1431 - Sort on attribute or aggregation function

SVN:trunk[5814]
This commit is contained in:
Eric Espié
2018-05-25 15:38:36 +00:00
parent 3ad64d9823
commit 04e41ab676
4 changed files with 186 additions and 166 deletions

View File

@@ -734,19 +734,21 @@ abstract class DashletGroupBy extends Dashlet
$this->aProperties['query'] = 'SELECT Contact';
$this->aProperties['group_by'] = 'status';
$this->aProperties['style'] = 'table';
$this->aProperties['agregation_function'] = 'count';
$this->aProperties['agregation_attribute'] = '';
$this->aProperties['aggregation_function'] = 'count';
$this->aProperties['aggregation_attribute'] = '';
$this->aProperties['limit'] = '';
$this->aProperties['order_direction'] = 'desc';
$this->aProperties['order_by'] = '';
$this->aProperties['order_direction'] = '';
}
protected $sGroupByLabel = null;
protected $sGroupByExpr = null;
protected $sGroupByAttCode = null;
protected $sFunction = null;
protected $sAgregationFunction = null;
protected $sAgregationAttribute = null;
protected $sAggregationFunction = null;
protected $sAggregationAttribute = null;
protected $sLimit = null;
protected $sOrderBy = null;
protected $sOrderDirection = null;
protected $sClass = null;
@@ -764,10 +766,22 @@ abstract class DashletGroupBy extends Dashlet
$sQuery = $this->aProperties['query'];
$sGroupBy = $this->aProperties['group_by'];
$this->sAgregationFunction = $this->aProperties['agregation_function'];
$this->sAgregationAttribute = $this->aProperties['agregation_attribute'];
$this->sAggregationFunction = $this->aProperties['aggregation_function'];
$this->sAggregationAttribute = $this->aProperties['aggregation_attribute'];
$this->sLimit = $this->aProperties['limit'];
$this->sOrderDirection = $this->aProperties['order_direction'];
$this->sOrderBy = $this->aProperties['order_by'];
if (empty($this->sOrderBy))
{
if ($this->aProperties['style'] == 'pie')
{
$this->sOrderBy = 'function';
}
else
{
$this->sOrderBy = 'attribute';
}
}
// First perform the query - if the OQL is not ok, it will generate an exception : no need to go further
try
@@ -782,6 +796,7 @@ abstract class DashletGroupBy extends Dashlet
$this->sClass = null;
$sClassAlias = '';
}
// Check groupby... it can be wrong at this stage
if (preg_match('/^(.*):(.*)$/', $sGroupBy, $aMatches))
{
@@ -793,6 +808,25 @@ abstract class DashletGroupBy extends Dashlet
$this->sGroupByAttCode = $sGroupBy;
$this->sFunction = null;
}
if (empty($this->aProperties['order_direction']))
{
$aAttributeTypes = $this->oModelReflection->ListAttributes($this->sClass);
$sAttributeType = $aAttributeTypes[$this->sGroupByAttCode];
if (is_subclass_of($sAttributeType, 'AttributeDateTime') || $sAttributeType == 'AttributeDateTime')
{
$this->sOrderDirection = 'asc';
}
else
{
$this->sOrderDirection = 'desc';
}
}
else
{
$this->sOrderDirection = $this->aProperties['order_direction'];
}
if ((!is_null($this->sClass)) && $this->oModelReflection->IsValidAttCode($this->sClass, $this->sGroupByAttCode))
{
$sAttLabel = $this->oModelReflection->GetLabel($this->sClass, $this->sGroupByAttCode);
@@ -864,10 +898,11 @@ abstract class DashletGroupBy extends Dashlet
'chart_title' => $sTitle,
'group_by' => $this->sGroupByExpr,
'group_by_label' => $this->sGroupByLabel,
'agregation_function' => $this->sAgregationFunction,
'agregation_attribute' => $this->sAgregationAttribute,
'aggregation_function' => $this->sAggregationFunction,
'aggregation_attribute' => $this->sAggregationAttribute,
'limit' => $this->sLimit,
'order_direction' => $this->sOrderDirection,
'order_by' => $this->sOrderBy,
);
$sHtmlTitle = ''; // done in the itop block
break;
@@ -879,10 +914,11 @@ abstract class DashletGroupBy extends Dashlet
'chart_title' => $sTitle,
'group_by' => $this->sGroupByExpr,
'group_by_label' => $this->sGroupByLabel,
'agregation_function' => $this->sAgregationFunction,
'agregation_attribute' => $this->sAgregationAttribute,
'aggregation_function' => $this->sAggregationFunction,
'aggregation_attribute' => $this->sAggregationAttribute,
'limit' => $this->sLimit,
'order_direction' => $this->sOrderDirection,
'order_by' => $this->sOrderBy,
);
$sHtmlTitle = ''; // done in the itop block
break;
@@ -894,10 +930,11 @@ abstract class DashletGroupBy extends Dashlet
$aExtraParams = array(
'group_by' => $this->sGroupByExpr,
'group_by_label' => $this->sGroupByLabel,
'agregation_function' => $this->sAgregationFunction,
'agregation_attribute' => $this->sAgregationAttribute,
'aggregation_function' => $this->sAggregationFunction,
'aggregation_attribute' => $this->sAggregationAttribute,
'limit' => $this->sLimit,
'order_direction' => $this->sOrderDirection,
'order_by' => $this->sOrderBy,
);
break;
}
@@ -1019,6 +1056,7 @@ abstract class DashletGroupBy extends Dashlet
{
$oField = new DesignerTextField('group_by', Dict::S('UI:DashletGroupBy:Prop-GroupBy'), $this->aProperties['group_by']);
$oField->SetReadOnly();
$aGroupBy = array();
}
$oForm->AddField($oField);
@@ -1035,7 +1073,7 @@ abstract class DashletGroupBy extends Dashlet
$aFunctionAttributes = $this->GetNumericAttributes($this->aProperties['query']);
$aFunctions = $this->GetAllowedFunctions($aFunctionAttributes);
$oSelectorField = new DesignerFormSelectorField('agregation_function', Dict::S('UI:DashletGroupBy:Prop-Function'), $this->aProperties['agregation_function']);
$oSelectorField = new DesignerFormSelectorField('aggregation_function', Dict::S('UI:DashletGroupBy:Prop-Function'), $this->aProperties['aggregation_function']);
$oForm->AddField($oSelectorField);
$oSelectorField->SetMandatory();
// Count sub-menu
@@ -1044,25 +1082,48 @@ abstract class DashletGroupBy extends Dashlet
foreach($aFunctions as $sFct => $sLabel)
{
$oSubForm = new DesignerForm();
$oField = new DesignerComboField('agregation_attribute', Dict::S('UI:DashletGroupBy:Prop-FunctionAttribute'), $this->aProperties['agregation_attribute']);
$oField = new DesignerComboField('aggregation_attribute', Dict::S('UI:DashletGroupBy:Prop-FunctionAttribute'), $this->aProperties['aggregation_attribute']);
$oField->SetMandatory();
$oField->SetAllowedValues($aFunctionAttributes);
$oSubForm->AddField($oField);
$oSelectorField->AddSubForm($oSubForm, $sLabel, $sFct);
}
$aOrderField = array(
'attribute' => $aGroupBy[$this->aProperties['group_by']],
);
if ($this->aProperties['aggregation_function'] == 'count')
{
$aOrderField['function'] = Dict::S('UI:GroupBy:count');
}
else
{
$aOrderField['function'] = $aFunctions[$this->aProperties['aggregation_function']];
}
$oSelectorField = new DesignerFormSelectorField('order_by', Dict::S('UI:DashletGroupBy:Prop-OrderField'), $this->aProperties['order_by']);
$oForm->AddField($oSelectorField);
$oSelectorField->SetMandatory();
foreach($aOrderField as $sField => $sLabel)
{
$oSubForm = new DesignerForm();
if ($sField == 'function')
{
$oField = new DesignerIntegerField('limit', Dict::S('UI:DashletGroupBy:Prop-Limit'), $this->aProperties['limit']);
$oSubForm->AddField($oField);
}
$oSelectorField->AddSubForm($oSubForm, $sLabel, $sField);
}
$aOrderDirections = array(
'asc' => Dict::S('UI:DashletGroupBy:Order:asc'),
'desc' => Dict::S('UI:DashletGroupBy:Order:desc'),
);
$oField = new DesignerComboField('order_direction', Dict::S('UI:DashletGroupBy:Prop-OrderDirection'), $this->aProperties['order_direction']);
$sOrderDirection = empty($this->aProperties['order_direction']) ? $this->sOrderDirection : $this->aProperties['order_direction'];
$oField = new DesignerComboField('order_direction', Dict::S('UI:DashletGroupBy:Prop-OrderDirection'), $sOrderDirection);
$oField->SetMandatory();
$oField->SetAllowedValues($aOrderDirections);
$oForm->AddField($oField);
$oField = new DesignerIntegerField('limit', Dict::S('UI:DashletGroupBy:Prop-Limit'), $this->aProperties['limit']);
$oForm->AddField($oField);
}
/**
@@ -1077,7 +1138,7 @@ abstract class DashletGroupBy extends Dashlet
}
return array(
$this->aProperties['group_by'] => $this->oModelReflection->GetLabel($this->sClass, $this->aProperties['group_by']),
'_itop_'.$this->aProperties['agregation_function'].'_' => Dict::S('UI:GroupBy:'.$this->aProperties['agregation_function']));
'_itop_'.$this->aProperties['aggregation_function'].'_' => Dict::S('UI:GroupBy:'.$this->aProperties['aggregation_function']));
}
/**
@@ -1177,11 +1238,11 @@ abstract class DashletGroupBy extends Dashlet
$oDashlet->bRedrawNeeded = true;
$oDashlet->bFormRedrawNeeded = true;
}
if (in_array('group_by', $aUpdatedFields) || in_array('agregation_attribute', $aUpdatedFields) || in_array('order_direction', $aUpdatedFields) || in_array('limit', $aUpdatedFields))
if (in_array('aggregation_attribute', $aUpdatedFields) || in_array('order_direction', $aUpdatedFields) || in_array('order_by', $aUpdatedFields) || in_array('limit', $aUpdatedFields))
{
$oDashlet->bRedrawNeeded = true;
}
if (in_array('agregation_function', $aUpdatedFields))
if (in_array('group_by', $aUpdatedFields) || in_array('aggregation_function', $aUpdatedFields))
{
$oDashlet->bRedrawNeeded = true;
$oDashlet->bFormRedrawNeeded = true;

View File

@@ -428,71 +428,7 @@ class DisplayBlock
case 'count':
if (isset($aExtraParams['group_by']))
{
$sAlias = $this->m_oFilter->GetClassAlias();
if (isset($aExtraParams['group_by_label']))
{
$oGroupByExp = Expression::FromOQL($aExtraParams['group_by']);
$sGroupByLabel = $aExtraParams['group_by_label'];
}
else
{
// Backward compatibility: group_by is simply a field id
$oGroupByExp = new FieldExpression($aExtraParams['group_by'], $sAlias);
$sGroupByLabel = MetaModel::GetLabel($this->m_oFilter->GetClass(), $aExtraParams['group_by']);
}
// Security filtering
$aFields = $oGroupByExp->ListRequiredFields();
foreach($aFields as $sFieldAlias)
{
if (preg_match('/^([^.]+)\\.([^.]+)$/', $sFieldAlias, $aMatches))
{
$sFieldClass = $this->m_oFilter->GetClassName($aMatches[1]);
$oAttDef = MetaModel::GetAttributeDef($sFieldClass, $aMatches[2]);
if ($oAttDef instanceof AttributeOneWayPassword)
{
throw new Exception('Grouping on password fields is not supported.');
}
}
}
$aGroupBy = array();
$aGroupBy['grouped_by_1'] = $oGroupByExp;
$aQueryParams = array();
if (isset($aExtraParams['query_params']))
{
$aQueryParams = $aExtraParams['query_params'];
}
$aFunctions = array();
$aOrderBy = array();
$sAgregationFunction = 'count';
$sFctVar = '_itop_count_';
$sAgregationAttr = '';
if (isset($aExtraParams['agregation_function']) && !empty($aExtraParams['agregation_attribute']))
{
$sAgregationFunction = $aExtraParams['agregation_function'];
$sAgregationAttr = $aExtraParams['agregation_attribute'];
$oAttrExpr = Expression::FromOQL('`'.$sAlias.'`.`'.$sAgregationAttr.'`');
$oFctExpr = new FunctionExpression(strtoupper($sAgregationFunction), array($oAttrExpr));
$sFctVar = '_itop_'.$sAgregationFunction.'_';
$aFunctions = array($sFctVar => $oFctExpr);
}
if (!empty($sAgregationAttr))
{
$sClass = $this->m_oFilter->GetClass();
$sAgregationAttr = MetaModel::GetLabel($sClass, $sAgregationAttr);
}
$iLimit = 0;
if (isset($aExtraParams['limit']))
{
$iLimit = intval($aExtraParams['limit']);
}
if (isset($aExtraParams['order_direction']))
{
$aOrderBy = array($sFctVar => ($aExtraParams['order_direction'] === 'asc'));
}
$sSql = $this->m_oFilter->MakeGroupByQuery($aQueryParams, $aGroupBy, true, $aFunctions, $aOrderBy, $iLimit);
$this->MakeGroupByQuery($aExtraParams, $oGroupByExp, $sGroupByLabel, $aGroupBy, $sAggregationFunction, $sFctVar, $sAggregationAttr, $sSql);
$aRes = CMDBSource::QueryToArray($sSql);
@@ -527,7 +463,7 @@ class DisplayBlock
}
$aAttribs =array(
'group' => array('label' => $sGroupByLabel, 'description' => ''),
'value' => array('label'=> Dict::S('UI:GroupBy:'.$sAgregationFunction), 'description' => Dict::Format('UI:GroupBy:'.$sAgregationFunction.'+', $sAgregationAttr))
'value' => array('label'=> Dict::S('UI:GroupBy:'.$sAggregationFunction), 'description' => Dict::Format('UI:GroupBy:'.$sAggregationFunction.'+', $sAggregationAttr))
);
$sFormat = isset($aExtraParams['format']) ? $aExtraParams['format'] : 'UI:Pagination:HeaderNoSelection';
$sHtml .= $oPage->GetP(Dict::Format($sFormat, $iTotalCount));
@@ -922,36 +858,6 @@ class DisplayBlock
}
$sAjaxLink = utils::GetAbsoluteUrlAppRoot().'webservices/export.php';
/*
$sCSVData = cmdbAbstractObject::GetSetAsCSV($this->m_oSet, array('fields_advanced' => $bAdvancedMode));
$sCharset = MetaModel::GetConfig()->Get('csv_file_default_charset');
if ($sCharset == 'UTF-8')
{
$bLostChars = false;
}
else
{
$sConverted = @iconv('UTF-8', $sCharset, $sCSVData);
$sRestored = @iconv($sCharset, 'UTF-8', $sConverted);
$bLostChars = ($sRestored != $sCSVData);
}
if ($bLostChars)
{
$sCharsetNotice = "&nbsp;&nbsp;<span id=\"csv_charset_issue\">";
$sCharsetNotice .= '<img src="../images/error.png" style="vertical-align:middle"/>';
$sCharsetNotice .= "</span>";
$sTip = "<p>".htmlentities(Dict::S('UI:CSVExport:LostChars'), ENT_QUOTES, 'UTF-8')."</p>";
$sTip .= "<p>".htmlentities(Dict::Format('UI:CSVExport:LostChars+', $sCharset), ENT_QUOTES, 'UTF-8')."</p>";
$oPage->add_ready_script("$('#csv_charset_issue').qtip( { content: '$sTip', show: 'mouseover', hide: 'mouseout', style: { name: 'dark', tip: 'leftTop' }, position: { corner: { target: 'rightMiddle', tooltip: 'leftTop' }} } );");
}
else
{
$sCharsetNotice = '';
}
*/
$sCharsetNotice = false;
$sHtml .= "<div>";
$sHtml .= '<table style="width:100%" class="transparent">';
@@ -1007,19 +913,19 @@ class DisplayBlock
$sFilter = $this->m_oFilter->serialize();
$oContext = new ApplicationContext();
$sContextParam = $oContext->GetForLink();
$sAgregationFunction = isset($aExtraParams['agregation_function']) ? $aExtraParams['agregation_function'] : '';
$sAgregationAttr = isset($aExtraParams['agregation_attribute']) ? $aExtraParams['agregation_attribute'] : '';
$sAggregationFunction = isset($aExtraParams['aggregation_function']) ? $aExtraParams['aggregation_function'] : '';
$sAggregationAttr = isset($aExtraParams['aggregation_attribute']) ? $aExtraParams['aggregation_attribute'] : '';
$sLimit = isset($aExtraParams['limit']) ? $aExtraParams['limit'] : '';
$sOrderBy = isset($aExtraParams['order_by']) ? $aExtraParams['order_by'] : '';
$sOrderDirection = isset($aExtraParams['order_direction']) ? $aExtraParams['order_direction'] : '';
if (isset($aExtraParams['group_by_label']))
{
$sUrl = json_encode(utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=chart&params[group_by]=$sGroupBy{$sGroupByExpr}&params[group_by_label]={$aExtraParams['group_by_label']}&params[chart_type]=$sChartType&params[currentId]=$sId{$iChartCounter}&params[order_direction]=$sOrderDirection&params[order_by]=$sOrderBy&params[limit]=$sLimit&params[agregation_function]=$sAgregationFunction&params[agregation_attribute]=$sAgregationAttr&id=$sId{$iChartCounter}&filter=".urlencode($sFilter).'&'.$sContextParam);
$sUrl = json_encode(utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=chart&params[group_by]=$sGroupBy{$sGroupByExpr}&params[group_by_label]={$aExtraParams['group_by_label']}&params[chart_type]=$sChartType&params[currentId]=$sId{$iChartCounter}&params[order_direction]=$sOrderDirection&params[order_by]=$sOrderBy&params[limit]=$sLimit&params[aggregation_function]=$sAggregationFunction&params[aggregation_attribute]=$sAggregationAttr&id=$sId{$iChartCounter}&filter=".urlencode($sFilter).'&'.$sContextParam);
}
else
{
$sUrl = json_encode(utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=chart&params[group_by]=$sGroupBy{$sGroupByExpr}&params[chart_type]=$sChartType&params[currentId]=$sId{$iChartCounter}&params[order_direction]=$sOrderDirection&params[order_by]=$sOrderBy&params[limit]=$sLimit&params[agregation_function]=$sAgregationFunction&params[agregation_attribute]=$sAgregationAttr&id=$sId{$iChartCounter}&filter=".urlencode($sFilter).'&'.$sContextParam);
$sUrl = json_encode(utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=chart&params[group_by]=$sGroupBy{$sGroupByExpr}&params[chart_type]=$sChartType&params[currentId]=$sId{$iChartCounter}&params[order_direction]=$sOrderDirection&params[order_by]=$sOrderBy&params[limit]=$sLimit&params[aggregation_function]=$sAggregationFunction&params[aggregation_attribute]=$sAggregationAttr&id=$sId{$iChartCounter}&filter=".urlencode($sFilter).'&'.$sContextParam);
}
$oPage->add_ready_script(
@@ -1038,47 +944,7 @@ EOF
if (isset($aExtraParams['group_by']))
{
$sAlias = $this->m_oFilter->GetClassAlias();
if (isset($aExtraParams['group_by_label']))
{
$oGroupByExp = Expression::FromOQL($aExtraParams['group_by']);
}
else
{
// Backward compatibility: group_by is simply a field id
$oGroupByExp = new FieldExpression($aExtraParams['group_by'], $sAlias);
}
$aGroupBy = array();
$aGroupBy['grouped_by_1'] = $oGroupByExp;
$aQueryParams = array();
if (isset($aExtraParams['query_params']))
{
$aQueryParams = $aExtraParams['query_params'];
}
$aFunctions = array();
$aOrderBy = array();
$sFctVar = '_itop_count_';
if (isset($aExtraParams['agregation_function']) && !empty($aExtraParams['agregation_attribute']))
{
$sAgregationFunction = $aExtraParams['agregation_function'];
$sAgregationAttr = $aExtraParams['agregation_attribute'];
$oAttrExpr = Expression::FromOQL('`'.$sAlias.'`.`'.$sAgregationAttr.'`');
$oFctExpr = new FunctionExpression(strtoupper($sAgregationFunction), array($oAttrExpr));
$sFctVar = '_itop_'.$sAgregationFunction.'_';
$aFunctions = array($sFctVar => $oFctExpr);
}
$iLimit = 0;
if (isset($aExtraParams['limit']))
{
$iLimit = intval($aExtraParams['limit']);
}
if (isset($aExtraParams['order_direction']))
{
$aOrderBy = array($sFctVar => ($aExtraParams['order_direction'] === 'asc'));
}
$sSql = $this->m_oFilter->MakeGroupByQuery($aQueryParams, $aGroupBy, true, $aFunctions, $aOrderBy, $iLimit);
$this->MakeGroupByQuery($aExtraParams, $oGroupByExp, $sGroupByLabel, $aGroupBy, $sAggregationFunction, $sFctVar, $sAggregationAttr, $sSql);
$aRes = CMDBSource::QueryToArray($sSql);
$oContext = new ApplicationContext();
$sContextParam = $oContext->GetForLink();
@@ -1190,6 +1056,7 @@ var chart = c3.generate({
var aURLs = $sJSURLs;
window.location.href= aURLs[d.index];
},
order: null,
},
legend: {
show: true,
@@ -1353,6 +1220,97 @@ EOF
{
return $this->m_oSet->Count();
}
/**
* @param $aExtraParams
* @param $oGroupByExp
* @param $sGroupByLabel
* @param $aGroupBy
* @param $sAggregationFunction
* @param $sFctVar
* @param $sAggregationAttr
* @param $sSql
*
* @throws \Exception
*/
protected function MakeGroupByQuery(&$aExtraParams, &$oGroupByExp, &$sGroupByLabel, &$aGroupBy, &$sAggregationFunction, &$sFctVar, &$sAggregationAttr, &$sSql)
{
$sAlias = $this->m_oFilter->GetClassAlias();
if (isset($aExtraParams['group_by_label']))
{
$oGroupByExp = Expression::FromOQL($aExtraParams['group_by']);
$sGroupByLabel = $aExtraParams['group_by_label'];
}
else
{
// Backward compatibility: group_by is simply a field id
$oGroupByExp = new FieldExpression($aExtraParams['group_by'], $sAlias);
$sGroupByLabel = MetaModel::GetLabel($this->m_oFilter->GetClass(), $aExtraParams['group_by']);
}
// Security filtering
$aFields = $oGroupByExp->ListRequiredFields();
foreach($aFields as $sFieldAlias)
{
$aMatches = array();
if (preg_match('/^([^.]+)\\.([^.]+)$/', $sFieldAlias, $aMatches))
{
$sFieldClass = $this->m_oFilter->GetClassName($aMatches[1]);
$oAttDef = MetaModel::GetAttributeDef($sFieldClass, $aMatches[2]);
if ($oAttDef instanceof AttributeOneWayPassword)
{
throw new Exception('Grouping on password fields is not supported.');
}
}
}
$aGroupBy = array();
$aGroupBy['grouped_by_1'] = $oGroupByExp;
$aQueryParams = array();
if (isset($aExtraParams['query_params']))
{
$aQueryParams = $aExtraParams['query_params'];
}
$aFunctions = array();
$sAggregationFunction = 'count';
$sFctVar = '_itop_count_';
$sAggregationAttr = '';
if (isset($aExtraParams['aggregation_function']) && !empty($aExtraParams['aggregation_attribute']))
{
$sAggregationFunction = $aExtraParams['aggregation_function'];
$sAggregationAttr = $aExtraParams['aggregation_attribute'];
$oAttrExpr = Expression::FromOQL('`'.$sAlias.'`.`'.$sAggregationAttr.'`');
$oFctExpr = new FunctionExpression(strtoupper($sAggregationFunction), array($oAttrExpr));
$sFctVar = '_itop_'.$sAggregationFunction.'_';
$aFunctions = array($sFctVar => $oFctExpr);
}
if (!empty($sAggregationAttr))
{
$sClass = $this->m_oFilter->GetClass();
$sAggregationAttr = MetaModel::GetLabel($sClass, $sAggregationAttr);
}
$iLimit = 0;
if (isset($aExtraParams['limit']))
{
$iLimit = intval($aExtraParams['limit']);
}
$aOrderBy = array();
if (isset($aExtraParams['order_direction']) && isset($aExtraParams['order_by']))
{
switch ($aExtraParams['order_by'])
{
case 'attribute':
$aOrderBy = array('grouped_by_1' => ($aExtraParams['order_direction'] === 'asc'));
break;
case 'function':
$aOrderBy = array($sFctVar => ($aExtraParams['order_direction'] === 'asc'));
break;
}
}
$sSql = $this->m_oFilter->MakeGroupByQuery($aQueryParams, $aGroupBy, true, $aFunctions, $aOrderBy, $iLimit);
}
}
/**

View File

@@ -475,7 +475,6 @@ Dict::Add('EN US', 'English', 'English', array(
'UI:Menu:CSVExport' => 'CSV Export...',
'UI:Menu:Modify' => 'Modify...',
'UI:Menu:Delete' => 'Delete...',
'UI:Menu:Manage' => 'Manage...',
'UI:Menu:BulkDelete' => 'Delete...',
'UI:UndefinedObject' => 'undefined',
'UI:Document:OpenInNewWindow:Download' => 'Open in new window: %1$s, Download: %2$s',
@@ -1222,6 +1221,7 @@ When associated with a trigger, each action is given an "order" number, specifyi
'UI:DashletGroupBy:Prop-Function' => 'Aggregation function',
'UI:DashletGroupBy:Prop-FunctionAttribute' => 'Function attribute',
'UI:DashletGroupBy:Prop-OrderDirection' => 'Direction',
'UI:DashletGroupBy:Prop-OrderField' => 'Order by',
'UI:DashletGroupBy:Prop-Limit' => 'Limit',
'UI:DashletGroupBy:Order:asc' => 'Ascending',

View File

@@ -1056,9 +1056,10 @@ Lors de l\'association à un déclencheur, on attribue à chaque action un numé
'UI:DashletGroupByTable:Description' => 'Table',
// New in 2.5
'UI:DashletGroupBy:Prop-Function' => 'Fonction d\'agregation',
'UI:DashletGroupBy:Prop-Function' => 'Fonction d\'agrégation',
'UI:DashletGroupBy:Prop-FunctionAttribute' => 'Attribut',
'UI:DashletGroupBy:Prop-OrderDirection' => 'Type de tri',
'UI:DashletGroupBy:Prop-OrderField' => 'Trié par',
'UI:DashletGroupBy:Prop-Limit' => 'Limite',
'UI:DashletGroupBy:Order:asc' => 'Croissant',