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 .= "