__( '[Review required] %s', 'ost-editorial-workflow' ),
/* translators: %s: post title. */
'published' => __( '[Published] %s', 'ost-editorial-workflow' ),
/* translators: %s: post title. */
'sent_back' => __( '[Sent back] %s', 'ost-editorial-workflow' ),
/* translators: %s: post title. */
'escalation_reminder' => __( '[Review reminder] %s', 'ost-editorial-workflow' ),
/* translators: %s: post title. */
'escalation_notice' => __( '[Escalation] %s', 'ost-editorial-workflow' ),
);
}
/**
* Send a workflow email.
*
* @param string $template Template slug.
* @param \WP_User $user Recipient.
* @param array $vars Merge variables.
* @return bool
*/
public function send( $template, $user, array $vars ) {
$opts = get_option( 'ostew_settings', array() );
if ( isset( $opts['notifications_enabled'] ) && ! $opts['notifications_enabled'] ) {
return false; // email notifications switched off in settings.
}
$vars['recipient_name'] = $user->display_name;
$subject = $this->subject( $template, $vars );
$body = $this->render( $template, $vars );
$headers = array(
'Content-Type: text/html; charset=UTF-8',
'From: ' . $this->from(),
);
$sent = wp_mail( $user->user_email, $subject, $body, $headers );
if ( ! $sent && defined( 'WP_DEBUG' ) && WP_DEBUG ) {
error_log( sprintf( '[ost-editorial-workflow] email to %s not sent (template %s)', $user->user_email, $template ) ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
}
return (bool) $sent;
}
/**
* Build the subject line.
*
* @param string $template Template slug.
* @param array $vars Merge vars.
* @return string
*/
private function subject( $template, array $vars ) {
$formats = $this->subject_formats();
/* translators: %s: post title. */
$format = isset( $formats[ $template ] ) ? $formats[ $template ] : __( '[Update] %s', 'ost-editorial-workflow' );
$subject = sprintf( $format, $vars['post_title'] );
/**
* Filter a workflow email subject.
*
* @param string $subject Subject.
* @param string $template Template slug.
* @param array $vars Merge vars.
*/
return apply_filters( 'ostew/email_subject', $subject, $template, $vars );
}
/**
* Render the inner template inside the base wrapper.
*
* @param string $template Template slug.
* @param array $vars Merge vars.
* @return string
*/
private function render( $template, array $vars ) {
$file = $this->template_path( $template );
if ( ! is_readable( $file ) ) {
$file = $this->template_path( 'review-request' );
}
$vars['content'] = $this->capture( $file, $vars );
$body = $this->capture( $this->template_path( 'base' ), $vars );
/**
* Filter the full rendered email body.
*
* @param string $body HTML body.
* @param string $template Template slug.
* @param array $vars Merge vars.
*/
return apply_filters( 'ostew/email_body', $body, $template, $vars );
}
/**
* Map a template slug to its file (slug uses underscores; files use hyphens).
*
* @param string $name Slug or file base.
* @return string
*/
private function template_path( $name ) {
$name = str_replace( '_', '-', $name );
return OSTEW_DIR . 'templates/emails/' . $name . '.php';
}
/**
* Include a template with vars in scope and capture the output.
*
* @param string $file Absolute path.
* @param array $vars Merge vars.
* @return string
*/
private function capture( $file, array $vars ) {
if ( ! is_readable( $file ) ) {
return '';
}
ob_start();
// phpcs:ignore WordPress.PHP.DontExtract.extract_extract
extract( $vars );
include $file;
return (string) ob_get_clean();
}
/**
* The From header value (configurable via ostew_settings, sensible defaults).
*
* @return string
*/
private function from() {
$opts = get_option( 'ostew_settings', array() );
$name = ! empty( $opts['from_name'] ) ? $opts['from_name'] : get_bloginfo( 'name' );
$email = ! empty( $opts['from_email'] ) ? $opts['from_email'] : get_option( 'admin_email' );
return sprintf( '%s <%s>', $name, $email );
}
}