diff --git a/application/modules/admin/controllers/MultimediaController.php b/application/modules/admin/controllers/MultimediaController.php
index 89d342cc56cb850ca5bb0cf5fafaacdcdbcacd57..34a7aaf07fa1d7e1c1477501b645b7ecbce61dd5 100644
--- a/application/modules/admin/controllers/MultimediaController.php
+++ b/application/modules/admin/controllers/MultimediaController.php
@@ -25,88 +25,6 @@ class Admin_MultimediaController extends ZendAfi_Controller_Action {
             'ZendAfi_Controller_Plugin_Manager_Multimedia'];
   }
 
-  public function getLocalisationFields() {
-    $libelles = [];
-    foreach (Class_Bib::findAllBy(['order' => 'libelle']) as $bib)
-      $libelles[$bib->getId()] = $bib->getLibelle();
-
-    return ['id_site' => ['element' => 'select',
-                          'options' => ['multioptions' => $libelles]]];
-  }
-
-
-  public function getConfigFields() {
-    return ['slot_size' => ['element' => 'text',
-                            'options' => ['label' => 'Durée d\'un créneau (en minutes)',
-                                          'title'=> 'en minutes',
-                                          'size'  => 4,
-                                          'required' => true,
-                                          'allowEmpty' => false,
-                                          'validators' => ['digits']]],
-
-            'max_slots' => ['element' => 'text',
-                            'options' => ['label' => 'Nombre maximum de créneaux réservables simultanément',
-                                          'title' => 'en nombre de "slots"',
-                                          'size' => 4,
-                                          'required' => true,
-                                          'allowEmpty' => false,
-                                          'validators' => ['digits']]],
-
-            'hold_delay_min' => ['element' => 'text',
-                                 'options' => ['label' => 'Nombre de jours au plus tard avant une réservation<br/> (0 pour résa le
-jour même)',
-                                               'title' => 'en jours, 0 autorise les réservations le jour même',
-                                               'size' => 4,
-                                               'required' => true,
-                                               'allowEmpty' => false,
-                                               'validators' => ['digits']]],
-
-            'hold_delay_max' => ['element' => 'text',
-                                 'options' => [
-                                               'label' => 'Nombre de jours au plus tôt avant une réservation<br/>(1 pour autoriser
-les réservations pour le lendemain)',
-                                               'title' => 'en jours, doit être supérieur au délai minimum',
-                                               'size' => 4,
-                                               'required' => true,
-                                               'allowEmpty' => false,
-                                               'validators' => ['digits', new ZendAfi_Validate_FieldGreater('hold_delay_min', 'Délai minimum de réservation')]]],
-
-            'auth_delay' => ['element' => 'text',
-                             'options' => ['label' => 'Délai de connexion avant d\'annuler une réservation (en minutes)',
-                                           'title' => 'en minutes, passé ce délai la réservation est annulée',
-                                           'size' => 4,
-                                           'required' => true,
-                                           'allowEmpty' => false,
-                                           'validators' => ['digits']]]];
-  }
-
-
-  public function getConfigAutoFields() {
-    return [
-            'autohold' => ['element' => 'checkbox',
-                           'options' => ['label' => 'Générer automatiquement une réservation à la connexion à un poste
-disponible',
-                                         'title' => 'quand un abonné se connecte sur un poste non réservé, une réservation lui est attribuée',
-                                         'required' => true,
-                                         'allowEmpty' => false]],
-
-            'autohold_min_time' => ['element' => 'text',
-                                    'options' => ['label' => 'Temps minimum de connexion avant la réservation suivante (en minutes)',
-                                                  'title' => 'quand un abonné se connecte et qu\'une réservation est prévue dans quelques minutes, permet de définir si la réservation automatique peut s\'effectuer',
-                                                  'size' => 4,
-                                                  'required' => true,
-                                                  'allowEmpty' => false,
-                                                  'validators' => ['digits']]],
-
-            'autohold_slots_max' => ['element' => 'text',
-                                     'options' => ['label' => 'Durée de la réservation automatique (en nombre de créneaux)',
-                                                   'title' => 'en nombre de "slots"',
-                                                   'size' => 4,
-                                                   'required' => true,
-                                                   'allowEmpty' => false,
-                                                   'validators' => ['digits']]]];
-  }
-
 
   public function browseAction() {
     if (!$location = Class_Multimedia_Location::find((int)$this->_getParam('id'))) {
diff --git a/application/modules/admin/controllers/OuverturesController.php b/application/modules/admin/controllers/OuverturesController.php
index 384f5a5c720a43f12ec88b7130bbca62e8667dd7..d89e451598c0aa1742ae1e7201d81320bbe3ba75 100644
--- a/application/modules/admin/controllers/OuverturesController.php
+++ b/application/modules/admin/controllers/OuverturesController.php
@@ -23,73 +23,45 @@ class Admin_OuverturesController extends ZendAfi_Controller_Action {
   protected $_library, $_is_multimedia = false;
 
   public function getPlugins() {
-    return ['ZendAfi_Controller_Plugin_Manager_Opening'];
+    return ['ZendAfi_Controller_Plugin_ResourceDefinition_Opening',
+            'ZendAfi_Controller_Plugin_Manager_Opening'];
   }
 
 
   public function init() {
-    if ((!$this->_library = Class_Bib::find($this->_getParam('id_site')))
+    if ((!$this->_library = $this->_getLibrary())
         || ($this->_getParam('multimedia') && !Class_AdminVar::isMultimediaEnabled())) {
       $this->_redirect('/admin/bib');
       return;
     }
 
-    $this->_is_multimedia = null !== $this->_getParam('multimedia');
+    $this->_is_multimedia = $this->_isMultimedia();
     parent::init();
   }
 
 
-  public function getRessourceDefinitions() {
-    return ['model' => ['class' => 'Class_Ouverture',
-                        'name' => 'ouverture',
-                        'scope' => ['id_site', 'multimedia'],
-                        'order' => 'jour desc, jour_semaine, validity_start'],
-
-            'sort' => ['Class_Ouverture', 'compare'],
-
-            'messages' => $this->_getRessourceMessages(),
-
-            'after_add' => function($model) { $this->_redirectToIndex(); },
-            'after_edit' => function($model) {  $this->_redirectToIndex(); },
-
-            'actions' => $this->_getRessourceActions(),
-
-            'form' => new ZendAfi_Form_Admin_Ouverture()];
-
+  protected function _getLibrary() {
+    return Class_Bib::find($this->_getParam('id_site'));
   }
 
 
-  protected function _getRessourceMessages() {
-    if(!$this->_library)
-      return [];
-
-    $lib_label = $this->_library->getLibelle();
-
-    return $this->_is_multimedia
-      ? ['successful_add' => $this->_('Plage horaire de réservation multimedia %s ajoutée', $lib_label),
-         'successful_save' => $this->_('Plage horaire de réservation multimedia %s sauvegardée', $lib_label),
-         'successful_delete' => $this->_('Plage horaire de réservation multimedia %s supprimée', $lib_label)]
-
-      : ['successful_add' => $this->_('Plage d\'ouverture %s ajoutée', $lib_label),
-         'successful_save' => $this->_('Plage d\'ouverture %s sauvegardée', $lib_label),
-         'successful_delete' => $this->_('Plage d\'ouverture %s supprimée', $lib_label)];
+  protected function _isMultimedia() {
+    return null !== $this->_getParam('multimedia');
   }
 
 
-  protected function _getRessourceActions() {
-    if(!$this->_library)
-      return [];
-
-    $lib_label = $this->_library->getLibelle();
-
-    return $this->_is_multimedia
-      ? ['edit' => ['title' => $this->_('%s : modifier une plage horaire de réservation multimedia', $lib_label)],
-         'add' => ['title' => $this->_('%s : ajouter une plage horaire de réservation multimedia', $lib_label)],
-         'index' => ['title' => $this->_('%s : plages horaire de réservation multimedia', $lib_label)]]
-
-      : ['edit' => ['title' => $this->_('%s : modifier une plage d\'ouverture', $lib_label)],
-         'add' => ['title' => $this->_('%s : ajouter une plage d\'ouverture', $lib_label)],
-         'index' => ['title' => $this->_('%s : plages d\'ouverture', $lib_label)]];
+  public function acceptVisitor($visitor) {
+    parent::acceptVisitor($visitor);
+    $visitor
+      ->visitLibrary(function()
+                     {
+                       return $this->_getLibrary();
+                     })
+      ->visitIsMultimedia(function()
+                          {
+                            return $this->_isMultimedia();
+                          });
+    return $this;
   }
 
 
diff --git a/library/ZendAfi/Controller/Action.php b/library/ZendAfi/Controller/Action.php
index f2d13eb4a34b5bef912cdfde8f3a04f286c9cb2e..76d00112ae07f61fbf1f93cc288895fbecf4fd60 100644
--- a/library/ZendAfi/Controller/Action.php
+++ b/library/ZendAfi/Controller/Action.php
@@ -340,10 +340,6 @@ class ZendAfi_Controller_Action extends Zend_Controller_Action {
                              {
                                $this->_redirectToIndex();
                              })
-      ->visitPreDispatch(function()
-                         {
-                           $this->preDispatch();
-                         })
       ;
 
     return $this;
diff --git a/library/ZendAfi/Controller/Plugin/ResourceDefinition/Multimedia.php b/library/ZendAfi/Controller/Plugin/ResourceDefinition/Multimedia.php
index 2ec7bbf7e1acf1ecabe1997b22d650caba5d5e4b..d69f5239298b1014b8ca441b9f89e3a9f63d46fe 100644
--- a/library/ZendAfi/Controller/Plugin/ResourceDefinition/Multimedia.php
+++ b/library/ZendAfi/Controller/Plugin/ResourceDefinition/Multimedia.php
@@ -22,19 +22,103 @@
 
 class ZendAfi_Controller_Plugin_ResourceDefinition_Multimedia extends ZendAfi_Controller_Plugin_ResourceDefinition_Abstract {
   public function getDefinitions() {
-    return ['model' => ['class' => 'Class_Multimedia_Location', 'name' => 'site'],
+    return ['model' => ['class' => 'Class_Multimedia_Location',
+                        'name' => 'site'],
             'messages' => ['successful_save' => 'Site %s sauvegardé'],
             'actions' => ['edit' => ['title' => 'Modifier un site multimédia'],
                           'index' => ['title' => 'Sites multimédia']],
             'display_groups' => ['localisation' => ['legend' => 'Localisation',
-                                                    'elements' => $this->getLocalisationFields()],
+                                                    'elements' => $this->_getLocalisationFields()],
 
                                  'config' => ['legend' => 'Réservation',
-                                              'elements' => $this->getConfigFields()],
+                                              'elements' => $this->_getConfigFields()],
 
                                  'config_auto' => ['legend' => 'Réservation automatique',
-                                                   'elements' => $this->getConfigAutoFields()]]
+                                                   'elements' => $this->_getConfigAutoFields()]]
     ];
   }
+
+
+  protected function _getLocalisationFields() {
+    $libelles = [];
+    foreach (Class_Bib::findAllBy(['order' => 'libelle']) as $bib)
+      $libelles[$bib->getId()] = $bib->getLibelle();
+
+    return ['id_site' => ['element' => 'select',
+                          'options' => ['multioptions' => $libelles]]];
+  }
+
+
+  protected function _getConfigFields() {
+    return ['slot_size' => ['element' => 'text',
+                            'options' => ['label' => 'Durée d\'un créneau (en minutes)',
+                                          'title'=> 'en minutes',
+                                          'size'  => 4,
+                                          'required' => true,
+                                          'allowEmpty' => false,
+                                          'validators' => ['digits']]],
+
+            'max_slots' => ['element' => 'text',
+                            'options' => ['label' => 'Nombre maximum de créneaux réservables simultanément',
+                                          'title' => 'en nombre de "slots"',
+                                          'size' => 4,
+                                          'required' => true,
+                                          'allowEmpty' => false,
+                                          'validators' => ['digits']]],
+
+            'hold_delay_min' => ['element' => 'text',
+                                 'options' => ['label' => 'Nombre de jours au plus tard avant une réservation<br/> (0 pour résa le
+jour même)',
+                                               'title' => 'en jours, 0 autorise les réservations le jour même',
+                                               'size' => 4,
+                                               'required' => true,
+                                               'allowEmpty' => false,
+                                               'validators' => ['digits']]],
+
+            'hold_delay_max' => ['element' => 'text',
+                                 'options' => [
+                                               'label' => 'Nombre de jours au plus tôt avant une réservation<br/>(1 pour autoriser
+les réservations pour le lendemain)',
+                                               'title' => 'en jours, doit être supérieur au délai minimum',
+                                               'size' => 4,
+                                               'required' => true,
+                                               'allowEmpty' => false,
+                                               'validators' => ['digits', new ZendAfi_Validate_FieldGreater('hold_delay_min', 'Délai minimum de réservation')]]],
+
+            'auth_delay' => ['element' => 'text',
+                             'options' => ['label' => 'Délai de connexion avant d\'annuler une réservation (en minutes)',
+                                           'title' => 'en minutes, passé ce délai la réservation est annulée',
+                                           'size' => 4,
+                                           'required' => true,
+                                           'allowEmpty' => false,
+                                           'validators' => ['digits']]]];
+  }
+
+
+  protected function _getConfigAutoFields() {
+    return [
+            'autohold' => ['element' => 'checkbox',
+                           'options' => ['label' => 'Générer automatiquement une réservation à la connexion à un poste
+disponible',
+                                         'title' => 'quand un abonné se connecte sur un poste non réservé, une réservation lui est attribuée',
+                                         'required' => true,
+                                         'allowEmpty' => false]],
+
+            'autohold_min_time' => ['element' => 'text',
+                                    'options' => ['label' => 'Temps minimum de connexion avant la réservation suivante (en minutes)',
+                                                  'title' => 'quand un abonné se connecte et qu\'une réservation est prévue dans quelques minutes, permet de définir si la réservation automatique peut s\'effectuer',
+                                                  'size' => 4,
+                                                  'required' => true,
+                                                  'allowEmpty' => false,
+                                                  'validators' => ['digits']]],
+
+            'autohold_slots_max' => ['element' => 'text',
+                                     'options' => ['label' => 'Durée de la réservation automatique (en nombre de créneaux)',
+                                                   'title' => 'en nombre de "slots"',
+                                                   'size' => 4,
+                                                   'required' => true,
+                                                   'allowEmpty' => false,
+                                                   'validators' => ['digits']]]];
+  }
 }
 ?>
\ No newline at end of file
diff --git a/library/ZendAfi/Controller/Plugin/ResourceDefinition/Opening.php b/library/ZendAfi/Controller/Plugin/ResourceDefinition/Opening.php
new file mode 100644
index 0000000000000000000000000000000000000000..e7e24dcfc710a16370e6ffe008e32dffa8681e7c
--- /dev/null
+++ b/library/ZendAfi/Controller/Plugin/ResourceDefinition/Opening.php
@@ -0,0 +1,99 @@
+<?php
+/**
+ * Copyright (c) 2012-2017, 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_Controller_Plugin_ResourceDefinition_Opening extends ZendAfi_Controller_Plugin_ResourceDefinition_Abstract {
+  public function getDefinitions() {
+    return ['model' => ['class' => 'Class_Ouverture',
+                        'name' => 'ouverture',
+                        'scope' => ['id_site', 'multimedia'],
+                        'order' => 'jour desc, jour_semaine, validity_start'],
+
+            'sort' => ['Class_Ouverture', 'compare'],
+
+            'messages' => $this->_getRessourceMessages(),
+
+            'after_add' => function($model) { $this->_redirectToIndex(); },
+            'after_edit' => function($model) {  $this->_redirectToIndex(); },
+
+            'actions' => $this->_getRessourceActions(),
+
+            'form' => new ZendAfi_Form_Admin_Ouverture()];
+
+  }
+
+
+  protected function _getRessourceMessages() {
+    if(!$this->_getLibrary())
+      return [];
+
+    $lib_label = $this->_library->getLibelle();
+
+    return $this->_isMultimedia()
+      ? ['successful_add' => $this->_('Plage horaire de réservation multimedia %s ajoutée', $lib_label),
+         'successful_save' => $this->_('Plage horaire de réservation multimedia %s sauvegardée', $lib_label),
+         'successful_delete' => $this->_('Plage horaire de réservation multimedia %s supprimée', $lib_label)]
+
+      : ['successful_add' => $this->_('Plage d\'ouverture %s ajoutée', $lib_label),
+         'successful_save' => $this->_('Plage d\'ouverture %s sauvegardée', $lib_label),
+         'successful_delete' => $this->_('Plage d\'ouverture %s supprimée', $lib_label)];
+  }
+
+
+  protected function _getRessourceActions() {
+    if(!$this->_getLibrary())
+      return [];
+
+    $lib_label = $this->_library->getLibelle();
+
+    return $this->_isMultimedia()
+      ? ['edit' => ['title' => $this->_('%s : modifier une plage horaire de réservation multimedia', $lib_label)],
+         'add' => ['title' => $this->_('%s : ajouter une plage horaire de réservation multimedia', $lib_label)],
+         'index' => ['title' => $this->_('%s : plages horaire de réservation multimedia', $lib_label)]]
+
+      : ['edit' => ['title' => $this->_('%s : modifier une plage d\'ouverture', $lib_label)],
+         'add' => ['title' => $this->_('%s : ajouter une plage d\'ouverture', $lib_label)],
+         'index' => ['title' => $this->_('%s : plages d\'ouverture', $lib_label)]];
+  }
+
+
+  public function visitLibrary($callback) {
+    $this->_library_callback = $callback;
+    return $this;
+  }
+
+
+  protected function _getLibrary() {
+    return $this->_library = call_user_func($this->_library_callback);
+  }
+
+
+  public function visitIsMultimedia($callback) {
+    $this->_is_multimedia_callback = $callback;
+    return $this;
+  }
+
+
+  protected function _isMultimedia() {
+    return $this->_is_multimedia = call_user_func($this->_is_multimedia_callback);
+  }
+}
+?>
\ No newline at end of file