diff --git a/application/dashlet.class.inc.php b/application/dashlet.class.inc.php index 9d37bfc8e..fa490ae77 100644 --- a/application/dashlet.class.inc.php +++ b/application/dashlet.class.inc.php @@ -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; diff --git a/application/displayblock.class.inc.php b/application/displayblock.class.inc.php index fc4fc4456..98caa513c 100644 --- a/application/displayblock.class.inc.php +++ b/application/displayblock.class.inc.php @@ -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 = "  "; - $sCharsetNotice .= ''; - $sCharsetNotice .= ""; - - $sTip = "

".htmlentities(Dict::S('UI:CSVExport:LostChars'), ENT_QUOTES, 'UTF-8')."

"; - $sTip .= "

".htmlentities(Dict::Format('UI:CSVExport:LostChars+', $sCharset), ENT_QUOTES, 'UTF-8')."

"; - $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 .= "
"; $sHtml .= ''; @@ -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¶ms[group_by]=$sGroupBy{$sGroupByExpr}¶ms[group_by_label]={$aExtraParams['group_by_label']}¶ms[chart_type]=$sChartType¶ms[currentId]=$sId{$iChartCounter}¶ms[order_direction]=$sOrderDirection¶ms[order_by]=$sOrderBy¶ms[limit]=$sLimit¶ms[agregation_function]=$sAgregationFunction¶ms[agregation_attribute]=$sAgregationAttr&id=$sId{$iChartCounter}&filter=".urlencode($sFilter).'&'.$sContextParam); + $sUrl = json_encode(utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=chart¶ms[group_by]=$sGroupBy{$sGroupByExpr}¶ms[group_by_label]={$aExtraParams['group_by_label']}¶ms[chart_type]=$sChartType¶ms[currentId]=$sId{$iChartCounter}¶ms[order_direction]=$sOrderDirection¶ms[order_by]=$sOrderBy¶ms[limit]=$sLimit¶ms[aggregation_function]=$sAggregationFunction¶ms[aggregation_attribute]=$sAggregationAttr&id=$sId{$iChartCounter}&filter=".urlencode($sFilter).'&'.$sContextParam); } else { - $sUrl = json_encode(utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=chart¶ms[group_by]=$sGroupBy{$sGroupByExpr}¶ms[chart_type]=$sChartType¶ms[currentId]=$sId{$iChartCounter}¶ms[order_direction]=$sOrderDirection¶ms[order_by]=$sOrderBy¶ms[limit]=$sLimit¶ms[agregation_function]=$sAgregationFunction¶ms[agregation_attribute]=$sAgregationAttr&id=$sId{$iChartCounter}&filter=".urlencode($sFilter).'&'.$sContextParam); + $sUrl = json_encode(utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=chart¶ms[group_by]=$sGroupBy{$sGroupByExpr}¶ms[chart_type]=$sChartType¶ms[currentId]=$sId{$iChartCounter}¶ms[order_direction]=$sOrderDirection¶ms[order_by]=$sOrderBy¶ms[limit]=$sLimit¶ms[aggregation_function]=$sAggregationFunction¶ms[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); + } } /** diff --git a/dictionaries/en.dictionary.itop.ui.php b/dictionaries/en.dictionary.itop.ui.php index 254fd7a7f..17b3495d1 100644 --- a/dictionaries/en.dictionary.itop.ui.php +++ b/dictionaries/en.dictionary.itop.ui.php @@ -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', diff --git a/dictionaries/fr.dictionary.itop.ui.php b/dictionaries/fr.dictionary.itop.ui.php index f0789fb7f..1e61dff59 100644 --- a/dictionaries/fr.dictionary.itop.ui.php +++ b/dictionaries/fr.dictionary.itop.ui.php @@ -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',