includes/emails/class.llms.email.php
<?php
/**
* Email Base
*
* @package LifterLMS/Emails/Classes
*
* @since 1.0.0
* @version 5.0.0
*/
defined( 'ABSPATH' ) || exit;
/**
* Email Base Class
*
* @since 1.0.0
* @since 3.30.3 Explicitly define class properties.
* @since 4.0.0 Always supply a from address even if the option is empty.
*/
class LLMS_Email {
/**
* @var array
* @since 3.15.0
*/
private $attachments = array();
/**
* @var string
* @since 3.8.0
*/
protected $body = '';
/**
* @var string
* @since 3.8.0
*/
protected $content_type = 'text/html';
/**
* @var WP_Post
* @since 3.26.1
*/
public $email_post;
/**
* @var array
* @since 1.0.0
*/
private $find = array();
/**
* @var array
* @since 3.8.0
*/
private $headers = array();
/**
* @var string
* @since 1.0.0
*/
protected $heading = '';
/**
* @var string
* @since 1.0.0
*/
protected $id = 'generic';
/**
* @var array
* @since 1.0.0
*/
private $recipient = array();
/**
* @var array
* @since 1.0.0
*/
private $replace = array();
/**
* @var string
* @since 1.0.0
*/
protected $subject = '';
/**
* @var string
* @since 3.8.0
*/
protected $template_html = 'emails/template.php';
/**
* Initializer
* Children can configure the email in this function called by the __construct() function
*
* @param array $args optional arguments passed in from the constructor
* @return void
* @since 3.8.0
* @version 3.8.0
*/
protected function init( $args ) {}
/**
* Constructor
* Sets up data needed to generate email content
*
* @since 1.0.0
* @version 3.8.0
*/
public function __construct( $args = array() ) {
$this->add_header( 'Content-Type', $this->get_content_type() );
$this->add_merge_data(
array(
'{blogname}' => get_bloginfo( 'name', 'display' ),
'{site_title}' => get_bloginfo( 'name', 'display' ),
'{divider}' => llms()->mailer()->get_divider_html(),
'{button_style}' => llms()->mailer()->get_button_style(),
)
);
$this->init( $args );
}
/**
* Add an attachment to the email
*
* @param string $attachment full system path to a file to attach
* @return void
* @since 3.15.0
* @version 3.15.0
*/
public function add_attachment( $attachment ) {
array_push( $this->attachments, $attachment );
}
/**
* Add a single header to the email headers array
*
* @param string $key header key eg: 'Cc'
* @param string $val header value eg: 'noreply@website.tld'
* @since 3.8.0
* @version 3.8.0
*/
public function add_header( $key, $val ) {
array_push( $this->headers, sprintf( '%1$s: %2$s', $key, $val ) );
}
/**
* Add merge data that will be used in the email
*
* @param array $data associative array where
* $key = merge field
* $val = merge value
* @since 3.8.0
* @version 3.8.0
*/
public function add_merge_data( $data = array() ) {
foreach ( $data as $find => $replace ) {
array_push( $this->find, $find );
array_push( $this->replace, $replace );
}
}
/**
* Add a single recipient for sending to, cc, or bcc
*
* @param int|string $address if string, must be a valid email address
* if int, must be the WP User ID of a user
* @param string $type recipient type [to,cc,bcc]
* @param string $name recipient name (optional)
* @return boolean
* @since 3.8.0
* @version 3.10.1
*/
public function add_recipient( $address, $type = 'to', $name = '' ) {
// If an ID was supplied, get the information from the student object.
if ( is_numeric( $address ) ) {
$student = llms_get_student( $address );
if ( ! $student ) {
return false;
}
$address = $student->get( 'user_email' );
$name = $student->get_name();
}
// Ensure address is a valid email.
if ( ! filter_var( $address, FILTER_VALIDATE_EMAIL ) ) {
return false;
}
// If a name is supplied format the name & address.
if ( $name ) {
$address = sprintf( '%1$s <%2$s>', $name, $address );
}
if ( 'to' === $type ) {
array_push( $this->recipient, $address );
return true;
} elseif ( 'cc' === $type || 'bcc' === $type ) {
$this->add_header( ucfirst( $type ), $address );
return true;
}
return false;
}
/**
* Add multiple recipients
*
* @param array $recipients array of recipient information
* @return void
* @since 3.8.0
* @version 3.8.0
*/
public function add_recipients( $recipients = array() ) {
foreach ( $recipients as $data ) {
$data = wp_parse_args(
$data,
array(
'address' => '',
'type' => 'to',
'name' => '',
)
);
if ( $data['address'] ) {
$this->add_recipient( $data['address'], $data['type'], $data['name'] );
}
}
}
/**
* Format string method
*
* Finds and replaces merge fields with appropriate data.
*
* @since 1.0.0
* @since 5.0.0 Process shortocdes when formatting a string.
*
* @param string $string String to be formatted.
* @return string
*/
public function format_string( $string ) {
return do_shortcode( str_replace( $this->find, $this->replace, $string ) );
}
/**
* Get attachments
*
* @return array
* @since 3.15.0
* @version 3.15.0
*/
public function get_attachments() {
return apply_filters( 'llms_email_get_attachments', $this->attachments, $this );
}
/**
* Get the body content of the email
*
* @return string
* @since 3.8.0
* @version 3.8.0
*/
public function get_body() {
return apply_filters( 'llms_email_body', $this->format_string( $this->body ), $this );
}
/**
* Get email content
*
* @return string
* @since 1.0.0
* @version 3.8.0
*/
public function get_content() {
$content = apply_filters( 'llms_email_content_get_content', $this->get_content_html(), $this );
return wordwrap( $content, 70 );
}
/**
* Get the HTML email content
*
* @return string
* @since 3.8.0
* @version 3.26.1
*/
public function get_content_html() {
global $post;
$temp = null;
// Override the $post global with the email post content (if it exists).
// This fixes Elementor / WC conflict outlined at https://github.com/gocodebox/lifterlms/issues/730.
if ( isset( $this->email_post ) ) {
$temp = $post;
$post = $this->email_post;
}
ob_start();
llms_get_template(
$this->template_html,
array(
'email_heading' => $this->get_heading(),
'email_message' => $this->get_body(),
)
);
$html = apply_filters( 'llms_email_content_get_content_html', ob_get_clean(), $this );
// Restore the default $post global.
if ( $temp ) {
$post = $temp;
}
return $html;
}
/**
* Get the content type
*
* @return string
* @since 1.0.0
* @version 3.8.0
*/
public function get_content_type() {
return apply_filters( 'llms_email_content_type', $this->content_type, $this );
}
/**
* Get from email option data
*
* @since 1.0.0
* @since 4.0.0 Use the address provided by `wp_mail_from` as the default if no option is stored.
*
* @return string
*/
public function get_from_address( $from_address ) {
return sanitize_email( get_option( 'lifterlms_email_from_address', $from_address ) );
}
/**
* Get from name option data
*
* @return string
* @since 1.0.0
* @version 1.0.0
*/
public function get_from_name() {
return wp_specialchars_decode( esc_html( get_option( 'lifterlms_email_from_name' ) ), ENT_QUOTES );
}
/**
* Get email headers
*
* @return string|array
* @since 1.0.0
* @version 3.8.0
*/
public function get_headers() {
return apply_filters( 'lifterlms_email_headers', $this->headers, $this->id );
}
/**
* Get the text of the email "heading"
*
* @return string
* @since 1.0.0
* @version 3.8.0
*/
public function get_heading() {
return apply_filters( 'lifterlms_email_heading', $this->format_string( $this->heading ), $this );
}
/**
* Get recipient email address
*
* @return string|array
* @since 1.0.0
* @version 3.8.0
*/
public function get_recipient() {
return apply_filters( 'lifterlms_email_recipient', $this->recipient, $this );
}
/**
* Get email subject
*
* @return string
* @since 1.0.0
* @version 3.8.0
*/
public function get_subject() {
return apply_filters( 'lifterlms_email_subject', $this->format_string( $this->subject ), $this );
}
/**
* Set the body for the email
*
* @param string $body text or html body content for the email
* @return $this
* @since 3.8.0
* @version 3.8.0
*/
public function set_body( $body = '' ) {
$this->body = $body;
return $this;
}
/**
* set the content_type for the email
*
* @param string $content_type content type (for the header)
* @return $this
* @since 3.8.0
* @version 3.8.0
*/
public function set_content_type( $content_type = 'text/html' ) {
$this->content_type = $content_type;
return $this;
}
/**
* set the heading for the email
*
* @param string $heading text string to use for the email heading
* @return $this
* @since 3.8.0
* @version 3.8.0
*/
public function set_heading( $heading = '' ) {
$this->heading = $heading;
return $this;
}
/**
* Set the ID of the email
*
* @param string $id id string
* @return $this
* @since 3.8.0
* @version 3.8.0
*/
public function set_id( $id = '' ) {
$this->id = $id;
return $this;
}
/**
* set the subject for the email
*
* @param string $subject Text string to use for the email subject.
* @return $this
* @since 3.8.0
* @version 3.24.0
*/
public function set_subject( $subject = '' ) {
$this->subject = html_entity_decode( $subject, ENT_QUOTES );
return $this;
}
/**
* Send email
*
* @return bool
* @since 1.0.0
* @version 3.15.0
*/
public function send() {
do_action( 'lifterlms_email_' . $this->id . '_before_send', $this );
add_filter( 'wp_mail_from', array( $this, 'get_from_address' ) );
add_filter( 'wp_mail_from_name', array( $this, 'get_from_name' ) );
add_filter( 'wp_mail_content_type', array( $this, 'get_content_type' ) );
$return = wp_mail( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );
remove_filter( 'wp_mail_from', array( $this, 'get_from_address' ) );
remove_filter( 'wp_mail_from_name', array( $this, 'get_from_name' ) );
remove_filter( 'wp_mail_content_type', array( $this, 'get_content_type' ) );
do_action( 'lifterlms_email_' . $this->id . '_after_send', $this, $return );
return $return;
}
}