Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update the subscriptions upon submit #19

Closed
leofeyer opened this issue Apr 18, 2018 · 2 comments
Closed

Update the subscriptions upon submit #19

leofeyer opened this issue Apr 18, 2018 · 2 comments
Labels

Comments

@leofeyer
Copy link
Member

Right now, the newsletter bundle tries to update the member subscriptions in the onload_callback:

$GLOBALS['TL_DCA']['tl_member']['config']['onload_callback'][] = array('Newsletter', 'updateAccount');

However, this will cause an integrity constraint violation if an e-mail address exists already:

Integrity constraint violation: 1062 Duplicate entry '1-d.evans@example.com' for key 'pid_email'

How to reproduce

  1. Allow members to subscribe to channels.
  2. Subscribe Donna Evans (d.evans@example.com) to a channel.
  3. Subscribe John Smith (j.smith@example.com) to the same channel.
  4. Try to change John's e-mail to d.evans@example.com.

The onload_callback is executed before the user input is validated and stored (tl_member.email has the 'unique' => true flag set). However, it should be executed upon submit instead, so Contao shows the "duplicate entry in field e-mail" error message and only updates the subscriptions after validating the user input.

@contao/developers Is this a bug or a feature?

@leofeyer leofeyer added the bug label Apr 18, 2018
@leofeyer leofeyer added this to the 4.4.19 milestone Apr 18, 2018
@leofeyer
Copy link
Member Author

Here is a quick fix that does not require using a different hook:

--- a/src/Resources/contao/classes/Newsletter.php
+++ b/src/Resources/contao/classes/Newsletter.php
@@ -802,8 +802,20 @@ class Newsletter extends \Backend
 				// E-mail address has changed
 				if (!empty($_POST) && $strEmail != '' && $strEmail != $objUser->email)
 				{
-					$this->Database->prepare("UPDATE tl_newsletter_recipients SET email=? WHERE email=?")
-								   ->execute($strEmail, $objUser->email);
+					$objCount = $this->Database->prepare("SELECT COUNT(*) AS count FROM tl_newsletter_recipients WHERE email=?")
+											   ->execute($strEmail);
+
+					// Delete the old subscription if the new e-mail address exists (see #19)
+					if ($objCount->count > 0)
+					{
+						$this->Database->prepare("DELETE FROM tl_newsletter_recipients WHERE email=?")
+									   ->execute($objUser->email);
+					}
+					else
+					{
+						$this->Database->prepare("UPDATE tl_newsletter_recipients SET email=? WHERE email=?")
+									   ->execute($strEmail, $objUser->email);
+					}
 
 					$objUser->email = $strEmail;
 				}

@leofeyer
Copy link
Member Author

I guess ebcd6c7 is enough for the time being.

@leofeyer leofeyer removed this from the 4.4.19 milestone Jun 14, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant