require_once(APPROOT.'application/forms.class.inc.php'); /** * Base class for all 'dashlets' (i.e. widgets to be inserted into a dashboard) * * @copyright Copyright (C) 2010-2017 Combodo SARL * @license http://opensource.org/licenses/AGPL-3.0 */ abstract class Dashlet { /** @var string */ const APPUSERPREFERENCES_PREFIX = 'Dashlet'; protected $oModelReflection; protected $sId; protected $bRedrawNeeded; protected $bFormRedrawNeeded; protected $aProperties; // array of {property => value} protected $aCSSClasses; protected $sDashletType; /** * Dashlet constructor. * * @param \ModelReflection $oModelReflection * @param string $sId */ public function __construct(ModelReflection $oModelReflection, $sId) { $this->oModelReflection = $oModelReflection; $this->sId = $sId; $this->bRedrawNeeded = true; // By default: redraw each time a property changes $this->bFormRedrawNeeded = false; // By default: no need to redraw the form (independent fields) $this->aProperties = array(); // By default: there is no property $this->aCSSClasses = array('dashlet'); $this->sDashletType = get_class($this); } /** * Assuming that a property has the type of its default value, set in the constructor * * @param string $sProperty * @param string $sValue * * @return mixed */ public function Str2Prop($sProperty, $sValue) { $refValue = $this->aProperties[$sProperty]; $sRefType = gettype($refValue); if (gettype($sValue) == $sRefType) { // Do not change anything in that case! $ret = $sValue; } elseif ($sRefType == 'boolean') { $ret = ($sValue == 'true'); } elseif ($sRefType == 'array') { $ret = explode(',', $sValue); } else { $ret = $sValue; settype($ret, $sRefType); } return $ret; } /** * @param mixed $value * * @return string */ public function Prop2Str($value) { $sType = gettype($value); if ($sType == 'boolean') { $sRet = $value ? 'true' : 'false'; } elseif ($sType == 'array') { $sRet = implode(',', $value); } else { $sRet = (string) $value; } return $sRet; } protected function OnUpdate() { } /** * @param \DOMElement $oDOMNode */ public function FromDOMNode($oDOMNode) { foreach ($this->aProperties as $sProperty => $value) { $oPropNode = $oDOMNode->getElementsByTagName($sProperty)->item(0); if ($oPropNode != null) { $this->aProperties[$sProperty] = $this->PropertyFromDOMNode($oPropNode, $sProperty); } } $this->OnUpdate(); } /** * @param \DOMElement $oDOMNode */ public function ToDOMNode($oDOMNode) { foreach ($this->aProperties as $sProperty => $value) { $oPropNode = $oDOMNode->ownerDocument->createElement($sProperty); $oDOMNode->appendChild($oPropNode); $this->PropertyToDOMNode($oPropNode, $sProperty, $value); } } /** * @param \DOMElement $oDOMNode * @param string $sProperty * * @return mixed */ protected function PropertyFromDOMNode($oDOMNode, $sProperty) { $res = $this->Str2Prop($sProperty, $oDOMNode->textContent); return $res; } /** * @param \DOMElement $oDOMNode * @param string $sProperty * @param mixed $value */ protected function PropertyToDOMNode($oDOMNode, $sProperty, $value) { $sXmlValue = $this->Prop2Str($value); $oTextNode = $oDOMNode->ownerDocument->createTextNode($sXmlValue); $oDOMNode->appendChild($oTextNode); } /** * @param string $sXml * * @throws \DOMException */ public function FromXml($sXml) { $oDomDoc = new DOMDocument('1.0', 'UTF-8'); libxml_clear_errors(); $oDomDoc->loadXml($sXml); $aErrors = libxml_get_errors(); if (count($aErrors) > 0) { throw new DOMException("Malformed XML"); } $this->FromDOMNode($oDomDoc->firstChild); } /** * @param array $aParams */ public function FromParams($aParams) { foreach ($this->aProperties as $sProperty => $value) { if (array_key_exists($sProperty, $aParams)) { $this->aProperties[$sProperty] = $aParams[$sProperty]; } } $this->OnUpdate(); } /** * @param \WebPage $oPage * @param bool $bEditMode * @param bool $bEnclosingDiv * @param array $aExtraParams */ public function DoRender($oPage, $bEditMode = false, $bEnclosingDiv = true, $aExtraParams = array()) { $sCSSClasses = implode(' ', $this->aCSSClasses); $sId = $this->GetID(); if ($bEnclosingDiv) { if ($bEditMode) { $oPage->add('
'.Dict::S('UI:DashletGroupBy:MissingGroupBy').'
'); } else { switch($sStyle) { case 'bars': $sType = 'chart'; $aParams = array( 'chart_type' => 'bars', 'chart_title' => $sTitle, 'group_by' => $this->sGroupByExpr, 'group_by_label' => $this->sGroupByLabel, '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; case 'pie': $sType = 'chart'; $aParams = array( 'chart_type' => 'pie', 'chart_title' => $sTitle, 'group_by' => $this->sGroupByExpr, 'group_by_label' => $this->sGroupByLabel, '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; case 'table': default: $sHtmlTitle = utils::HtmlEntities(Dict::S($sTitle)); // done in the itop block $sType = 'count'; $aParams = array( 'group_by' => $this->sGroupByExpr, 'group_by_label' => $this->sGroupByLabel, 'aggregation_function' => $this->sAggregationFunction, 'aggregation_attribute' => $this->sAggregationAttribute, 'limit' => $this->sLimit, 'order_direction' => $this->sOrderDirection, 'order_by' => $this->sOrderBy, ); break; } $oPage->add(''.Dict::Format('UI:Pagination:HeaderNoSelection', $iTotal).'
'); $oPage->add('| '.$this->sGroupByLabel.' | '); $oPage->add(''.Dict::S('UI:GroupBy:Count').' | '); $oPage->add('
|---|---|
| '.$aDisplayData['label'].' | '); $oPage->add(''.$aDisplayData['value'].' | '); $oPage->add('
| '.$sValueLabel.' | '); } $oPage->add('
|---|
| '.$iCount.' | '); } $oPage->add('
');
$oPage->add(' '.$sClassLabel.': 947');
$oPage->add('
');
$oPage->add(' '.Dict::Format('UI:ClickToCreateNew', $sClassLabel).'');
$oPage->add('
');
$oPage->add(' '.Dict::Format('UI:SearchFor_Class', $sClassLabel).'');
$oPage->add('