From 48bc93c757c6d826778c18d38a343e2c225e6967 Mon Sep 17 00:00:00 2001
From: Ghislain Loas <ghislo@sandbox.pergame.net>
Date: Mon, 25 Aug 2014 17:12:49 +0200
Subject: [PATCH] dev #15696 user has only one subscription by newsletter

---
 .../opac/controllers/AbonneController.php     | 74 +++++++++----------
 library/Class/Users.php                       | 11 +++
 .../AbonneControllerNewslettersTest.php       | 69 +++++++++++++----
 3 files changed, 100 insertions(+), 54 deletions(-)

diff --git a/application/modules/opac/controllers/AbonneController.php b/application/modules/opac/controllers/AbonneController.php
index a4c1c6b7650..8666ab51d62 100644
--- a/application/modules/opac/controllers/AbonneController.php
+++ b/application/modules/opac/controllers/AbonneController.php
@@ -16,7 +16,7 @@
  *
  * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
  * along with AFI-OPAC 2.0; 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 AbonneController extends ZendAfi_Controller_Action {
 	use Trait_Translator;
@@ -30,7 +30,7 @@ class AbonneController extends ZendAfi_Controller_Action {
 				return;
 
 		$this->_user = Class_Users::getLoader()->getIdentity();
-		
+
 		$this->clearEmprunteurCache();
 
 		$this->view->getHelper('PageContext')->setContextHelper('Abonne_Resume', [$this->_user]);
@@ -56,7 +56,7 @@ class AbonneController extends ZendAfi_Controller_Action {
 
 
 	public function inscrireSessionAction() {
-		if (($session = Class_SessionFormation::getLoader()->find((int)$this->_getParam('id'))) && 
+		if (($session = Class_SessionFormation::getLoader()->find((int)$this->_getParam('id'))) &&
 				!$session->isInscriptionClosed()) {
 			$session->addStagiaire($this->_user);
 
@@ -69,7 +69,7 @@ class AbonneController extends ZendAfi_Controller_Action {
 		} else {
 			$this->_helper->notify('L\'inscription à cette session est fermée');
 		}
-		
+
 		$this->_redirect('/abonne/formations');
 	}
 
@@ -94,13 +94,11 @@ class AbonneController extends ZendAfi_Controller_Action {
 
 	public function subscribeNewsletterAction() {
 		$this->_stayOnPage();
-		
 		if (!$newsletter = Class_Newsletter::find((int)$this->_getParam('id'))) {
 			$this->_helper->notify('Newsletter non trouvée');
 			return;
 		}
 
-		
 		$this->_user->addNewsletter($newsletter);
 
 		if ($this->_user->save()) {
@@ -117,7 +115,7 @@ class AbonneController extends ZendAfi_Controller_Action {
 			return;
 		}
 
-		
+
 		$this->_user->removeNewsletter($newsletter);
 
 		if ($this->_user->save()) {
@@ -146,7 +144,7 @@ class AbonneController extends ZendAfi_Controller_Action {
 																											'redirect' =>'abonne/viewavis/id/'.$this->_user->getId(),
 																											'js_redirect' => $this->_getParam('expressionRecherche')? true: false]);
 	}
-		
+
 
 	private function handleAvis($readSourceMethod, $writeAvisMethod) {
 		$cls_user= new Class_Users();
@@ -234,7 +232,7 @@ class AbonneController extends ZendAfi_Controller_Action {
 		if ($this->_request->isPost()) {
 			if ($avis == null)
 				$avis = new Class_AvisNotice();
-		
+
 			$avis
 				->setEntete($this->_request->getParam('avisEntete'))
 				->setAvis($this->_request->getParam('avisTexte'))
@@ -279,11 +277,11 @@ class AbonneController extends ZendAfi_Controller_Action {
 		}
 
 		$this->manageAvisEditWith(
-			$avis, 
+			$avis,
 			function($form) use ($avis) {
 				$avis
 					->setAvis($form->avis->getValue())
-					->setEntete($form->entete->getValue());				
+					->setEntete($form->entete->getValue());
 			});
 	}
 
@@ -297,7 +295,7 @@ class AbonneController extends ZendAfi_Controller_Action {
 		}
 
 		$this->manageAvisEditWith(
-			$avis, 
+			$avis,
 			function($form) use ($avis) {
 				$avis
 					->setAvis($form->avis->getValue())
@@ -396,7 +394,7 @@ class AbonneController extends ZendAfi_Controller_Action {
 		$result = $cls_comm->prolongerPret($this->_user, $id_pret);
 
 		$this->view->fiche = $this->_user->getFicheSigb();
-		$this->_helper->notify($result['statut'] == 1 
+		$this->_helper->notify($result['statut'] == 1
 													 ? $this->_('Prêt prolongé')
 													 : $result['erreur']);
 
@@ -487,25 +485,25 @@ class AbonneController extends ZendAfi_Controller_Action {
 
 		if ($identification_fields = array_intersect(['nom', 'prenom', 'pseudo', 'password', 'confirm_password'],
 																								 $fields_to_show))
-			$form->addDisplayGroup($identification_fields, 
-														 'identification', 
+			$form->addDisplayGroup($identification_fields,
+														 'identification',
 														 ['legend' => 'Identification']);
 
 		if ($coordonnees_fields = array_intersect(['adresse', 'code_postal', 'ville'],
 																								$fields_to_show))
-			$form->addDisplayGroup($coordonnees_fields, 
-														 'coordonnees', 
+			$form->addDisplayGroup($coordonnees_fields,
+														 'coordonnees',
 														 ['legend' => 'Coordonnées']);
 
 		if ($contact_fields = array_intersect(['mail', 'telephone'],
-																					$fields_to_show)) 
-			$form->addDisplayGroup($contact_fields, 
-														 'contact', 
+																					$fields_to_show))
+			$form->addDisplayGroup($contact_fields,
+														 'contact',
 														 ['legend' => 'Contact']);
 
 		if (in_array('mode_contact', $fields_to_show)) {
-			$form->addElement('radio', 
-												'mode_contact', 
+			$form->addElement('radio',
+												'mode_contact',
 												['label' => '',
 												 'multiOptions' => [Class_Users::MODE_CONTACT_LETTER => $this->_(' par courrier postal'),
 																						Class_Users::MODE_CONTACT_MAIL => $this->_(' par E-Mail'),
@@ -532,9 +530,9 @@ class AbonneController extends ZendAfi_Controller_Action {
 			$subscriptions->setValue($checked_subscriptions);
 			$form
 			  ->addElement($subscriptions)
-			  ->addDisplayGroup(['subscriptions'], 
-													'newsletters', 
-													['legend' => 'Lettres d\'information']); 
+			  ->addDisplayGroup(['subscriptions'],
+													'newsletters',
+													['legend' => 'Lettres d\'information']);
 		}
 
 
@@ -564,7 +562,7 @@ class AbonneController extends ZendAfi_Controller_Action {
 
 				$fields_to_save = Class_AdminVar::getChampsFicheUtilisateur();
 				$attributes = [];
-				foreach($fields_to_save as $field) 
+				foreach($fields_to_save as $field)
 				  $attributes[$field] = $this->_request->getParam($field);
 
 				$this->_user
@@ -592,14 +590,14 @@ class AbonneController extends ZendAfi_Controller_Action {
 
 	public function authenticateAction() {
 		$this->getHelper('ViewRenderer')->setNoRender();
-		
+
 		$response = new StdClass();
 		$response->auth = 0;
 		$response->until = '';
 
-		$request = Class_Multimedia_AuthenticateRequest::newWithRequest($this->_request);		
+		$request = Class_Multimedia_AuthenticateRequest::newWithRequest($this->_request);
 		if ($user = $request->getUser()) {
-			foreach (['id', 'login', 'password', 'nom', 
+			foreach (['id', 'login', 'password', 'nom',
 								'prenom', 'date_debut', 'date_fin'] as $attribute)
 				$response->$attribute = $user->$attribute;
 			$response->groupes = $user->getUserGroupsLabels();
@@ -658,14 +656,14 @@ class AbonneController extends ZendAfi_Controller_Action {
 					break;
 			}
 		}
-				
+
 		/* Choix valide, passage à l'écran suivant */
 		if (null != $day && null == $quotaErrorType) {
 			$bean->day = $day;
 			$this->_redirect('/abonne/multimedia-hold-hours');
 			return;
 		}
-		
+
 		$this->getRequest()->setParam('day', 0);
 		if (!$bean->isCurrentStateValidForRequest($this->getRequest())) {
 			$this->_redirect('/abonne/'.$bean->currentState());
@@ -685,7 +683,7 @@ class AbonneController extends ZendAfi_Controller_Action {
 		);
 
 		$js_opened_days = implode(',', array_map(
-																						 function ($day) { return '"'.$day.'"'; }, 
+																						 function ($day) { return '"'.$day.'"'; },
 																						 $location->getHoldableDays()));
 
 
@@ -701,7 +699,7 @@ class AbonneController extends ZendAfi_Controller_Action {
 			  return result;
 			}
 		});
-		if (-1 == $.inArray($.datepicker.formatDate(\'yy-mm-dd\', date), 
+		if (-1 == $.inArray($.datepicker.formatDate(\'yy-mm-dd\', date),
                         [' . $js_opened_days . '])) {
 			result[0] = false;
 		}
@@ -738,7 +736,7 @@ class AbonneController extends ZendAfi_Controller_Action {
 				return;
 			}
 		}
-		
+
 		$this->view->timelineActions = $this->_getTimelineActions('hours');
 		$this->view->form = $this->multimediaHoldHoursForm($bean, $location);
 	}
@@ -815,14 +813,14 @@ class AbonneController extends ZendAfi_Controller_Action {
 			$this->_redirect('/abonne/fiche');
 			return;
 		}
-			
+
 		$this->view->location = $hold->getLibelleBib();
 		$this->view->day = strftime('%d %B %Y', $hold->getStart());
 		$this->view->time = strftime('%Hh%M', $hold->getStart());
 		$this->view->duration = (($hold->getEnd() - $hold->getStart()) / 60)  . 'mn';
 		$this->view->device = $hold->getLibelleDevice() . ' - ' . $hold->getOs();
 	}
-		
+
 
 	/**
 	 * @param $current string
@@ -878,7 +876,7 @@ class AbonneController extends ZendAfi_Controller_Action {
 			$this->_forward('suggestion-achat-ok');
 			return;
 		}
-			
+
 		$form = new ZendAfi_Form_SuggestionAchat();
 
 		if ($this->_request->isPost()) {
@@ -925,7 +923,7 @@ class AbonneController extends ZendAfi_Controller_Action {
 		if ($this->_user->canAccessBackend())
 			$data[] = (new Class_Catalogue())->getDomainesJson(['removeCheckbox' => true]);
 		$JSON = json_encode($data);
-		
+
 		$this->getResponse()->setHeader('Content-Type', 'application/json; charset=utf-8');
 		$this->getResponse()->setBody($JSON);
 	}
diff --git a/library/Class/Users.php b/library/Class/Users.php
index 086a67e39d4..d7b2b0fe7e5 100644
--- a/library/Class/Users.php
+++ b/library/Class/Users.php
@@ -1390,5 +1390,16 @@ class Class_Users extends Storm_Model_Abstract {
 		}
 		return $paniers;
 	}
+
+
+	public function addNewsletter($newsletter) {
+		return $this->isAlreadyRegisteredTo($newsletter) ? $this : parent::addNewsletter($newsletter);
+	}
+
+
+	public function isAlreadyRegisteredTo($newsletter) {
+		return 0 < Class_NewsletterSubscription::countBy(['user_id' => $this->getId(),
+																											'newsletter_id' => $newsletter->getId()]);
+	}
 }
 ?>
\ No newline at end of file
diff --git a/tests/application/modules/opac/controllers/AbonneControllerNewslettersTest.php b/tests/application/modules/opac/controllers/AbonneControllerNewslettersTest.php
index 45699072ba4..1452fdb2135 100644
--- a/tests/application/modules/opac/controllers/AbonneControllerNewslettersTest.php
+++ b/tests/application/modules/opac/controllers/AbonneControllerNewslettersTest.php
@@ -16,7 +16,7 @@
  *
  * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
  * along with AFI-OPAC 2.0; 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
  */
 require_once 'AbstractControllerTestCase.php';
 
@@ -25,7 +25,7 @@ abstract class AbstractAbonneControllerNewslettersTestCase extends AbstractContr
 	public function setUp() {
 		parent::setUp();
 
-		Class_AdminVar::newInstanceWithId('CHAMPS_FICHE_UTILISATEUR', 
+		Class_AdminVar::newInstanceWithId('CHAMPS_FICHE_UTILISATEUR',
 																			['valeur' => 'pseudo;nom;prenom;mail;password']);
 
 
@@ -37,7 +37,7 @@ abstract class AbstractAbonneControllerNewslettersTestCase extends AbstractContr
 			->setPseudo('mimi')
 			->setDateDebut(null)
 			->setPassword('mysecret')
-			->setFicheSIGB(['type_comm' => 0, 
+			->setFicheSIGB(['type_comm' => 0,
 											'nom_aff' => 'Marcus'])
 			->setRole('abonne_sigb')
 			->setRoleLevel(3)
@@ -59,17 +59,20 @@ abstract class AbonneControllerWithTwoNewslettersTestCase extends AbstractAbonne
 	public function setUp() {
 		parent::setUp();
 
-		$this->concerts = Class_Newsletter::newInstanceWithId(12, ['titre' =>'Concerts',
-																															 'contenu' => 'Festival jazz']);
+		Class_NewsletterSubscription::beVolatile();
 
-		$this->visites = Class_Newsletter::newInstanceWithId(14, [ 'titre' =>'Visites',
-																															 'contenu' => 'du patrimoine']);
+		$this->concerts =	$this->fixture('Class_Newsletter',
+																		 ['id' => 12,
+																			'titre' =>'Concerts',
+																			'contenu' => 'Festival jazz']);
+
+		$this->visites = $this->fixture('Class_Newsletter',
+																		['id' => 14,
+																		 'titre' =>'Visites',
+																		 'contenu' => 'du patrimoine']);
 
-		$this->newsletter_loader->whenCalled('findAll')
-													 ->answers(array($this->concerts, $this->visites));
 
-		$this->marcus
-			->setNewsletters(array($this->concerts));	//Marcus is subscribed to concerts newsletter
+		$this->marcus->setNewsletters([$this->concerts])->save();
 	}
 }
 
@@ -148,7 +151,7 @@ class AbonneControllerNewslettersFicheActionWithTwoSubscriptionsTest extends Abo
 	public function setUp() {
 		parent::setUp();
 
-		$this->marcus->addNewsletter($this->visites);
+		$this->marcus->addNewsletter($this->visites)->save();
 
 		$this->dispatch('/opac/abonne/fiche');
 		$this->assertController('abonne');
@@ -397,8 +400,8 @@ class AbonneControllerNewslettersSubscriptionTest extends AbonneControllerWithTw
 		parent::setUp();
 		$_SERVER['HTTP_REFERER'] = '/opac/index';
 		$this->dispatch('/opac/abonne/subscribe-newsletter/id/14',true);
-		
-	}	
+
+	}
 
 
 	/** @test **/
@@ -433,8 +436,8 @@ class AbonneControllerNewslettersUnsubscriptionTest extends AbonneControllerWith
 		parent::setUp();
 		$_SERVER['REQUEST_URI'] = '/';
 		$this->dispatch('/opac/abonne/unsubscribe-newsletter/id/14',true);
-		
-	}	
+
+	}
 
 	/** @test **/
 	public function unsubscribeActionShouldCallSubscribenewsletterAction() {
@@ -516,4 +519,38 @@ class AbonneControllerNewslettersValidationsTest extends AbonneControllerWithTwo
 }
 
 
+
+
+class AbonneControllerNewslettersSubscriptionTwiceTest extends AbstractControllerTestCase {
+
+	public function setUp() {
+		parent::setUp();
+		$_SERVER['HTTP_REFERER'] = '/opac/index';
+
+		$newsletter = $this->fixture('Class_Newsletter',
+																 ['id' => 5,
+																	'titre' => 'Daily News']);
+
+		$user = $this->fixture('Class_Users',
+															 ['id' => 156,
+																'login' => 'tomato',
+																'password' => 'pwd']);
+
+		$this->fixture('Class_NewsletterSubscription',
+									 ['id' => 1,
+										'user' => $user,
+										'newsletter' => $newsletter]);
+
+		ZendAfi_Auth::getInstance()
+			->logUser($user);
+
+		$this->dispatch('/opac/abonne/subscribe-newsletter/id/5',true);
+	}
+
+
+	/** @test **/
+	public function dailyNewsSubscribersShouldContainsTomatoOnlyOne() {
+		$this->assertEquals(1 , Class_NewsletterSubscription::countBy(['user_id' => 156]));
+	}
+}
 ?>
\ No newline at end of file
-- 
GitLab