Skip to content

Newsletter subscriptions status not isolated between multi stores #10014

Closed
@mikelevy300

Description

@mikelevy300

When a customer with the same email address has an account on different multi stores in the same Magento installation, changes to the newsletter subscription in one account affect the other.

Preconditions

  1. Magento 2.1.5
  2. PHP 7.0.16
  3. MySQL 5.7
  4. Apache 2.4
  5. At least two stores setup with nothing shared
  6. A customer exists in both stores with the same email address

Steps to reproduce

  1. Login with customer 1 in store A, go to My Account -> Newsletter Subscriptions, and make sure he's subscribed to the general newsletter
  2. Login with customer 2 in store B, go to My Account -> Newsletter Subscriptions, and make sure he's subscribed to the general newsletter
  3. Unsubscribe customer 1 from the newsletter
  4. Refresh the page for customer 2

Expected result

  1. Customer 1 is unsubscribed
  2. Customer 2 is subscribed

Actual Result

  1. Customer 1 is unsubscribed
  2. Customer 2 is unsubscribed

Extra info

When looking in the newsletter_subscriber table, instead of there being one record for each customer per store, there's one global record. When customer 1 in store A updates, the store_id in newsletter subscriber is updated to store A's ID. When customer 2 in store B updates, the store_id in newsletter_subscriber is updated to store B's ID.

Tracing the code out, I think the problem is in Magento_Newsletter\Model\ResourceModel\Subscriber.php, specifically the loadByCustomerData function.
Here's the function:

public function loadByCustomerData(\Magento\Customer\Api\Data\CustomerInterface $customer){
	$select = $this->connection->select()->from($this->getMainTable())->where('customer_id=:customer_id');

	$result = $this->connection->fetchRow($select, ['customer_id' => $customer->getId()]);

	if ($result) {
		return $result;
	}

	$select = $this->connection->select()->from($this->getMainTable())->where('subscriber_email=:subscriber_email');

	$result = $this->connection->fetchRow($select, ['subscriber_email' => $customer->getEmail()]);

	if ($result) {
		return $result;
	}

	return [];
}

It basically uses the customerId as the lookup key but then falls back to the customerEmail if nothing is found. This creates the unintended consequence where updates in one store show in the other. A suggested fix would be to either only use the customerId or add an additional field to the select that matches the store_id of the customer, something like

select * from newsletter_subscriber where subscriber_email = $customer->getEmail() and store_id = $customer->getStoreId()

Metadata

Metadata

Assignees

Labels

Component: CustomerFixed in 2.2.xThe issue has been fixed in 2.2 release lineFixed in 2.3.xThe issue has been fixed in 2.3 release lineIssue: Clear DescriptionGate 2 Passed. Manual verification of the issue description passedIssue: ConfirmedGate 3 Passed. Manual verification of the issue completed. Issue is confirmedIssue: Format is validGate 1 Passed. Automatic verification of issue format passedIssue: Ready for WorkGate 4. Acknowledged. Issue is added to backlog and ready for developmentReproduced on 2.1.xThe issue has been reproduced on latest 2.1 releaseReproduced on 2.2.xThe issue has been reproduced on latest 2.2 releaseReproduced on 2.3.xThe issue has been reproduced on latest 2.3 releasebug report

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions