<?php

if (!defined('ABSPATH')) die('No direct access allowed');

// Files can easily get too big for this method

if (!class_exists('UpdraftPlus_BackupModule')) updraft_try_include_file('methods/backup-module.php', 'require_once');

class UpdraftPlus_BackupModule_email extends UpdraftPlus_BackupModule {

	/**
	 * Input and option field mappings with default values and supported contexts.
	 *
	 * @var array
	 */
	protected $input_option_field_mappings = array(
		'email_address' => array(
			'default_value' => '',
			'contexts' => array('input'),
		),
	);

	public function backup($backup_array) {

		global $updraftplus;

		$updraft_dir = trailingslashit($updraftplus->backups_dir_location());

		$email = $updraftplus->just_one_email(UpdraftPlus_Options::get_updraft_option('updraft_email'), true);
		
		if (!is_array($email)) $email = array_filter(array($email));
		
		foreach ($backup_array as $type => $file) {

			$descrip_type = preg_match('/^(.*)\d+$/', $type, $matches) ? $matches[1] : $type;

			$fullpath = $updraft_dir.$file;

			if (file_exists($fullpath) && filesize($fullpath) > UPDRAFTPLUS_WARN_EMAIL_SIZE) {
				$size_in_mb_of_big_file = round(filesize($fullpath)/1048576, 1);
				$toobig_hash = md5($file);
				/* translators: %s: Backup file size in MB */
				$this->log($file.': '.sprintf(__('This backup archive is %s MB in size - the attempt to send this via email is likely to fail (few email servers allow attachments of this size).', 'updraftplus'), $size_in_mb_of_big_file).' '.__('If so, you should switch to using a different remote storage method.', 'updraftplus'), 'warning', 'toobigforemail_'.$toobig_hash);
			}

			$any_attempted = false;
			$any_sent = false;
			$any_skip = false;
			foreach ($email as $ind => $addr) {

				if (apply_filters('updraftplus_email_backup', true, $addr, $ind, $type)) {
					foreach (explode(',', $addr) as $sendmail_addr) {
						if (!preg_match('/^https?:\/\//i', $sendmail_addr)) {
							$send_short = (strlen($sendmail_addr)>5) ? substr($sendmail_addr, 0, 5).'...' : $sendmail_addr;
							$this->log("$file: email to: $send_short");
							$any_attempted = true;
							$headers = array();
		
							$subject = __("WordPress Backup", 'updraftplus').': '.get_bloginfo('name').' (UpdraftPlus '.$updraftplus->version.') '.get_date_from_gmt(gmdate('Y-m-d H:i:s', $updraftplus->backup_time), 'Y-m-d H:i');
							$from_email = apply_filters('updraftplus_email_from_header', $updraftplus->get_email_from_header());
							$from_name = apply_filters('updraftplus_email_from_name_header', $updraftplus->get_email_from_name_header());
							$use_wp_from_name_filter = '' === $from_email;
							// Notice that we don't use the 'wp_mail_from' filter, but only the 'From:' header to set sender name and sender email address, the reason behind it is that some SMTP plugins override the "wp_mail()" function and they do anything they want inside their own "wp_mail()" function, including not to call the php_mailer filter nor the wp_mail_from and wp_mail_from_name filters, but since the function signature remain the same as the WP one, so they may evaluate and do something with the header parameter
							if (!$use_wp_from_name_filter) {
								$headers[] = sprintf('From: %s <%s>', $from_name, $from_email);
							} else {
								add_filter('wp_mail_from_name', array($updraftplus, 'get_email_from_name_header'), 9);
							}
							add_action('wp_mail_failed', array($updraftplus, 'log_email_delivery_failure'));
							/* translators: %s: Site URL and description type */
							$sent = wp_mail(trim($sendmail_addr), $subject, sprintf(__("Backup is of: %s.", 'updraftplus'), site_url().' ('.$descrip_type.')'), $headers, array($fullpath));
							remove_action('wp_mail_failed', array($updraftplus, 'log_email_delivery_failure'));
							if ($use_wp_from_name_filter) remove_filter('wp_mail_from_name', array($this, 'get_email_from_name_header'), 9);
							if ($sent) $any_sent = true;
						}
					}
				} else {
					$log_message = apply_filters('updraftplus_email_backup_skip_log_message', '', $addr, $ind, $descrip_type);
					if (!empty($log_message)) {
						$this->log($log_message);
					}
					$any_skip = true;
				}
			}
			if ($any_sent) {
				if (isset($toobig_hash)) {
					$updraftplus->log_remove_warning('toobigforemail_'.$toobig_hash);
					// Don't leave it still set for the next archive
					unset($toobig_hash);
				}
				$updraftplus->uploaded_file($file);
			} elseif ($any_attempted) {
				$this->log('Mails were not sent successfully');
				$this->log(__('The attempt to send the backup via email failed (probably the backup was too large for this method)', 'updraftplus'), 'error');
			} elseif ($any_skip) {
				$this->log('No email addresses were configured to send email to '.$descrip_type);
			} else {
				$this->log('No email addresses were configured to send to');
			}
		}
		return null;
	}

	/**
	 * Acts as a WordPress options filter
	 *
	 * @param  Array $options - An array of options
	 *
	 * @return Array - the returned array can either be the set of updated settings or a WordPress error array
	 */
	public function options_filter($options) {
		global $updraftplus;
		return $updraftplus->just_one_email($options);
	}
	
	public function config_print() {
		global $updraftplus;
		?>
		<tr class="updraftplusmethod email">
			<th><?php esc_html_e('Email:', 'updraftplus');?></th>
			<td><?php

				$used = apply_filters('updraftplus_email_whichaddresses',
					/* translators: %s: Admin email address */
					sprintf(__("Your site's admin email address (%s) will be used.", 'updraftplus'), get_bloginfo('admin_email').' - <a href="'.esc_attr(admin_url('options-general.php')).'">'.__("configure it here", 'updraftplus').'</a>').
					' <a href="'.$updraftplus->get_url('premium_email').'" target="_blank">'.__('For more options, use Premium', 'updraftplus').'</a>'
				);

				$allowed_html = array(
					'a' => array(
						'href'   => array(),
						'target' => array(),
					)
				);

				/* translators: %s: Approximate email size limit in MB */
				echo wp_kses($used.' '.sprintf(__('Be aware that mail servers tend to have size limits; typically around %s MB; backups larger than any limits will likely not arrive.', 'updraftplus'), '10-20'), $allowed_html);
				?>
			</td>
		</tr>
		<?php
	}

	public function delete($files, $data = null, $sizeinfo = array()) {// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Unused parameter is present because the caller uses 3 arguments.
		return true;
	}

	/**
	 * Retrieve a list of template properties by taking all the persistent variables and methods of the parent class and combining them with the ones that are unique to this module, also the necessary HTML element attributes and texts which are also unique only to this backup module
	 * NOTE: Please sanitise all strings that are required to be shown as HTML content on the frontend side (i.e. wp_kses()), or any other technique to prevent XSS attacks that could come via WP hooks
	 *
	 * @return array an associative array keyed by names that describe themselves as they are
	 */
	public function get_template_properties() {
		$properties = array(
			'input_email_address_type' => 'email',
			'input_email_address_label' => __('Email address', 'updraftplus'),
			'input_email_address_placeholder' => __('Enter your email address', 'updraftplus')
		);
		
		return wp_parse_args($properties, $this->get_persistent_variables_and_methods());
	}
}
