Index: main/plugin-web/i18n/messages_en.xml
===================================================================
--- main/plugin-web/i18n/messages_en.xml	(revision 32913)
+++ main/plugin-web/i18n/messages_en.xml	(working copy)
@@ -2434,4 +2446,12 @@
     <message key="PLUGINS_WEB_SITE_COOKIE_BANNER_LABEL">Enable cookie consent banner</message>
     <message key="PLUGINS_WEB_SITE_COOKIE_BANNER_DESCRIPTION">Check the box if you want to let the user decide if he allows the use of cookies to collect anonymous visitor statistics. Enabling this could be a legal obligation, depending on the country.</message>
     <message key="PLUGINS_WEB_SITE_COOKIES_GROUP">Cookies</message>
+    <!-- +
+         | PARAMETER CHECKERS   
+         + -->
+    <message key="PLUGINS_WEB_FRONTOFFICE_SQL_CONNECTION_CHECKER_LABEL">Connection to the front office database</message>
+    <message key="PLUGINS_WEB_FRONTOFFICE_SQL_CONNECTION_CHECKER_DESC">This test checks if the given information allows the connection to the front office database.</message>
+    <message key="PLUGINS_WEB_MONITORING_SQL_CONNECTION_CHECKER_LABEL">Connection to the monitoring database</message>
+    <message key="PLUGINS_WEB_MONITORING_SQL_CONNECTION_CHECKER_DESC">This test checks if the given information allows the connection to the monitoring database.</message>
+    
 </catalogue>
Index: main/plugin-web/i18n/messages_fr.xml
===================================================================
--- main/plugin-web/i18n/messages_fr.xml	(revision 32913)
+++ main/plugin-web/i18n/messages_fr.xml	(working copy)
@@ -2423,7 +2439,14 @@
     <message key="PLUGINS_WEB_DAOS_SITEMAP_ERROR">Une erreur a empêché de retrouver les informations sur la racine du plan du site.</message>
     <message key="PLUGINS_WEB_DAOS_SITEMAP_NOT_FOUND">Erreur de sélection.</message>
     <message key="PLUGINS_WEB_DAOS_SITEMAP_NOT_FOUND_HINT">Le plan du site n'existe plus.</message>
-    
+
+    <!-- +
+         | PARAMETER CHECKERS   
+         + -->
+    <message key="PLUGINS_WEB_FRONTOFFICE_SQL_CONNECTION_CHECKER_LABEL">Connexion à la base front office</message>
+    <message key="PLUGINS_WEB_FRONTOFFICE_SQL_CONNECTION_CHECKER_DESC">Ce test vérifie que les informations rentrées permettent bien d'établir une connexion avec la base de données du front office.</message>
+    <message key="PLUGINS_WEB_MONITORING_SQL_CONNECTION_CHECKER_LABEL">Connexion à la base de monitoring</message>
+    <message key="PLUGINS_WEB_MONITORING_SQL_CONNECTION_CHECKER_DESC">Ce test vérifie que les informations rentrées permettent bien d'établir une connexion avec la base de données de monitoring.</message>
     <!-- +
          | RELATIONS
          + -->
Index: main/plugin-web/plugin.xml
===================================================================
--- main/plugin-web/plugin.xml	(revision 32913)
+++ main/plugin-web/plugin.xml	(working copy)
@@ -86,6 +86,27 @@
             <group i18n="true">plugin.core:PLUGINS_CORE_DEBUG_GROUP</group>
             <order>50</order>
         </param>
+        
+        <param-checker id="sql-connection-checker-fo" class="org.ametys.plugins.core.impl.checker.SqlConnectionChecker">
+            <label i18n="true">PLUGINS_WEB_FRONTOFFICE_SQL_CONNECTION_CHECKER_LABEL</label>
+            <description i18n="true">PLUGINS_WEB_FRONTOFFICE_SQL_CONNECTION_CHECKER_DESC</description>
+            <icon-large plugin="core-impl">img/config/check/test_sqlconnect_48.png</icon-large>
+            <icon-medium plugin="core-impl">img/config/check/test_sqlconnect_32.png</icon-medium>
+            <icon-small plugin="core-impl">img/config/check/test_sqlconnect_16.png</icon-small>
+                        
+            <ui-ref>
+                <order>1</order>
+                <category i18n="true">plugin.core-impl:PLUGINS_CORE_DATASOURCE_CORE_CONFIG_JDBC_CATEGORY_DATASOURCE</category>
+                <group i18n="true">PLUGINS_WEB_DATASOURCE_FO_CONFIG_JDBC_CATEGORY_DATASOURCE_GROUP_CORE</group>
+            </ui-ref>
+            
+            <linked-params>
+                <param-ref id="front-office.usersManager.jdbc.driver"/>
+                <param-ref id="front-office.usersManager.jdbc.url"/>
+                <param-ref id="front-office.usersManager.jdbc.user"/>
+                <param-ref id="front-office.usersManager.jdbc.passwd"/>
+            </linked-params>
+        </param-checker>
 	</config>
         
@@ -608,7 +629,7 @@
                     <action>Ametys.plugins.web.site.SiteActions.saveConfig</action>
                     
                     <selection-target-type>^(site)$</selection-target-type>
-                    <selection-subtarget-type>^(site-config-form)$</selection-subtarget-type>
+                    <selection-subtarget-type>^(site-configuration)$</selection-subtarget-type>
                     
                     <label i18n="true">PLUGINS_WEB_ADMINISTRATOR_SITES_SAVE_CONFIG_LABEL</label>
                     <description i18n="true">PLUGINS_WEB_ADMINISTRATOR_SITES_SAVE_CONFIG_DESC</description>
@@ -629,7 +650,7 @@
                     <action>Ametys.plugins.web.site.SiteActions.unsaveConfig</action>
                     
                     <selection-target-type>^(site)$</selection-target-type>
-                    <selection-subtarget-type>^(site-config-form)$</selection-subtarget-type>
+                    <selection-subtarget-type>^(site-configuration)$</selection-subtarget-type>
                     
                     <label i18n="true">PLUGINS_WEB_ADMINISTRATOR_SITES_UNSAVE_CONFIG_LABEL</label>
                     <description i18n="true">PLUGINS_WEB_ADMINISTRATOR_SITES_UNSAVE_CONFIG_DESC</description>
@@ -2420,6 +2441,28 @@
                 <order>10</order>
                 <widget>edition.string-time</widget>
             </param>
+            
+            <param-checker id="upload-directory-checker-2" class="org.ametys.plugins.core.impl.checker.DirectoryChecker">
+                <label i18n="true">plugin.core:PLUGINS_CORE_UPLOAD_DIRECTORY_CHECKER_LABEL</label>
+                <description i18n="true">plugin.core:PLUGINS_CORE_UPLOAD_DIRECTORY_CHECKER_DESC</description>
+                <icon-large>img/config/check/test_directorywrite_48.png</icon-large>
+                <icon-medium>img/config/check/test_directorywrite_32.png</icon-medium>
+                <icon-small>img/config/check/test_directorywrite_16.png</icon-small>
+                           
+                <configuration>
+                    <check-write/>
+                    <creates-if-required/>
+                </configuration>
+                            
+                <ui-ref>
+                    <order>1</order>
+                    <param-ref id="rebuild.live.timer.hour"/>
+                </ui-ref>
+                
+                <linked-params>
+                    <param-ref id="rebuild.live.timer.hour"/>
+                </linked-params>
+            </param-checker>
         </config>
         
         <extensions>
Index: main/plugin-web/resources/js/Ametys/plugins/web/site/SiteActions.js
===================================================================
--- main/plugin-web/resources/js/Ametys/plugins/web/site/SiteActions.js	(revision 32871)
+++ main/plugin-web/resources/js/Ametys/plugins/web/site/SiteActions.js	(working copy)
@@ -492,58 +518,31 @@
 	 */
 	saveConfig: function (controller)
 	{
-		var target = controller.getMatchingTargets()[0];
-		if (target != null)
+		var form = Ametys.form.SaveHelper.getForm(controller.getMatchingTargets());
+		if (form != null)
 		{
-			var tool = Ametys.tool.ToolsManager.getFocusedTool();
-			
-			var siteName = target.getParameters().name;
-			var siteId = target.getParameters().id;
-			var formTarget = target.getSubtarget(Ametys.message.MessageTarget.SITE_CONFIGURATION_FORM);
-			var form = formTarget != null ? formTarget.getParameters().object.owner : null;
-			
-			// Validate form
-			var invalidFields = Ext.Array.merge(form.getInvalidFields(), form.getInvalidRepeaters());
-			if (invalidFields.length > 0)
-			{
-				Ametys.Msg.show({
-					   title: "<i18n:text i18n:key='PLUGINS_WEB_ADMINISTRATOR_SITES_SAVE_CONFIG'/>", 
-					   msg: "<i18n:text i18n:key='PLUGINS_WEB_ADMINISTRATOR_SITES_SAVE_CONFIG_INVALIDFIELDS'/>" + invalidFields.join(', '), //"<i18n:text i18n:key='CONTENT_EDITION_SAVE_INVALID_FIELD'/>",
-					   buttons: Ext.Msg.OK,
-					   icon: Ext.MessageBox.ERROR
-				});
-				return;
-			}
-			
-			var warnedFields = form.getWarnedFields();
-			if (warnedFields.length > 0)
-			{
-			    Ametys.Msg.show({
-			        title: "<i18n:text i18n:key='PLUGINS_WEB_ADMINISTRATOR_SITES_SAVE_CONFIG'/>",
-			        msg: "<i18n:text i18n:key='PLUGINS_WEB_ADMINISTRATOR_SITES_SAVE_CONFIG_WARNED_FIELDS_START'/>" + warnedFields.join(', ') + '.' + "<i18n:text i18n:key='PLUGINS_WEB_ADMINISTRATOR_SITES_SAVE_CONFIG_WARNED_FIELDS_END'/>",
-			        buttons: Ext.Msg.YESNO,
-			        icon: Ext.Msg.QUESTION,
-			        modal: true,
-			        fn: Ext.bind (this._bypassWarnedFields, this, [tool, form, siteName, siteId], 1),
-			        scope: this
-			    });
-			    return;
-			}
-			
-			this._doSave (tool, form, siteName, siteId);
-		}
+            Ametys.form.SaveHelper.canSave(form, Ext.bind(this._doSave, this, [controller, true], 1));
+        }
 	},
 	
 	/**
 	 * @private
 	 * Save the site configuration
-	 * @param {Ametys.tool.Tool} tool The content tool
-	 * @param {Ametys.form.ConfigurableFormPanel} form The form panel
-	 * @param {String} siteName The site name
-	 * @param {String} siteId The site ID
+	 * @param {Boolean} canSave true if the saving was allowed, false otherwise
+	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The button's controller
+	 * @param {Boolean} quit True to quit edition after saving
  	 */
-	_doSave: function (tool, form, siteName, siteId)
+	_doSave: function (canSave, controller, quit)
 	{
+		var target = controller.getMatchingTargets()[0];
+		
+		var tool = Ametys.tool.ToolsManager.getFocusedTool();
+		
+		var siteName = target.getParameters().name;
+		var siteId = target.getParameters().id;
+		var formTarget = target.getSubtarget(Ametys.message.MessageTarget.FORM);
+		var form = formTarget != null ? formTarget.getParameters().object.owner : null;
+		
 		Ametys.data.ServerComm.callMethod({
 			role: "org.ametys.web.repository.site.SiteDAO",
 			methodName: "configureSite",
@@ -603,29 +585,20 @@
 		var errors = response.errors || [];
 		if (errors.length > 0)
 		{
-			detailedMsg += '<ul>';
+			var fieldErrors = {};
 			
 			for (var i=0; i < errors.length; i++)
 			{
 				var fdName = errors[i].name;
 				var errorMsg = errors[i].errorMessages.join("<br/>");
 				
-				fieldsInError[fdName] = errorMsg;
-				
-				var fd = params.form.getForm().findField(fdName);
-				detailedMsg += '<li><b>' + (fd != null ? fd.getFieldLabel() : fdName) + '</b><br/>' + errorMsg + '</li>';
+				fieldErrors[fdName] = errorMsg;
 			}
 			
-			detailedMsg += '</ul>';
-		}
-		
-		if (errors.length > 0 && params.form)
-		{
 			var msg = "<i18n:text i18n:key='PLUGINS_WEB_ADMINISTRATOR_SITES_SAVE_CONFIG_FAILED_DESC'/>";
 			msg += errors.length  == 1 ? "<i18n:text i18n:key='PLUGINS_WEB_ADMINISTRATOR_SITES_SAVE_CONFIG_FAILED_DESC_SINGLE'/>" : errors.length + "<i18n:text i18n:key='PLUGINS_WEB_ADMINISTRATOR_SITES_SAVE_CONFIG_FAILED_DESC_MULTI'/>";
-			Ametys.helper.SaveErrorDialog.showErrorDialog (null, msg, detailedMsg);
 			
-			params.form.markFieldsInvalid (fieldsInError);
+			Ametys.form.SaveHelper.handleServerErrors(params.form, null, msg, fieldErrors);
 			return;
 		}
 		
Index: main/plugin-web/resources/js/Ametys/plugins/web/site/SiteConfigurationTool.js
===================================================================
--- main/plugin-web/resources/js/Ametys/plugins/web/site/SiteConfigurationTool.js	(revision 32871)
+++ main/plugin-web/resources/js/Ametys/plugins/web/site/SiteConfigurationTool.js	(working copy)
@@ -124,10 +124,9 @@
 					id: this._siteId
 				},
 				subtargets : {
-					type: Ametys.message.MessageTarget.SITE_CONFIGURATION_FORM,
-					parameters: {
-						object: this._formPanel.getForm()
-					}
+					type: Ametys.message.MessageTarget.SITE_CONFIGURATION,
+					parameters: {},
+					subtargets: [ this._formPanel.getMessageTargetConf() ]
 				}
 			}
 		});
@@ -166,9 +165,9 @@
 		/**
 		 * @member Ametys.message.MessageTarget
 		 * @readonly
-		 * @property {String} SITE_CONFIGURATION_FORM The target of the message is the site onfiguration form  
+		 * @property {String} SITE_CONFIGURATION The target of the message is the site configuration   
 		*/
-		SITE_CONFIGURATION_FORM: "site-config-form"
+		SITE_CONFIGURATION: "site-configuration"
 	}
 });
 
