<?php

/**
 * Пример вызова:
 * /usr/bin/php /var/www/site.ru/httpdocs/cron/getmessages.php
 * 
 * Пример вызова с передачей php.ini (например, если бинарный php по умолчанию не видит ZendOptimizer)
 * /usr/bin/php --php-ini /etc/php.ini /var/www/site.ru/httpdocs/cron/getmessages.php
 * 
 * Реальный путь на сервере к корневой директории сайта уточните в службе поддержки хостинга.
 * 
 */

@set_time_limit(90000);

// Подключаем основные классы с учетов размещения в директории ./cron/
// При размещении в корневой директории '/../' заменить на '/'
require_once(dirname(__FILE__) . '/../' . 'main_classes.php');

$kernel = & singleton('kernel');

// Загрузка модулей
$kernel->LoadModules();

define('CURRENT_SITE', 1);

$helpdesk = new helpdesk();
$Mail = new Mail();

// Инициализация констант.
$kernel->InitConstants();

// Получаем список всех служб технической поддержки сайта
$helpdesk_result = $helpdesk->GetAllHelpdesk(CURRENT_SITE);

if ($helpdesk_result)
{
	while ($helpdesk_row = mysql_fetch_assoc($helpdesk_result))
	{
		// Получаем маску, по которой формируются название тикетов службы техподдержки
		$helpdesk_ticket_mask = $helpdesk_row['helpdesk_ticket_mask'];
		$helpdesk_ticket_category_id = $helpdesk_row['helpdesk_ticket_category_id'];
		$helpdesk_critical_level_id = $helpdesk_row['helpdesk_critical_level_id'];
		$helpdesk_id = $helpdesk_row['helpdesk_id'];
		$helpdesk_status_new_id = $helpdesk_row['helpdesk_status_new_id'];

		// Шаблон отчета
		$report_template = $helpdesk_row['helpdesk_report_for_query'];
		$helpdesk_report_for_query_subject = $helpdesk_row['helpdesk_report_for_query_subject'];
		$helpdesk_notify_for_query = $helpdesk_row['helpdesk_notify_for_query'];
		$helpdesk_message_type = $helpdesk_row['helpdesk_message_type'];
		$helpdesk_name = $helpdesk_row['helpdesk_name'];

		// Получаем список всех электронных адресов техподдержки
		$email_result = $helpdesk->GetAllEmail($helpdesk_id);

		// Счетчик добавленных тикетов
		$counter = 0;

		if ($email_result)
		{
			while ($email_row = mysql_fetch_assoc($email_result))
			{
				// Формируем массив параметров для получения корреспонденции
				$param_email = array();

				$param_email['email_login'] = $email_row['helpdesk_email_login'];
				$param_email['email_password'] = $email_row['helpdesk_email_password'];
				$param_email['delete'] = $email_row['helpdesk_email_delete_message'];
				$param_email['secury'] = to_bool($email_row['helpdesk_email_use_secury_protocol']);
				$param_email['email_pop3'] = $email_row['helpdesk_email_pop3'];
				$param_email['email_imap'] = $email_row['helpdesk_email_imap'];

				// Активность электронного адреса
				$is_active = $email_row['helpdesk_email_active'];

				// Получаем почту только с активных адресов
				if ($is_active)
				{
					// Получаем массив писем
					$mails_array = $Mail->GetMsgList($param_email);
					//										print_r($mails_array);
					// Возникли ошибки при доступе к электтронной почте
					if (isset($mails_array['error']))
					{
						if (count($mails_array['error']) > 0)
						{
							if (isset($mails_array['error']['no_letters']))
							{
								show_message(sprintf($GLOBALS['MSG_helpdesk']['receive_mail_error'], $email_row['helpdesk_email_email']) . " " .  $GLOBALS['MSG_helpdesk']['receive_mail_error_mailbox_empty']);

							}
							else
							{
								$EventJournal = & singleton('EventsJournal');
								show_error_message(sprintf($GLOBALS['MSG_helpdesk']['receive_mail_error'], $email_row['helpdesk_email_email']));

								foreach ($mails_array['error'] as $key => $value)
								{
									// Отображаем  ошибки пользователю
									show_error_message($value);

									// Получаем имя пользователя
									if (isset($_SESSION['valid_user']))
									{
										$login = to_str($_SESSION['valid_user']);
									}
									else
									{
										$login = USER_NONE;
									}

									// Записываем в журнал событий
									$EventJournal->log_access($login, $value, $status = 2, $send_email = true);
								}
							}
						}
					}
					else
					{
						// Получаем информацию о текущей службе техподдержки
						$helpdesk_row = $helpdesk->GetHelpdesk($helpdesk_id);

						//=======================================================================
						// Записываем сообщения
						//=======================================================================

						// Записываем информацию о сообщениях
						for ($i = 1; $i <= count($mails_array); $i++)
						{
							$param_email = array();

							// Проверяем, зарегистрированный ли пользователь, с e-mailа которого получено сообщение
							// Ищем e-mail  в таблице пользователей сайта
							$site_user_row = $helpdesk->GetSiteUserByEmail($mails_array[$i]['e_mail_from']);

							if ($site_user_row)
							{
								$param_email['site_users_id'] = $site_user_row['site_users_id'];
							}
							else
							{
								$param_email['site_users_id'] = 0;
							}

							// Разбираем тему сообщения

							// Получаем маску, по которой формируются название тикетов службы техподдержки
							if ($helpdesk_row)
							{
								$helpdesk_ticket_mask = $helpdesk_row['helpdesk_ticket_mask'];
							}
							else
							{
								$helpdesk_ticket_mask = '%09d';
							}

							// Маска формирования темы сообщения
							$format = str_replace("%", "%1$", $helpdesk_ticket_mask) . ":%2\$d";

							// Подстрока с именем тикета и порядковым номером письма-родителя
							$str = '';

							preg_match_all("'.*?\[([^\]]*?)\].*?'si", $mails_array[$i]['subject_letter'], $matches);

							// Имя тикета
							$param_email['helpdesk_ticket_name'] = '';

							// В теме есть название тикета
							if (isset($matches[1]))
							{
								for ($j = 0; $j < count($matches[1]); $j++)
								{
									// Проверяем тему по маске формирования имени тикета
									$scanf = sscanf($matches[1][$j], $format);

									// Есть имя тикета
									if (isset($scanf[0]) && isset($scanf[1]))
									{
										$param_email['helpdesk_ticket_name'] = sprintf($helpdesk_ticket_mask, to_int($scanf[0]));

										// Есть порядковый номер родительского письма
										if (isset($scanf[1]))
										{
											$param_email['helpdesk_message_parent_num'] = to_int($scanf[1]);
										}

										$str .= $matches[1][$j];
									}
								}
							}

							// Проверим, существует ли тикет с полученным из темы именем
							if ($param_email['helpdesk_ticket_name'] !== '')
							{
								if ($helpdesk_ticket_row = $helpdesk->GetTicketByName($param_email['helpdesk_ticket_name']))
								{
									$param_email['helpdesk_ticket_id'] = $helpdesk_ticket_row['helpdesk_ticket_id'];

									// Адрес пользователя, указанный  в настройках тикета
									$e_mail_from = $helpdesk_ticket_row['helpdesk_ticket_email'];
								}
							}
							else
							{
								$param_email['helpdesk_ticket_id'] = 0;
								$e_mail_from = -1;
							}

							//=======================================================================
							// Создаем новый тикет, если название тикета не указано в теме,
							// либо указанный в теме тикет не существует, либо сообщение пришло
							// с другого адреса, нежели указан в настройках тикета
							//=======================================================================

							if (!isset($param_email['helpdesk_ticket_id']) || $param_email['helpdesk_ticket_id'] == 0 || ($mails_array[$i]['e_mail_from'] != $e_mail_from))
							{
								$ticket_param = array();

								// Определяем категорию тикетов, к которой нужно отнести создаваемый тикет
								// Если категория по умолчанию для электронного ящика имеет идентификатор отличный от нуля
								if ($email_row['helpdesk_ticket_category_id'])
								{
									$ticket_param['helpdesk_ticket_category_id'] = to_int($email_row['helpdesk_ticket_category_id']);
								}
								// Вкладываем тикет в категорию по умолчанию для всех тикетов
								else
								{
									$ticket_param['helpdesk_ticket_category_id'] = to_int($helpdesk_row['helpdesk_ticket_category_id']);
								}
								
								// Проверяем, существует ли указанная категория тикетов. Если нет, то тикет определяем в корневую категорию
								$ticket_category_row = $helpdesk->GetTicketCategory($ticket_param['helpdesk_ticket_category_id']);

								if (!$ticket_category_row)
								{
									$ticket_param['helpdesk_ticket_category_id'] = 0;
								}

								$ticket_param['users_id'] = 0;
								$ticket_param['helpdesk_critical_level_id'] = to_int($helpdesk_row['helpdesk_critical_level_id']);
								$ticket_param['site_users_id'] = to_int($param_email['site_users_id']);
								$ticket_param['helpdesk_id'] = to_int($helpdesk_id);
								
								if (isset($mails_array[$i]['e_mail_from']))
								{
									$ticket_param['helpdesk_ticket_email'] = to_str($mails_array[$i]['e_mail_from']);
								}
								
								$ticket_param['helpdesk_ticket_datetime'] = date("Y-m-d H:i:s");
								$ticket_param['helpdesk_ticket_notify_status_message_change'] = 1;
								$ticket_param['helpdesk_ticket_sent_answer_for_message'] = 1;
								$ticket_param['helpdesk_ticket_is_open'] = 1;
								$ticket_param['helpdesk_ticket_source'] = 1;
								$ticket_param['helpdesk_email_id'] = to_int($email_row['helpdesk_email_id']);
								$ticket_param['show_message'] = false;

								// Добавляем информацию в БД.
								if ($helpdesk_ticket_id = $helpdesk->InsertTicket($ticket_param))
								{

									// ID тикета
									$param_email['helpdesk_ticket_id'] = $helpdesk_ticket_id;

									// Число созданных тикетов
									$counter++;
								}
								else
								{
									// ID тикета
									$param_email['helpdesk_ticket_id'] = 0;
								}
							}

							// если тикет создан успешно
							if ($param_email['helpdesk_ticket_id'])
							{
								// Получаем информацию о тикете
								$helpdesk_ticket_row = $helpdesk->GetTicket($param_email['helpdesk_ticket_id']);

								if ($helpdesk_ticket_row)
								{
									// Открываем тикет, если он был закрыт
									if ($helpdesk_ticket_row['helpdesk_ticket_is_open'] == 0)
									{
										$helpdesk->TicketStatusChange($helpdesk_ticket_row['helpdesk_ticket_id'], 1);
									}
									
									$ticket_email = $helpdesk_ticket_row['helpdesk_ticket_email'];
									
									// Проверяем, можно ли отсылать отчеты о получении сообщений и автоответы пользователю (защита от зацикливания - автоответы почтовых программ)
									$is_helpdesk_email = $helpdesk->GetEmailIsHelpdeskEmail($helpdesk_id, $ticket_email, $mails_array[$i]['subject_letter'], $param_email['helpdesk_ticket_id']);

									// Если в теме не указано родительское сообщение
									if (!isset($param_email['helpdesk_message_parent_num']))
									{
										// Кладем сообщение в корень
										$param_email['helpdesk_message_parent_id'] = 0;
									}
									else
									{
										// получаем id родительского сообщения
										if ($message_row = $helpdesk->GetMessageByNumber($param_email['helpdesk_ticket_id'], $param_email['helpdesk_message_parent_num']))
										{
											$param_email['helpdesk_message_parent_id'] = $message_row['helpdesk_message_id'];
										}
									}

									$param_email['helpdesk_status_id'] = $helpdesk_row['helpdesk_status_new_id'];
									$param_email['helpdesk_message_subject'] = html_entity_decode($mails_array[$i]['subject_letter']);

									if (strstr(strtolower($mails_array[$i]['type']), 'html'))
									{
										// тип - html
										$param_email['helpdesk_message_type'] = 0;

										$text = $helpdesk->CutQuotetion($mails_array[$i]['body'], $param_email['helpdesk_message_type']);
										$param_email['helpdesk_message_message'] = strip_tags_attributes($text, "<b><br><br/><br /><li><ol><ul><pre><em><i>");
									}
									else
									{
										// тип - text
										$param_email['helpdesk_message_type'] = 1;
										$param_email['helpdesk_message_message'] = $helpdesk->CutQuotetion($mails_array[$i]['body'], $param_email['helpdesk_message_type']);
									}

									$param_email['helpdesk_message_creation_datetime'] = $mails_array[$i]['date'];
									$param_email['helpdesk_message_modification_datetime'] = $mails_array[$i]['date'];
									$param_email['helpdesk_message_grade'] = 0;
									$param_email['helpdesk_message_responsible_description'] = '';
									$param_email['helpdesk_message_processed'] = 0;
									$param_email['helpdesk_message_number'] = 0;
									$param_email['helpdesk_message_inbox'] = 1;
									$param_email['users_id'] = 0;
									
									$param_email['helpdesk_message_headers'] = $mails_array[$i]['headers'];

									if (isset($mails_array[$i]['structure']))
									{
										$param_email['helpdesk_message_headers'] .= $mails_array[$i]['structure'];
									}

									$helpdesk_message_id = $helpdesk->InsertMessage($param_email);

									// Рассчитываем примерное время ответа
									$helpdesk->RecountAnswerDateTime($param_email['helpdesk_ticket_id']);

									$ticket_id = intval($param_email['helpdesk_ticket_id']);

									//=======================================================================
									// Сохраняем вложенные файлы
									//=======================================================================

									// Сохраняем вложенные файлы
									if (isset($mails_array[$i]['attachments']))
									{
										$param_attachments = array();
										$param_attachments = $helpdesk->LoadAttachments($mails_array[$i]['attachments'], $helpdesk_id, $param_email['helpdesk_ticket_id'], $helpdesk_message_id);

										$param_attach = array();

										foreach ($param_attachments as $key => $val)
										{
											$param['helpdesk_attachment_file_name'] = $val['name'];
											$param['helpdesk_attachment_file_path'] = $val['path'];

											// Вносим в БД имена записанных на сервер вложенных файлов
											$helpdesk->InsertAttachments($helpdesk_message_id, $param);
										}
									}

									//=======================================================================
									// Отправка отчета о получении запроса в службу техподдержки
									//=======================================================================

									// Отправка уведомления о получении запроса в службу техподдержки
									if ($helpdesk_row)
									{
										// Шаблон отчета
										$report_template = $helpdesk_row['helpdesk_report_for_query'];

										$helpdesk_report_for_query_subject = $helpdesk_row['helpdesk_report_for_query_subject'];

										$helpdesk_notify_for_query = $helpdesk_row['helpdesk_notify_for_query'];

										$helpdesk_message_type = $helpdesk_row['helpdesk_message_type'];
									}
									else
									{
										$report_template = '';
										$helpdesk_report_for_query_subject = '';
										$helpdesk_notify_for_query = 1;
										$helpdesk_message_type = 0;
									}

									// Необходимо отсылать отчет о получении запроса (должно быть указано как в настройках службы техподдержки, так и в настройках тикета, т.к. может произойти бесконечная автоматическая переписка с почтовыми агентами)
									if($helpdesk_notify_for_query && $helpdesk_ticket_row['helpdesk_ticket_sent_answer_for_message'])
									{										
										// При поступлении запроса с обратным адресом, эквивалентным одному из тех, с которых получаем, отправлять автоматический ответ не нужно. Т.к. получится зацикливание и хэлпдеск сам себе будет слать письма
										if (!$is_helpdesk_email)
										{
											if ($helpdesk_report_for_query_subject == '')
											{
												$helpdesk_report_for_query_subject = $GLOBALS['MSG_helpdesk']['template_report_for_query_subject'];
											}

											$arr = array();
											$arr['helpdesk_message_id'] = $helpdesk_message_id;

											$report_template = $helpdesk->ReFormat($report_template, $helpdesk_message_type);

											$report_text = $helpdesk->ReplaceMailMacro($report_template, $arr);
											$helpdesk_report_for_query_subject = $helpdesk->ReplaceMailMacro($helpdesk_report_for_query_subject, $arr);

											$param_email['helpdesk_status_id'] = $helpdesk_row['helpdesk_status_new_id'];
											$param_email['helpdesk_ticket_id'] = $ticket_id;
											$param_email['helpdesk_message_message'] = $report_text;
											$param_email['helpdesk_message_parent_id'] = $helpdesk_message_id;
											$param_email['helpdesk_message_subject'] = $helpdesk_report_for_query_subject;
											$param_email['helpdesk_message_creation_datetime'] = $param['helpdesk_message_modification_datetime'] = date("Y-m-d H:i:s");
											$param_email['helpdesk_message_grade'] = 0;

											$param_email['users_id'] = 0;
											$param_email['site_users_id'] = 0;
											$param_email['helpdesk_message_processed'] = 1;
											$param_email['helpdesk_message_number'] = 0;
											$param_email['helpdesk_message_inbox'] = 0;

											// Отсылаем сообщение
											$helpdesk->SendMessage($param_email, $helpdesk_message_type);
										}
									}

									//=======================================================================
									// Отправка автоответа (только на первое сообщение тикета)
									//=======================================================================

									// Получаем информацию о сообщении
									$message_row = $helpdesk->GetMessage($helpdesk_message_id);

									if ($message_row)
									{
										// При поступлении запроса с обратным адресом, эквивалентным одному из тех, с которых получаем, отправлять автоматический ответ не нужно. Т.к. получится зацикливание и хэлпдеск сам себе будет слать письма
										if (!$is_helpdesk_email)
										{
											if ($message_row['helpdesk_message_number'] == 1)
											{
												// Анализируем текст сообщения для автоматического ответа
												$helpdesk_letter_template_id = $helpdesk->AnalizeForKeyWords($helpdesk_id, $message_row['helpdesk_message_subject'] . "\n\n" . $message_row['helpdesk_message_message']);

												// Для автоматического ответа на сообщение подходит стандартный ответ
												// Формируем ответ на сообщение
												if ($helpdesk_letter_template_id)
												{
													$helpdesk->SentAutoAnswer($helpdesk_id, $helpdesk_letter_template_id, $helpdesk_message_id);
												}
											}
										}
									}
								}//if(ticket_row)
							}//if(helpdesk_ticket_id)
						}//for
					}
				}//if(is_active)
			}//while

			if ($counter)
			{
				if ($counter == 1)
				{
					?><h1><?php echo $GLOBALS['MSG_helpdesk']['add_ticket_success']; ?></h1><?php
				}
				else
				{
					?><h1><?php echo $GLOBALS['MSG_helpdesk']['add_ticket_many_success']; ?></h1><?php
				}
			}

			?><h2><?php echo "Получение корреспонденции для службы техподдержки \"$helpdesk_name\" завершено."; ?></h2><?php
		}
		
		// Закрываем старые тикеты
		$helpdesk->CloseOldTicket(to_int($helpdesk_id));
	}
}
else 
{
	echo "Error: Helpdesk's not found";
}

?>