Problem/Motivation
hook_simplenews_subscribe is fired before the subscriber is saved, so before the subscription actually happens at a point when it may not happen for sure.
Current code
public function subscribe($newsletter_id, $status = SIMPLENEWS_SUBSCRIPTION_STATUS_SUBSCRIBED, $source = 'unknown', $timestamp = REQUEST_TIME) {
if ($subscription = $this->getSubscription($newsletter_id)) {
$subscription->status = $status;
}
else {
$data = [
'target_id' => $newsletter_id,
'status' => $status,
'source' => $source,
'timestamp' => $timestamp,
];
$this->subscriptions->appendItem($data);
}
if ($status == SIMPLENEWS_SUBSCRIPTION_STATUS_SUBSCRIBED) {
\Drupal::moduleHandler()->invokeAll('simplenews_subscribe', [$this, $newsletter_id]);
}
}
Proposed resolution
Fire the hook in Subscriber::postSave().
Comments
Comment #2
adamps commentedChanging this could break existing sites however. It could probably be fixed quite naturally as part of #3035367: Track history of subscribe/unsubscribe and proof of consent but nobody especially seems interested in supporting that yet😃.
Comment #3
adamps commentedProbably in postSave() there is no longer the information to fire the same hook
Comment #4
jonathanshawAll we need is the newsletter id. We could get that by comparing current subscriptions with those of $subscriber->original.
Comment #5
jonathanshawThe problem may be worse than I realised, because in SubscriptionsBlockForm we do this:
Which looks like we fire this "subscribe" hook whenever the form is loaded? Maybe even when no email is entered. It makes me wonder if this is so broken that BC should not be the main concern.
Comment #6
adamps commentedA site could use the "broken" hooks and workaround the bugs. "Fixing" the brokenness could break their workarounds.
Presumably people could use functions from entity.api.php and check the original entity? So I'm not sure of the purpose of this hook in the long term. The second and third parameters are probably dubious.
As per #2, I don't see much advantage to change this without getting it right for the longer term in context of #3035367: Track history of subscribe/unsubscribe and proof of consent
Comment #7
adamps commentedWe have a new 4.x in alpha, so it's a good time to look at this again
Comment #8
adamps commentedWe could fire the hook in postSave() with code roughly like this.
Does that sound good?
Comment #9
jonathanshawYeah, looks good.
Comment #10
smokrisI've attached patches (based on AdamPS's snippet above) for simplenews 3.x and 4.x.
Comment #11
adamps commentedThanks @smokris
1) Actually my comment #8 wasn't quite right. I think we need like this:
2) Let's create a variable for the current ones too so we don't calculate them twice:
3) Plus a variable for the result of
\Drupal::moduleHandler()so we don't calculate it many times.4) It would be great to have a test for the hooks. But if you don't want to, it's still useful to fix the other comments😃.
Comment #12
adamps commentedReroll of #10
Comment #13
adamps commentedComment #14
adamps commentedComment #15
adamps commentedComment #16
adamps commentedComment #17
adamps commentedComment #19
adamps commentedComment #20
adamps commented