<?php

	class WorkDocs
	{
		//-- Templates directory
		public static $tpl_dir;


		/* ---------------------------------------------------------------------------------------------------------------------- */
		/* ---------------------------------------------------------------------------------------------------------------------- */
		/* ---------------------------------------------------------------------------------------------------------------------- */


		/*
		 |-----------------------------------------------------------------------------------------------------------------------
		 | _json
		 |-----------------------------------------------------------------------------------------------------------------------
		 |
		 | Return array in JSON format
		 |
		 */
		public static function _json ($data, $exit = false)
		{
			header("Content-Type: application/json;charset=utf-8");

			$json = json_encode($data);

			if ($json === false)
			{
				$json = json_encode(array("jsonError", json_last_error_msg()));

				if ($json === false)
					$json = '{"jsonError": "unknown"}';

				http_response_code(500);
			}

			echo $json;

			if ($exit)
				exit;
		}


		private static function _get_all_rubrics ()
		{
			global $AVE_DB;

			$sql = "
				SELECT
					Id,
					rubric_title
				FROM
					" . PREFIX . "_rubrics
				ORDER BY rubric_position ASC
			";

			$sql = $AVE_DB->Query($sql);

			$rubrics = [];

			while ($rub = $sql->FetchAssocArray())
				array_push($rubrics, $rub);

			return $rubrics;
		}


		private static function _get_rubric ($rubric_id = null)
		{
			global $AVE_DB;

			$rubric_id = (isset($_REQUEST['rubric_id']) ? (int)$_REQUEST['rubric_id'] : $rubric_id);

			$sql = "
				SELECT
					*
				FROM
					" . PREFIX . "_rubrics
				WHERE
					Id = {$rubric_id}
				LIMIT 0,1
			";

			$sql = $AVE_DB->Query($sql);

			return $sql->FetchAssocArray();
		}


		private static function _get_rubric_fields ($rubric_id = null)
		{
			global $AVE_DB, $AVE_Template;

			$rubric_id = (isset($_REQUEST['rubric_id']) ? (int)$_REQUEST['rubric_id'] : $rubric_id);

			// Поля
			$sql = "
				SELECT
					a.*,
					b.group_title,
					b.group_description,
					b.group_position
				FROM
					" . PREFIX . "_rubric_fields AS a
				LEFT JOIN
					" . PREFIX . "_rubric_fields_group AS b
					ON a.rubric_field_group = b.Id
				WHERE
					a.rubric_id = '" . $rubric_id . "'
				ORDER BY
					b.group_position ASC, a.rubric_field_position ASC
			";

			$sql = $AVE_DB->Query($sql);

			$fields_list = [];

			while ($row = $sql->FetchRow())
			{
				$group_id = ($row->rubric_field_group) ? $row->rubric_field_group : 0;

				$fields_list[$group_id]['group_position'] = ($row->group_position) ? $row->group_position : 100;
				$fields_list[$group_id]['group_title'] = $row->group_title;
				$fields_list[$group_id]['group_description'] = $row->group_description;
				$fields_list[$group_id]['fields'][$row->Id]['Id'] = $row->Id;
				$fields_list[$group_id]['fields'][$row->Id]['rubric_id'] = $row->rubric_id;
				$fields_list[$group_id]['fields'][$row->Id]['rubric_field_group'] = $row->rubric_field_group;
				$fields_list[$group_id]['fields'][$row->Id]['rubric_field_alias'] = $row->rubric_field_alias;
				$fields_list[$group_id]['fields'][$row->Id]['rubric_field_title'] = $row->rubric_field_title;
				$fields_list[$group_id]['fields'][$row->Id]['rubric_field_type'] = $row->rubric_field_type;
				$fields_list[$group_id]['fields'][$row->Id]['rubric_field_numeric'] = $row->rubric_field_numeric;
				$fields_list[$group_id]['fields'][$row->Id]['rubric_field_default'] = $row->rubric_field_default;
				$fields_list[$group_id]['fields'][$row->Id]['rubric_field_search'] = $row->rubric_field_search;
			}

			$fields_list = msort($fields_list, 'group_position');

			$AVE_Template->assign('groups_count', count($fields_list));
			$AVE_Template->assign('fields_list', $fields_list);
			$AVE_Template->assign('field_array', get_field_type());
		}


		private static function _get_work ($work_id = null)
		{
			global $AVE_DB;

			$work_id = (isset($_REQUEST['work_id']) ? (int)$_REQUEST['work_id'] : $work_id);

			$sql = "
				SELECT
					*
				FROM
					" . PREFIX . "_module_workdocs
				WHERE
					id = {$work_id}
				LIMIT 0,1
			";

			$sql = $AVE_DB->Query($sql);

			return $sql->FetchAssocArray();
		}


		private static function _get_works ()
		{
			global $AVE_DB;

			$sql = "
				SELECT
					*
				FROM
					" . PREFIX . "_module_workdocs
			";

			$sql = $AVE_DB->Query($sql);

			$works = [];

			while ($work = $sql->FetchAssocArray())
				array_push($works, $work);

			return $works;
		}


		private static function _get_num_docs ($rubric_id = null)
		{
			global $AVE_DB;

			$rubric_id = (isset($_REQUEST['rubric_id']) ? (int)$_REQUEST['rubric_id'] : $rubric_id);

			$sql = "
				SELECT
					count(Id)
				FROM
					" . PREFIX . "_documents
				WHERE
					rubric_id = {$rubric_id}
			";

			$sql = $AVE_DB->Query($sql);

			return $sql->GetCell();
		}


		private static function _get_document ($doc_id = null)
		{
			if (! is_numeric($doc_id) OR $doc_id < 1)
				return false;

			$data = get_document($doc_id);

			$fields = get_document_fields ($doc_id);

			foreach ($fields AS $k => $v)
				if (is_numeric($k))
					$data['feld'][$k] = self::_field_type_value($v);


			unset ($fields);

			return $data;
		}


		private static function _field_type_value ($data = [])
		{
			if (empty($data))
				return false;

			$func = 'get_field_' . $data['rubric_field_type'];

			if (! is_callable($func))
				$func = 'get_field_default';

			$field_value = $func($data['field_value'], 'api', $data['rubric_field_id'], null, null, $x, null, null, null, $data['rubric_field_default']);

			return $field_value;
		}


		private static function _set_first_start ($work_id)
		{
			global $AVE_DB;

			if (! $work_id)
				return false;

			$sql = "
				DELETE FROM
					" . PREFIX . "_module_workdocs_logs
				WHERE
					work_id = {$work_id}
			";

			$AVE_DB->Query($sql);

			$sql = "
				UPDATE
					" . PREFIX . "_module_workdocs
				SET
					last_run = '" . time() . "',
					last_count = 0
				WHERE
					id = {$work_id}
			";

			$AVE_DB->Query($sql);

			return true;
		}


		private static function _save_logs ($work_id, $document_id, $document_title, $rubric_id, $document_logs, $limit)
		{
			global $AVE_DB;

			$document_title = htmlspecialchars($document_title, ENT_QUOTES);

			if ($document_logs)
			{
				$sql = "
					INSERT INTO
						" . PREFIX . "_module_workdocs_logs
					SET
						`work_id` = '{$work_id}',
						`rubric_id` = '{$rubric_id}',
						`document_id` = '{$document_id}',
						`document_title` = '{$document_title}',
						`last_run` = '" . time() . "',
						`logs` = '" . serialize($document_logs) . "'
				";

				$AVE_DB->Query($sql);
			}

			$sql = "
				UPDATE
					" . PREFIX . "_module_workdocs
				SET
					last_count = '" . ($limit + 1) . "'
				WHERE
					id = '{$work_id}'
			";

			$AVE_DB->Query($sql);

			return true;
		}


		private static function _doc_save ($document_id, $rubric_id, $data, $code, $revisions, $logs)
		{
			include_once BASE_DIR . '/class/class.docs.php';

			$AVE_Document = new AVE_Document();

			$document_id = $AVE_Document->documentSave($rubric_id, $document_id, $data, false, $code, $revisions, $logs, false);

			return $document_id;
		}


		private static function _get_logs_json ($work_id = null)
		{
			global $AVE_DB;

			$work = self::_get_work($work_id);

			$where = '';

			switch ($_REQUEST['iSortCol_0'])
			{
				case '0':
					$order = 'ORDER BY document_id ';
					break;

				case '1':
					$order = 'ORDER BY document_title ';
					break;

				case '2':
					$order = 'ORDER BY last_run ';
					break;

				case '3':
					$order = 'ORDER BY logs ';
					break;
			}

			$order .= $_REQUEST['sSortDir_0'];

			$start = $_REQUEST['iDisplayStart'] ? (int)$_REQUEST['iDisplayStart'] : 0;
			$finish = $_REQUEST['iDisplayLength'] ? (int)$_REQUEST['iDisplayLength'] : 40;

			if (isset($_REQUEST['sSearch']) && $_REQUEST['sSearch'] != '')
			{
				$where = "AND (document_id LIKE '%{$_REQUEST['sSearch']}%'";
				$where .= " OR document_title LIKE '%{$_REQUEST['sSearch']}%'";
				$where .= " OR last_run LIKE '%{$_REQUEST['sSearch']}%'";
				$where .= " OR logs LIKE '%{$_REQUEST['sSearch']}%')";
			}

			$sql = "
				SELECT SQL_CALC_FOUND_ROWS
					*
				FROM
					" . PREFIX . "_module_workdocs_logs
				WHERE
					work_id = '{$work_id}'
				{$where}
				{$order}
				LIMIT {$start},{$finish}
			";

			$sql = $AVE_DB->Query($sql);

			$num = $AVE_DB->GetFoundRows();

			$output = [
				'sEcho' => (int)$_REQUEST['sEcho'],
				'iTotalRecords' => $num,
				'iTotalDisplayRecords' => $num,
				'aaData' => []
			];

			while ($log = $sql->FetchAssocArray())
			{
				$output['aaData'][] = [
					'<a title="Edit" href="index.php?do=docs&action=edit&rubric_id='. $work['rubric_id'] .'&Id='. $log['document_id'] .'&cp='.SESSION.'" target="_blank">'. $log['document_id'] .'</a>',
					'<a title="Show" href="/index.php?id='. $log['document_id'] .'" target="_blank"><strong>' . $log['document_title'] . '</strong></a>',
					'<span class="date_text dgrey">' . translate_date(strftime(TIME_FORMAT, $log['last_run'])) . '</span>',
					'<small>' . implode('<br>', unserialize($log['logs'])) . '</small>'
				];
			}

			return $output;
		}


		public static function _clear_text ($string = null, $span = false)
		{
			// Убираем пробелы начало/конец
			$string = trim($string);

			// Замена <br>
			$replace = [
				'<br />' => '<br>',
				'<br/>' => '<br>'
			];

			$string = str_replace(array_keys($replace), array_values($replace), $string);

			// RegExp
			$expression = [
				// Убираем пустые теги
				'~<(p|span)>(?>\s+|&nbsp;|(?R))*</\1>~' => '',
				// Убираем стили из тегов
				'/(<[^>]+) style=".*?"/i' => '$1',
				// Убираем двойные пробелы
				'/\s{2,}/' => ' ',
				// Убираем переходы на новую строку
				'/[\t\n]/' => ' ',
				// Убираем пустые теги
				'/<(\w+)\b(?:\s+[\w\-.:]+(?:\s*=\s*(?:"[^"]*"|"[^"]*"|[\w\-.:]+))?)*\s*\/?>\s*<\/\1\s*>/' => ''
			];

			// Очищаем текст по условиям
			$string = preg_replace(array_keys($expression), array_values($expression), $string);

			// Убираем span
			if ($span)
			{
				$replace = [
					'<span>' => '',
					'</span>' => ''
				];

				$string = str_replace(array_keys($replace), array_values($replace), $string);
			}

			// Повторно проходимся по условиям
			$string = preg_replace(array_keys($expression), array_values($expression), $string);

			// Убираем пробелы начало/конец
			$string = trim($string);

			return $string;
		}


		public static function _is_image ($path = null)
		{
			if (@is_array(getimagesize($path)))
				return true;

			return false;
		}


		public static function _if_exists ($path = null)
		{
			if (file_exists($path))
				return true;

			return false;
		}


		public static function _link_exists ($string = null)
		{
			preg_match_all('#\bhttps?://[^,\s()<>]+(?:\([\w\d]+\)|([^,[:punct:]\s]|/))#', $string, $match);

			return $match[0];
		}


		/* ---------------------------------------------------------------------------------------------------------------------- */
		/* ---------------------------------------------------------------------------------------------------------------------- */
		/* ---------------------------------------------------------------------------------------------------------------------- */


		public static function mainPage ()
		{
			global $AVE_Template;

			$AVE_Template->assign('works', self::_get_works());
			$AVE_Template->assign('rubrics', self::_get_all_rubrics());
			$AVE_Template->assign('content', $AVE_Template->fetch(self::$tpl_dir . 'main.tpl'));
		}


		public static function editWork ()
		{
			global $AVE_Template;

			$work_id = (isset($_REQUEST['work_id']) ? (int)$_REQUEST['work_id'] : '');
			$rubric_id = (isset($_REQUEST['rubric_id']) ? (int)$_REQUEST['rubric_id'] : '');

			if (! $work_id)
			{
				$work = [
					'title' => (isset($_REQUEST['title']) ? $_REQUEST['title'] : 'Без названия'),
					'description' => (isset($_REQUEST['description']) ? $_REQUEST['description'] : ''),
					'rubric_id' => $rubric_id
				];

				$AVE_Template->assign('work', $work);
			}
			else
				{
					$work = self::_get_work();

					$rubric_id = $work['rubric_id'];
				}

			self::_get_rubric_fields($rubric_id);

			$AVE_Template->assign('work', $work);
			$AVE_Template->assign('work_id', $work_id);
			$AVE_Template->assign('rubric', self::_get_rubric($rubric_id));
			$AVE_Template->assign('rubric_id', $rubric_id);
			$AVE_Template->assign('rubrics', self::_get_all_rubrics());
			$AVE_Template->assign('content', $AVE_Template->fetch(self::$tpl_dir . 'edit.tpl'));
		}


		public static function saveWork ()
		{
			global $AVE_DB, $AVE_Template;

			$work_id = (int)$_REQUEST['work_id'];

			if (! $work_id)
			{
				$sql = "
					INSERT INTO
						" . PREFIX . "_module_workdocs
					SET
						title                = '" . $_REQUEST['title'] . "',
						description          = '" . $_REQUEST['description'] . "',
						rubric_id            = '" . (int)$_REQUEST['rubric_id'] . "',
						save_enable          = '" . ($_REQUEST['save_enable'] ? '1' : '0') . "',
						code_enable          = '" . ($_REQUEST['code_enable'] ? '1' : '0') . "',
						revisions_enable     = '" . ($_REQUEST['revisions_enable'] ? '1' : '0') . "',
						logs_enable          = '" . ($_REQUEST['logs_enable'] ? '1' : '0') . "',
						self_sql             = '" . $_REQUEST['self_sql'] . "',
						code_before          = '" . $_REQUEST['code_before'] . "',
						code_after           = '" . $_REQUEST['code_after'] . "'
				";

				$sql = $AVE_DB->Query($sql);

				$work_id = $AVE_DB->InsertId();
			}
			else
				{
					$sql = "
						UPDATE
							" . PREFIX . "_module_workdocs
						SET
							title                = '" . $_REQUEST['title'] . "',
							description          = '" . $_REQUEST['description'] . "',
							save_enable          = '" . ($_REQUEST['save_enable'] ? '1' : '0') . "',
							code_enable          = '" . ($_REQUEST['code_enable'] ? '1' : '0') . "',
							revisions_enable     = '" . ($_REQUEST['revisions_enable'] ? '1' : '0') . "',
							logs_enable          = '" . ($_REQUEST['logs_enable'] ? '1' : '0') . "',
							self_sql             = '" . $_REQUEST['self_sql'] . "',
							code_before          = '" . $_REQUEST['code_before'] . "',
							code_after           = '" . $_REQUEST['code_after'] . "'
						WHERE
							id = '" . $work_id . "'
					";

					$sql = $AVE_DB->Query($sql);
				}

			$return = [
				'success' => $sql ? true : false,
				'work_id' => $work_id,
				'message' => $sql ? $AVE_Template->get_config_vars('mod_edit_save_succes_t') : $AVE_Template->get_config_vars('mod_edit_save_error_t'),
				'header' => $sql ? $AVE_Template->get_config_vars('mod_edit_save_succes_h') : $AVE_Template->get_config_vars('mod_edit_save_error_h'),
				'theme' => $sql ? 'accept' : 'error',
			];

			if (isAjax())
			{
				self::_json($return, true);
			}
			else
				{
					$location = $work_id
						? 'index.php?do=modules&action=modedit&mod=workdocs&moduleaction=1&cp=' . SESSION
						: 'index.php?do=modules&action=modedit&mod=workdocs&moduleaction=1&cp=' . SESSION;
					header('Location:' . $location);
					exit;
				}
		}


		public static function runWork ()
		{
			global $AVE_Template;

			$work_id = (int)$_REQUEST['work_id'];

			$work = self::_get_work($work_id);

			$rubric_id = $work['rubric_id'];

			$counts = self::_get_num_docs($rubric_id);

			$diff = ($counts == $work['last_count']);

			$AVE_Template->assign('work_id', $work_id);
			$AVE_Template->assign('work', $work);
			$AVE_Template->assign('diff', $diff);
			$AVE_Template->assign('rubric_id', $rubric_id);
			$AVE_Template->assign('count', $counts);
			$AVE_Template->assign('content', $AVE_Template->fetch(self::$tpl_dir . 'run.tpl'));
		}


		public static function stepOne ()
		{
			global $AVE_DB, $AVE_Template;

			Debug::startTime('step');

			// Логи
			$document_logs = [];

			// Лимит
			$limit = (isset($_REQUEST['limit']) ? (int)$_REQUEST['limit'] : 0);

			// ID Работы
			$work_id = (int)$_REQUEST['work_id'];

			// Если не получено, то
			if (! $work_id)
			{
				$return = ['success' => false];

				self::_json($return, true);
			}

			// Получаем настройки
			$work = self::_get_work($work_id);

			// ID рубрики
			$rubric_id = (int)$work['rubric_id'];

			// Если первый документ, очищаем логи и ставим время обхода
			if ($limit == 0)
				self::_set_first_start($work_id);

			// Свой SQL, код
			if ($work['self_sql'])
				eval (' ?>' . $work['self_sql'] . '<?'.'php ');

			// SQL запрос, на получение ID документа
			if (! isset($sql))
			{
				$sql = "
					SELECT
						Id
					FROM
						" . PREFIX . "_documents
					WHERE
						rubric_id = {$work['rubric_id']}
					ORDER BY Id DESC
					LIMIT {$limit}, 1;
				";
			}

			// Получаем ID документа
			if (! isset($document_id))
				$document_id = $AVE_DB->Query($sql)->GetCell();

			// Получаем данные документа, включая данные полей
			$data = self::_get_document($document_id);

			// Выполняем код перед сохранением документа
			if ($work['code_before'] > '')
				eval (' ?>' . $work['code_before'] . '<?'.'php ');

			// Сохранение документа, если стоит галочка и есть данные
			if ($work['save_enable'] == 1 && $data)
				$save_id = self::_doc_save($document_id, $rubric_id, $data, (bool)$work['code_enable'], (bool)$work['revisions_enable'], (bool)$work['logs_enable']);

			// Выполняем код после сохранением документа
			if ($work['code_after'] > '')
				eval (' ?>' . $work['code_after'] . '<?'.'php ');

			// Сохраняем логи
			self::_save_logs($work_id, $document_id, $data['document_title'], $rubric_id, $document_logs, $limit);

			// Ответ
			$return = [
				'success' => true,
				'time' => Debug::endTime('step'),
				'limit' => $limit + 1,
				'document_id' => $document_id,
				'rubric_id' => $rubric_id,
				'document_title' => $data['document_title'],
				'document_alias' => $data['document_alias'],
				'document_log'  => implode('<br>', $document_logs)
			];

			self::_json($return, true);
		}


		public static function logWork ()
		{
			global $AVE_Template;

			$work_id = (int)$_REQUEST['work_id'];

			$AVE_Template->assign('work_id', $work_id);
			$AVE_Template->assign('work', self::_get_work($work_id));
			$AVE_Template->assign('content', $AVE_Template->fetch(self::$tpl_dir . 'log.tpl'));
		}


		public static function logJson ()
		{
			$work_id = (int)$_REQUEST['work_id'];

			$output = self::_get_logs_json($work_id);

			self::_json($output, true);
		}


		public static function delWork ()
		{
			global $AVE_DB;

			$work_id = (int)$_REQUEST['work_id'];

			$location = 'index.php?do=modules&action=modedit&mod=workdocs&moduleaction=1&cp=' . SESSION;

			if (! $work_id)
			{
				header('Location:' . $location);
				exit;
			}

			$sql = "
				DELETE FROM
					" . PREFIX . "_module_workdocs
				WHERE
					id = '{$work_id}'
			";

			$AVE_DB->Query($sql);

			$sql = "
				DELETE FROM
					" . PREFIX . "_module_workdocs_logs
				WHERE
					work_id = '{$work_id}'
			";

			$AVE_DB->Query($sql);

			header('Location:' . $location);
			exit;
		}


		public static function clearWork ()
		{
			global $AVE_DB;

			$work_id = (int)$_REQUEST['work_id'];

			$sql = "
				DELETE FROM
					" . PREFIX . "_module_workdocs_logs
				WHERE
					work_id = '{$work_id}'
			";

			$AVE_DB->Query($sql);

			$sql = "
				UPDATE
					" . PREFIX . "_module_workdocs
				SET
					last_run = '',
					last_count = '0'
				WHERE
					id = '{$work_id}'
			";

			$AVE_DB->Query($sql);

			$return = [
				'success' => true
			];

			self::_json($return, true);
		}


		public static function clearWorks ()
		{
			global $AVE_DB;

			$sql = "
				TRUNCATE TABLE " . PREFIX . "_module_workdocs_logs
			";

			$AVE_DB->Query($sql);

			$sql = "
				UPDATE
					" . PREFIX . "_module_workdocs
				SET
					last_run = '',
					last_count = '0'
			";

			$AVE_DB->Query($sql);

			$return = [
				'success' => true
			];

			self::_json($return, true);
		}
	}