<?php
/*
	Copyright © Eleanor CMS
	http://eleanor-cms.ru
	info@eleanor-cms.ru
*/
class Minify
{
	public static
		$folder,#Путь к каталогу на сервере
		$http;#Путь к каталогу по HTTP

	/**
	 * Обфускатор css. Добавляет BOM в начало файла результата.
	 * @param string|array $source Файлы, которые необходимо сжать
	 * @return string Путь к файлу для доступа через HTTP
	 */
	public static function Css($source)
	{
		$source=(array)$source;
		return static::GetFile(md5(join(',',$source)).'.css',$source,array(get_called_class(),'CssGenerator'));
	}

	protected static function CssGenerator($source,$dest)
	{
		if(!class_exists('CssMinifier',false))
			include Eleanor::$root.'extra/cssmin.php';

		$h=fopen($dest,'wb');
		fwrite($h,"\xEF\xBB\xBF");#Запись BOM

		foreach($source as $v)
		{
			$M=new CssMinifier(
				preg_replace("#^\xEF\xBB\xBF#",'',file_get_contents($v)),
				array
				(
					'ImportImports'=>array('BasePath'=>dirname($v)),
					'RemoveComments'=>true,
					'RemoveEmptyRulesets'=>true,
					'RemoveEmptyAtBlocks'=>true,
					'ConvertLevel3AtKeyframes'=>array('RemoveSource'=>false),#Анимация
					'ConvertLevel3Properties'=>true,#Автоматические приставки типа -webkit
					'Variables'=>true,
					'RemoveLastDelarationSemiColon'=>true,
				),
				array(
					'Variables'=>true,
					'ConvertFontWeight'=>true,
					'ConvertHslColors'=>true,
					'ConvertRgbColors'=>true,
					'ConvertNamedColors'=>false,
					'CompressColorValues'=>true,
					'CompressUnitValues'=>false,#0 0 преобразовывается в 0, что не совсем корректно
					'CompressExpressionValues'=>false#Expression все-равно уже deprecated
				)
			);
			fwrite($h,$M->getMinified());
		}
		fclose($h);
	}

	/**
	 * Обфускатор Javascript
	 * @param string|array $files Файлы, которые необходимо сжать
	 * @return string Путь к сжатому файлу для доступа через HTTP
	 */
	public static function Script($source)
	{
		$source=(array)$source;
		return static::GetFile(md5(join(',',$source)).'.js',$source,array(get_called_class(),'ScriptGenerator'));
	}

	protected static function ScriptGenerator($source,$dest)
	{
		if(!class_exists('JavaScriptPacker',false))
			include Eleanor::$root.'extra/JavaScriptPacker.php';

		$s='';
		foreach($source as $v)
			$s.=preg_replace("#^\xEF\xBB\xBF#",'',file_get_contents($v))."\n";

		$M=new JavaScriptPacker($s,62,true,true);

		$h=fopen($dest,'wb');
		fwrite($h,"\xEF\xBB\xBF".$M->pack());#Запись BOM
		fclose($h);
	}

	/**
	 * Создание кэша произвольных файлов (сжатые css, javascript, картинки и т.п.)
	 * @param string $file Имя файла, в котором будет хранится результат
	 * @param string|array Перечень файлов-источников, у которых будет проверяться fileMtime (время последнего изменения файла)
	 * @callback $generator Генератор кэша, метод получит на вход 2 переменные: $source и полный путь к файлу, куда нужно сохранить результат.
	 */
	public static function GetFile($file,$source,$generator)
	{
		$f=static::$folder.$file;

		if(is_file($f))
		{
			$create=false;
			$mt=filemtime($f);
			foreach((array)$source as $v)
				if(is_file($v) and filemtime($v)>$mt)
				{
					$create=true;
					unlink($f);
					break;
				}
		}
		else
			$create=true;

		if($create)
			call_user_func($generator,$source,$f);
		return static::$http.$file;
	}
}
Minify::$folder=Eleanor::$root.'/cache/';
Minify::$http='cache/';
