<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
 * MaxSite CMS
 * (c) https://max-3000.com/
 * Функции для загрузки файлов, создания миниатюры и описания файла.
 */

// функция преобразует $_FILES в массив, годный для mso_upload
// если используется множественная загрузка файлов 
// <input type="file" name="f_userfile[]">
function mso_prepare_files($field_userfile = 'f_userfile')
{
	$new_files = [];

	// алгоритм преобразования: http://code-igniter.ru/wiki/Multi_upload
	foreach ($_FILES[$field_userfile]['name'] as $index => $val) {
		if ($val) {
			foreach ($_FILES[$field_userfile] as $key => $val_arr) {
				$new_files[$field_userfile . $index][$key] = $val_arr[$index];
			}
		}
	}

	// обнуляем $_FILES
	unset($_FILES[$field_userfile]);

	return $new_files;
}

// функция загрузки
// автоматом загружает, меняет размеры, делает миниатюры, описания и т.д.
function mso_upload($config_library = [], $field_userfile = 'f_userfile', $r = [])
{
	$CI = &get_instance();
	$CI->load->library('upload', $config_library);
	$CI->upload->initialize($config_library);

	// если была отправка файла, то нужно заменить поле имени с русского на что-то другое
	// это ошибка при копировании на сервере - он не понимает русские буквы
	if (isset($_FILES[$field_userfile]['name'])) {
		$f_temp = $_FILES[$field_userfile]['name'];

		// оставим только точку
		$f_temp = str_replace('.', '__mso_t__', $f_temp);
		$f_temp = mso_slug($f_temp); // остальное как обычно mso_slug
		$f_temp = str_replace('__mso_t__', '.', $f_temp);

		$ext = str_replace('.', '', strrchr($f_temp, '.')); // расширение файла
		if ($f_temp == '.' . $ext) // имя файла состоит только из расширения «.jpg»
			$f_temp = '1' . $f_temp; // добавляем к нему единицу

		$_FILES[$field_userfile]['name'] = $f_temp;
	}

	$res = $CI->upload->do_upload($field_userfile);

	if (!isset($r['message1'])) $r['message1'] = '<div class="update">' . t('Загрузка выполнена') . '</div>';
	if (!isset($r['message2'])) $r['message2'] = '<div class="error">' . t('Не удалось перименовать файл в нижний регистр') . '</div>';

	// описание файла
	if (!isset($r['userfile_title'])) $r['userfile_title'] = false;

	// файл, где хранится описание
	if (!isset($r['fn_mso_descritions'])) $r['fn_mso_descritions'] = false;

	// нужно ли менять размер
	if (!isset($r['userfile_resize'])) $r['userfile_resize'] = true;
	if (!isset($r['userfile_resize_size'])) $r['userfile_resize_size'] = false; // какой размер

	// водяной знак
	if (!isset($r['userfile_water'])) $r['userfile_water'] = false; // нужен ли водяной знак
	if (!isset($r['userfile_water_file'])) $r['userfile_water_file'] = false; // файл водяного знака
	if (!isset($r['water_type'])) $r['water_type'] = 1; // тип водяного знака

	// миниатюры всегда хранятся в подкаталоге mini
	if (!isset($r['userfile_mini'])) $r['userfile_mini'] = true; // делать миниатюру?
	if (!isset($r['userfile_mini_size'])) $r['userfile_mini_size'] = false; // размер миниатюры
	if (!isset($r['mini_type'])) $r['mini_type'] = 1; // тип миниатюры

	// превьюхи всегда хранятся в подкаталоге _mso_i
	if (!isset($r['prev_size'])) $r['prev_size'] = 100; // размер превьюхи

	// делать превью?
	if (!isset($r['prev_make'])) $r['prev_make'] = true;

	// делать миниатюру?
	if (!isset($r['mini_make'])) $r['mini_make'] = true;

	if ($res) {
		echo $r['message1'];

		// если это файл картинки, то нужно сразу сделать скриншот маленький в _mso_i 100px, который будет выводиться в
		// списке файлов
		$up_data = $CI->upload->data();

		// файл нужно поменять к нижнему регистру
		if ($up_data['file_name'] != strtolower($up_data['file_name'])) {
			// переименуем один раз
			if (rename($up_data['full_path'], $up_data['file_path'] . strtolower('__' . $up_data['file_name']))) {
				// потом второй в уже нужный - это из-за бага винды
				rename(
					$up_data['file_path'] . strtolower('__' . $up_data['file_name']),
					$up_data['file_path'] . strtolower($up_data['file_name'])
				);

				$up_data['file_name'] = strtolower($up_data['file_name']);
				$up_data['full_path'] = $up_data['file_path'] . $up_data['file_name'];
				// echo '<div class="update">' . $up_data['full_path'] . $up_data['file_name'] . '</div>';
			} else {
				echo $r['message2'];
			}
		}

		// если указано описание файла и файл, где это описание хранится
		if ($r['userfile_title'] and $r['fn_mso_descritions']) {
			$fn_descr = trim(strip_tags($r['userfile_title'])); // описание файла
			$fn_descr = str_replace('"', '', $fn_descr); // удалим лишнее
			$fn_descr = str_replace('\'', '', $fn_descr);

			if (file_exists($r['fn_mso_descritions'])) {
				// файла нет, нужно его создать
				// массив данных: fn => описание )
				$mso_descritions = unserialize(read_file($r['fn_mso_descritions'])); // получим из файла все описания
			} else {
				$mso_descritions = [];
			}

			$mso_descritions[$up_data['file_name']] = $fn_descr;

			write_file($r['fn_mso_descritions'], serialize($mso_descritions)); // сохраняем в файл
		}

		/*
			[file_name] => warfare7.jpg
			[file_type] => image/jpeg
			[file_path] => D:/xampplite/htdocs/codeigniter/uploads/
			[full_path] => D:/xampplite/htdocs/codeigniter/uploads/warfare7.jpg
			[raw_name] => warfare7
			[orig_name] => warfare.jpg
			[file_ext] => .jpg
			[file_size] => 52.09
			[is_image] => 1
			[image_width] => 450
			[image_height] => 300
			[image_type] => jpeg
			[image_size_str] => width="450" height="300"
		*/
        
		if ($up_data['is_image']) {
			// это картинка
			$CI->load->library('image_lib');
			$CI->image_lib->clear();

			// вначале нужно изменить размер
			// потом делаем миниатюру с указанными размерами
			// потом делаем такую же миниатюру для  _mso_i с размером 100x100

			// меняем размер
			if ($r['userfile_resize'] and $r['userfile_resize_size']) {

				$size = abs((int) $r['userfile_resize_size']);

				($up_data['image_width'] >= $up_data['image_height']) ? ($max = $up_data['image_width']) : ($max = $up_data['image_height']);

				if ($size > 1 and $size < $max) {
					// корректный размер
					$r_conf = [
						'image_library' => 'gd2',
						'source_image' => $up_data['full_path'],
						'new_image' => $up_data['full_path'],
						'maintain_ratio' => true,
						'width' => $size,
						'height' => $size,
					];

					$CI->image_lib->initialize($r_conf);

					if (!$CI->image_lib->resize())
						echo '<div class="error">' . t('Уменьшение изображения:') . ' ' . $CI->image_lib->display_errors() . '</div>';
				}
			}

			// Меняли или не меняли размер, но теперь проверяем, нужна ли нам ватермарка.
			if ($r['userfile_water'] and $r['userfile_water_file']) {
				// todo — проверка, всё ли нам прислали, всё ли на месте. В идеале бы проверить размеры картинки по отношению к ватермарке.
				if (!file_exists($r['userfile_water_file'])) {
					echo '<div class="error">' . t('Водяной знак:') . ' ' . t('файл водяного знака не найден! Загрузите его в каталог uploads/') . '</div>';
				} else {
					$water_type = $r['water_type']; // Расположение ватермарка
					$hor = 'right'; //Инитим дефолтом.
					$vrt = 'bottom'; //Инитим дефолтом.

					if (($water_type == 2) or ($water_type == 4)) $hor = 'left';
					if (($water_type == 2) or ($water_type == 3)) $vrt = 'top';

					if ($water_type == 1) {
						$hor = 'center';
						$vrt = 'middle';
					}

					$r_conf = [
						'image_library' => 'gd2',
						'source_image' => $up_data['full_path'],
						'new_image' => $up_data['full_path'],
						'wm_type' => 'overlay',
						'wm_vrt_alignment' => $vrt,
						'wm_hor_alignment' => $hor,
						'wm_overlay_path' => $r['userfile_water_file'], //Жёстко, а что делать?

						// fix CodeIgniter in PHP 7.2
						'wm_vrt_offset' => 0,
						'wm_hor_offset' => 0,
						'wm_padding' => 0,
					];

					$CI->image_lib->initialize($r_conf);

					if (!$CI->image_lib->watermark())
						echo '<div class="error">' . t('Водяной знак:') . ' ' . $CI->image_lib->display_errors() . '</div>';
				}
			}

			// делаем миниатюру
			if ($r['mini_make']) mso_upload_mini($up_data, $r);

			// превьюшка
			if ($r['prev_make']) mso_upload_prev($up_data, $r);
		}

		return true;
	} else {
		$er = $CI->upload->display_errors();
		echo '<div class="error">' . t('Ошибка загрузки файла.') . $er . '</div>';

		return false;
	}
}

// функция делает миниатюры
// $up_data - массив данных из $CI->upload->data()
// $r - параметры из mso_upload()
function mso_upload_mini($up_data, $r = [])
{
	// получим размеры файла
	$image_info = GetImageSize($up_data['full_path']);

	if (!$image_info) return; // это не изображение

	$image_width = $image_info[0];
	$image_height = $image_info[1];

	// нужно создать в этом каталоге mini если нет
	if (!is_dir($up_data['file_path'] . 'mini')) @mkdir($up_data['file_path'] . 'mini', 0777); // нет каталога, пробуем создать

	$CI = &get_instance();
	$CI->load->library('image_lib');
	$CI->image_lib->clear();

	// теперь нужно сделать миниатюру указанного размера в mini
	if ($r['userfile_mini'] and $r['userfile_mini_size']) {
		$size = abs((int) $r['userfile_mini_size']);

		($image_width >= $image_height) ? ($max = $image_width) : ($max = $image_height);

		if ($size > 1 and $size < $max) // корректный размер
		{
			$r_conf = [
				'image_library' => 'gd2',
				'source_image' => $up_data['full_path'],
				'new_image' => $up_data['file_path'] . 'mini/' . $up_data['file_name'],
				'maintain_ratio' => true,
				'width' => $size,
				'height' => $size,
			];

			// pr($r_conf);

			$mini_type = $r['mini_type']; // тип миниатюры
			/*
			1 Пропорционального уменьшения
			2 Обрезки (crop) по центру
			3 Обрезки (crop) с левого верхнего края
			4 Обрезки (crop) с левого нижнего края
			5 Обрезки (crop) с правого верхнего края
			6 Обрезки (crop) с правого нижнего края
			7 Уменьшения и обрезки (crop) в квадрат
			*/

			if ($mini_type == 2) // Обрезки (crop) по центру
			{
				$r_conf['x_axis'] = round($image_width / 2 - $size / 2);
				$r_conf['y_axis'] = round($image_height / 2 - $size / 2);
				$CI->image_lib->initialize($r_conf);

				if (!$CI->image_lib->crop())
					echo '<div class="error">' . t('Создание миниатюры:') . ' ' . $CI->image_lib->display_errors() . '</div>';
			} elseif ($mini_type == 3) {
				// Обрезки (crop) с левого верхнего края
				$r_conf['x_axis'] = 0;
				$r_conf['y_axis'] = 0;

				$CI->image_lib->initialize($r_conf);

				if (!$CI->image_lib->crop())
					echo '<div class="error">' . t('Создание миниатюры:') . ' ' . $CI->image_lib->display_errors() . '</div>';
			} elseif ($mini_type == 4) {
				// Обрезки (crop) с левого нижнего края
				$r_conf['x_axis'] = 0;
				$r_conf['y_axis'] = round($image_height - $size * $image_height / $image_width);

				$CI->image_lib->initialize($r_conf);

				if (!$CI->image_lib->crop())
					echo '<div class="error">' . t('Создание миниатюры:') . ' ' . $CI->image_lib->display_errors() . '</div>';
			} elseif ($mini_type == 5) {
				// Обрезки (crop) с правого верхнего края
				$r_conf['x_axis'] = $image_width - $size;
				$r_conf['y_axis'] = 0;

				$CI->image_lib->initialize($r_conf);

				if (!$CI->image_lib->crop())
					echo '<div class="error">' . t('Создание миниатюры:') . ' ' . $CI->image_lib->display_errors() . '</div>';
			} elseif ($mini_type == 6) {
				// Обрезки (crop) с правого нижнего края
				$r_conf['x_axis'] = $image_width - $size;
				$r_conf['y_axis'] = $image_height - $size;

				$CI->image_lib->initialize($r_conf);

				if (!$CI->image_lib->crop())
					echo '<div class="error">' . t('Создание миниатюры:') . ' ' . $CI->image_lib->display_errors() . '</div>';
			} elseif ($mini_type == 7) {
				// Уменьшения и обрезки (crop) в квадрат
				if ($image_width > $image_height) {
					// Если ширина больше высоты
					$resize = round($size * $image_width / $image_height); // Для ресайза по минимальной стороне
					$r_conf['width'] = $resize;

					$CI->image_lib->initialize($r_conf);

					if (!$CI->image_lib->resize())
						echo '<div class="error">' . t('Создание миниатюры:') . ' ' . $CI->image_lib->display_errors() . '</div>';

					$r_conf['x_axis'] = round(($resize - $size) / 2);
					$r_conf['y_axis'] = 0;
					$r_conf['width'] = $size;
					$r_conf['maintain_ratio'] = false;
					$r_conf['source_image'] = $r_conf['new_image'];

					$CI->image_lib->initialize($r_conf);

					if (!$CI->image_lib->crop())
						echo '<div class="error">' . t('Создание миниатюры:') . ' ' . $CI->image_lib->display_errors() . '</div>';
				} elseif ($image_width < $image_height) {
					// Если высота больше ширины
					$resize = round($size * $image_height / $image_width);
					$r_conf['height'] = $resize;

					$CI->image_lib->initialize($r_conf);

					if (!$CI->image_lib->resize())
						echo '<div class="error">' . t('Создание миниатюры:') . ' ' . $CI->image_lib->display_errors() . '</div>';

					$r_conf['x_axis'] = 0;
					$r_conf['y_axis'] = round(($resize - $size) / 2);
					$r_conf['height'] = $size;
					$r_conf['maintain_ratio'] = false;
					$r_conf['source_image'] = $r_conf['new_image'];

					$CI->image_lib->initialize($r_conf);

					if (!$CI->image_lib->crop())
						echo '<div class="error">' . t('Создание миниатюры:') . ' ' . $CI->image_lib->display_errors() . '</div>';
				} else {
					// Равны
					$CI->image_lib->initialize($r_conf);

					if (!$CI->image_lib->resize())
						echo '<div class="error">' . t('Создание миниатюры:') . ' ' . $CI->image_lib->display_errors() . '</div>';
				}
			} else {
				// ничего не указано - Пропорционального уменьшения
				$CI->image_lib->initialize($r_conf);

				if (!$CI->image_lib->resize())
					echo '<div class="error">' . t('Создание миниатюры:') . ' ' . $CI->image_lib->display_errors() . '</div>';
			}
		} else {
			//Размер некорректный и миниатюру просто копируем из большого изображения.
			copy($up_data['full_path'], $up_data['file_path'] . 'mini/' . $up_data['file_name']);
		}
	}
}

// функция делает превьюшку 100x100
// $up_data - массив данных из $CI->upload->data()
// $r - параметры из mso_upload()
function mso_upload_prev($up_data, $r = [])
{
	// получим размеры файла
	$image_info = GetImageSize($up_data['full_path']);

	if (!$image_info) return; // это не изображение

	$image_width = $image_info[0];
	$image_height = $image_info[1];

	// нужно создать в этом каталоге _mso_i если нет
	if (!is_dir($up_data['file_path'] . '_mso_i')) @mkdir($up_data['file_path'] . '_mso_i', 0777); // нет каталога, пробуем создать

	$CI = &get_instance();
	$CI->load->library('image_lib');
	$CI->image_lib->clear();

	// всегда делаем 100 на 100
	// алгоритм тот же, что и у миниатюры
	$size = $r['prev_size'];

	if ($size > 0) {
		// если нужно делать превьюху
		$r_conf = [
			'image_library' => 'gd2',
			'source_image' => $up_data['full_path'],
			'new_image' => $up_data['file_path'] . '_mso_i/' . $up_data['file_name'],
			'maintain_ratio' => true,
			'width' => $size,
			'height' => $size,
		];

		$mini_type = $r['mini_type']; // тип миниатюры
		/*
		1 Пропорционального уменьшения
		2 Обрезки (crop) по центру
		3 Обрезки (crop) с левого верхнего края
		4 Обрезки (crop) с левого нижнего края
		5 Обрезки (crop) с правого верхнего края
		6 Обрезки (crop) с правого нижнего края
		7 Уменьшения и обрезки (crop) в квадрат
		*/

		if ($mini_type == 2) {
			// Обрезки (crop) по центру
			$r_conf['x_axis'] = round($image_width / 2 - $size / 2);
			$r_conf['y_axis'] = round($image_height / 2 - $size / 2);

			$CI->image_lib->initialize($r_conf);

			if (!$CI->image_lib->crop())
				echo '<div class="error">' . t('Создание миниатюры:') . ' ' . $CI->image_lib->display_errors() . '</div>';
		} elseif ($mini_type == 3) {
			// Обрезки (crop) с левого верхнего края
			$r_conf['x_axis'] = 0;
			$r_conf['y_axis'] = 0;

			$CI->image_lib->initialize($r_conf);

			if (!$CI->image_lib->crop())
				echo '<div class="error">' . t('Создание миниатюры:') . ' ' . $CI->image_lib->display_errors() . '</div>';
		} elseif ($mini_type == 4) {
			// Обрезки (crop) с левого нижнего края
			$r_conf['x_axis'] = 0;
			$r_conf['y_axis'] = round($image_height - $size * $image_height / $image_width);

			$CI->image_lib->initialize($r_conf);

			if (!$CI->image_lib->crop())
				echo '<div class="error">' . t('Создание миниатюры:') . ' ' . $CI->image_lib->display_errors() . '</div>';
		} elseif ($mini_type == 5) {
			// Обрезки (crop) с правого верхнего края
			$r_conf['x_axis'] = $image_width - $size;
			$r_conf['y_axis'] = 0;

			$CI->image_lib->initialize($r_conf);

			if (!$CI->image_lib->crop())
				echo '<div class="error">' . t('Создание миниатюры:') . ' ' . $CI->image_lib->display_errors() . '</div>';
		} elseif ($mini_type == 6) {
			// Обрезки (crop) с правого нижнего края
			$r_conf['x_axis'] = $image_width - $size;
			$r_conf['y_axis'] = $image_height - $size;

			$CI->image_lib->initialize($r_conf);

			if (!$CI->image_lib->crop())
				echo '<div class="error">' . t('Создание миниатюры:') . ' ' . $CI->image_lib->display_errors() . '</div>';
		} elseif ($mini_type == 7) {
			// Уменьшения и обрезки (crop) в квадрат

			if ($image_width > $image_height) {
				// Если ширина больше высоты
				$resize = round($size * $image_width / $image_height); // Для ресайза по минимальной стороне
				$r_conf['width'] = $resize;

				$CI->image_lib->initialize($r_conf);

				if (!$CI->image_lib->resize())
					echo '<div class="error">' . t('Создание миниатюры:') . ' ' . $CI->image_lib->display_errors() . '</div>';

				$r_conf['x_axis'] = round(($resize - $size) / 2);
				$r_conf['y_axis'] = 0;
				$r_conf['width'] = $size;
				$r_conf['maintain_ratio'] = false;
				$r_conf['source_image'] = $r_conf['new_image'];

				$CI->image_lib->initialize($r_conf);

				if (!$CI->image_lib->crop())
					echo '<div class="error">' . t('Создание миниатюры:') . ' ' . $CI->image_lib->display_errors() . '</div>';
			} elseif ($image_width < $image_height) {
				// Если высота больше ширины
				$resize = round($size * $image_height / $image_width);
				$r_conf['height'] = $resize;

				$CI->image_lib->initialize($r_conf);

				if (!$CI->image_lib->resize())
					echo '<div class="error">' . t('Создание миниатюры:') . ' ' . $CI->image_lib->display_errors() . '</div>';

				$r_conf['x_axis'] = 0;
				$r_conf['y_axis'] = round(($resize - $size) / 2);
				$r_conf['height'] = $size;
				$r_conf['maintain_ratio'] = false;
				$r_conf['source_image'] = $r_conf['new_image'];

				$CI->image_lib->initialize($r_conf);

				if (!$CI->image_lib->crop())
					echo '<div class="error">' . t('Создание миниатюры:') . ' ' . $CI->image_lib->display_errors() . '</div>';
			} else {
				// Равны
				$CI->image_lib->initialize($r_conf);

				if (!$CI->image_lib->resize())
					echo '<div class="error">' . t('Создание миниатюры:') . ' ' . $CI->image_lib->display_errors() . '</div>';
			}
		} else {
			// ничего не указано - Пропорционального уменьшения
			$CI->image_lib->initialize($r_conf);

			if (!$CI->image_lib->resize())
				echo '<div class="error">' . t('Создание миниатюры:') . ' ' . $CI->image_lib->display_errors() . '</div>';
		}
	}
}

# end of file
