From 2371a9b5f0cae68e2375330a5097a8f5542a35c3 Mon Sep 17 00:00:00 2001
From: llaffont <llaffont@afi-sa.fr>
Date: Mon, 9 Nov 2015 17:21:54 +0100
Subject: [PATCH] rel #31761 notify article validators based on validation
 rights

---
 VERSIONS_WIP/31761                            |  1 +
 .../admin/controllers/CmsController.php       | 22 ++---
 library/Class/Permission.php                  | 12 ++-
 .../admin/controllers/CmsControllerTest.php   | 80 +++++++++++++++----
 4 files changed, 84 insertions(+), 31 deletions(-)
 create mode 100644 VERSIONS_WIP/31761

diff --git a/VERSIONS_WIP/31761 b/VERSIONS_WIP/31761
new file mode 100644
index 00000000000..a57d065acd7
--- /dev/null
+++ b/VERSIONS_WIP/31761
@@ -0,0 +1 @@
+ - ticket #31761 : CMS Workflow / notifications: seul les utilisateurs qui ont le droit de valider un article sont notifiés par mail de l'attente de validation
\ No newline at end of file
diff --git a/application/modules/admin/controllers/CmsController.php b/application/modules/admin/controllers/CmsController.php
index 6b08929418d..cd79ccf4c6a 100644
--- a/application/modules/admin/controllers/CmsController.php
+++ b/application/modules/admin/controllers/CmsController.php
@@ -297,7 +297,7 @@ class Admin_CmsController extends ZendAfi_Controller_Action {
          $article->getStatus() == Class_Article::STATUS_VALIDATION_PENDING)
         || ($article->getStatus() > 5
             && $article->old_status != $article->getStatus()))  {
-      $this->_sendMailToAdmin($article);
+      $this->_sendMailToValidators($article);
     }
   }
 
@@ -359,18 +359,12 @@ class Admin_CmsController extends ZendAfi_Controller_Action {
   }
 
 
-  protected function _sendMailToAdmin($article) {
+  protected function _sendMailToValidators($article) {
     $mail = new ZendAfi_Mail('utf8');
-    $all_admins=Class_Users::findAllBy(['role_level' => ZendAfi_Acl_AdminControllerRoles::ADMIN_PORTAIL]);
-    $mails=[];
+    $mails = array_filter(array_map(function($user) {return $user->getMail();},
+                                    Class_Permission::validateArticle()->getUsers()));
 
-    foreach ($all_admins as $admin) {
-      if (!$mail_admin=$admin->getMail())
-        continue;
-      $mails[]=$mail_admin;
-    }
-
-    if(!$mail_address = implode(',',$mails))
+    if (empty($mails))
       return;
 
     $body = Class_AdminVar::getWorkflowTextMailArticlePending();
@@ -383,12 +377,12 @@ class Admin_CmsController extends ZendAfi_Controller_Action {
 
     $mail
       ->setFrom('no-reply@afi-sa.fr')
-      ->addTo($mail_address)
-      ->setSubject('[Bokeh] Validation d\'article en attente: '.$article->getTitre())
+      ->addTo(implode(',',$mails))
+      ->setSubject($this->_('[Bokeh] Validation d\'article en attente: ') . $article->getTitre())
       ->setBodyText($body);
 
     if($this->_sendMail($mail))
-      $this->_helper->notify('Mail de validation envoyé aux administrateurs.');
+      $this->_helper->notify($this->_('Mail de validation envoyé aux validateurs.'));
   }
 
 
diff --git a/library/Class/Permission.php b/library/Class/Permission.php
index 000d23d912b..3b7a26bb29f 100644
--- a/library/Class/Permission.php
+++ b/library/Class/Permission.php
@@ -69,6 +69,12 @@ class PermissionLoader extends Storm_Model_Loader {
   }
 
 
+  public function validateArticle() {
+    return Class_Permission::findFirstBy(['module' => static::MODULE_ARTICLE,
+                                          'code' => 'VALIDATED']);
+  }
+
+
   public function createArticleCategory() {
     return Class_Permission::findFirstBy(['module' => static::MODULE_ARTICLE,
                                           'code' => 'CATEGORY']);
@@ -96,7 +102,11 @@ class Class_Permission extends Storm_Model_Abstract {
   protected $_has_many = ['group_permissions' =>
                           ['model' => 'Class_UserGroup_Permission',
                            'role' => 'permission',
-                           'dependents' => 'delete']];
+                           'dependents' => 'delete'],
+
+                          'groups' => ['through' => 'group_permissions'],
+
+                          'users' => ['through' => 'groups']];
 
 
   public function permitTo($group, $model) {
diff --git a/tests/application/modules/admin/controllers/CmsControllerTest.php b/tests/application/modules/admin/controllers/CmsControllerTest.php
index 588f5824cd4..5faa3b69ad7 100644
--- a/tests/application/modules/admin/controllers/CmsControllerTest.php
+++ b/tests/application/modules/admin/controllers/CmsControllerTest.php
@@ -22,10 +22,18 @@ require_once 'AdminAbstractControllerTestCase.php';
 
 
 abstract class CmsControllerTestCase extends Admin_AbstractControllerTestCase {
-  /** @var Class_Article */
-  protected $concert;
-  protected $lieu_bonlieu, $lieu_arcadium;
-  protected $_admin_bib, $_laurent,$_bernard;
+  protected
+    $concert,  /** @var Class_Article */
+    $lieu_bonlieu,
+    $lieu_arcadium,
+    $_admin_bib,
+    $_laurent,
+    $_bernard,
+    $_group_testing,
+    $_group_admin,
+    $_cat_a_la_une;
+
+
   public function setUp() {
     parent::setUp();
     $_SERVER['SCRIPT_NAME'] = '';
@@ -33,15 +41,20 @@ abstract class CmsControllerTestCase extends Admin_AbstractControllerTestCase {
     Storm_Model_Loader::defaultToVolatile();
     $this->setupBib();
 
-    $this->fixture('Class_UserGroup', ['id' => 22,
-                                       'libelle' => 'Testing group']);
+    $this->_group_testing = $this->fixture('Class_UserGroup', ['id' => 22,
+                                                               'libelle' => 'Testing group']);
+
+
+    $this->_group_admin = $this->fixture('Class_UserGroup', ['id' => 24,
+                                                             'libelle' => 'Admin group']);
 
     $this->_laurent = $this->fixture('Class_Users', ['id'=>20,
                                                      'login' => 'laurent',
                                                      'mail' => 'laurent@afi-sa.fr',
                                                      'bib' => $this->annecy,
                                                      'password' => 'toto',
-                                                     'role_level' => ZendAfi_Acl_AdminControllerRoles::ADMIN_PORTAIL]);
+                                                     'role_level' => ZendAfi_Acl_AdminControllerRoles::ADMIN_PORTAIL,
+                                                     'user_groups' => [$this->_group_admin]]);
 
     $this->_admin_bib = $this->fixture('Class_Users',['id' => 10,
                                                       'login' => 'AdminBibConnected',
@@ -50,14 +63,15 @@ abstract class CmsControllerTestCase extends Admin_AbstractControllerTestCase {
                                                       'mail' => 'admin@afi-sa.fr',
                                                       'password' => 'toto',
                                                       'role_level' => ZendAfi_Acl_AdminControllerRoles::ADMIN_BIB,
-                                                      'user_groups' => [Class_UserGroup::find(22)]]);
+                                                      'user_groups' => [$this->_group_testing]]);
 
     $this->_bernard = $this->fixture('Class_Users',['id' =>30,
                                                     'login' => 'bernie',
                                                     'bib' => $this->annecy,
                                                     'mail' => 'bernard@afi-sa.fr',
                                                     'password' => 'bernie',
-                                                    'role_level' => ZendAfi_Acl_AdminControllerRoles::ADMIN_PORTAIL]);
+                                                    'role_level' => ZendAfi_Acl_AdminControllerRoles::ADMIN_PORTAIL,
+                                                    'user_groups' => [$this->_group_admin]]);
 
 
     ZendAfi_Auth::getInstance()->logUser($this->_admin_bib);
@@ -141,7 +155,7 @@ abstract class CmsControllerTestCase extends Admin_AbstractControllerTestCase {
     $this->root_category = $this->fixture('Class_ArticleCategorie',
                                           ['id' => 1, 'libelle' => 'Root']);
 
-    $cat_a_la_une = $this->fixture('Class_ArticleCategorie',
+    $this->_cat_a_la_une = $this->fixture('Class_ArticleCategorie',
                                    ['id' => 23,
                                     'libelle' => 'A la Une',
                                     'parent_categorie' => $this->root_category]);
@@ -149,9 +163,9 @@ abstract class CmsControllerTestCase extends Admin_AbstractControllerTestCase {
     $this->cat_evenements = $this->fixture('Class_ArticleCategorie',
                                            ['id' => 34,
                                             'libelle' => 'Evènements',
-                                            'parent_categorie' => $cat_a_la_une,
+                                            'parent_categorie' => $this->_cat_a_la_une,
                                             'sous_categories' => []]);
-    $cat_a_la_une->setSousCategories([$this->cat_evenements]);
+    $this->_cat_a_la_une->setSousCategories([$this->cat_evenements]);
 
     $this->annecy
       ->setArticleCategories([$this->root_category])
@@ -246,10 +260,13 @@ abstract class CmsControllerWithPermissionTestCase extends CmsControllerTestCase
 
   public function setUp() {
     parent::setUp();
-    $group = Class_UserGroup::find(22);
-    $category = Class_ArticleCategorie::find(23);
-    Class_Permission::createArticle()->permitTo($group, $category);
-    Class_Permission::createArticleCategory()->permitTo($group, $category);
+    Class_Permission::createArticle()->permitTo($this->_group_testing, $this->_cat_a_la_une);
+    Class_Permission::createArticleCategory()->permitTo($this->_group_testing, $this->_cat_a_la_une);
+
+    Class_Permission::validateArticle()->permitTo($this->_group_admin,
+                                                  $this->_cat_a_la_une);
+
+
   }
 }
 
@@ -1673,12 +1690,43 @@ class CmsControllerNewsAddActionPostWithWorkflowTest
   public function newArticleSavedWithStatusAValiderShouldSendMail() {
     $data = $this->_basePostDatas;
     $data['status'] = Class_Article::STATUS_VALIDATION_PENDING;
+
     $this->postDispatch('/admin/cms/add/id_cat/23',
                         $data);
     $this->assertEquals(['laurent@afi-sa.fr', 'bernard@afi-sa.fr'],$this->mock_transport->getSentMails()[0]->getRecipients());
   }
 
 
+  /** @test */
+  public function newArticleSavedWithStatusAValiderShouldSendDeduplicatedMails() {
+    $data = $this->_basePostDatas;
+    $data['status'] = Class_Article::STATUS_VALIDATION_PENDING;
+
+    $this->_group_testing->addUser($this->_laurent)->save();
+    Class_Permission::validateArticle()->permitTo($this->_group_testing,
+                                                  $this->_cat_a_la_une);
+    $this->postDispatch('/admin/cms/add/id_cat/23',
+                        $data);
+    $this->assertEquals(['laurent@afi-sa.fr', 'bernard@afi-sa.fr', 'admin@afi-sa.fr'],
+                        $this->mock_transport->getSentMails()[0]->getRecipients());
+  }
+
+
+
+  /** @test */
+  public function withoutValidationRightsNewArticleSavedWithStatusAValiderShouldNotSendMail() {
+    $data = $this->_basePostDatas;
+    $data['status'] = Class_Article::STATUS_VALIDATION_PENDING;
+
+    Class_Permission::validateArticle()->denyTo($this->_group_admin,
+                                                $this->_cat_a_la_une);
+
+    $this->postDispatch('/admin/cms/add/id_cat/23',
+                        $data);
+    $this->assertEmpty($this->mock_transport->getSentMails());
+  }
+
+
   /** @test */
   public function statusBrouillonUpdatedToAValiderShouldSendMail() {
     Class_Article::find(18)->setStatus(Class_Article::STATUS_DRAFT)->save();
-- 
GitLab