diff --git a/VERSIONS_HOTLINE/155213 b/VERSIONS_HOTLINE/155213
new file mode 100644
index 0000000000000000000000000000000000000000..294d280c9fecbcc4e2160ce64cf661f12a627c9b
--- /dev/null
+++ b/VERSIONS_HOTLINE/155213
@@ -0,0 +1 @@
+ - correctif #155213 : Administration : Correction de la disparition des menus d'administration après modification des préférences en affichage public
\ No newline at end of file
diff --git a/application/modules/admin/controllers/UsersController.php b/application/modules/admin/controllers/UsersController.php
index 9c88f54a0cb12deddf0d4a56448ba540e382bf80..6ac369ee3503b6cc6bb95834c1f2a59387e5400f 100644
--- a/application/modules/admin/controllers/UsersController.php
+++ b/application/modules/admin/controllers/UsersController.php
@@ -38,16 +38,14 @@ class Admin_UsersController extends ZendAfi_Controller_Action {
 
 
   public function changeAdminSkinAction() {
-    $admin_skin = $this->_request->getParam(Class_User_Settings::ADMIN_SKIN, '');
-    $color = $this->_request->getParam(Class_User_Settings::ADMIN_SKIN_COLOR, '');
-
-    if($this->_request->isPost() && $admin_skin && $user = Class_Users::getIdentity()) {
-      $user->setAdminSkin([Class_User_Settings::ADMIN_SKIN => $admin_skin,
-                           Class_User_Settings::ADMIN_SKIN_COLOR => $color]);
-      $user->save();
-      $this->_helper->notify($this->_('Préférences utilisateur sauvegardées'));
-    }
+    if ((!$user = Class_Users::getIdentity()) || !$this->_request->isPost())
+      return $this->_redirectToReferer();
+
+    $settings = new Class_User_Settings($user);
+    $settings->setAdminSkin($this->_request->getPost())
+             ->save();
 
+    $this->_helper->notify($this->_('Préférences utilisateur sauvegardées'));
     $this->_redirectToReferer();
   }
 
diff --git a/application/modules/opac/controllers/AbonneController.php b/application/modules/opac/controllers/AbonneController.php
index 7dbd50b89bda75370d9c5bdea977aedf8a310219..c0b145a1aac5dba08fc95888d98fd0583a78f5af 100644
--- a/application/modules/opac/controllers/AbonneController.php
+++ b/application/modules/opac/controllers/AbonneController.php
@@ -1192,10 +1192,10 @@ class AbonneController extends ZendAfi_Controller_Action {
     $data = $this->_request->getPost();
     unset($data['id_items']);
 
-    $this->_user->setSettings(Class_User_Settings::serializeSettings($data));
-    $this->_user->save();
+    $this->_user->updateAttributes($data)->save();
 
     Class_User_Settings::clearCache();
+
     $this->_helper->notify($this->_('Mes paramètres ont bien été sauvegardé'));
     return $this->_redirectClose($this->_getReferer());
   }
diff --git a/library/Class/Admin/Skin.php b/library/Class/Admin/Skin.php
index 8f4c426007257bead0a569158e2287a5bd913e09..17d7ef05331c84a005ed5dd709b7c781278ccd27 100644
--- a/library/Class/Admin/Skin.php
+++ b/library/Class/Admin/Skin.php
@@ -36,7 +36,7 @@ class Class_Admin_Skin {
     $_color,
     $_skin_config;
 
-  protected static $_instance;
+  protected static $_instance, $_root_path;
 
 
   public static function current() {
@@ -57,7 +57,18 @@ class Class_Admin_Skin {
   }
 
 
-  public function __construct($name = self::DEFAULT_ADMIN_SKIN, $color = self::DEFAULT_ADMIN_SKIN_COLOR) {
+  /** @category testing */
+  public static function setRootPath(?string $path) {
+    static::$_root_path = $path;
+  }
+
+
+  protected static function _rootPath() : string {
+    return static::$_root_path ?? ROOT_PATH;
+  }
+
+
+  public function __construct($name=self::DEFAULT_ADMIN_SKIN, $color=self::DEFAULT_ADMIN_SKIN_COLOR) {
     $this->_name = $name;
     $this->_color = $color;
     static::$_instance = $this;
@@ -203,6 +214,6 @@ class Class_Admin_Skin {
 
 
   protected function _getSkinPath() {
-    return ROOT_PATH  . self::DEFAULT_ADMIN_PATH . $this->getName() . '/';
+    return static::_rootPath() . static::DEFAULT_ADMIN_PATH . $this->getName() . '/';
   }
 }
\ No newline at end of file
diff --git a/library/Class/Feature.php b/library/Class/Feature.php
index 8721eced010359cfb5e496d18175ccc55708afa3..188771d6c278b6ce19ba8ee2c60d7ae3a87326cf 100644
--- a/library/Class/Feature.php
+++ b/library/Class/Feature.php
@@ -133,7 +133,7 @@ class Class_Feature {
     if($this->getUserPopupKey($user))
       return;
 
-    $session = new Zend_Session_Namespace(Class_User_Settings::POPUP_FEATURES);
+    $session = Zend_Registry::get('session');
 
     if ($session->features_seen)
       return;
@@ -146,13 +146,9 @@ class Class_Feature {
 
 
   public function isPopupReady($user) {
-    if(!$user)
-      return false;
-
-    if(!$user->isAdmin())
-      return false;
-
-    return Class_AdminVar::getValueOrDefault('FEATURES_TRACKING_ENABLE');
+    return ($user
+            && $user->isAdmin()
+            && Class_AdminVar::getValueOrDefault('FEATURES_TRACKING_ENABLE'));
   }
 
 
diff --git a/library/Class/Profil/Skin.php b/library/Class/Profil/Skin.php
index 4ecfaecf45dd9f782c91e4874d5b6de6fcb88b52..0dadc06f5b41ca45e927a80c956b9fc69fa77154 100644
--- a/library/Class/Profil/Skin.php
+++ b/library/Class/Profil/Skin.php
@@ -43,14 +43,6 @@ class Class_Profil_Skin {
   }
 
 
-  public static function newWith($datas) {
-    $instance = new self(Class_Profil::getCurrentProfil());
-    return $instance
-      ->setName($datas[Class_User_Settings::ADMIN_SKIN])
-      ->setColor($datas[Class_User_Settings::ADMIN_SKIN_COLOR]);
-  }
-
-
   public function __construct($profil) {
     $this->_name = ($profil->getSkin()) ? $profil->getSkin() : self::DEFAULT_SKIN;
     $this->_is_telephone = $profil->isTelephone();
diff --git a/library/Class/User/Setting.php b/library/Class/User/Setting.php
new file mode 100644
index 0000000000000000000000000000000000000000..69168d168de794380d1363bccbc7a2e3ef2d22d3
--- /dev/null
+++ b/library/Class/User/Setting.php
@@ -0,0 +1,457 @@
+<?php
+/**
+ * Copyright (c) 2012-2022, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+
+class Class_User_Setting {
+  use Trait_Translator;
+
+  const
+    BOOKMARKED_DOMAINS = 'domain_ids',
+    BOOKMARKED_LIBRARIES = 'library_ids',
+    REDMINE_LIBRARY = 'redmine_library',
+    ADMIN_SKIN = 'admin_skin',
+    ADMIN_SKIN_COLOR = 'admin_skin_color',
+    CHECKED_FEATURE = 'checked_features',
+    POPUP_FEATURES = 'popup_features',
+    MENU_ADMIN_COMPOSITION = 'menu_admin_composition',
+    MENU_ADMIN_FRONT_COMPOSITION = 'menu_admin_front_composition',
+    PROFILE_IMAGE = 'profile_image',
+    SEARCH_ORDER = 'search_order',
+    SEARCH_LAYOUT = 'search_layout',
+    SEARCH_PAGE_SIZE = 'search_page_size',
+    FORM_COLUMNS = 'form_columns';
+
+  protected static $_known_keys = [self::BOOKMARKED_DOMAINS,
+                                   self::BOOKMARKED_LIBRARIES,
+                                   self::REDMINE_LIBRARY,
+                                   self::ADMIN_SKIN,
+                                   self::ADMIN_SKIN_COLOR,
+                                   self::CHECKED_FEATURE,
+                                   self::POPUP_FEATURES,
+                                   self::MENU_ADMIN_COMPOSITION,
+                                   self::MENU_ADMIN_FRONT_COMPOSITION,
+                                   self::PROFILE_IMAGE,
+                                   self::SEARCH_ORDER,
+                                   self::SEARCH_LAYOUT,
+                                   self::SEARCH_PAGE_SIZE,
+                                   self::FORM_COLUMNS];
+
+  protected $_name, $_value;
+
+
+  public static function filterKnown(array $datas) : array {
+    return array_filter($datas,
+                        fn($key) => in_array($key, static::$_known_keys),
+                        ARRAY_FILTER_USE_KEY);
+  }
+
+
+  public static function filterUnknown(array $datas) : array {
+    return array_filter($datas,
+                        fn($key) => !in_array($key, static::$_known_keys),
+                        ARRAY_FILTER_USE_KEY);
+  }
+
+
+  public static function newFor(string $name, $value=null) {
+    $map =
+      [
+       static::BOOKMARKED_LIBRARIES => Class_User_SettingBookmarkedLibraries::class,
+       static::BOOKMARKED_DOMAINS => Class_User_SettingBookmarkedDomains::class,
+       static::CHECKED_FEATURE => Class_User_SettingCheckedFeature::class,
+       static::POPUP_FEATURES => Class_User_SettingPopupFeatures::class,
+       static::MENU_ADMIN_COMPOSITION => Class_User_SettingMenuCompositionAdmin::class,
+       static::MENU_ADMIN_FRONT_COMPOSITION => Class_User_SettingMenuCompositionFront::class,
+       static::SEARCH_ORDER => Class_User_SettingSearchOrder::class,
+       static::SEARCH_LAYOUT => Class_User_SettingSearchLayout::class,
+       static::SEARCH_PAGE_SIZE => Class_User_SettingSearchPageSize::class,
+       static::ADMIN_SKIN => Class_User_SettingAdminSkin::class,
+      ];
+
+    if (array_key_exists($name, $map)) {
+      $class_name = $map[$name];
+      return new $class_name($name, $value);
+    }
+
+    return new static($name, $value);
+  }
+
+
+  public function __construct(string $name, $value=null) {
+    $this->_name = $name;
+    $this->setValue($value);
+  }
+
+
+  public function name() : string {
+    return $this->_name;
+  }
+
+
+  public function value() {
+    return $this->_value;
+  }
+
+
+  public function setValue($value) : self {
+    $this->_value = $value;
+    return $this;
+  }
+
+
+  /** @return array of element names added to form */
+  public function addElementTo(Zend_Form $form) : array {
+    return [];
+  }
+}
+
+
+
+
+abstract class Class_User_SettingStormIds extends Class_User_Setting {
+  public function setValue($value) : self {
+    $this->_value = is_array($value)
+      ? implode('-', $value)
+      : $value;
+
+    return $this;
+  }
+
+
+  public function add($id) : self {
+    $ids = $this->_stormIds();
+    $ids[] = $id;
+    return $this->setValue(array_filter(array_unique($ids)));
+  }
+
+
+  public function remove($id) : self {
+    return ($ids = $this->_stormIds())
+      ? $this->setValue(array_filter($ids, fn($existing) => $existing != $id))
+      : $this;
+  }
+
+
+  protected function _stormIds() : array {
+    return $this->_value
+      ? array_filter(preg_split('/[-;,]/', $this->_value))
+      : [];
+  }
+
+
+  /** @return array of element names added to form */
+  public function addElementTo(Zend_Form $form) : array {
+    $form
+      ->addElement('cochesSuggestion',
+                   $this->_name,
+                   ['label' => $this->_elementLabel(),
+                    'name' => $this->_name,
+                    'rubrique' => $this->_elementDatasourceCallback(),
+                    'selected_all_means_nothing' => false]);
+
+    return [$this->_name];
+  }
+
+
+  protected function _elementLabel() : string {
+    return '';
+  }
+
+
+  protected function _elementDatasourceCallback() : Closure {
+    return fn() => new class { public function getList() { return []; } };
+  }
+
+
+  abstract public function getModels() : array;
+}
+
+
+
+
+class Class_User_SettingBookmarkedDomains extends Class_User_SettingStormIds {
+  public function getModels() : array {
+    return ($ids = $this->_stormIds())
+      ? Class_Catalogue::findAllBy(['id_catalogue' => $ids, 'indexer' => '1'])
+      : [];
+  }
+
+
+  protected function _elementLabel() : string {
+    return $this->_('Mes thèmes préférés');
+  }
+
+
+  protected function _elementDatasourceCallback() : Closure {
+    return fn() => new class {
+      public function getList() {
+        $datas = [];
+        foreach(Class_Catalogue::findAllIndexableNotEmpty() as $domain)
+          $datas[$domain->getId()] = $domain->getLibelle();
+
+        return $datas;
+      }
+    };
+  }
+}
+
+
+
+
+class Class_User_SettingBookmarkedLibraries extends Class_User_SettingStormIds {
+  public function getModels() : array {
+    if (!$ids = $this->_stormIds())
+      return [];
+
+    return (Class_Profil_ItemsSettings::current()->isItemAnnexDisplay()
+       ? Class_CodifAnnexe::findAllBy(['id_annexe' => $ids])
+       : Class_Bib::findAllBy(['id_site' => $ids]));
+  }
+
+
+  protected function _elementLabel() : string {
+    return $this->_('Mes bibliothèques préférées');
+  }
+
+
+  protected function _elementDatasourceCallback() : Closure {
+    return fn() => new class {
+      public function getList() {
+        $datas = [];
+        foreach(Class_Profil::getCurrentProfil()->getLibraries() as $library)
+          $datas[$library->getId()] = $library->getLabel();
+
+        return $datas;
+      }
+    };
+  }
+}
+
+
+
+
+class Class_User_SettingCheckedFeature extends Class_User_SettingStormIds {
+  public function getModels() : array {
+    return ($ids = $this->_stormIds())
+      ? (new Class_Feature)->findAllBy($ids)
+      : [];
+  }
+
+
+  /** @return array of element names added to form */
+  public function addElementTo(Zend_Form $form) : array {
+    return [];
+  }
+}
+
+
+
+
+class Class_User_SettingMenuComposition extends Class_User_Setting {
+  const SEPARATOR = '|';
+
+  protected $_admin_menu;
+
+  public function setValue($value) : self {
+    $this->_value = is_array($value)
+      ? implode(static::SEPARATOR, $value)
+      : $value;
+
+    return $this;
+  }
+
+
+  public function entries() : array {
+    return $this->_value
+      ? array_filter(explode(static::SEPARATOR, $this->_value))
+      : [];
+  }
+
+
+  public function contains(string $url) : bool {
+    return in_array($url, $this->entries());
+  }
+
+
+  public function setAdminMenu(Class_User_AdminMenu_Abstract $menu) : self {
+    $this->_admin_menu = $menu;
+    return $this;
+  }
+
+
+  /** @return array of element names added to form */
+  public function addElementTo(Zend_Form $form) : array {
+    if (!$this->_admin_menu)
+      return [];
+
+    $visitor = new Class_User_SettingsMenuVisitor;
+    $this->_admin_menu->acceptVisitor($visitor);
+
+    $form
+      ->addElement('multiCheckbox',
+                   $this->_name,
+                   ['label' => $this->_elementLabel(),
+                    'separator' => ' ',
+                    'multiOptions' => $visitor->options()]);
+
+    return [$this->_name];
+  }
+
+
+  protected function _elementLabel() : string {
+    return '';
+  }
+}
+
+
+
+
+class Class_User_SettingMenuCompositionAdmin extends Class_User_SettingMenuComposition {
+  protected function _elementLabel() : string {
+    return $this->_('Composition du menu d\'administration');
+  }
+}
+
+
+
+
+class Class_User_SettingMenuCompositionFront extends Class_User_SettingMenuComposition {
+  protected function _elementLabel() : string {
+    return $this->_('Composition du menu d\'administration dans l\'interface publique');
+  }
+}
+
+
+
+
+class Class_User_SettingPopupFeatures extends Class_User_Setting {
+  /** @return array of element names added to form */
+  public function addElementTo(Zend_Form $form) : array {
+    $form->addElement('checkbox', $this->_name,
+                      ['label' => $this->_('Masquer la popup des nouvelles fonctionnalités')]);
+
+    return [$this->_name];
+  }
+}
+
+
+
+
+class Class_User_SettingSearchOrder extends Class_User_Setting {
+  /** @return array of element names added to form */
+  public function addElementTo(Zend_Form $form) : array {
+    $form->addElement('select', $this->_name,
+                      ['label' => $this->_('Ordre préféré de la recherche'),
+                       'multiOptions' => array_filter((new Class_CriteresRecherche)->getListeTris())]);
+
+    return [$this->_name];
+  }
+}
+
+
+
+
+class Class_User_SettingSearchLayout extends Class_User_Setting {
+  /** @return array of element names added to form */
+  public function addElementTo(Zend_Form $form) : array {
+    $form->addElement('select', $this->_name,
+                      ['label' => $this->_('Disposition préférée de la recherche'),
+                       'multiOptions' => [Class_Systeme_ModulesAppli::LISTE_FORMAT_LIST => $this->_('Liste'),
+                                          Class_Systeme_ModulesAppli::LISTE_FORMAT_MUR => $this->_('Mur')]]);
+
+    return [$this->_name];
+  }
+}
+
+
+
+
+class Class_User_SettingSearchPageSize extends Class_User_Setting {
+  /** @return array of element names added to form */
+  public function addElementTo(Zend_Form $form) : array {
+    $form->addElement('select', $this->_name,
+                      ['label' => $this->_('Nombre de résultats par page préféré dans la recherche'),
+                       'multiOptions' => (new Class_CriteresRecherche)->getAvailablePageSize()]);
+
+    return [$this->_name];
+  }
+}
+
+
+
+
+class Class_User_SettingAdminSkin extends Class_User_Setting {
+  protected $_current_skin;
+
+  public function setCurrentSkin(Class_Admin_Skin $skin) : self {
+    $this->_current_skin = $skin;
+    return $this;
+  }
+
+
+  /** @return array of element names added to form */
+  public function addElementTo(Zend_Form $form) : array {
+    $form
+      ->addElement('select',
+                   $this->_name,
+                   ['label' => $this->_('Le thème de l\'interface d\'administration'),
+                    'value' => $this->_current_skin->getName(),
+                    'multiOptions' => $this->_current_skin->getAvailableSkins()])
+
+      ->addElement('select',
+                   static::ADMIN_SKIN_COLOR,
+                   ['label' => $this->_('La couleur du thème de l\'interface d\'administration'),
+                    'value' => $this->_current_skin->getColor(),
+                    'multiOptions' => array_merge([$this->_('Aucune couleur')],
+                                                  $this->_current_skin->getAvailableColors())]);
+
+    return [$this->_name, static::ADMIN_SKIN_COLOR];
+  }
+}
+
+
+
+
+class Class_User_SettingsMenuVisitor {
+  protected array $_options = [];
+
+  public function visitBackEntries(array $entries) {
+    $this->_receive($entries);
+  }
+
+
+  public function setFrontEntries(array $entries) {
+    $this->_receive($entries);
+  }
+
+
+  protected function _receive(array $entries) {
+    $this->_options=[];
+    foreach($entries as $entry)
+      $this->_options[$entry->getUrlOrKey()] = $entry->getLabel();
+    natsort($this->_options);
+  }
+
+
+  public function options() : array {
+    return $this->_options;
+  }
+}
\ No newline at end of file
diff --git a/library/Class/User/Settings.php b/library/Class/User/Settings.php
index 646be73499347e09980538b1d0afd8f84f540bba..7e4ef16eaec3343c4e66cc23c1d09c8db0c5e71b 100644
--- a/library/Class/User/Settings.php
+++ b/library/Class/User/Settings.php
@@ -20,23 +20,8 @@
  */
 
 class Class_User_Settings {
-  use Trait_StormFileSystem;
-
-  const
-    BOOKMARKED_DOMAINS = 'domain_ids',
-    BOOKMARKED_LIBRARIES = 'library_ids',
-    REDMINE_LIBRARY = 'redmine_library',
-    ADMIN_SKIN = 'admin_skin',
-    ADMIN_SKIN_COLOR = 'admin_skin_color',
-    CHECKED_FEATURE = 'checked_features',
-    POPUP_FEATURES = 'popup_features',
-    MENU_ADMIN_COMPOSITION = 'menu_admin_composition',
-    MENU_ADMIN_FRONT_COMPOSITION = 'menu_admin_front_composition',
-    PROFILE_IMAGE = 'profile_image',
-    SEARCH_ORDER = 'search_order',
-    SEARCH_LAYOUT = 'search_layout',
-    SEARCH_PAGE_SIZE = 'search_page_size',
-    FORM_COLUMNS = 'form_columns';
+  use Trait_StormFileSystem, Trait_Translator;
+
 
   protected static
     $_cache = [],
@@ -95,89 +80,88 @@ class Class_User_Settings {
   }
 
 
-  public function __construct($user) {
-    return $this->setUser($user);
-  }
-
-
-  public function setUser($user) {
+  public function __construct(?Class_Users $user) {
     if (!$user)
       return $this;
 
     $this->_user = $user;
-    $this->_user_settings = unserialize($user->getSettings());
-    return $this;
+    $this->_user_settings = $this->_unserialize($user->getSettings());
   }
 
 
-  public function setUserSettings($settings) {
-    $this->_user_settings = $settings;
-    return $this;
+  public function get(string $name) {
+    return isset($this->_user_settings[$name])
+      ? $this->_user_settings[$name]->value()
+      : null;
   }
 
 
-  public function get($name) {
+  protected function _getSettingModel(string $name) {
     return isset($this->_user_settings[$name])
       ? $this->_user_settings[$name]
       : null;
   }
 
 
-  public function set($name, $value) {
+  public function set(string $name, $value) : self {
     if (!$this->_user)
       return $this;
 
-    $this->_user_settings[$name] = $value;
-    $this->_user->setSettings(static::serializeSettings($this->_user_settings));
-    return $this;
+    $this->_user_settings[$name] = $this->_updateOrCreate($name, $value);
+    return $this->_updateUser();
   }
 
 
-  public function setBookmarkedDomains($domain_ids) {
-    $this->set(self::BOOKMARKED_DOMAINS, implode('-', $domain_ids));
-    return $this->_user;
+  protected function _updateOrCreate(string $name, $value) : Class_User_Setting {
+    return isset($this->_user_settings[$name])
+      ? $this->_user_settings[$name]->setValue($value)
+      : Class_User_Setting::newFor($name, $value);
   }
 
 
-  public function setBookmarkedLibraries($libraries_ids) {
-    $this->set(self::BOOKMARKED_LIBRARIES, implode('-', $libraries_ids));
+  protected function _updateUser() : self {
+    if (!$this->_user)
+      return $this;
+
+    $this->_user->setSettings($this->_serialize());
+    return $this;
+  }
+
+
+  public function setBookmarkedDomains($domain_ids) : ?Class_Users {
+    $this->set(Class_User_Setting::BOOKMARKED_DOMAINS, $domain_ids);
     return $this->_user;
   }
 
 
-  public function getBookmarkedDomains() {
-    if (!$value = $this->get(self::BOOKMARKED_DOMAINS))
-      return [];
+  public function getBookmarkedDomains() : array {
+    return ($setting = $this->_getSettingModel(Class_User_Setting::BOOKMARKED_DOMAINS))
+      ? $setting->getModels()
+      : [];
+  }
 
-    if (!$storm_ids = $this->_getStormIds($value))
-      return [];
 
-    return Class_Catalogue::findAllBy(['id_catalogue' => $storm_ids,
-                                       'indexer' => '1']);
+  public function setBookmarkedLibraries($libraries_ids) : ?Class_Users {
+    $this->set(Class_User_Setting::BOOKMARKED_LIBRARIES, $libraries_ids);
+    return $this->_user;
   }
 
 
-  public function getBookmarkedLibraries() {
+  public function getBookmarkedLibraries() : array {
     if (isset($this->_bookmarked_librairies_cache))
       return $this->_bookmarked_librairies_cache;
 
     if (!static::isBookmarkLibraryReady())
       return $this->_bookmarked_librairies_cache = $this->_clearBookmarkedLibraries();
 
-    if (!$value = $this->get(self::BOOKMARKED_LIBRARIES))
+    if (!$setting = $this->_getSettingModel(Class_User_Setting::BOOKMARKED_LIBRARIES))
       return $this->_bookmarked_librairies_cache = $this->_initDefaultLibrary();
 
-    if (!$storm_ids = $this->_getStormIds($value))
-      return $this->_bookmarked_librairies_cache = [];
-
-    return $this->_bookmarked_librairies_cache =
-      (Class_Profil_ItemsSettings::current()->isItemAnnexDisplay()
-       ? Class_CodifAnnexe::findAllBy(['id_annexe' => $storm_ids])
-       : Class_Bib::findAllBy(['id_site' => $storm_ids]));
+    return $this->_bookmarked_librairies_cache = $setting->getModels();
   }
 
 
-  protected function _initDefaultLibrary() {
+  protected function _initDefaultLibrary() : array {
     if(!$lib = $this->_user->getBib())
       return [];
 
@@ -189,186 +173,160 @@ class Class_User_Settings {
   }
 
 
-  protected function _clearBookmarkedLibraries() {
+  protected function _clearBookmarkedLibraries() : array {
     $this->_saveUserWithLib('');
     return [];
   }
 
 
-  public function getRedmineLibrary() {
-    return ($lib_id = $this->get(self::REDMINE_LIBRARY))
+  public function getRedmineLibrary() : ?Class_Bib {
+    return ($lib_id = $this->get(Class_User_Setting::REDMINE_LIBRARY))
       ? Class_Bib::find($lib_id)
       : $this->getUserLib();
   }
 
 
-  protected function getUserLib() {
-    return $this->_user->getBib();
+  protected function getUserLib() : ?Class_Bib {
+    return $this->_user
+      ? $this->_user->getBib()
+      : null;
   }
 
 
-  public function setRedmineLibrary($library_id) {
-    $this->set(self::REDMINE_LIBRARY, $library_id);
+  public function setRedmineLibrary($library_id) : ?Class_Users {
+    $this->set(Class_User_Setting::REDMINE_LIBRARY, $library_id);
     return $this->_user;
   }
 
 
-  public function getAdminSkin() {
-    $admin_skin = $this->get(self::ADMIN_SKIN);
+  public function getAdminSkin() : Class_Admin_Skin {
+    $admin_skin = $this->get(Class_User_Setting::ADMIN_SKIN);
 
-    return is_a($admin_skin, 'Class_Admin_Skin')
+    return is_a($admin_skin, Class_Admin_Skin::class)
       ? new Class_Admin_Skin($admin_skin->getName(), $admin_skin->getColor())
       : new Class_Admin_Skin();
   }
 
 
-  public function setAdminSkin($datas) {
-    if(!$datas || !isset($datas[self::ADMIN_SKIN]))
+  public function setAdminSkin(array $datas) : ?Class_Users {
+    if (!$datas || !isset($datas[Class_User_Setting::ADMIN_SKIN]))
       return $this->_user;
 
-    $this->set(self::ADMIN_SKIN, new Class_Admin_Skin($datas[self::ADMIN_SKIN],
-                                                      $datas[self::ADMIN_SKIN_COLOR]));
-    return $this->_user;
-  }
+    $skin = isset($datas[Class_User_Setting::ADMIN_SKIN_COLOR])
+      ? new Class_Admin_Skin($datas[Class_User_Setting::ADMIN_SKIN],
+                             $datas[Class_User_Setting::ADMIN_SKIN_COLOR])
+      : new Class_Admin_Skin($datas[Class_User_Setting::ADMIN_SKIN]);
 
+    $this->set(Class_User_Setting::ADMIN_SKIN, $skin);
 
-  public function getCheckedFeatures() {
-    if(!$ids = $this->get(static::CHECKED_FEATURE))
-      return [];
-
-    $ids = $this->_getStormIds($ids);
-
-    return (new Class_Feature)->findAllBy($ids);
+    return $this->_user;
   }
 
 
-  public function addCheckedFeature($id) {
-    $checked_features = $this->_getCheckedFeatures($id);
-    $this->set(static::CHECKED_FEATURE, implode('-', $checked_features));
-    return $this->_user;
+  public function getCheckedFeatures() : array {
+    return ($setting = $this->_getSettingModel(Class_User_Setting::CHECKED_FEATURE))
+      ? $setting->getModels()
+      : [];
   }
 
 
-  public function removeCheckedFeature($id) {
-    $checked_features = array_diff($this->_getCheckedFeatures($id), [$id]);
-    $this->set(static::CHECKED_FEATURE, implode('-', $checked_features));
-    return $this->_user;
+  public function addCheckedFeature($id) : ?Class_Users {
+    return $this->_addInIds(Class_User_Setting::CHECKED_FEATURE, $id);
   }
 
 
-  public function getPopupFeatures() {
-    return $this->get(Class_User_Settings::POPUP_FEATURES);
+  public function removeCheckedFeature($id) : ?Class_Users {
+    return $this->_removeFromIds(Class_User_Setting::CHECKED_FEATURE, $id);
   }
 
 
-  public function setPopupFeatures($boolean) {
-    $this->set(Class_User_Settings::POPUP_FEATURES, $boolean);
-    return $this;
+  public function addLibraryToBookmarks($id) : ?Class_Users {
+    return static::isBookmarkLibraryReady()
+      ? $this->_addInIds(Class_User_Setting::BOOKMARKED_LIBRARIES, $id)
+      : $this->_user;
   }
 
 
-  protected function _getCheckedFeatures($id) {
-    $checked_features = explode('-', $this->get(static::CHECKED_FEATURE));
-    return array_values(array_unique(array_merge($checked_features,
-                                                 [$id])));
+  public function removeLibraryFromBookmarks($id) : ?Class_Users {
+    return static::isBookmarkLibraryReady()
+      ? $this->_removeFromIds(Class_User_Setting::BOOKMARKED_LIBRARIES, $id)
+      : $this->_user;
   }
 
 
-  public function addLibraryToBookmarks($id) {
-    if (!static::isBookmarkLibraryReady())
+  public function _addInIds($name, $id) : ?Class_Users {
+    if ($setting = $this->_getSettingModel($name)) {
+      $setting->add($id);
+      $this->_updateUser();
       return $this->_user;
+    }
 
-    $this->set(self::BOOKMARKED_LIBRARIES,
-               (string)$this->get(self::BOOKMARKED_LIBRARIES) . '-' .$id);
+    $this->set($name, [$id]);
     return $this->_user;
   }
 
 
-  public function removeLibraryFromBookmarks($id) {
-    if (!static::isBookmarkLibraryReady())
+  public function _removeFromIds($name, $id) : ?Class_Users {
+    if (!$setting = $this->_getSettingModel($name))
       return $this->_user;
 
-    if (!$ids = $this->get(self::BOOKMARKED_LIBRARIES))
-      return $this->_user;
-
-    $current_settings = $this->_getStormIds($ids);
-    $this->set(self::BOOKMARKED_LIBRARIES,
-               implode('-', array_diff($current_settings, [$id])));
+    $setting->remove($id);
+    $this->_updateUser();
     return $this->_user;
   }
 
 
-  public static function serializeSettings($data) {
-    return serialize($data);
-  }
-
-
-  public static function unserializeSettings($data) {
-    if(!$data)
-      return [];
-    return unserialize($data);
+  public function getPopupFeatures() {
+    return $this->get(Class_User_Setting::POPUP_FEATURES);
   }
 
 
-  protected function _getStormIds($str_ids) {
-    return array_filter(preg_split('/[-;,]/', $str_ids));
+  public function setPopupFeatures($boolean) : self {
+    $this->set(Class_User_Setting::POPUP_FEATURES, $boolean);
+    return $this;
   }
 
 
   protected function _saveUserWithLib($id) : self {
-    if ($id === $this->get(static::BOOKMARKED_LIBRARIES))
+    if ($id === $this->get(Class_User_Setting::BOOKMARKED_LIBRARIES))
       return $this;
 
-    $this->set(static::BOOKMARKED_LIBRARIES, $id);
+    $this->set(Class_User_Setting::BOOKMARKED_LIBRARIES, [$id]);
     $this->_user->save();
     return $this;
   }
 
 
-  public function updateAttributes($datas) {
-    if(array_key_exists(static::POPUP_FEATURES, $datas)) {
-      $value = $datas[static::POPUP_FEATURES];
-      unset($datas[static::POPUP_FEATURES]);
-      $this->set(static::POPUP_FEATURES, $value);
-    }
-
-    if (array_key_exists(static::MENU_ADMIN_COMPOSITION, $datas)) {
-      $value = $datas[static::MENU_ADMIN_COMPOSITION];
-      unset($datas[static::MENU_ADMIN_COMPOSITION]);
-      $this->setMenuAdminComposition($value);
-    }
-
-    if (array_key_exists(static::MENU_ADMIN_FRONT_COMPOSITION, $datas)) {
-      $value = $datas[static::MENU_ADMIN_FRONT_COMPOSITION];
-      unset($datas[static::MENU_ADMIN_FRONT_COMPOSITION]);
-      $this->setMenuAdminFrontComposition($value);
-    }
+  public function updateAttributes(array $datas) : array {
+    foreach(Class_User_Setting::filterKnown($datas) as $name => $value)
+      $this->_user_settings[$name] = $this->_updateOrCreate($name, $value);
 
+    $this->_updateUser();
     static::clearCache();
 
-    return $datas;
+    return Class_User_Setting::filterUnknown($datas);
   }
 
 
-  public function injectAttributesIn($datas) {
-    $datas[static::POPUP_FEATURES] = $this->get(static::POPUP_FEATURES);
-    $datas[static::MENU_ADMIN_COMPOSITION] = $this->getMenuAdminComposition();
-    $datas[static::MENU_ADMIN_FRONT_COMPOSITION] = $this->getMenuAdminFrontComposition();
+  public function injectAttributesIn(array $datas) : array {
+    $datas[Class_User_Setting::POPUP_FEATURES] = $this->get(Class_User_Setting::POPUP_FEATURES);
+    $datas[Class_User_Setting::MENU_ADMIN_COMPOSITION] = $this->getMenuAdminComposition();
+    $datas[Class_User_Setting::MENU_ADMIN_FRONT_COMPOSITION] = $this->getMenuAdminFrontComposition();
     return $datas;
   }
 
 
-  public function setProfileImage($path) {
-    $this->set(self::PROFILE_IMAGE, $path);
+  public function setProfileImage(string $path) : ?Class_Users {
+    $this->set(Class_User_Setting::PROFILE_IMAGE, $path);
     return $this->_user;
   }
 
 
-  public function getProfileImage() {
-    if (! $path = $this->get(self::PROFILE_IMAGE))
+  public function getProfileImage() : string {
+    if (!$path = $this->get(Class_User_Setting::PROFILE_IMAGE))
       $path = $this->_initDefaultProfileImage();
 
-    if ( !$this->getFileSystem()->fileExists($path) ) {
+    if (!$this->getFileSystem()->fileExists($path) ) {
       $path = $this->_initDefaultProfileImage();
       $this->setProfileImage($path);
     }
@@ -377,38 +335,47 @@ class Class_User_Settings {
   }
 
 
+  protected function _initDefaultProfileImage() : string {
+    $paths = explode(';', Class_AdminVar::getValueOrDefault('USER_PROFILE_IMAGES'));
+
+    return (!$paths || empty($paths))
+      ? ''
+      : $paths[0];
+  }
+
+
   public function getSearchOrder() {
-    return $this->get(static::SEARCH_ORDER);
+    return $this->get(Class_User_Setting::SEARCH_ORDER);
   }
 
 
   public function setSearchOrder($order) {
-    return $this->set(static::SEARCH_ORDER, $order);
+    return $this->set(Class_User_Setting::SEARCH_ORDER, $order);
   }
 
 
   public function getSearchLayout() {
-    return $this->get(static::SEARCH_LAYOUT);
+    return $this->get(Class_User_Setting::SEARCH_LAYOUT);
   }
 
 
   public function setSearchLayout($layout) {
-    return $this->set(static::SEARCH_LAYOUT, $layout);
+    return $this->set(Class_User_Setting::SEARCH_LAYOUT, $layout);
   }
 
 
   public function getSearchPageSize() {
-    return $this->get(static::SEARCH_PAGE_SIZE);
+    return $this->get(Class_User_Setting::SEARCH_PAGE_SIZE);
   }
 
 
   public function setSearchPageSize($size) {
-    return $this->set(static::SEARCH_PAGE_SIZE, $size);
+    return $this->set(Class_User_Setting::SEARCH_PAGE_SIZE, $size);
   }
 
 
   public function getFormColumns($article_id) {
-    if (!$columns = $this->get(static::FORM_COLUMNS))
+    if (!$columns = $this->get(Class_User_Setting::FORM_COLUMNS))
       return [];
 
     return isset($columns[$article_id])
@@ -418,69 +385,67 @@ class Class_User_Settings {
 
 
   public function setFormColumns($article_id, $columns) {
-    if (!$current = $this->get(static::FORM_COLUMNS))
+    if (!$current = $this->get(Class_User_Setting::FORM_COLUMNS))
       $current = [];
 
     $current[$article_id] = $columns;
-    $this->set(static::FORM_COLUMNS, $current);
+    $this->set(Class_User_Setting::FORM_COLUMNS, $current);
 
     return $this->_user;
   }
 
 
   public function getMenuAdminComposition() : array {
-    return $this->_getMenuComposition(static::MENU_ADMIN_COMPOSITION);
+    return $this->_getMenuComposition(Class_User_Setting::MENU_ADMIN_COMPOSITION);
   }
 
 
-  protected function _getMenuComposition(string $key) : array {
-    return array_filter(explode('|', (string) $this->get($key)));
+  public function setMenuAdminComposition(array $entries) : self {
+    return $this->set(Class_User_Setting::MENU_ADMIN_COMPOSITION, $entries);
   }
 
 
   public function isInMenuAdminComposition(string $url) : bool {
-    return in_array($url, $this->getMenuAdminComposition());
-  }
-
-
-  public function isInMenuAdminFrontComposition(string $url) : bool {
-    return in_array($url, $this->getMenuAdminFrontComposition());
+    return $this->_isInMenuComposition(Class_User_Setting::MENU_ADMIN_COMPOSITION, $url);
   }
 
 
   public function getMenuAdminFrontComposition() : array {
-    return $this->_getMenuComposition(static::MENU_ADMIN_FRONT_COMPOSITION);
+    return $this->_getMenuComposition(Class_User_Setting::MENU_ADMIN_FRONT_COMPOSITION);
   }
 
 
   public function setMenuAdminFrontComposition(array $entries) : self {
-    return $this->_setMenuComposition(static::MENU_ADMIN_FRONT_COMPOSITION, $entries);
+    return $this->set(Class_User_Setting::MENU_ADMIN_FRONT_COMPOSITION, $entries);
   }
 
 
-  protected function _setMenuComposition(string $key, array $entries) : self{
-    return $this->set($key, implode('|', $entries));
+  public function isInMenuAdminFrontComposition(string $url) : bool {
+    return $this->_isInMenuComposition(Class_User_Setting::MENU_ADMIN_FRONT_COMPOSITION, $url);
   }
 
 
-  public function setMenuAdminComposition(array $entries) : self {
-    return $this->_setMenuComposition(static::MENU_ADMIN_COMPOSITION,
-                                      $entries);
+  protected function _getMenuComposition(string $name) : array {
+    return ($setting = $this->_getSettingModel($name))
+      ? $setting->entries()
+      : [];
   }
 
 
-  protected function _initDefaultProfileImage() {
-    $paths = explode(';', Class_AdminVar::getValueOrDefault('USER_PROFILE_IMAGES'));
+  protected function _isInMenuComposition(string $name, string $url) : bool {
+    return (($setting = $this->_getSettingModel($name)) && $setting->contains($url));
+  }
 
-    if (!$paths || empty($paths))
-      return '';
 
-    return $paths[0];
+  public function save() : self {
+    $this->_user->save();
+    return $this;
   }
 
 
-  public function save() {
-    $this->_user->save();
+  public function populate(Zend_Form $form) : self {
+    $form->populate(array_map(fn($setting) => $setting->value(),
+                              $this->_user_settings));
     return $this;
   }
 
@@ -496,4 +461,31 @@ class Class_User_Settings {
 
     return $this;
   }
+
+
+  protected function _serialize() : string {
+    $data = array_filter($this->_user_settings,
+                         fn($setting) => ($setting instanceof Class_User_Setting) && null !== $setting->value());
+
+    $settings = [];
+    foreach($data as $setting)
+      $settings[$setting->name()] = $setting->value();
+
+    return serialize($settings);
+  }
+
+
+  protected function _unserialize(?string $data) : array {
+    if (!$data)
+      return [];
+
+    if (!$unserialized = unserialize($data))
+      return [];
+
+    $settings = [];
+    foreach($unserialized as $name => $value)
+      $settings[$name] = Class_User_Setting::newFor($name, $value);
+
+    return $settings;
+  }
 }
diff --git a/library/Class/User/SettingsForm.php b/library/Class/User/SettingsForm.php
new file mode 100644
index 0000000000000000000000000000000000000000..cfa13c846267a50d9288215fd6f6c3e159e4c664
--- /dev/null
+++ b/library/Class/User/SettingsForm.php
@@ -0,0 +1,92 @@
+<?php
+/**
+ * Copyright (c) 2012-2022, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+
+class Class_User_SettingsForm {
+  protected Class_Users $_user;
+
+  public function __construct(Class_Users $user) {
+    $this->_user = $user;
+  }
+
+
+  public function addLibrariesElementTo(Zend_Form $form) : array {
+    return Class_User_Settings::isBookmarkLibraryReady()
+      ? (Class_User_Setting::newFor(Class_User_Setting::BOOKMARKED_LIBRARIES)
+         ->addElementTo($form))
+      : [];
+  }
+
+
+  public function addDomainsElementTo(Zend_Form $form) : array {
+    return Class_User_Settings::isBookmarkDomainsReady()
+      ? (Class_User_Setting::newFor(Class_User_Setting::BOOKMARKED_DOMAINS)
+         ->addElementTo($form))
+      : [];
+  }
+
+
+  public function addPopupFeaturesElementTo(Zend_Form $form) : array {
+    return ((new Class_Feature)->isPopupReady($this->_user))
+      ? (Class_User_Setting::newFor(Class_User_Setting::POPUP_FEATURES)
+         ->addElementTo($form))
+      : [];
+  }
+
+
+  public function addMenuAdminElementTo(Zend_Form $form) : array {
+    return Class_User_Setting::newFor(Class_User_Setting::MENU_ADMIN_COMPOSITION)
+      ->setAdminMenu(new Class_User_AdminMenu_Back($this->_user))
+      ->addElementTo($form);
+  }
+
+
+  public function addMenuAdminFrontElementTo(Zend_Form $form) : array {
+    return Class_User_Setting::newFor(Class_User_Setting::MENU_ADMIN_FRONT_COMPOSITION)
+      ->setAdminMenu(new Class_User_AdminMenu_Front($this->_user))
+      ->addElementTo($form);
+  }
+
+
+  public function addSearchOrderElementTo(Zend_Form $form) : array {
+    return Class_User_Setting::newFor(Class_User_Setting::SEARCH_ORDER)
+      ->addElementTo($form);
+  }
+
+
+  public function addSearchLayoutElementTo(Zend_Form $form) : array {
+    return Class_User_Setting::newFor(Class_User_Setting::SEARCH_LAYOUT)
+      ->addElementTo($form);
+  }
+
+
+  public function addSearchPageSizeElementTo(Zend_Form $form) : array {
+    return Class_User_Setting::newFor(Class_User_Setting::SEARCH_PAGE_SIZE)
+      ->addElementTo($form);
+  }
+
+
+  public function addAdminSkinElementTo(Zend_Form $form) : array {
+    return Class_User_Setting::newFor(Class_User_Setting::ADMIN_SKIN)
+      ->setCurrentSkin($this->_user->getAdminSkin())
+      ->addElementTo($form);
+  }
+}
diff --git a/library/Class/Users.php b/library/Class/Users.php
index cb32fee471ba49df1f2e3ec75fa07f2cd56af8a9..f6bb684462b2dcadf19a60a56e7c7eccb79d046e 100644
--- a/library/Class/Users.php
+++ b/library/Class/Users.php
@@ -1786,7 +1786,7 @@ class Class_Users extends Storm_Model_Abstract {
 
   public function getBookmarks() {
     return array_filter(array_merge($this->getBookmarkedDomains(),
-                                          $this->getBookmarkedLibraries()));
+                                    $this->getBookmarkedLibraries()));
   }
 
 
@@ -1940,7 +1940,7 @@ class Class_Users extends Storm_Model_Abstract {
 
 
   public function updateAttributes(Array $datas) {
-    return parent::updateAttributes((new Class_User_Settings($this))->updateAttributes($datas));
+    return parent::updateAttributes($this->getSettingsModel()->updateAttributes($datas));
   }
 
 
diff --git a/library/ZendAfi/Form/Admin/User.php b/library/ZendAfi/Form/Admin/User.php
index 38f80f32dae8769bc8333d33b23c0aeaf7b17c51..60530ed9ca793f24f58c30171b8b87d2752ad741 100644
--- a/library/ZendAfi/Form/Admin/User.php
+++ b/library/ZendAfi/Form/Admin/User.php
@@ -221,36 +221,16 @@ class ZendAfi_Form_Admin_User extends ZendAfi_Form {
 
 
   protected function addPreferences() {
-    $display_group_element_keys = [];
-    if((new Class_Feature)->isPopupReady($this->_user)) {
-      $this->addElement('checkbox',
-                        Class_User_Settings::POPUP_FEATURES,
-                        ['label' => $this->_('Masquer la popup des nouvelles fonctionnalités')]);
-      $display_group_element_keys[] = Class_User_Settings::POPUP_FEATURES;
-    }
+    $settings_form = new Class_User_SettingsForm($this->_user);
 
-    $display_group_element_keys[] = 'menu_admin_composition';
-    $display_group_element_keys[] = 'menu_admin_front_composition';
+    $added = $settings_form->addPopupFeaturesElementTo($this);
+    $added = array_merge($added, $settings_form->addMenuAdminElementTo($this));
+    $added = array_merge($added, $settings_form->addMenuAdminFrontElementTo($this));
 
-    (new Class_User_AdminMenu_Back($this->_user))->acceptVisitor($this);
-    (new Class_User_AdminMenu_Front($this->_user))->acceptVisitor($this);
-
-    $this
-      ->addElement('multiCheckbox',
-                   'menu_admin_composition',
-                   ['label' => $this->_('Composition du menu d\'administration'),
-                    'separator' => ' ',
-                    'multiOptions' => $this->_menu_back_entries])
-
-      ->addElement('multiCheckbox',
-                   'menu_admin_front_composition',
-                   ['label' => $this->_('Composition du menu d\'administration dans l\'interface publique'),
-                    'separator' => ' ',
-                    'multiOptions' => $this->_menu_front_entries])
-
-      ->addDisplayGroup($display_group_element_keys,
-                        'preferences_group',
-                        ['legend' => $this->_('Préférences')]);
+    if ($added)
+      $this->addDisplayGroup($added,
+                             'preferences_group',
+                             ['legend' => $this->_('Préférences')]);
 
     return $this;
   }
@@ -336,26 +316,4 @@ class ZendAfi_Form_Admin_User extends ZendAfi_Form {
                                     'library' => $user_library]);
     return $this;
   }
-
-
-  public function visitBackEntries(array $entries) : self {
-    $this->_menu_back_entries = $this->_entriesAsMultiOptions($entries);
-    return $this;
-  }
-
-
-  public function setFrontEntries(array $entries) : self {
-    $this->_menu_front_entries = $this->_entriesAsMultiOptions($entries);
-    return $this;
-  }
-
-
-  protected function _entriesAsMultiOptions(array $entries) : array {
-    $multi_options = [];
-    foreach ($entries as $entry)
-      $multi_options [$entry->getUrlOrKey()] = $entry->getLabel();
-
-    natsort($multi_options);
-    return $multi_options;
-  }
 }
diff --git a/library/ZendAfi/Form/Decorator/CochesSuggestion.php b/library/ZendAfi/Form/Decorator/CochesSuggestion.php
index d737af8bdf7b4d535b053ea99b1e0e2663561667..bf0d8ac1d35f6791a120cdb562f99ef8fb8b384c 100644
--- a/library/ZendAfi/Form/Decorator/CochesSuggestion.php
+++ b/library/ZendAfi/Form/Decorator/CochesSuggestion.php
@@ -18,18 +18,11 @@
  * along with BOKEH; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
+
 class ZendAfi_Form_Decorator_CochesSuggestion extends Zend_Form_Decorator_Abstract {
-  /**
-   * @param  string $content
-   * @return string
-   */
   public function render($content) {
-    $helper = $this->_element->getView()->getHelper('tagListeCoches');
-    $helper->setSelectedAllMeansNothing($this->_element->getSelectedAllMeansNothing());
     $this->_element->setAttribs(['onkeypress' => 'if (event.keyCode == 13) { this.form.submit();return false;}']);
-    return $content
-      .$this->_element->getView()->tagListeCochesSuggestion(
-                                                  $this->_element);
+
+    return $content . $this->_element->getView()->tagListeCochesSuggestion($this->_element);
   }
 }
-?>
\ No newline at end of file
diff --git a/library/ZendAfi/Form/Element/CochesSuggestion.php b/library/ZendAfi/Form/Element/CochesSuggestion.php
index 1c9fc89d890dd2c7fefb9bee4bad759a4a25719a..61be9987f325d49d0107d13852bded9f3fd8c459 100644
--- a/library/ZendAfi/Form/Element/CochesSuggestion.php
+++ b/library/ZendAfi/Form/Element/CochesSuggestion.php
@@ -16,7 +16,7 @@
  *
  * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
  * along with BOKEH; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA 
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
 class ZendAfi_Form_Element_CochesSuggestion extends ZendAfi_Form_Element_AbstractSuggest {
   protected $selected_all_means_nothing=true;
@@ -24,13 +24,14 @@ class ZendAfi_Form_Element_CochesSuggestion extends ZendAfi_Form_Element_Abstrac
     return new ZendAfi_Form_Decorator_CochesSuggestion();
   }
 
+
   public function setSelectedAllMeansNothing($value) {
     $this->selected_all_means_nothing=$value;
     return $this;
   }
 
+
   public function getSelectedAllMeansNothing() {
     return $this->selected_all_means_nothing;
   }
 }
-?>
\ No newline at end of file
diff --git a/library/ZendAfi/Form/User/Settings.php b/library/ZendAfi/Form/User/Settings.php
index c6007618022f111a18a86bc880698637189abb80..10544b140460c1b9ef8d0a08654a7475f4c1b760 100644
--- a/library/ZendAfi/Form/User/Settings.php
+++ b/library/ZendAfi/Form/User/Settings.php
@@ -25,65 +25,37 @@ class ZendAfi_Form_User_Settings extends ZendAfi_Form {
   protected $_user;
 
 
+  public static function forUser($user) {
+    return (new static())->setUser($user);
+  }
+
+
   public function init() {
     parent::init();
 
     $this
       ->setAttrib('id', 'user-settings')
-      ->setAttrib('action', Class_Url::assemble(['module' => 'opac',
-                                                 'controller' => 'abonne',
-                                                 'action' => 'settings']))
-      ->addDomainsElement()
-      ->addLibrariesElement();
-
-    Class_Template::current()->customUserSettingsForm($this);
+      ->setAction(Class_Url::assemble(['module' => 'opac',
+                                       'controller' => 'abonne',
+                                       'action' => 'settings']));
   }
 
 
-  public static function forUser($user) {
-    return (new static())->setUser($user);
-  }
-
-
-  protected function addLibrariesElement() {
-    if (!Class_User_Settings::isBookmarkLibraryReady())
-      return $this;
-
-    return $this
-      ->addElement('cochesSuggestion',
-                   'library_ids',
-                   ['label' => $this->_('Mes bibliothèques préférées'),
-                    'name' => 'library_ids',
-                    'rubrique' => function() {
-                       return new ZendAfi_Form_User_Settings_LibrariesSource;
-                    },
-                    'selected_all_means_nothing' => false])
-
-      ->addDisplayGroup(['library_ids'], 'library_group');
-  }
+  public function setUser(Class_Users $user) : self {
+    $this->_user = $user;
 
+    $settings_form = new Class_User_SettingsForm($user);
 
-  protected function addDomainsElement() {
-    if (!Class_User_Settings::isBookmarkDomainsReady())
-      return $this;
+    if ($added = $settings_form->addDomainsElementTo($this))
+      $this->addDisplayGroup($added, 'domains_group');
 
-    return $this
-      ->addElement('cochesSuggestion',
-                   'domain_ids',
-                   ['label' => $this->_('Mes thèmes préférés'),
-                    'name' => 'domain_ids',
-                    'rubrique' => function() {
-                       return new ZendAfi_Form_User_Settings_DomainsSource;
-                    },
-                    'selected_all_means_nothing' => false])
+    if ($added = $settings_form->addLibrariesElementTo($this))
+      $this->addDisplayGroup($added, 'library_group');
 
-        ->addDisplayGroup(['domain_ids'], 'domains_group');
-  }
+    Class_Template::current()->customUserSettingsForm($this);
 
+    (new Class_User_Settings($user))->populate($this);
 
-  public function setUser($user) {
-    $this->_user = $user;
-    $this->populate(Class_User_Settings::unserializeSettings($this->_user->getSettings()));
     return $this;
   }
 
@@ -92,27 +64,3 @@ class ZendAfi_Form_User_Settings extends ZendAfi_Form {
     $this->setAttrib('data-backurl', $url);
   }
 }
-
-
-
-
-class ZendAfi_Form_User_Settings_LibrariesSource {
-  public function getList() {
-    $datas = [];
-    foreach(Class_Profil::getCurrentProfil()->getLibraries() as $library)
-      $datas[$library->getId()] = $library->getLabel();
-    return $datas;
-  }
-}
-
-
-
-
-class ZendAfi_Form_User_Settings_DomainsSource {
-  public function getList() {
-    $datas = [];
-    foreach(Class_Catalogue::findAllIndexableNotEmpty() as $domain)
-      $datas[$domain->getId()] = $domain->getLibelle();
-    return $datas;
-  }
-}
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/Admin/SkinSelector.php b/library/ZendAfi/View/Helper/Admin/SkinSelector.php
index bc8d9eaecc27a89be8c3196a9fe922cc27780eff..8df6d84a850c2ffbbfaf74017aaa9024c1dd37fa 100644
--- a/library/ZendAfi/View/Helper/Admin/SkinSelector.php
+++ b/library/ZendAfi/View/Helper/Admin/SkinSelector.php
@@ -22,31 +22,33 @@
 
 class ZendAfi_View_Helper_Admin_SkinSelector extends ZendAfi_View_Helper_BaseHelper {
   public function Admin_SkinSelector() {
-    if(!$user = Class_Users::getIdentity())
+    if (!$user = Class_Users::getIdentity())
       return '';
 
-    Class_ScriptLoader::getInstance()->addJQueryReady('$("select[id*=\'admin_skin\']").change(function() {$(this).closest("form").submit();});');
+    Class_ScriptLoader::getInstance()
+      ->addJQueryReady('$("select[id*=\'admin_skin\']").change(function() {$(this).closest("form").submit();});');
 
-    $current_skin = $user->getAdminSkin();
-    $skins = $current_skin->getAvailableSkins();
-    $skin_colors = $current_skin->getAvailableColors();
+    $settings_form = new Class_User_SettingsForm($user);
+    $form = new ZendAfi_Form;
 
-    $skin_selector = $this->view->formSelect('admin_skin',
-                                             $current_skin->getName(),
-                                             null,
-                                             $skins);
+    $added = $settings_form->addAdminSkinElementTo($form);
+    $elements = [];
+    foreach($added as $element_name)
+      $elements[] = $form->getElement($element_name)
+                         ->setLabel(null)
+                         ->clearDecorators()
+                         ->addDecorator('ViewHelper')
+                         ->render($this->view);
 
-    $color_selector = $this->view->formSelect('admin_skin_color',
-                                              $current_skin->getColor(),
-                                              null,
-                                              array_merge([$this->_('Aucune couleur')], $skin_colors));
-
-    return $this->view->tag('form',$skin_selector . $color_selector,
-                            ['name' => 'admin_skin',
-                             'method' => 'post',
-                             'action' => $this->view->url(['module' => 'admin',
-                                                           'controller' => 'users',
-                                                           'action' => 'change-admin-skin'], null, true)]);
+    return $elements
+      ? $this->view->tag('form',
+                         implode($elements),
+                         ['name' => 'admin_skin',
+                          'method' => 'post',
+                          'action' => $this->view->url(['module' => 'admin',
+                                                        'controller' => 'users',
+                                                        'action' => 'change-admin-skin'],
+                                                       null, true)])
+      : '';
   }
 }
-?>
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/TagListeCoches.php b/library/ZendAfi/View/Helper/TagListeCoches.php
index 604e382584feb0db4eace31b6d1a37632b7ee45e..b4f867b3637c7fd893a54d70d609da0700121570 100644
--- a/library/ZendAfi/View/Helper/TagListeCoches.php
+++ b/library/ZendAfi/View/Helper/TagListeCoches.php
@@ -206,6 +206,7 @@ class ZendAfi_View_Helper_TagListeCoches extends ZendAfi_View_Helper_BaseHelper
 
 
 
+
 class ZendAfi_View_Helper_TagListeCochesSource extends Class_Entity {
   public function __construct($model) {
     $this->setModelClass($model);
@@ -241,6 +242,7 @@ class ZendAfi_View_Helper_TagListeCochesSource extends Class_Entity {
 
 
 
+
 class ZendAfi_View_Helper_TagListeCochesSourceDocType extends ZendAfi_View_Helper_TagListeCochesSource {
   public function __construct() {
     parent::__construct('Class_TypeDoc');
@@ -266,6 +268,7 @@ class ZendAfi_View_Helper_TagListeCochesSourceDocType extends ZendAfi_View_Helpe
 
 
 
+
 class ZendAfi_View_Helper_TagListeCochesSourceProfile extends ZendAfi_View_Helper_TagListeCochesSource {
   use Trait_Translator;
 
@@ -294,6 +297,7 @@ class ZendAfi_View_Helper_TagListeCochesSourceProfile extends ZendAfi_View_Helpe
 
 
 
+
 class ZendAfi_View_Helper_TagListeCochesSourceAnnexe extends ZendAfi_View_Helper_TagListeCochesSource {
   public function __construct() {
     parent::__construct('Class_CodifAnnexe');
@@ -306,41 +310,6 @@ class ZendAfi_View_Helper_TagListeCochesSourceAnnexe extends ZendAfi_View_Helper
 }
 
 
-class ZendAfi_View_Helper_TagListeCochesSuggestion extends ZendAfi_View_Helper_TagListeCoches {
-  protected
-    $_element_attribs= [];
-
-  public function tagListeCochesSuggestion($element) {
-    $this->_element_attribs = $element->getAttribs();
-
-    return parent::tagListeCoches($element->getRubrique(),
-                                  $element->getName(),
-                                  $element->getValue());
-  }
-
-
-  protected function _renderListItem($clef, $libelle) {
-    $attribs = ['type' => 'checkbox',
-                'style' => 'width: inherit;',
-                'value' => 1,
-                'clef' => $clef,
-                'onclick' => 'getCoches(\'' . $this->_name . '\',' . $this->_cant_select_all . ')'
-    ];
-    $attribs += $this->_element_attribs;
-
-    if (array_key_exists($clef, $this->_coche)
-        && $this->_coche[$clef])
-      $attribs['checked'] = 'checked';
-
-    return $this->_tag('input', null, $attribs)
-      . $libelle
-      . $this->_tag('br');
-  }
-
-}
-
-
-
 
 
 class ZendAfi_View_Helper_TagListeCochesSourcePnb extends ZendAfi_View_Helper_TagListeCochesSource {
diff --git a/library/ZendAfi/View/Helper/TagListeCochesSuggestion.php b/library/ZendAfi/View/Helper/TagListeCochesSuggestion.php
new file mode 100644
index 0000000000000000000000000000000000000000..3fb0d612eb821d3e1ee47b506c768dd1f3339c71
--- /dev/null
+++ b/library/ZendAfi/View/Helper/TagListeCochesSuggestion.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Copyright (c) 2022, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+
+class ZendAfi_View_Helper_TagListeCochesSuggestion extends ZendAfi_View_Helper_TagListeCoches {
+  protected $_element_attribs= [];
+
+  public function tagListeCochesSuggestion(ZendAfi_Form_Element_CochesSuggestion $element) {
+    $this->_element_attribs = $element->getAttribs();
+    $this->setSelectedAllMeansNothing($element->getSelectedAllMeansNothing());
+
+    return parent::tagListeCoches($element->getRubrique(),
+                                  $element->getName(),
+                                  $element->getValue());
+  }
+
+
+  protected function _renderListItem($clef, $libelle) {
+    $attribs = ['type' => 'checkbox',
+                'style' => 'width: inherit;',
+                'value' => 1,
+                'clef' => $clef,
+                'onclick' => 'getCoches(\'' . $this->_name . '\',' . $this->_cant_select_all . ')'
+    ];
+    $attribs += $this->_element_attribs;
+
+    if (array_key_exists($clef, $this->_coche)
+        && $this->_coche[$clef])
+      $attribs['checked'] = 'checked';
+
+    return $this->_tag('input', null, $attribs)
+      . $libelle
+      . $this->_tag('br');
+  }
+}
diff --git a/library/templates/Intonation/Library/FormCustomizer/UserSettings.php b/library/templates/Intonation/Library/FormCustomizer/UserSettings.php
index 7d88bd1cd3fbd93afc585e7adc6d8270cc4985a4..d9b24ebe33e4aae1413dd34066e0028ecf0d77c8 100644
--- a/library/templates/Intonation/Library/FormCustomizer/UserSettings.php
+++ b/library/templates/Intonation/Library/FormCustomizer/UserSettings.php
@@ -36,30 +36,15 @@ class Intonation_Library_FormCustomizer_UserSettings extends Intonation_Library_
       return $this;
 
     $user = Class_Users::getIdentity();
-    $current_skin = $user->getAdminSkin();
-    $skins = $current_skin->getAvailableSkins();
-    $skin_colors = array_merge([$this->_('Aucune couleur')], $current_skin->getAvailableColors());
+    $settings_form = new Class_User_SettingsForm($user);
+    $added = $settings_form->addAdminSkinElementTo($this->_form);
+    $added = array_merge($added, $settings_form->addPopupFeaturesElementTo($this->_form));
+
+    if (!$added)
+      return $this;
 
     $this->_form
-      ->addElement('select',
-                   Class_User_Settings::ADMIN_SKIN,
-                   ['label' => $this->_('Le thème de l\'interface d\'administration'),
-                    'value' => $current_skin->getName(),
-                    'multiOptions' => $skins])
-
-      ->addElement('select',
-                   Class_User_Settings::ADMIN_SKIN_COLOR,
-                   ['label' => $this->_('La couleur du thème de l\'interface d\'administration'),
-                    'value' => $current_skin->getColor(),
-                    'multiOptions' => $skin_colors])
-
-      ->addElement('checkbox',
-                   Class_User_Settings::POPUP_FEATURES,
-                   ['label' => $this->_('Masquer la fenêtre des nouvelles fonctionnalités')])
-
-      ->addDisplayGroup([Class_User_Settings::ADMIN_SKIN,
-                         Class_User_Settings::ADMIN_SKIN_COLOR,
-                         Class_User_Settings::POPUP_FEATURES],
+      ->addDisplayGroup($added,
                         'admin_user_settings',
                         ['legend' => $this->_('Administration')]);
 
@@ -68,31 +53,20 @@ class Intonation_Library_FormCustomizer_UserSettings extends Intonation_Library_
 
 
   protected function _addSearchSettings() {
-    $search_criteria = new Class_CriteresRecherche;
+    if (!$user = Class_Users::getIdentity())
+      return $this;
 
-    $this->_form
+    $settings_form = new Class_User_SettingsForm($user);
+    $added = $settings_form->addSearchOrderElementTo($this->_form);
+    $added = array_merge($added, $settings_form->addSearchLayoutElementTo($this->_form));
+    $added = array_merge($added, $settings_form->addSearchPageSizeElementTo($this->_form));
+
+    if (!$added)
+      return $this;
 
-      ->addElement('select',
-                   Class_User_Settings::SEARCH_ORDER,
-                   ['label' => $this->_('Ordre préféré de la recherche'),
-                    'multiOptions' => array_filter($search_criteria->getListeTris())])
-
-      ->addElement('select',
-                   Class_User_Settings::SEARCH_LAYOUT,
-                   ['label' => $this->_('Disposition préférée de la recherche'),
-                    'multiOptions' => [Class_Systeme_ModulesAppli::LISTE_FORMAT_LIST => $this->_('Liste'),
-                                       Class_Systeme_ModulesAppli::LISTE_FORMAT_MUR => $this->_('Mur')]])
-
-      ->addElement('select',
-                   Class_User_Settings::SEARCH_PAGE_SIZE,
-                   ['label' => $this->_('Nombre de résultats par page préféré dans la recherche'),
-                    'multiOptions' => $search_criteria->getAvailablePageSize()])
-
-      ->addDisplayGroup([Class_User_Settings::SEARCH_ORDER,
-                         Class_User_Settings::SEARCH_LAYOUT,
-                         Class_User_Settings::SEARCH_PAGE_SIZE],
-                        'search_user_settings',
-                        ['legend' => $this->_('Préférences de la recherche')]);
+    $this->_form->addDisplayGroup($added,
+                                  'search_user_settings',
+                                  ['legend' => $this->_('Préférences de la recherche')]);
     return $this;
   }
 
@@ -100,11 +74,11 @@ class Intonation_Library_FormCustomizer_UserSettings extends Intonation_Library_
   protected function _addProfileImage() {
     $this->_form
       ->addElement('link',
-                             'user_image_selector',
-                             ['value' => ['controller' => 'abonne',
-                                          'action' => 'change-image'],
-                              'data-popup' => 1,
-                              'label' => $this->_('Changer l\'image de profil')])
+                   'user_image_selector',
+                   ['value' => ['controller' => 'abonne',
+                                'action' => 'change-image'],
+                    'data-popup' => 1,
+                    'label' => $this->_('Changer l\'image de profil')])
 
       ->addDisplayGroup(['user_image_selector'],
                         'user_image_group',
diff --git a/library/templates/Intonation/Library/View/Wrapper/User/RichContent/Settings.php b/library/templates/Intonation/Library/View/Wrapper/User/RichContent/Settings.php
index 87e6a8dbb46c6b52aa2a5fbff867c5222dda022a..d87682b199386c01e40093f3ef23d9a3c382b447 100644
--- a/library/templates/Intonation/Library/View/Wrapper/User/RichContent/Settings.php
+++ b/library/templates/Intonation/Library/View/Wrapper/User/RichContent/Settings.php
@@ -116,12 +116,15 @@ class Intonation_Library_View_Wrapper_User_RichContent_Settings extends Intonati
   protected function _renderSettingsForm() {
     $form = ZendAfi_Form_User_Settings::forUser($this->_model);
 
-    if ($domain_ids = $form->getElement('domain_ids'))
+    if ($domain_ids = $form->getElement(Class_User_Setting::BOOKMARKED_DOMAINS))
       $domain_ids->setLabel($this->_('Mes thèmes préférés pour la recherche'));
 
-    if ($libraries_ids = $form->getElement('library_ids'))
+    if ($libraries_ids = $form->getElement(Class_User_Setting::BOOKMARKED_LIBRARIES))
       $libraries_ids->setLabel($this->_('Mes bibliothèques préférées pour la recherche'));
 
+    if ($popup_features = $form->getElement(Class_User_Setting::POPUP_FEATURES))
+      $popup_features->setLabel($this->_('Masquer la fenêtre des nouvelles fonctionnalités'));
+
     $form->setAction($this->_view->url(['controller' => 'abonne',
                                         'action' => 'manage-preferences']));
 
diff --git a/tests/application/modules/admin/controllers/IndexControllerFeaturesTrackingTest.php b/tests/application/modules/admin/controllers/IndexControllerFeaturesTrackingTest.php
index 617168086baf54843f2a3c3bfda9672a092c52d0..aef8f50ab4ad53f366ab32be5dad775ef78a428c 100644
--- a/tests/application/modules/admin/controllers/IndexControllerFeaturesTrackingTest.php
+++ b/tests/application/modules/admin/controllers/IndexControllerFeaturesTrackingTest.php
@@ -82,10 +82,10 @@ class IndexControllerFeaturesTrackingSecondVisitTest
 
   public function setUp() {
     parent::setUp();
-    $this->dispatch('/', true);
+    $this->dispatch('/');
     $this->_response->setBody('');
     Class_ScriptLoader::resetInstance();
-    $this->dispatch('/', true);
+    $this->dispatch('/');
   }
 
 
@@ -97,7 +97,7 @@ class IndexControllerFeaturesTrackingSecondVisitTest
 
   /** @test */
   public function adminShouldNotHavePopupKey() {
-    $this->assertNull((new Class_User_Settings($this->_user))->get(Class_User_Settings::POPUP_FEATURES));
+    $this->assertNull((new Class_User_Settings($this->_user))->getPopupFeatures());
   }
 }
 
diff --git a/tests/application/modules/admin/controllers/IndexControllerTest.php b/tests/application/modules/admin/controllers/IndexControllerTest.php
index ddfc63928bace4d11bd6538daa764b381c71fd0e..64439fa431083af62cd1beeb8528a388236c84ea 100644
--- a/tests/application/modules/admin/controllers/IndexControllerTest.php
+++ b/tests/application/modules/admin/controllers/IndexControllerTest.php
@@ -465,18 +465,35 @@ class Admin_IndexControllerWithSkinSelectorTest extends Admin_AbstractController
   public function setUp() {
     parent::setUp();
 
-    Class_Admin_Skin::setFileSystem(
-                                    (new Storm_FileSystem_Volatile())
-                                    ->mkdir(Class_Admin_Skin::DEFAULT_ADMIN_PATH . 'bokeh88')
-                                    ->mkdir(Class_Admin_Skin::DEFAULT_ADMIN_PATH . 'bokeh2000')
-                                    ->mkdir(Class_Admin_Skin::DEFAULT_ADMIN_PATH . 'bokeh88/' . Class_Admin_Skin::ADMIN_COLORS_FOLDER)
-                                    ->mkdir(Class_Admin_Skin::DEFAULT_ADMIN_PATH . 'bokeh2000/' . Class_Admin_Skin::ADMIN_COLORS_FOLDER)
-                                    ->touch(Class_Admin_Skin::DEFAULT_ADMIN_PATH . 'bokeh2000/' . Class_Admin_Skin::ADMIN_COLORS_FOLDER . '/blue.css')
-    );
-
-    Class_Users::getIdentity()->setAdminSkin([Class_User_Settings::ADMIN_SKIN => 'bokeh2000',
-                                              Class_User_Settings::ADMIN_SKIN_COLOR => 'blue.css']);
-    $this->dispatch('admin/index', true);
+    $color_folder = Class_Admin_Skin::ADMIN_COLORS_FOLDER;
+    $file_system = (new Storm_FileSystem_Volatile)
+      ->mkdir($this->_skinPath('bokeh88'))
+      ->mkdir($this->_skinPath('bokeh2000'))
+      ->mkdir($this->_skinPath('bokeh88/' . $color_folder))
+      ->mkdir($this->_skinPath('bokeh2000/' . $color_folder))
+      ->touch($this->_skinPath('bokeh2000/' . $color_folder . '/blue.css'))
+      ;
+
+    Class_Admin_Skin::setFileSystem($file_system);
+    Class_Admin_Skin::setRootPath('');
+
+    (new Class_User_Settings(Class_Users::getIdentity()))
+      ->setAdminSkin(['admin_skin' => 'bokeh2000',
+                      'admin_skin_color' => 'blue.css'])
+      ->assertSave();
+
+    $this->dispatch('admin/index');
+  }
+
+
+  public function tearDown() {
+    Class_Admin_Skin::setRootPath(null);
+    parent::tearDown();
+  }
+
+
+  protected function _skinPath(string $path) : string {
+    return Class_Admin_Skin::DEFAULT_ADMIN_PATH . $path;
   }
 
 
diff --git a/tests/application/modules/opac/controllers/AbonneControllerSettingsTest.php b/tests/application/modules/opac/controllers/AbonneControllerSettingsTest.php
index 1cc9a995dc0c97ebc381cd37f4abf5b5c22e1725..1e85460a468e480497e7efd95ce099d76004edfd 100644
--- a/tests/application/modules/opac/controllers/AbonneControllerSettingsTest.php
+++ b/tests/application/modules/opac/controllers/AbonneControllerSettingsTest.php
@@ -32,17 +32,17 @@ abstract class AbonneControllerSettingsTestCase extends AbstractControllerTestCa
   public function setUp() {
     parent::setUp();
 
-    $this->_user = $this->fixture('Class_Users',
-                           ['id' => 89,
-                            'login' => 'Once upon a time',
-                            'password' => 'A nude monkey ... ?',
-                            'id_site' => '654321',
-                            'idabon' => '456789',
-                            'role_level' => ZendAfi_Acl_AdminControllerRoles::ABONNE_SIGB]);
+    $this->_user = $this->fixture(Class_Users::class,
+                                  ['id' => 89,
+                                   'login' => 'Once upon a time',
+                                   'password' => 'A nude monkey ... ?',
+                                   'id_site' => '654321',
+                                   'idabon' => '456789',
+                                   'role_level' => ZendAfi_Acl_AdminControllerRoles::ABONNE_SIGB]);
 
     ZendAfi_Auth::getInstance()->logUser($this->_user);
 
-    $this->onLoaderOfModel('Class_Catalogue')
+    $this->onLoaderOfModel(Class_Catalogue::class)
          ->whenCalled('updateNoticesWithFacette')
          ->answers(true)
 
@@ -52,51 +52,50 @@ abstract class AbonneControllerSettingsTestCase extends AbstractControllerTestCa
          ->whenCalled('deleteThesaurusInFacette')
          ->answers(true);
 
-    $this->_music = $this->fixture('Class_Catalogue',
+    $this->_music = $this->fixture(Class_Catalogue::class,
                                    ['id' => 1,
                                     'libelle' => 'Music',
                                     'indexer' => '1',
                                     'section' => 'music']);
 
-    $this->_sport = $this->fixture('Class_Catalogue',
+    $this->_sport = $this->fixture(Class_Catalogue::class,
                                    ['id' => 2,
                                     'libelle' => 'Sport',
                                     'indexer' => '1',
                                     'section' => 'sport']);
 
-    $this->_cinema = $this->fixture('Class_Catalogue',
+    $this->_cinema = $this->fixture(Class_Catalogue::class,
                                     ['id' => 3,
                                      'libelle' => 'Cinema',
                                      'section' => 'cinema',
-                                     'sous_domaines' => [ $this->fixture('Class_Catalogue',
-                                                                         ['id' => 31,
-                                                                          'libelle' => 'Muet',
-                                                                          'indexer' => '1',
-                                                                          'section' => 'muet']),
-
-                                                         $this->fixture('Class_Catalogue',
-                                                                         ['id' => 32,
-                                                                          'libelle' => 'Couleurs',
-                                                                          'indexer' => '1',
-                                                                          'section' => 'couleurs'])
+                                     'sous_domaines' => [$this->fixture(Class_Catalogue::class,
+                                                                        ['id' => 31,
+                                                                         'libelle' => 'Muet',
+                                                                         'indexer' => '1',
+                                                                         'section' => 'muet']),
+
+                                                         $this->fixture(Class_Catalogue::class,
+                                                                        ['id' => 32,
+                                                                         'libelle' => 'Couleurs',
+                                                                         'indexer' => '1',
+                                                                         'section' => 'couleurs'])
                                      ]]);
 
-    $this->_mel = $this->fixture('Class_Bib',
+    $this->_mel = $this->fixture(Class_Bib::class,
                                  ['id' => 56,
                                   'libelle' => 'MEL']);
 
-    $this->_cinema = $this->fixture('Class_Catalogue',
+    $this->_cinema = $this->fixture(Class_Catalogue::class,
                                     ['id' => 8,
                                      'libelle' => 'Danse',
-                                     'sous_domaines' => [ $this->fixture('Class_Catalogue',
-                                                                         ['id' => 81,
-                                                                          'libelle' => 'Kizomba',
-                                                                          'indexer' => '1',
-                                                                          'section' => 'danse angola'])]]);
+                                     'sous_domaines' => [$this->fixture(Class_Catalogue::class,
+                                                                        ['id' => 81,
+                                                                         'libelle' => 'Kizomba',
+                                                                         'indexer' => '1',
+                                                                         'section' => 'danse angola'])]]);
     $this->_user
       ->setBookmarkedDomains([3])
       ->assertSave();
-
   }
 }
 
@@ -106,7 +105,7 @@ abstract class AbonneControllerSettingsTestCase extends AbstractControllerTestCa
 class AbonneControllerSettingsWithOneLibraryFormTest extends AbonneControllerSettingsTestCase {
   public function setUp() {
     parent::setUp();
-    $this->dispatch('/abonne/manage-settings/render/popup', true);
+    $this->dispatch('/abonne/manage-settings/render/popup');
   }
 
 
@@ -137,7 +136,7 @@ class AbonneControllerSettingsWithNoDomainsFormTest extends AbstractControllerTe
 
   public function setUp() {
     parent::setUp();
-    $this->dispatch('/abonne/manage-settings', true);
+    $this->dispatch('/abonne/manage-settings');
   }
 
 
@@ -162,7 +161,7 @@ class AbonneControllerSettingsFormTest extends AbonneControllerSettingsTestCase
     parent::setUp();
 
 
-    $this->fixture('Class_Bib',
+    $this->fixture(Class_Bib::class,
                    ['id' => 59,
                     'libelle' => 'ANNECY']);
 
@@ -170,8 +169,7 @@ class AbonneControllerSettingsFormTest extends AbonneControllerSettingsTestCase
       ->setBookmarkedLibraries([56, 59, 87])
       ->assertSave();
 
-
-    $this->dispatch('/abonne/manage-settings', true);
+    $this->dispatch('/abonne/manage-settings');
   }
 
 
@@ -206,7 +204,7 @@ class AbonneControllerSettingsFormTest extends AbonneControllerSettingsTestCase
 
 
   /** @test */
-  public function userBookmarkedDomainShouldNotContainsCinema() {
+  public function userBookmarkedDomainShouldBeEmpty() {
     $this->assertEmpty($this->_user->getBookmarkedDomains());
   }
 }
@@ -224,6 +222,7 @@ class AbonneControllerSettingsFormPostTest extends AbonneControllerSettingsTestC
 
     $post = ['library_ids' => '56',
              'domain_ids' => '1-2'];
+
     $this->postDispatch('/abonne/manage-settings', $post);
   }
 
@@ -475,7 +474,8 @@ class AbonneControllerWithLibrariesAndNoDomainsBookmarkableTest extends Abstract
 
 
 
-class AbonneControllerSettingsAdminSettingsTest extends AbonneControllerSettingsTestCase {
+
+class AbonneControllerSettingsAdminShowAdminIconsTest extends AbonneControllerSettingsTestCase {
   public function setUp() {
     parent::setUp();
     $this->_user->beAdminPortail();
@@ -484,14 +484,58 @@ class AbonneControllerSettingsAdminSettingsTest extends AbonneControllerSettings
 
   /** @test */
   public function userShowAdminIconsShouldBeEnabled() {
-    $this->dispatch('/admin/users/settings/key/show_admin_icons/value/1', true);
+    $this->dispatch('/admin/users/settings/key/show_admin_icons/value/1');
     $this->assertEquals(1, Class_User_Settings::newWith($this->_user)->get('show_admin_icons'));
   }
 
 
   /** @test */
   public function userShowAdminIconsShouldBeDisabled() {
-    $this->dispatch('/admin/users/settings/key/show_admin_icons/value/0', true);
+    $this->dispatch('/admin/users/settings/key/show_admin_icons/value/0');
     $this->assertEquals(0, Class_User_Settings::newWith($this->_user)->get('show_admin_icons'));
   }
 }
+
+
+
+
+class AbonneControllerSettingsAdminWithMenuCompositionsPostTest
+  extends AbonneControllerSettingsTestCase {
+
+  public function setUp() {
+    parent::setUp();
+
+    $this->_user->beAdminPortail()->assertSave();
+
+    $this->fixture(Class_Bib::class,
+                   ['id' => 59,
+                    'libelle' => 'ANNECY']);
+
+    $this->postDispatch('/abonne/manage-preferences',
+                        ['library_ids' => '59', 'domain_ids' => '1-2']);
+  }
+
+
+  /** @test */
+  public function musicAndSportShouldBeBookmarkedDomains() {
+    $this->assertEquals([$this->_music, $this->_sport], $this->_user->getBookmarkedDomains());
+  }
+
+
+  /** @test */
+  public function annecyShouldBeBookmarkedLibrary() {
+    $this->assertEquals('ANNECY', $this->_user->getBookmarkedLibraries()[0]->getLibelle());
+  }
+
+
+  /** @test */
+  public function menuAdminCompositionShouldNotBeEmpty() {
+    $this->assertNotEmpty($this->_user->getMenuAdminComposition());
+  }
+
+
+  /** @test */
+  public function menuAdminFrontCompositionShouldNotBeEmpty() {
+    $this->assertNotEmpty($this->_user->getMenuAdminFrontComposition());
+  }
+}
\ No newline at end of file
diff --git a/tests/application/modules/opac/controllers/IndexControllerTest.php b/tests/application/modules/opac/controllers/IndexControllerTest.php
index a70b6a57c62fffbd052ed9eacd90bb0de28ea40f..c09268e187d8f5e66db136daa7d0d77de44cd816 100644
--- a/tests/application/modules/opac/controllers/IndexControllerTest.php
+++ b/tests/application/modules/opac/controllers/IndexControllerTest.php
@@ -832,20 +832,22 @@ class IndexControllerStatusTest extends AbstractControllerTestCase {
 
 
 class IndexControllerWithBibAdminLoggedTest extends AbstractControllerTestCase {
-  protected
-    $_storm_default_to_volatile = true;
+  protected $_storm_default_to_volatile = true;
 
 
   public function setUp() {
     parent::setUp();
-    $joe = $this->fixture('Class_Users',
+    $joe = $this->fixture(Class_Users::class,
                           ['id' => 23,
                            'login' => 'Joe',
                            'password' => 'unsupermotdepasse',
                            'id_site' => 1,
-                           'settings' => Class_User_Settings::serializeSettings(['show_admin_icons' => '1']),
                            'role_level' => ZendAfi_Acl_AdminControllerRoles::MODO_BIB]);
 
+    (new Class_User_Settings($joe))
+      ->set('show_admin_icons', 1)
+      ->save();
+
     ZendAfi_Auth::getInstance()->logUser($joe);
     $this->dispatch('/');
   }
@@ -938,9 +940,12 @@ class IndexControllerWithAdminPortalLoggedTest extends AbstractControllerTestCas
                            'login' => 'Joe',
                            'password' => 'unsupermotdepasse',
                            'id_site' => 1,
-                           'settings' => Class_User_Settings::serializeSettings(['show_admin_icons' => '1']),
                            'role_level' => ZendAfi_Acl_AdminControllerRoles::ADMIN_PORTAIL]);
 
+    (new Class_User_Settings($joe))
+      ->set('show_admin_icons', 1)
+      ->save();
+
     ZendAfi_Auth::getInstance()->logUser($joe);
     $this->dispatch('/');
   }
@@ -991,10 +996,13 @@ class IndexControllerWithSuperAdminLoggedTest extends AbstractControllerTestCase
                            'login' => 'Joe',
                            'password' => 'unsupermotdepasse',
                            'id_site' => 1,
-                           'settings' => Class_User_Settings::serializeSettings(['show_admin_icons' => '1',
-                                                                                 'amber_ide' => 1]),
                            'role_level' => ZendAfi_Acl_AdminControllerRoles::SUPER_ADMIN]);
 
+    (new Class_User_Settings($joe))
+      ->set('show_admin_icons', 1)
+      ->set('amber_ide', 1)
+      ->save();
+
     ZendAfi_Auth::getInstance()->logUser($joe);
     $this->dispatch('/', true);
   }
@@ -1039,10 +1047,13 @@ class IndexControllerWithSuperAdminLoggedAndBlockSortingDisabledTest
                            'login' => 'Joe',
                            'password' => 'unsupermotdepasse',
                            'id_site' => 1,
-                           'settings' => Class_User_Settings::serializeSettings(['show_admin_icons' => '1',
-                                                                                 'amber_ide' => 1]),
                            'role_level' => ZendAfi_Acl_AdminControllerRoles::SUPER_ADMIN]);
 
+    (new Class_User_Settings($joe))
+      ->set('show_admin_icons', 1)
+      ->set('amber_ide', 1)
+      ->save();
+
     ZendAfi_Auth::getInstance()->logUser($joe);
     Class_AdminVar::set('DISABLE_BLOCKS_SORTING', 1);
 
diff --git a/tests/application/modules/opac/controllers/RechercheControllerTest.php b/tests/application/modules/opac/controllers/RechercheControllerTest.php
index 1a1f803c28391344ae80ddc7e988a9b73ed71326..d6634db50b236b7d60fdd62723b4437d7abb23bb 100644
--- a/tests/application/modules/opac/controllers/RechercheControllerTest.php
+++ b/tests/application/modules/opac/controllers/RechercheControllerTest.php
@@ -1481,7 +1481,9 @@ abstract class RechercheAvanceeControllerSimpleActionTestCase extends RechercheC
 
 
 
-class RechercheAvanceeControllerSimpleActionWithDefaultConfigTest extends RechercheAvanceeControllerSimpleActionTestCase {
+class RechercheAvanceeControllerSimpleActionWithDefaultConfigTest
+  extends RechercheAvanceeControllerSimpleActionTestCase {
+
   public function setUp() {
     parent::setUp();
 
@@ -1576,28 +1578,28 @@ class RechercheAvanceeControllerSimpleActionWithDefaultConfigTest extends Recher
 
     Class_MoteurRecherche::setInstance($mock_moteur_recherche);
 
-    $lok = $this->fixture('Class_Users',
-                   ['id' => 1,
-                    'login' => 'Lok',
-                    'password' => 'Lik']);
-
-    (new Class_User_Settings($lok))
-      ->setBookmarkedLibraries(['3'])
-      ->setBookmarkedDomains(['1'])
-      ->save();
-
-    $this->fixture('Class_Catalogue',
+    $this->fixture(Class_Catalogue::class,
                    ['id' => 1,
                     'libelle' => 'Des BD',
                     'indexer' => 1]);
 
-    $this->fixture('Class_Bib',
+    $this->fixture(Class_Bib::class,
                    ['id' => 3,
                    'libelle' => 'I like real fixtures']);
 
+    $lok = $this->fixture(Class_Users::class,
+                          ['id' => 1,
+                           'login' => 'Lok',
+                           'password' => 'Lik']);
+
+    (new Class_User_Settings($lok))
+      ->setBookmarkedLibraries(['3'])
+      ->setBookmarkedDomains(['1'])
+      ->save();
+
     ZendAfi_Auth::getInstance()->logUser($lok);
 
-    $this->dispatch('/recherche/simple?rech_titres=maupassant',true);
+    $this->dispatch('/recherche/simple?rech_titres=maupassant');
   }
 
 
@@ -1609,9 +1611,9 @@ class RechercheAvanceeControllerSimpleActionWithDefaultConfigTest extends Recher
 
   /** @test */
   public function userSettingBookmarkedDomainShouldBeOne() {
-    $this->assertEquals(1,
+    $this->assertEquals([Class_Catalogue::find(1)],
                         (new Class_User_Settings(Class_Users::find(1)))
-                        ->get(Class_User_Settings::BOOKMARKED_DOMAINS));
+                        ->getBookmarkedDomains());
   }
 
 
diff --git a/tests/library/Class/MoteurRecherche/MoteurRechercheFacettesTest.php b/tests/library/Class/MoteurRecherche/MoteurRechercheFacettesTest.php
index 4ef4900528718d7e31827d16668b477aaed55304..0414aee50ffbb6d1682bc654d67a0204c79c8bbb 100644
--- a/tests/library/Class/MoteurRecherche/MoteurRechercheFacettesTest.php
+++ b/tests/library/Class/MoteurRecherche/MoteurRechercheFacettesTest.php
@@ -58,13 +58,14 @@ class MoteurRechercheFacettesTest extends ModelTestCase {
                              ['id' => 2,
                               'libelle' => 'Seynod']);
 
-    ZendAfi_Auth::getInstance()->logUser($this->fixture('Class_Users',
-                                                        ['id' => 1,
-                                                         'login' => 'Lok',
-                                                         'password' => 'Lik',
-                                                         'settings' => Class_User_Settings::serializeSettings([Class_User_Settings::BOOKMARKED_DOMAINS => '4-1',
-                                                                                                               Class_User_Settings::BOOKMARKED_LIBRARIES => '2;3']),
-                                                         'bib' => $seynod]));
+    $lok = $this->fixture(Class_Users::class,
+                          ['id' => 1,
+                           'login' => 'Lok',
+                           'password' => 'Lik',
+                           'settings' => 'a:2:{s:11:"library_ids";s:3:"2;3";s:10:"domain_ids";s:3:"4-1";}',
+                           'bib' => $seynod]);
+
+    ZendAfi_Auth::getInstance()->logUser($lok);
 
     $this->fixture('Class_Catalogue',
                    ['id' => 1,
@@ -167,13 +168,16 @@ class MoteurRechercheFacettesTest extends ModelTestCase {
 
   /** @test */
   public function emptySearchWithDefaultBookmarkedLibShoulSucced() {
-    Class_Users::getIdentity()->setSettings(Class_User_Settings::serializeSettings([Class_User_Settings::BOOKMARKED_DOMAINS => 1]))->save();
+    Class_Users::getIdentity()
+      ->setSettings('a:1:{s:10:"domain_ids";s:1:"1";}')
+      ->assertSave();
     $this->setupSearch('');
 
     $this->assertEquals([['id' => 'HCCCC0001',
                           'label' => 'Domaines : Games (1)'],
                          ['id' => 'Y2',
-                          'label' => 'Site : Seynod (1)']], $this->facettes['bookmarks']);
+                          'label' => 'Site : Seynod (1)']],
+                        $this->facettes['bookmarks']);
   }
 
 
diff --git a/tests/library/ZendAfi/View/Helper/Accueil/SitoTest.php b/tests/library/ZendAfi/View/Helper/Accueil/SitoTest.php
index d7ccd8bc7e59f319593d51686ee2cb8d001ce097..537e1c644904313a15947a422da56a86274f333d 100644
--- a/tests/library/ZendAfi/View/Helper/Accueil/SitoTest.php
+++ b/tests/library/ZendAfi/View/Helper/Accueil/SitoTest.php
@@ -390,57 +390,45 @@ class SitoViewHelperAdminTest extends SitoViewHelperTestCase {
     $this->parentSetup();
   }
 
-  protected function logAdmin() {
-    $joe = $this->fixture('Class_Users',
-                          ['id' => 23,
-                           'login' => 'Joe',
-                           'password' => 'unsupermotdepasse',
-                           'id_site' => 1,
-                           'settings' => Class_User_Settings::serializeSettings(['show_admin_icons' => '1']),
-                           'role_level' => ZendAfi_Acl_AdminControllerRoles::ADMIN_PORTAIL]);
 
+  protected function _logUserWithAttribs(array $attribs) : self {
+    $joe = $this->fixture(Class_Users::class,
+                          array_merge(['id' => 23,
+                                       'login' => 'Joe',
+                                       'password' => 'unsupermotdepasse',
+                                       'id_site' => 1,
+                                       'role_level' => ZendAfi_Acl_AdminControllerRoles::ADMIN_PORTAIL],
+                                      $attribs));
+
+    (new Class_User_Settings($joe))
+      ->set('show_admin_icons', 1)
+      ->save();
 
     ZendAfi_Auth::getInstance()->logUser($joe);
     $this->addFixturesSito();
     $this->createBoxAndHelper();
+    return $this;
   }
 
 
-  protected function logModo() {
-    $joe = $this->fixture('Class_Users',
-                          ['id' => 23,
-                           'login' => 'Joe',
-                           'password' => 'unsupermotdepasse',
-                           'id_site' => 1,
-                           'settings' => Class_User_Settings::serializeSettings(['show_admin_icons' => '1']),
-                           'role_level' => ZendAfi_Acl_AdminControllerRoles::MODO_PORTAIL]);
+  protected function logAdmin() {
+    $this->_logUserWithAttribs(['role_level' => ZendAfi_Acl_AdminControllerRoles::ADMIN_PORTAIL]);
+  }
 
 
-    ZendAfi_Auth::getInstance()->logUser($joe);
-    $this->addFixturesSito();
-    $this->createBoxAndHelper();
+  protected function logModo() {
+    $this->_logUserWithAttribs(['role_level' => ZendAfi_Acl_AdminControllerRoles::MODO_PORTAIL]);
   }
 
 
   protected function logModoAllowed() {
-    $group_sito= $this->fixture('Class_UserGroup',
-                                           ['id' => 22,
-                                            'libelle' => 'Testing group',
-                                            'rights' => [Class_UserGroup::RIGHT_USER_SITOTHEQUE]]);
-
-    $joe = $this->fixture('Class_Users',
-                          ['id' => 23,
-                           'login' => 'Joe',
-                           'password' => 'unsupermotdepasse',
-                           'id_site' => 1,
-                           'settings' => Class_User_Settings::serializeSettings(['show_admin_icons' => '1']),
-                           'role_level' => ZendAfi_Acl_AdminControllerRoles::MODO_PORTAIL,
-                           'user_groups' => [$group_sito]]);
-
+    $group_sito = $this->fixture(Class_UserGroup::class,
+                                ['id' => 22,
+                                 'libelle' => 'Testing group',
+                                 'rights' => [Class_UserGroup::RIGHT_USER_SITOTHEQUE]]);
 
-    ZendAfi_Auth::getInstance()->logUser($joe);
-    $this->addFixturesSito();
-    $this->createBoxAndHelper();
+    $this->_logUserWithAttribs(['role_level' => ZendAfi_Acl_AdminControllerRoles::MODO_PORTAIL,
+                                'user_groups' => [$group_sito]]);
   }
 
 
@@ -448,8 +436,7 @@ class SitoViewHelperAdminTest extends SitoViewHelperTestCase {
   public function editAdminButtonSitoShouldBeDisplayed() {
     $this->logAdmin();
     $this->assertXPath($this->html,
-                       '//a[contains(@href,"/admin/sito/edit/id/12")]//img[@alt="Modifier le site"]',$this->html);
-
+                       '//a[contains(@href,"/admin/sito/edit/id/12")]//img[@alt="Modifier le site"]');
   }
 
 
@@ -457,8 +444,7 @@ class SitoViewHelperAdminTest extends SitoViewHelperTestCase {
   public function editAdminButtonSitoShouldNotBeDisplayedWithModo() {
     $this->logModo();
     $this->assertNotXPath($this->html,
-                          '//img[@alt="Modifier le site"]',$this->html);
-
+                          '//img[@alt="Modifier le site"]');
   }
 
 
@@ -466,8 +452,7 @@ class SitoViewHelperAdminTest extends SitoViewHelperTestCase {
   public function addAdminButtonSitoShouldNotBeDisplayedWithModo() {
     $this->logModo();
     $this->assertNotXPath($this->html,
-                          '//img[contains(@alt,"Ajouter un site")]',$this->html);
-
+                          '//img[contains(@alt,"Ajouter un site")]');
   }
 
 
@@ -475,8 +460,7 @@ class SitoViewHelperAdminTest extends SitoViewHelperTestCase {
   public function addAdminButtonNewSitoShouldBeDisplayedWithUserWithRights() {
     $this->logModoAllowed();
     $this->assertXPath($this->html,
-                       '//img[contains(@alt,"Ajouter un nouveau site")]',$this->html);
-
+                       '//img[contains(@alt,"Ajouter un nouveau site")]');
   }
 
 
@@ -484,8 +468,7 @@ class SitoViewHelperAdminTest extends SitoViewHelperTestCase {
   public function editAdminButtonAddSitoShouldBeDisplayed() {
     $this->logAdmin();
     $this->assertXPath($this->html,
-                       '//a[contains(@href,"/admin/sito/add/id_cat/9")]//img[@alt="Ajouter un site dans la catégorie: France"]',$this->html);
-
+                       '//a[contains(@href,"/admin/sito/add/id_cat/9")]//img[@alt="Ajouter un site dans la catégorie: France"]');
   }
 
 
@@ -493,10 +476,8 @@ class SitoViewHelperAdminTest extends SitoViewHelperTestCase {
   public function editWithUserGroupSitoButtonAddSitoShouldBeDisplayed() {
     $this->logModoAllowed();
     $this->assertXPath($this->html,
-                       '//a[contains(@href,"/admin/sito/add/id_cat/9")]//img[@alt="Ajouter un site dans la catégorie: France"]',$this->html);
-
+                       '//a[contains(@href,"/admin/sito/add/id_cat/9")]//img[@alt="Ajouter un site dans la catégorie: France"]');
   }
-
 }