diff --git a/VERSIONS_HOTLINE/134652 b/VERSIONS_HOTLINE/134652
new file mode 100644
index 0000000000000000000000000000000000000000..8c4574c69efb992eaf9653bee9d24d2a115255fb
--- /dev/null
+++ b/VERSIONS_HOTLINE/134652
@@ -0,0 +1 @@
+ - ticket #134652 : Articles : la variable pour changer l'expéditeur utilisé dans le workflow des articles est aussi utilisée pour la notification des articles à valider
\ No newline at end of file
diff --git a/library/Class/Article/WorkflowNotification.php b/library/Class/Article/WorkflowNotification.php
new file mode 100644
index 0000000000000000000000000000000000000000..8dbdafc26b3e57b8e909eff309a0cdd63aef350f
--- /dev/null
+++ b/library/Class/Article/WorkflowNotification.php
@@ -0,0 +1,220 @@
+<?php
+/**
+ * Copyright (c) 2012-2021, 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_Article_WorkflowNotification {
+  use Trait_Translator;
+
+  protected
+    $_article,
+    $_helper;
+
+
+  public static function newFor($article, $helper) {
+    if ($article->getStatus() == $article->old_status)
+      return new static($article, $helper);
+
+    if (static::_isValidationPending($article))
+      return new Class_Article_WorkflowNotification_ValidationPending($article, $helper);
+
+    if (static::_isBecoming($article, Class_Article::STATUS_VALIDATED))
+      return new Class_Article_WorkflowNotification_Validated($article, $helper);
+
+    if (static::_isBecoming($article, Class_Article::STATUS_REFUSED))
+      return new Class_Article_WorkflowNotification_Refused($article, $helper);
+
+    return new static($article, $helper);
+  }
+
+
+  protected static function _isValidationPending($article) {
+    return static::_isBecoming($article, Class_Article::STATUS_VALIDATION_PENDING)
+      || ($article->getStatus() > Class_Article::STATUS_REFUSED);
+  }
+
+
+  protected static function _isBecoming($article, $new_status) {
+    return $article->getStatus() == $new_status;
+  }
+
+
+  public function __construct($article, $helper) {
+    $this->_article = $article;
+    $this->_helper = $helper;
+    $this->_user = Class_Users::getIdentity();
+  }
+
+
+  public function notify() {
+    if (!Class_AdminVar::isWorkflowEnabled() || !$this->_user)
+      return $this;
+
+    if (!$recipients = $this->_loadRecipients())
+      return $this;
+
+    $mail = (new ZendAfi_Mail)
+      ->addTo(implode(',', $recipients))
+      ->setSubject($this->_subject())
+      ->setBodyText($this->_bodyText())
+      ->setFrom(Class_AdminVar::getValueOrDefault('WORKFLOW_MAIL_FROM'))
+      ;
+
+    if ($this->_sendMail($mail))
+      $this->_helper->notify($this->_successMessage($mail));
+
+    return $this;
+  }
+
+
+  protected function _bodyText() {
+    $replacements = ['TITRE_ARTICLE' => $this->_article->getTitre(),
+                     'URL_ARTICLE' => Class_Url::absolute($this->_article->getUrl(), null, true),
+                     'AUTHOR_ARTICLE' => $this->_article->getNomCompletAuteur(),
+                     'SAVED_BY_ARTICLE' => $this->_user->getNomComplet(),
+                     'NEXT_STATUS_ARTICLE' => $this->_article->getNextWorkflowStatusLabel(),
+                     'STATUS_ARTICLE' => $this->_article->getStatusLabel()];
+
+    return str_replace(array_keys($replacements),
+                       array_values($replacements),
+                       $this->_bodyTextTemplate());
+  }
+
+
+
+  protected function _sendMail($mail) {
+    try {
+      $mail->send();
+      return true;
+    } catch (Exception $e) {
+      $this->_helper
+        ->notify($this->_('Mail non envoyé: vérifier la configuration du serveur de mail.'));
+      return false;
+    }
+  }
+
+
+  protected function _loadRecipients() {
+    return [];
+  }
+
+
+  protected function _subject() {
+    return '';
+  }
+
+
+  protected function _bodyTextTemplate() {
+    return '';
+  }
+
+
+  protected function _successMessage($sent_mail) {
+    return '';
+  }
+}
+
+
+
+
+class Class_Article_WorkflowNotification_ValidationPending
+  extends Class_Article_WorkflowNotification {
+
+  protected function _loadRecipients() {
+    return array_unique(Class_Permission::getWorkflow($this->_article->getNextWorkflowStatus())
+                        ->getUsersOnModel($this->_article->getCategorie())
+                        ->collect('mail')
+                        ->getArrayCopy());
+  }
+
+
+  protected function _subject() {
+    return $this->_('[Bokeh] Validation d\'article en attente: %s',
+                    $this->_article->getTitre());
+  }
+
+
+  protected function _bodyTextTemplate() {
+    return Class_AdminVar::getWorkflowTextMailArticlePending();
+  }
+
+
+  protected function _successMessage($sent_mail) {
+    return $this->_('Mail de validation envoyé aux validateurs.');
+  }
+}
+
+
+
+
+class Class_Article_WorkflowNotification_ToAuthor
+  extends Class_Article_WorkflowNotification {
+
+  protected function _loadRecipients() {
+    if (!$author = $this->_article->getAuteur()) {
+      $this->_helper->notify($this->_('Mail non envoyé: article sans auteur'));
+      return [];
+    }
+
+    if (!$mail_address = $author->getMail()) {
+      $this->_helper->notify($this->_('Mail non envoyé: %s sans mail.', $author->getNomComplet()));
+      return [];
+    }
+
+    return [$mail_address];
+  }
+
+
+  protected function _successMessage($sent_mail) {
+    return $this->_('Mail envoyé à: %s', $sent_mail->getRecipients()[0]);
+  }
+}
+
+
+
+
+class Class_Article_WorkflowNotification_Validated
+  extends Class_Article_WorkflowNotification_ToAuthor {
+
+  protected function _subject() {
+    return $this->_('[Bokeh] Validation de l\'article %s', $this->_article->getTitre());
+  }
+
+
+  protected function _bodyTextTemplate() {
+    return $this->_article->getValideMessage();
+  }
+}
+
+
+
+
+class Class_Article_WorkflowNotification_Refused
+  extends Class_Article_WorkflowNotification_ToAuthor {
+
+  protected function _subject() {
+    return $this->_('[Bokeh] Refus de l\'article %s', $this->_article->getTitre());
+  }
+
+
+  protected function _bodyTextTemplate() {
+    return $this->_article->getRefusMessage();
+  }
+}
diff --git a/library/ZendAfi/Controller/Plugin/Manager/Article.php b/library/ZendAfi/Controller/Plugin/Manager/Article.php
index c090644422418adb3822d37becfcf446a1f92715..97475c779ebb76cc3918a2188b9a014fd4111cd8 100644
--- a/library/ZendAfi/Controller/Plugin/Manager/Article.php
+++ b/library/ZendAfi/Controller/Plugin/Manager/Article.php
@@ -27,13 +27,10 @@ class ZendAfi_Controller_Plugin_Manager_Article extends ZendAfi_Controller_Plugi
       return;
     }
 
-    $this->_view->titre = $this->_view->_('Supprimer l\'article : %s',
-                                          $article->getTitre());
-
+    $this->_view->titre = $this->_('Supprimer l\'article : %s', $article->getTitre());
 
     if (!$this->_canModify($article->getCategorie())) {
-      $this->_helper->notify($this->_view->_('Vous n\'avez pas la permission "%s"',
-                                             $this->_view->titre));
+      $this->_helper->notify($this->_('Vous n\'avez pas la permission "%s"', $this->_view->titre));
       $this->_redirectToIndex();
       return;
     }
@@ -47,8 +44,7 @@ class ZendAfi_Controller_Plugin_Manager_Article extends ZendAfi_Controller_Plugi
       return $this->_redirect('admin/cms');
 
     if (!$this->_canModify($model->getCategorie())) {
-      $this->_helper->notify($this->_view->_('Vous n\'avez pas la permission "%s"',
-                                             $this->_view->titre));
+      $this->_helper->notify($this->_('Vous n\'avez pas la permission "%s"', $this->_view->titre));
       return $this->_redirectToIndex();
     }
 
@@ -58,7 +54,8 @@ class ZendAfi_Controller_Plugin_Manager_Article extends ZendAfi_Controller_Plugi
     parent::addAction();
     if ($this->_response->isRedirect())
       return;
-    $this->_view->titre = $this->_view->_('Dupliquer l\'article : %s', $model->getTitre());
+
+    $this->_view->titre = $this->_('Dupliquer l\'article : %s', $model->getTitre());
     $this->_view->form
       ->setAction($this->_view->url(['module' => 'admin',
                                      'controller' => 'cms',
@@ -87,9 +84,9 @@ class ZendAfi_Controller_Plugin_Manager_Article extends ZendAfi_Controller_Plugi
     }
 
     if (!$this->_canModify($article->getCategorie())) {
-      $this->_helper->notify($this->_view->_('Vous n\'avez pas la permission "%s"',
-                                            $this->_view->_('Supprimer l\'article : %s',
-                                                           $article->getTitre())));
+      $this->_helper
+        ->notify($this->_('Vous n\'avez pas la permission "%s"',
+                          $this->_('Supprimer l\'article : %s', $article->getTitre())));
       $this->_redirectToIndex();
       return;
     }
@@ -101,7 +98,7 @@ class ZendAfi_Controller_Plugin_Manager_Article extends ZendAfi_Controller_Plugi
                               {
                                 $plugin->notifyAfterDelete($article);
                               });
-    $this->_helper->notify($this->_view->_('Article supprimé'));
+    $this->_helper->notify($this->_('Article supprimé'));
     $this->_redirect($this->_backDeleteUrl($article));
   }
 
@@ -137,6 +134,7 @@ class ZendAfi_Controller_Plugin_Manager_Article extends ZendAfi_Controller_Plugi
     $article->setCategorie($category);
     if ($domaine = Class_Catalogue::findWithSamePathAs($category))
       $article->setDomaineIds($domaine->getId());
+
     return $this;
   }
 
@@ -155,7 +153,6 @@ class ZendAfi_Controller_Plugin_Manager_Article extends ZendAfi_Controller_Plugi
   }
 
 
-
   protected function _doBeforeSave($article) {
     $article->updateDateMaj();
     return $this;
@@ -183,10 +180,10 @@ class ZendAfi_Controller_Plugin_Manager_Article extends ZendAfi_Controller_Plugi
     }
 
     if (!$this->_canModify($article->getCategorie())) {
-      $this->_helper->notify($this->_view->_('Vous n\'avez pas la permission "%s"',
-                                            $this->_view->_('Rendre %s l\'article : %s',
-                                                           $visibility,
-                                                           $article->getTitre())));
+      $this->_helper
+        ->notify($this->_('Vous n\'avez pas la permission "%s"',
+                          $this->_('Rendre %s l\'article : %s',
+                                   $visibility, $article->getTitre())));
       $this->_redirectToIndex();
       return;
     }
@@ -224,8 +221,8 @@ class ZendAfi_Controller_Plugin_Manager_Article extends ZendAfi_Controller_Plugi
 
   protected function _getEditActionTitle($model) {
     return $model->isTraduction()
-      ? $this->_view->_('Traduire un article: %s', $model->getLibelle())
-      : $this->_view->_('Modifier un article: %s', $model->getLibelle());
+      ? $this->_('Traduire un article: %s', $model->getLibelle())
+      : $this->_('Modifier un article: %s', $model->getLibelle());
   }
 
 
@@ -273,8 +270,8 @@ class ZendAfi_Controller_Plugin_Manager_Article extends ZendAfi_Controller_Plugi
       return 'admin/cms/index' . (!$model->isNew() ? '/id/' . $model->getId() : '');
 
     return $this->_view->absoluteUrl(['module' => 'admin',
-                                     'controller' => 'cms',
-                                     'action' => 'index']);
+                                      'controller' => 'cms',
+                                      'action' => 'index']);
   }
 
 
@@ -284,141 +281,9 @@ class ZendAfi_Controller_Plugin_Manager_Article extends ZendAfi_Controller_Plugi
                    ($page = $this->_getParam('page')) ? '/page/'.$page : '');
   }
 
-  protected function _notifyArticleChanged($article) {
-    if (!Class_AdminVar::isWorkflowEnabled())
-      return;
-    $this->_sendMailWhenUpdatedStatusToValidationPending($article);
-    $this->_sendMailWhenUpdatedStatusToRefused($article);
-    $this->_sendMailWhenUpdatedStatusToValidated($article);
-  }
-
-
-  protected function _sendMailWhenUpdatedStatusToRefused($article) {
-    if ($article->old_status != Class_Article::STATUS_REFUSED &&
-        $article->getStatus() == Class_Article::STATUS_REFUSED)  {
-      $this->_sendRefusedMailToAuteur($article);
-    }
-  }
-
-
-  protected function _sendMailWhenUpdatedStatusToValidated($article) {
-    if ($article->old_status != Class_Article::STATUS_VALIDATED &&
-        $article->getStatus() == Class_Article::STATUS_VALIDATED)  {
-      $this->_sendValidatedMailToAuteur($article);
-    }
-  }
-
-
-  protected function _sendMailWhenUpdatedStatusToValidationPending($article) {
-    if (($article->old_status != Class_Article::STATUS_VALIDATION_PENDING &&
-         $article->getStatus() == Class_Article::STATUS_VALIDATION_PENDING)
-        || ($article->getStatus() > 5
-            && $article->old_status != $article->getStatus()))  {
-      $this->_sendMailToValidators($article);
-    }
-  }
-
-
-  protected function prepareMailForAuteur($article) {
-    $mail = new ZendAfi_Mail();
-    if(!$article->getAuteur()) {
-      $this->_helper->notify($this->_('Mail non envoyé: article sans auteur'));
-      return;
-    }
-
-    if(!$mail_address = $article->getAuteur()->getMail()) {
-      $this->_helper->notify($this->_('Mail non envoyé: %s sans mail.', $article->getNomCompletAuteur()));
-      return;
-    }
-
-    $mail->setFrom(Class_AdminVar::getValueOrDefault('WORKFLOW_MAIL_FROM'))
-         ->addTo($mail_address);
-    return $mail;
-  }
-
 
-  protected function prepareBodyMail($article, $message) {
-    $this->identity = Class_Users::getIdentity();
-    $replacements =
-      ['TITRE_ARTICLE' => $article->getTitre(),
-       'URL_ARTICLE' => $this->_view->absoluteUrl($article->getUrl(), null, true),
-       'AUTHOR_ARTICLE' => $article->getNomCompletAuteur(),
-       'SAVED_BY_ARTICLE' => $this->identity->getNomComplet(),
-       'NEXT_STATUS_ARTICLE' => $article->getNextWorkflowStatusLabel(),
-       'STATUS_ARTICLE' => $article->getStatusLabel()];
-
-    return
-      str_replace(array_keys($replacements),
-                  array_values($replacements),
-                  $message);
-  }
-
-
-  protected function _sendRefusedMailToAuteur($article) {
-    if(!$mail = $this->prepareMailForAuteur($article))
-      return;
-    $body = $this->prepareBodyMail($article, $article->getRefusMessage());
-    $this->sendPreparedMail($mail,
-                            '[Bokeh] Refus de l\'article '.$article->getTitre(),
-                            $body);
-  }
-
-
-  protected function sendPreparedMail($mail, $subject, $body) {
-    $mail->setSubject(quoted_printable_decode($subject))
-         ->setBodyText($body,'utf-8',Zend_Mime::ENCODING_8BIT);
-
-    if ($this->_sendMail($mail))
-      $this->_helper->notify($this->_('Mail envoyé à: %s', $mail->getRecipients()[0]));
-  }
-
-
-  protected function _sendValidatedMailToAuteur($article) {
-    if(!$mail = $this->prepareMailForAuteur($article))
-      return;
-
-    $body = $this->prepareBodyMail($article, $article->getValideMessage());
-    $this->sendPreparedMail($mail,
-                            '[Bokeh] Validation de l\'article '.$article->getTitre(),
-                            $body);
-  }
-
-
-  protected function _getValidatorsMail($article) {
-    return array_unique(
-                        Class_Permission::getWorkflow($article->getNextWorkflowStatus())
-                        ->getUsersOnModel($article->getCategorie())
-                        ->collect('mail')
-                        ->getArrayCopy());
-  }
-
-
-  protected function _sendMailToValidators($article) {
-    if (!$mails = $this->_getValidatorsMail($article))
-      return;
-
-    $mail = new ZendAfi_Mail();
-    $mail
-      ->setFrom('no-reply@afi-sa.fr')
-      ->addTo(implode(',', $mails))
-      ->setSubject($this->_view->_('[Bokeh] Validation d\'article en attente: ') . $article->getTitre())
-      ->setBodyText($this->prepareBodyMail($article,
-                                           Class_AdminVar::getWorkflowTextMailArticlePending()));
-
-    if($this->_sendMail($mail))
-      $this->_helper->notify($this->_view->_('Mail de validation envoyé aux validateurs.'));
-  }
-
-
-  protected function _sendMail($mail) {
-    try {
-      $mail->send();
-      return true;
-
-    } catch (Exception $e) {
-      $this->_helper->notify($this->_('Mail non envoyé: vérifier la configuration du serveur de mail.'));
-      return false;
-    }
+  protected function _notifyArticleChanged($article) {
+    Class_Article_WorkflowNotification::newFor($article, $this->_helper)->notify();
   }
 
 
diff --git a/tests/application/modules/admin/controllers/CmsControllerTest.php b/tests/application/modules/admin/controllers/CmsControllerTest.php
index 8325644ba2a936d13a31544e041c5e04b0694ac9..65cb5d945015926cc3e32515470d72fad85e697c 100644
--- a/tests/application/modules/admin/controllers/CmsControllerTest.php
+++ b/tests/application/modules/admin/controllers/CmsControllerTest.php
@@ -1703,6 +1703,7 @@ class CmsControllerNewsAddActionPostWithWorkflowTest
     $this->postDispatch('/admin/cms/edit/id/18', $data);
   }
 
+
   /** @test */
   public function statusShouldBeUpdated() {
     $this->postArticleValidated();
@@ -1799,16 +1800,15 @@ class CmsControllerNewsAddActionPostWithWorkflowTest
 
 
   /** @test */
-  public function statusDraftToValidationPendingShouldSendByNoReplayAtAfiSaDotFr() {
+  public function statusDraftToValidationPendingShouldSendByNoReplyAtAfiSaDotFr() {
     Class_Article::find(18)->setStatus(Class_Article::STATUS_DRAFT)->save();
     $data = $this->_basePostDatas;
     $data['status'] = Class_Article::STATUS_VALIDATION_PENDING;
     $this->postDispatch('/admin/cms/edit/id/18', $data);
-    $this->assertEquals('no-reply@afi-sa.fr' ,$this->mock_transport->getSentMails()[0]->getFrom());
+    $this->assertEquals('no-reply@afi-sa.fr', $this->mock_transport->getSentMails()[0]->getFrom());
   }
 
 
-
   public function postArticleAValider() {
     Class_Article::find(18)->setStatus(Class_Article::STATUS_DRAFT)->save();
     $data = $this->_basePostDatas;
@@ -1832,6 +1832,23 @@ class CmsControllerNewsAddActionPostWithWorkflowTest
   }
 
 
+  /** @test */
+  public function toValidateArticleMailShouldBeSentFromDefaultNoReplyAtAfi() {
+    $this->postArticleAValider();
+    $this->assertEquals('no-reply@afi-sa.fr',
+                        $this->mock_transport->getSentMails()[0]->getFrom());
+  }
+
+
+  /** @test */
+  public function withConfiguredSenderToValidateArticleMailShouldBeSentFromUserAtServerDotOrg() {
+    Class_AdminVar::set('WORKFLOW_MAIL_FROM', 'user@server.org');
+    $this->postArticleAValider();
+    $this->assertEquals('user@server.org',
+                        $this->mock_transport->getSentMails()[0]->getFrom());
+  }
+
+
   /** @test */
   public function domainesShouldBeUpdated() {
     $data = $this->_basePostDatas;