<?php
/**
 * Отправка письма
 * 
 * Серверная часть ajax приложения
 * Принимает POST данные из модального окна и формирует почтовое сообщение.
 * 
 * @author veselka.ua
 * @version 0.36
 *
 * @package veselka_ua/themes
 */

class FormsMail extends FormsKernel {

	/**
	 * Данные для отправки сообщения.
	 */
	private $to;
	private $subject;
	private $headers;
	/**
	 * Флаг статической формы.
	 */
	private $static_form;
	/**
	 * Уведомления (проверка заполнения полей формы).
	 */
	private $notifications;
	/**
	 * Отправка письма с другого доменного имени.
	 */
	private $home_ip;


	public function __construct($static_form = false, $subject = false, $message = false) {
		// Запись аргументов
		//$this->to = $to;
		$this->static_form = $static_form;
		$this->subject = $subject;
		$this->message = $message;
		// Кросс доменная пересылка
		$this->home_ip = false;
		// Пути
		$this->path_construct();
		// Родительский конструктор
		parent::__construct();
	}

//////////////////// Публичные методы ////////////////////


	

	/**
	 * Обертка для получения уведомлений о незаполненных полях.
	 */
	final public function get_notifications() {
		return $this->notifications;
	}

	/**
	 * Обертка для получения адреса получателя.
	 */
	final public function get_to() {
		return $this->to;
	}

	/**
	 * Обертка для получения темы письма.
	 */
	final public function get_subject() {
		return $this->subject;
	}

	/**
	 * Обертка для получения заголовка письма.
	 */
	final public function get_header() {
		return $this->headers;
	}

	/**
	 * Обертка для получения заголовка.
	 */
	final public function get_remoute() {
		if( $this->home_ip ) {
			$this->remoute();
		} else {
			return false;
		}
	}


	/**
	 * Обертка для заменды данных письма.
	 * Отправка клиенту.
	 */
	final public function reset_to_client() {
		return $this->reset_data_to_client();
	}

//////////////////// Приватные и защищенные методы ////////////////////


	/**
	 * Получение и обработка данных формы.
	 */
	protected function input_data_processing() {

		if( !isset($_POST['form_name']) ) {
			if( !$this->static_form ) {
				throw new Exception('No form specification!' );
			} else {
				return false;
			}
		}

		// Имя формы в формате css
		$this->options['form_name'] = htmlspecialchars($_POST['form_name']);
		unset($_POST['form-name']);
		// Имя формы в формате php
		$this->options['array_name'] = str_replace( '-', '_', $this->options['form_name'] );
		// Получение префикса имен полей
		$form_name_prefix = $this->options['form_name'] . '-';
		// Обработка POST данных и запись в локальный массив
		$this->post_data_handling($form_name_prefix);
		// Получение параметров отправки письма и запись в локальный массив
		$this->get_options();
		// Замена переносов строк на <br> в опциях товара
		if( isset($this->post_data['options']) ) {
			$this->post_data['options'] = str_replace('; ', ';<br>', $this->post_data['options']);
			$this->post_data['options'] = '<br>' . $this->post_data['options'];
		}
	}



	/**
	 * Получение массивов с параметрами. Местоположение стандартное.
	 */
	private function get_options() {

		// Проверка наличия файла с разметкой письма.
		$this->check_file_path('/conf/', 'send_mail.php');

		// Подключение файла с параметрами отправки почтового сообщеия
		require_once $this->files_path['send_mail'];

		// Суффикс заголовка письма
		if( !$this->subject || $this->subject == '' ) {
			$this->subject = get_bloginfo();
			$this->subject = mb_strtoupper( $this->subject );
			$this->subject = '[' . $this->subject . ']';
		}
		/**
		 * Запись данных по умолчанию для отпраки письма если это необходимо.
		 */
		foreach( $defaults as $name => $default) {
			// Если аргумент не был передан в массив по умолчанию было записано false
			// Для таких значений сработает следующее условие и значение из параметров запишется
			if( !$this->$name ) {
				$this->$name = $default;
			}
		}

		/**
		 * Запись основных параметров.
		 */
		if( !isset($general) ) {
			throw new Exception('No send_mail option!' );
		}
		foreach( $general as $key => $option ) {
			$this->options[$key] = $option;
		}
	}


	/**
	 * Построение результата.
	 */
	protected function result_construct() {
		// Проверка заполнения полей формы
		if( $this->static_form ) {
			$this->check_filling_form_fields();
		}
		// Заголовок письма
		$this->set_subject_data();
		// Header
		$this->set_common_header_data();
		// Данные для отправки письма
		$this->set_mail_data();
		// Тело письма
		$this->html_construct($this->post_data);
	}


	/**
	 * Проверка заполнены ли все необходимые поля контактной формы.
	 */
	private function check_filling_form_fields() {
		foreach( $this->fields as $name => $options ) {
			if( $options['required'] && ( !isset($this->post_data[$name]) || $this->post_data[$name] = '' ) ) {
				$notifications[] = 'missed';
			}
			if( $options['type'] == 'email' && filter_var($this->post_data[$name], FILTER_VALIDATE_EMAIL) ) {
				$notifications[] = 'email';
			}
		}

	}



	/**
	 * Проверка заполнены ли все необходимые поля контактной формы.
	 */
	private function reset_data_to_client() {
		// Проверка необходимости отправки письма клиенту
		if( !(bool)$this->options['mail_gratitude'] && !(bool)$this->options['mail_notification'] ) {
			return false;
		}
		if( !(bool)$this->post_data['email'] ) {
			return false;
		}
		// Адес получателя
		$this->to = $this->post_data['email'];
		// Тело письма
		$massage = '';
		if( (bool)$this->options['mail_gratitude'] ) {
			$massage .= $this->block_header_construct($this->options['mail_gratitude']);
		}
		if( (bool)$this->options['mail_notification'] ) {
			$massage .= '<p>' . $this->options['mail_notification'] . '</p>';
		}
		// Паспорт товара
		if( (bool)$this->post_data['pdf'] ) {
			$massage .= '<p>' . $this->labels['order']['pdf'] . ': <a href="' . $this->post_data['pdf'] . '" title="' . $this->placeholders['order']['pdf'] . '">' . $this->placeholders['order']['pdf'] . '</a></p>';
		}
		// Счет на оплату
		if( (bool)$this->post_data['invoice'] ) {
			$massage .= '<p>' . $this->labels['order']['invoice'] . ': <a href="' . $this->post_data['invoice'] . '" title="' . $this->placeholders['order']['invoice'] . '">' . $this->placeholders['order']['invoice'] . '</a></p>';
		}
		// Номер корзины
		if( (bool)$this->post_data['cartcode'] ) {
			$massage .= '<p>' . $this->labels['order']['cartcode'] . ': <span style="font-size:1.5em;">' . $this->post_data['cartcode'] . '</span></p>';
		}
		// Обертка
		$this->html_wrapper_construct([$massage],true);

		return true;
	}


	/**
	 * Заголовок письма.
	 */
	private function set_subject_data() {

		// формирование темы почтового сообщения
		if( $this->subject && $this->subject != '' ) {
			$this->subject .= ' - ';
		}
		$this->subject .= $this->options['mail_title'];
		// Кодирование
		$this->subject = '=?' . $this->options['charset'] . '?b?' . base64_encode($this->subject) . '?=';

	}


	/**
	 * Header.
	 */
	private function set_common_header_data() {

		// Формирование заголовка почтового сообщения
		if( isset($this->options['mime']) && $this->options['mime'] ) {
			$this->headers = 'MIME-Version: 1.0' . "\r\n";
		}
		// Тип письма
		if( isset($this->options['content-type']) && $this->options['content-type'] ) {
			$this->headers .= 'Content-type: ' . $this->options['content-type'] . ';';
		}
		// Кодировка
		if( isset($this->options['charset']) && $this->options['charset'] ) {
			$this->headers .= ' charset="' . $this->options['charset'] . '"' . "\r\n";
		}
		// Тип кодирования
		if( isset($this->options['transfer_encoding']) && $this->options['transfer_encoding'] ) {
			$this->headers .= 'Content-Transfer-Encoding: ' . $this->options['transfer_encoding'] . ';' . "\r\n";
		}
		// Информация о программе отправки письма
		if( isset($this->options['x_mailer']) && $this->options['x_mailer'] ) {
			$this->headers .= 'X-Mailer: ' . $this->options['x_mailer'] . ';' . "\r\n";
		}
	}


	/**
	 * Преобразование данных из формы в необходимый для отправки письма вид.
	 */
	private function set_mail_data() {

		// Отправитель Имя From:
		$this->headers .= 'From: ';
		if( isset($this->post_data['name']) && $this->post_data['name'] != '' && $this->options['customer_name'] === true ) {
			$this->headers .= '=?' . $this->options['charset'] . '?b?' . base64_encode($this->post_data['name']) . '?=';
			//$this->headers .= $this->post_data['name'];
		} elseif( is_string($this->options['customer_name']) ) {
			$this->headers .= $this->options['customer_name'];
		}
		// Отправитель email
		if( isset($this->post_data['email']) && $this->post_data['email'] != '' && $this->options['customer_email'] === true ) {
			$this->headers .= ' <' . $this->post_data['email'] . '>';
		} elseif( is_string($this->options['customer_email']) ) {
			$this->headers .= ' <' . $this->options['customer_email'] . '>';
		}
		$this->headers .= "\r\n";

		// Адрес для ответа Reply-to:
		if( isset($this->post_data['email']) && $this->post_data['email'] != '' ) {
			$this->headers .= 'Reply-to: ';
			if(  isset($this->post_data['name']) && $this->post_data['name'] != ''  ) {
				$this->headers .= '=?' . $this->options['charset'] . '?b?' . base64_encode($this->post_data['name']) . '?=';
			}
			$this->headers .= ' <' . $this->post_data['email'] . '>';
		}
	}



	/**
	 * Построение разметки заголовка блока полей.
	 */ 
	protected function block_header_construct($block_title) {
		// Проверка установлена ли в параметрах запись загловков блоков и есть ли она в наличии
		if( $this->options['show_titles'] && isset($block_title) && $block_title != ''  ) {
			// Запись заголовка в начало блока
			return '<h3 style="color:#999;">' . $block_title . '</h3>' . "\r\n";
		} else {
			return '';
		}
	}

	/**
	 * Построение разметки для текущего одиночного поля (поля формы или строки письма).
	 */ 
	protected function single_line_construct($incoming_value, $lable, $lable_name, $block_name) {
		// Названия пустых значений не записываются
		if( $incoming_value != '' || $this->options['show_empty'] ) {
			// Запись значения поля
			return '<p style="color:#090;">' . $lable . ': <span style="color:#333;">' . $incoming_value . '</sapan></p>';
		} else {
			return '';
		}
	}

	/**
	 * Построение html обертки для сформированного результата.
	 */ 
	protected function html_wrapper_construct($result_set,$customer=false) {

		// Оформление результата
		$this->result_set = '';
		foreach( $result_set as $message_part ) {
			// Проверка наличия имени поля в соответствующем массиве
			if( $message_part != '' ) {
				// Запись данных
				$this->result_set .= $message_part . '<br>' . "\r\n";
			}
		}
		
		// Выбор обертки
		$template = 'mail_form';
		if( $customer ) {
			$template = 'mail_form_customer';
		}
		// Проверка наличия файла с названиями полей
		$this->check_file_path('/view/forms/', $template . '.php');
		// Получение html разметки письма из файла
		$mail_form_content = file_get_contents($this->files_path[$template]);
		// Замена заголовка
		$mail_form_content = str_replace( '[MAIL_TITLE]', $this->options['mail_title'], $mail_form_content );
		// Замена уведомлений
		$mail_form_content = str_replace( '[MAIL_ORIGIN_MSG]', __('The message was sent using the contact form on the website','spiral'), $mail_form_content );
		$mail_form_content = str_replace( '[MAIL_AUTOMATIC_MSG]', __('The message is sent automatically from the website','spiral'), $mail_form_content );
		$mail_form_content = str_replace( '[MAIL_NOREPLY]', __('Please do not reply to this message.','spiral'), $mail_form_content );
		// Замена адреса сайта
		$mail_form_content = str_replace( '[MAIL_SITE]', $_SERVER["SERVER_NAME"], $mail_form_content );
		//

		// Замена маркера на данные
		$this->result_set = str_replace( '[MAIL_DATA]', $this->result_set, $mail_form_content );

		// Кодирование текста письма
		//$this->result_set = base64_encode($this->result_set);
	}


	/**
	 * Перезаписывает http заголовок, чтобы браузеры думали что это таже страница
	 * Актуально если этот файл лежит на другом сайте
	 */
	private function remoute() {
		$host = parse_url($_SERVER['HTTP_ORIGIN']);
		$ip = gethostbyname($host['host']);
		// При пременениии данного участка не на рабочем сервере - заменить IP
		$this->home_ip = '91.239.233.33';

		// Проверка соответствия места загрузки файла
		if( "POST" == $_SERVER["REQUEST_METHOD"] ) {
			if( $_SERVER["HTTP_ORIGIN"] ) {
				$address = "http://".$_SERVER["SERVER_NAME"];
				if( strpos($address, $_SERVER["HTTP_ORIGIN"] ) !== 0) {
					// Проверка принадлежности к серверу т.к действия ниже - нарушение безопасности
					// Ограничение работы по IP - песочница для уязвимости
					if( $ip == $home_ip ) {
						header('Content-Type: application/json; charset=utf-8');
						header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_ORIGIN']);
						header('Access-Control-Allow-Methods: POST, OPTIONS');
						header('Access-Control-Max-Age: 1000');
						header('Access-Control-Allow-Headers: Content-Type');
					}
				}
			}
		}
	}

} // end FormsMail
?>