scheduled reminders incorrectly exclude emails with on_hold = opt-out
- create a contact with an email and flag it on_hold = opt out
- create a scheduled reminder that can be easily triggered. e.g. on creation of a scheduled activity
- create the conditions for the scheduled reminder (e.g. create a scheduled activity of the selected type)
- run the scheduled reminder job
Result: the contact will not receive the scheduled reminder because it skips email addresses with on_hold of either type (either bound or opt out).
Expected result: contact receives email.
This is worth some discussion as I know scheduled reminders sometimes fall into a grey area between bulk email and transactional email. Personally I believe they are more transactional than bulk, and believe we have historically viewed them that way.
The offending code is in: CRM_Contact_BAO_Contact::getPrimaryEmail(). That method has a parameter $polite = (bool) which is only used once in the codebase when called by CRM_Core_BAO_ActionSchedule::sendReminderEmail(). When that is true we condition on civicrm_email.on_hold = 0. I believe it should be civicrm_email.on_hold != 1 (doesn't equal bounce). As it's the only place that parameter/condition is used, we just need to decide if scheduled reminders are indeed transactional and should not exclude opt outs.
It's worth noting that the condition in that function also excludes civicrm_contact.do_not_email but does NOT exclude civicrm_contact.is_opt_out. We're not currently treating it like a bulk email at the contact level -- just at the email level.