瀏覽代碼

#1020 Restrict dashboard/shortcut refresh interval

git-svn-id: http://svn.code.sf.net/p/itop/code/trunk@3448 a333f486-631f-4898-b8df-5754b55c2be0
romainq 10 年之前
父節點
當前提交
c6c813a878

+ 7 - 6
application/dashboard.class.inc.php

@@ -91,7 +91,7 @@ abstract class Dashboard
 			}
 			if ($oAutoReloadInterval = $oAutoReloadNode->getElementsByTagName('interval')->item(0))
 			{
-				$this->iAutoReloadSec = max(5, (int)$oAutoReloadInterval->textContent);
+				$this->iAutoReloadSec = max(MetaModel::GetConfig()->Get('min_reload_interval'), (int)$oAutoReloadInterval->textContent);
 			}
 		}
 
@@ -235,7 +235,7 @@ abstract class Dashboard
 		$this->sLayoutClass = $aParams['layout_class'];
 		$this->sTitle = $aParams['title'];
 		$this->bAutoReload = $aParams['auto_reload'] == 'true';
-		$this->iAutoReloadSec = max(5, (int) $aParams['auto_reload_sec']);
+		$this->iAutoReloadSec = max(MetaModel::GetConfig()->Get('min_reload_interval'), (int) $aParams['auto_reload_sec']);
 		
 		foreach($aParams['cells'] as $aCell)
 		{
@@ -300,7 +300,7 @@ abstract class Dashboard
 
 	public function SetAutoReloadInterval($iAutoReloadSec)
 	{
-		$this->iAutoReloadSec = max(5, (int)$iAutoReloadSec);
+		$this->iAutoReloadSec = max(MetaModel::GetConfig()->Get('min_reload_interval'), (int)$iAutoReloadSec);
 	}
 
 	public function AddDashlet($oDashlet)
@@ -357,16 +357,17 @@ abstract class Dashboard
 		$oField = new DesignerBooleanField('auto_reload', Dict::S('UI:DashboardEdit:AutoReload'), $this->bAutoReload);
 		$oForm->AddField($oField);
 
-		$oField = new DesignerTextField('auto_reload_sec', Dict::S('UI:DashboardEdit:AutoReloadSec'), $this->iAutoReloadSec);
-		$oField->SetValidationPattern('^$|^0*([5-9]|[1-9][0-9]+)$'); // Can be empty, or a number > 4
+		$oField = new DesignerIntegerField('auto_reload_sec', Dict::S('UI:DashboardEdit:AutoReloadSec'), $this->iAutoReloadSec);
+		$oField->SetBoundaries(MetaModel::GetConfig()->Get('min_reload_interval'), null); // no upper limit
 		$oForm->AddField($oField);
 
+
 		$this->SetFormParams($oForm);
 		$oForm->RenderAsPropertySheet($oPage, false, '.itop-dashboard');	
 
 		$oPage->add('</div>');
 
-		$sRateTitle = addslashes(Dict::S('UI:DashboardEdit:AutoReloadSec+'));
+		$sRateTitle = addslashes(Dict::Format('UI:DashboardEdit:AutoReloadSec+', MetaModel::GetConfig()->Get('min_reload_interval')));
 		$oPage->add_ready_script(
 <<<EOF
 	// Note: the title gets deleted by the validation mechanism

+ 1 - 1
application/displayblock.class.inc.php

@@ -226,7 +226,7 @@ class DisplayBlock
 				if (is_numeric($aExtraParams['auto_reload']) && ($aExtraParams['auto_reload'] > 0))
 				{
 					$bAutoReload = true;
-					$iReloadInterval = max(5, $aExtraParams['auto_reload'])*1000;
+					$iReloadInterval = max(MetaModel::GetConfig()->Get('min_reload_interval'), $aExtraParams['auto_reload'])*1000;
 				}
 				else
 				{

+ 68 - 0
application/forms.class.inc.php

@@ -954,6 +954,74 @@ EOF
 	}
 }
 
+class DesignerIntegerField extends DesignerFormField
+{
+	protected $iMin; // Lower boundary, inclusive
+	protected $iMax; // Higher boundary, inclusive
+
+	public function __construct($sCode, $sLabel = '', $defaultValue = '')
+	{
+		parent::__construct($sCode, $sLabel, $defaultValue);
+		$this->iMin = 0; // Positive integer is the default
+		$this->iMax = null;
+	}
+
+	public function SetBoundaries($iMin = null, $iMax = null)
+	{
+		$this->iMin = $iMin;
+		$this->iMax = $iMax;
+	}
+	
+	public function Render(WebPage $oP, $sFormId, $sRenderMode='dialog')
+	{
+		$sId = $this->oForm->GetFieldId($this->sCode);
+		
+		$sName = $this->oForm->GetFieldName($this->sCode);
+		if ($this->IsReadOnly())
+		{
+			$sHtmlValue = "<span>".htmlentities($this->defaultValue, ENT_QUOTES, 'UTF-8')."<input type=\"hidden\" id=\"$sId\" name=\"$sName\" value=\"".htmlentities($this->defaultValue, ENT_QUOTES, 'UTF-8')."\"/></span>";
+		}
+		else
+		{
+			$sMin = json_encode($this->iMin);
+			$sMax = json_encode($this->iMax);
+			$sMandatory = $this->bMandatory ? 'true' :  'false';
+			$oP->add_ready_script(
+<<<EOF
+$('#$sId').bind('change keyup validate', function() { ValidateInteger('$sId', $sMandatory, '$sFormId', $sMin, $sMax); } );
+{
+	var myTimer = null;
+	$('#$sId').bind('keyup', function() { clearTimeout(myTimer); myTimer = setTimeout(function() { $('#$sId').trigger('change', {} ); }, 100); });
+}
+EOF
+			);
+			$sCSSClasses = '';
+			if (count($this->aCSSClasses) > 0)
+			{
+				$sCSSClasses = 'class="'.implode(' ', $this->aCSSClasses).'"';
+			}
+			$sHtmlValue = "<input type=\"text\" $sCSSClasses id=\"$sId\" name=\"$sName\" value=\"".htmlentities($this->defaultValue, ENT_QUOTES, 'UTF-8')."\">";
+		}
+		return array('label' => $this->sLabel, 'value' => $sHtmlValue);
+	}
+
+	public function ReadParam(&$aValues)
+	{
+		parent::ReadParam($aValues);
+
+		if (!is_null($this->iMin) && ($aValues[$this->sCode] < $this->iMin))
+		{
+			// Reject the value...
+			$aValues[$this->sCode] = $this->defaultValue;
+		}
+		if (!is_null($this->iMax) && ($aValues[$this->sCode] > $this->iMax))
+		{
+			// Reject the value...
+			$aValues[$this->sCode] = $this->defaultValue;
+		}
+	}
+}
+
 class DesignerComboField extends DesignerFormField
 {
 	protected $aAllowedValues;

+ 3 - 3
application/shortcut.class.inc.php

@@ -254,8 +254,8 @@ class ShortcutOQL extends Shortcut
 		$oField = new DesignerBooleanField('auto_reload', Dict::S('Class:ShortcutOQL/Attribute:auto_reload'), false);
 		$oForm->AddField($oField);
 
-		$oField = new DesignerTextField('auto_reload_sec', Dict::S('Class:ShortcutOQL/Attribute:auto_reload_sec'), MetaModel::GetConfig()->GetStandardReloadInterval());
-		$oField->SetValidationPattern('^$|^0*([5-9]|[1-9][0-9]+)$'); // Can be empty, or a number > 4
+		$oField = new DesignerIntegerField('auto_reload_sec', Dict::S('Class:ShortcutOQL/Attribute:auto_reload_sec'), MetaModel::GetConfig()->GetStandardReloadInterval());
+		$oField->SetBoundaries(MetaModel::GetConfig()->Get('min_reload_interval'), null); // no upper limit
 		$oField->SetMandatory(false);
 		$oForm->AddField($oField);
 
@@ -284,7 +284,7 @@ class ShortcutOQL extends Shortcut
 		$oAppContext = new ApplicationContext();
 		$sContext = $oAppContext->GetForLink();
 
-		$sRateTitle = addslashes(Dict::S('Class:ShortcutOQL/Attribute:auto_reload_sec+'));
+		$sRateTitle = addslashes(Dict::Format('Class:ShortcutOQL/Attribute:auto_reload_sec/tip', MetaModel::GetConfig()->Get('min_reload_interval')));
 
 		$oPage->add_ready_script(
 <<<EOF

+ 9 - 1
core/config.class.inc.php

@@ -792,7 +792,15 @@ class Config
 			'value' => '',
 			'source_of_value' => '',
 			'show_in_conf_sample' => false,
-		),		
+		),
+		'min_reload_interval' => array(
+			'type' => 'integer',
+			'description' => 'Minimum refresh interval (seconds) for dashboards, shortcuts, etc. Even if the interval is set programmatically, it is forced to that minimum',
+			'default' => 5, // In iTop 2.0.3, this was the hardcoded value
+			'value' => '',
+			'source_of_value' => '',
+			'show_in_conf_sample' => false,
+		),
 	);
 
 	public function IsProperty($sPropCode)

+ 2 - 2
dictionaries/dictionary.itop.ui.php

@@ -1093,7 +1093,7 @@ When associated with a trigger, each action is given an "order" number, specifyi
 	'UI:DashboardEdit:DashboardTitle' => 'Title',
 	'UI:DashboardEdit:AutoReload' => 'Automatic refresh',
 	'UI:DashboardEdit:AutoReloadSec' => 'Automatic refresh interval (seconds)',
-	'UI:DashboardEdit:AutoReloadSec+' => 'The minimum allowed is 5 seconds',
+	'UI:DashboardEdit:AutoReloadSec+' => 'The minimum allowed is %1$d seconds',
 
 	'UI:DashboardEdit:Layout' => 'Layout',
 	'UI:DashboardEdit:Properties' => 'Dashboard Properties',
@@ -1193,7 +1193,7 @@ When associated with a trigger, each action is given an "order" number, specifyi
 	'Class:ShortcutOQL/Attribute:auto_reload/Value:none' => 'Disabled',
 	'Class:ShortcutOQL/Attribute:auto_reload/Value:custom' => 'Custom rate',
 	'Class:ShortcutOQL/Attribute:auto_reload_sec' => 'Automatic refresh interval (seconds)',
-	'Class:ShortcutOQL/Attribute:auto_reload_sec+' => 'The minimum allowed is 5 seconds',
+	'Class:ShortcutOQL/Attribute:auto_reload_sec/tip' => 'The minimum allowed is %1$d seconds',
 
 	'UI:FillAllMandatoryFields' => 'Please fill all mandatory fields.',
 	'UI:ValueMustBeSet' => 'Please specify a value',

+ 2 - 2
dictionaries/es_cr.dictionary.itop.ui.php

@@ -1085,7 +1085,7 @@ Cuando se asocien con un disparador, cada acción recibe un número de "orden",
 	'UI:DashboardEdit:DashboardTitle' => 'Título',
 	'UI:DashboardEdit:AutoReload' => 'Actualización Automática',
 	'UI:DashboardEdit:AutoReloadSec' => 'Interválo de Actualización Automática (segundos)',
-	'UI:DashboardEdit:AutoReloadSec+' => 'El interválo mínimo es de 5 segundos',
+	'UI:DashboardEdit:AutoReloadSec+' => 'El interválo mínimo es de %1$d segundos',
 	'UI:DashboardEdit:Layout' => 'Distribución',
 	'UI:DashboardEdit:Properties' => 'Propiedades',
 	'UI:DashboardEdit:Dashlets' => 'Dashlets disponibles',	
@@ -1184,7 +1184,7 @@ Cuando se asocien con un disparador, cada acción recibe un número de "orden",
 	'Class:ShortcutOQL/Attribute:auto_reload/Value:none' => 'Deshabilitado',
 	'Class:ShortcutOQL/Attribute:auto_reload/Value:custom' => 'Frecuencia configurable',
 	'Class:ShortcutOQL/Attribute:auto_reload_sec' => 'Interválo de Actualización Automática (segundos)',
-	'Class:ShortcutOQL/Attribute:auto_reload_sec+' => 'El interválo mínimo es de 5 segundos',
+	'Class:ShortcutOQL/Attribute:auto_reload_sec/tip' => 'El interválo mínimo es de %1$d segundos',
 	'UI:FillAllMandatoryFields' => 'Por favor llenar los campos obligatorios.',
 	'UI:CSVImportConfirmTitle' => 'Por favor confirme la operación',
 	'UI:CSVImportConfirmMessage' => '¿Está seguro?',

+ 2 - 2
dictionaries/fr.dictionary.itop.ui.php

@@ -934,7 +934,7 @@ Lors de l\'association à un déclencheur, on attribue à chaque action un numé
 	'UI:DashboardEdit:DashboardTitle' => 'Titre',
 	'UI:DashboardEdit:AutoReload' => 'Réactualisation automatique',
 	'UI:DashboardEdit:AutoReloadSec' => 'Réactualisation toutes les (secondes)',
-	'UI:DashboardEdit:AutoReloadSec+' => 'Le minimum permis est de 5 secondes',
+	'UI:DashboardEdit:AutoReloadSec+' => 'Le minimum permis est de %1$d secondes',
 	'UI:DashboardEdit:Layout' => 'Mise en page',
 	'UI:DashboardEdit:Properties' => 'Propriétés du tableau de bord',
 	'UI:DashboardEdit:Dashlets' => 'Indicateurs',	
@@ -1033,7 +1033,7 @@ Lors de l\'association à un déclencheur, on attribue à chaque action un numé
 	'Class:ShortcutOQL/Attribute:auto_reload/Value:none' => 'Désactivée',
 	'Class:ShortcutOQL/Attribute:auto_reload/Value:custom' => 'Personnalisée',
 	'Class:ShortcutOQL/Attribute:auto_reload_sec' => 'Réactualisation toutes les (secondes)',
-	'Class:ShortcutOQL/Attribute:auto_reload_sec+' => 'Le minimum permis est de 5 secondes',
+	'Class:ShortcutOQL/Attribute:auto_reload_sec/tip' => 'Le minimum permis est de %1$d secondes',
 
 	'UI:FillAllMandatoryFields' => 'Veuillez remplir tous les champs obligatoires.',
 	'UI:ValueMustBeSet' => 'Veuillez spécifier une valeur pour ce champ',

+ 2 - 2
dictionaries/pt_br.dictionary.itop.ui.php

@@ -1084,7 +1084,7 @@ When associated with a trigger, each action is given an "order" number, specifyi
 	'UI:DashboardEdit:DashboardTitle' => 'Título',
 	'UI:DashboardEdit:AutoReload' => 'Atualizar automaticamente',
 	'UI:DashboardEdit:AutoReloadSec' => 'Intervalo atualização automática (segundos)',
-	'UI:DashboardEdit:AutoReloadSec+' => 'O mínimo permitido é 5 segundos',
+	'UI:DashboardEdit:AutoReloadSec+' => 'O mínimo permitido é %1$d segundos',
 
 	'UI:DashboardEdit:Layout' => 'Layout',
 	'UI:DashboardEdit:Properties' => 'Propriedades',
@@ -1184,7 +1184,7 @@ When associated with a trigger, each action is given an "order" number, specifyi
 	'Class:ShortcutOQL/Attribute:auto_reload/Value:none' => 'Desabilitado',
 	'Class:ShortcutOQL/Attribute:auto_reload/Value:custom' => 'Avaliar',
 	'Class:ShortcutOQL/Attribute:auto_reload_sec' => 'Intervalo atualização automática (segundos)',
-	'Class:ShortcutOQL/Attribute:auto_reload_sec+' => 'O mínimo permitido é 5 sgundos',
+	'Class:ShortcutOQL/Attribute:auto_reload_sec/tip' => 'O mínimo permitido é %1$d sgundos',
 
 	'UI:FillAllMandatoryFields' => 'Por favor, preencha todos os campos obrigatórios.',
 	'UI:CSVImportConfirmTitle' => 'Por favor, confirme a operação',

+ 2 - 2
dictionaries/ru.dictionary.itop.ui.php

@@ -1077,7 +1077,7 @@ Dict::Add('RU RU', 'Russian', 'Русский', array(
 	'UI:DashboardEdit:DashboardTitle' => 'Заголовок',
 	'UI:DashboardEdit:AutoReload' => 'Обновлять автоматически',
 	'UI:DashboardEdit:AutoReloadSec' => 'Интервал обновления (секунды)',
-	'UI:DashboardEdit:AutoReloadSec+' => 'Минимальный интервал 5 секунд',
+	'UI:DashboardEdit:AutoReloadSec+' => 'Минимальный интервал %1$d секунд',
 
 	'UI:DashboardEdit:Layout' => 'Макет',
 	'UI:DashboardEdit:Properties' => 'Свойства дашборда',
@@ -1177,7 +1177,7 @@ Dict::Add('RU RU', 'Russian', 'Русский', array(
 	'Class:ShortcutOQL/Attribute:auto_reload/Value:none' => 'Disabled',
 	'Class:ShortcutOQL/Attribute:auto_reload/Value:custom' => 'Custom rate',
 	'Class:ShortcutOQL/Attribute:auto_reload_sec' => 'Automatic refresh interval (seconds)',
-	'Class:ShortcutOQL/Attribute:auto_reload_sec+' => 'The minimum allowed is 5 seconds',
+	'Class:ShortcutOQL/Attribute:auto_reload_sec/tip' => 'The minimum allowed is %1$d seconds',
 
 	'UI:FillAllMandatoryFields' => 'Пожалуйста, заполните все обязательные поля.',
 	

+ 71 - 0
js/property_field.js

@@ -297,6 +297,77 @@ function ValidateWithPattern(sFieldId, bMandatory, sPattern, sFormId, aForbidden
 	}
 }
 
+function ValidateInteger(sFieldId, bMandatory, sFormId, iMin, iMax, sExplainFormat)
+{
+	var currentVal = $('#'+sFieldId).val();
+	var bValid = true;
+	var sMessage = null;
+	
+	if (bMandatory && (currentVal == ''))
+	{
+		bValid = false;
+	}
+
+	re = new RegExp('^$|^-?[0-9]+$');
+	bValid = re.test(currentVal);
+
+	if (bValid && (currentVal != ''))
+	{
+		// It is a valid number, let's check the boundaries
+		var iValue = parseInt(currentVal, 10);
+	
+		if ((iMin != null) && (iValue < iMin))
+		{
+			bValid = false;
+		}
+	
+		if ((iMax != null) && (iValue > iMax))
+		{
+			bValid = false;
+		}
+
+		if (!bValid && (sExplainFormat != undefined))
+		{
+			sMessage = sExplainFormat;
+		}
+	}
+
+	if (oFormValidation[sFormId] == undefined) oFormValidation[sFormId] = [];
+	if (!bValid)
+	{
+		$('#v_'+sFieldId).addClass('ui-state-error');
+		iFieldIdPos = jQuery.inArray(sFieldId, oFormValidation[sFormId]);
+		if (iFieldIdPos == -1)
+		{
+			oFormValidation[sFormId].push(sFieldId);			
+		}
+		if (sMessage)
+		{
+			$('#'+sFieldId).attr('title', sMessage).tooltip();
+			if ($('#'+sFieldId).is(":focus"))
+			{
+				$('#'+sFieldId).tooltip('open');
+			}
+		}
+	}
+	else
+	{
+		$('#v_'+sFieldId).removeClass('ui-state-error');
+		if ($('#'+sFieldId).data('uiTooltip'))
+		{
+			$('#'+sFieldId).tooltip('close');
+		}
+		$('#'+sFieldId).removeAttr('title');
+		// Remove the element from the array 
+		iFieldIdPos = jQuery.inArray(sFieldId, oFormValidation[sFormId]);
+		if (iFieldIdPos > -1)
+		{
+			oFormValidation[sFormId].splice(iFieldIdPos, 1);			
+		}
+	}
+}
+
+
 function ValidateForm(sFormId, bValidateAll)
 {
 	oFormValidation[sFormId] = [];

+ 1 - 1
pages/ajax.render.php

@@ -1021,7 +1021,7 @@ EOF
 		$iAutoReload = (int)$aValues['auto_reload_sec'];
 		if (($aValues['auto_reload']) && ($iAutoReload > 0))
 		{
-			$oShortcut->Set("auto_reload_sec", max(5, $iAutoReload));
+			$oShortcut->Set("auto_reload_sec", max(MetaModel::GetConfig()->Get('min_reload_interval'), $iAutoReload));
 			$oShortcut->Set("auto_reload", 'custom');
 		}
 		$iId = $oShortcut->DBInsertNoReload();