<?
require_once(dirname(__FILE__) . '/sessionCore.php');
require_once(dirname(__FILE__) . '/../user/dbUser.php');
require_once(dirname(__FILE__) . '/../lang/lang-fr.php');

if (file_exists('lang-fr.php'))
	require_once('lang-fr.php');

date_default_timezone_set('Europe/Paris');

function my_autoloader($class_name)
{
	$target = dirname(__FILE__) . "/../include/" . $class_name . ".php";
	if (file_exists($target)) {
		require_once($target);
	} else {

		if ($class_name == "TabBarItem")
			require_once(dirname(__FILE__) . "/../include/TabBarHTML.php");
		else if ($class_name == "PageTitleAction" || $class_name == "PageTitleInfo")
			require_once(dirname(__FILE__) . "/../include/PageTitleHTML.php");
		//echo "<br>KO ".$class_name;
	}
}
spl_autoload_register('my_autoloader');


class Pagination
{
	var $page = '';
	var $lastPage = '';
	var $startSQL = '';
	var $maxPerPage = '';
	var $maxLink = 5;
	var $startPage = '';
	var $endPage = '';

	var $from = '';
	var $to = '';
	var $counter = '';


	function __construct($page, $maxPerPage, $counter)
	{
		if (isset($page)) {
			if ($counter < (($page - 1) * $maxPerPage))
				$page = 1;
		} else {
			$page = 1;
		}
		$this->page = $page;

		$this->lastPage = ceil($counter / $maxPerPage);
		$this->startSQL = ($this->page - 1) * $maxPerPage;
		$this->maxPerPage = $maxPerPage;

		$this->startPage = $this->page - $this->maxLink;
		$this->endPage = $this->page + $this->maxLink;
		if ($this->startPage < 1) {
			$this->startPage = 1;
		}
		if ($this->endPage > $this->lastPage) {
			$this->endPage = $this->lastPage;
		}
		$this->counter = $counter;
		$this->from = $this->startSQL + 1;
		$this->to = $this->startSQL + $this->maxPerPage;
		if ($this->to > $this->counter) {
			$this->to = $this->counter;
		}
	}
}

class Filter
{
	var $name = null;
	var $default = null;
	var $label = null;
	var $enumList = null;
	var $pattern = null;
	var $type = null;

	function __construct($name, $default, $label, $args)
	{
		$this->name = $name;
		$this->default = $default;
		$this->label = $label;
		$this->enumList = NULL;
		$this->pattern = NULL;
		$this->type = NULL;
		if ($args) {
			if ($args["enumList"])
				$this->enumList = $args["enumList"];
			if ($args["pattern"])
				$this->pattern = $args["pattern"];
			if ($args["type"])
				$this->type = $args["type"];
		}
	}
	function getSQL()
	{
		$sql = "";
		if (isset($this->default)) {
			if ($this->pattern) {
				$val = mysqli_real_escape_string(DBTools::getConnection(), $this->default);
				$sql = str_replace("{v}", $val, $this->pattern);
				return $sql;
			} else {
				$keys = array_keys($this->enumList);
				return $keys[$this->default];
			}
		}
		return null;
	}
}

class PageContext
{
	var $type = "";
	var $page = 1;
	var $maxPerPage = 50;
	var $sort = "id";
	var $order = "DESC";
	var $filters = array();
	var $filtersQuery = array();
	var $isNew = true;

	function __construct($type = null)
	{
		$this->type = $type;
	}

	function addFilter($name, $value)
	{
		$this->filters[$name] = $value;
	}
	function removeFilter($name)
	{
		unset($this->filters[$name]);
	}

	function getFilter($name)
	{
		return $this->filters[$name];
	}

	function resetFilters()
	{
		$this->filters = array();
		$this->filtersQuery = array();
	}

	function setFilters($filters = null)
	{
		$this->filtersQuery = array();
		if (!$filters) {
			return;
		}

		$filtersDef = array();
		foreach ($filters as $filter) {
			$filtersDef[$filter->name] = $filter;
		}

		foreach ($this->filters as $n => $f) {
			$filterDef = $filtersDef[$n];
			if ($filterDef) {
				$sql = $filterDef->getSQL();
				if ($sql) {
					array_push($this->filtersQuery, $sql);
				}
			}
		}
		return true;
	}

	function setFilterValue($name, $value)
	{
		$this->filters[$name] = $value;
	}

	function getFiltersQuery()
	{
		return $this->filtersQuery;
	}

	function getFilterValue($name)
	{
		if ($this->filters[$name] != null && $this->filters[$name] != "")
			return $this->filters[$name];
		else
			return NULL;
	}

	function setSort($sort)
	{
		$this->sort = $sort;
	}

	function setOrder($order)
	{
		$this->order = $order;
	}

	function setPage($page)
	{
		$this->page = $page;
	}

	function setMaxPerPage($maxPerPage)
	{
		$this->maxPerPage = $maxPerPage;
	}

	function getOrderBy()
	{
		return $this->sort . " " . $this->order;
	}

	function reset()
	{
		$this->page = 1;
		$this->sort = "id";
		$this->order = "DESC";
		$this->isNew = true;
		$this->resetFilters();
	}
}


class Context
{
	var $list = array();

	function load($type)
	{
		$pSort  = $_REQUEST["sorted"];
		$pPage = $_REQUEST["page"];
		$pReset = $_REQUEST["reset"];
		$pMaxPerPage = $_REQUEST["maxPerPage"];


		//RESET
		if (!isset($this->list[$type]) || isset($pReset)) {
			$pc = new PageContext($type);
		} else {
			$pc = $this->list[$type];
			$pc->isNew = false;
		}

		//SORT
		if (isset($pSort) && $pSort != "") {
			if ($pc->sort == $pSort) {
				$pc->setOrder($pc->order == "ASC" ? "DESC" : "ASC");
			}
			$pc->setSort($pSort);
		}


		//FILTER
		if ($_REQUEST["filters"] && is_array($_REQUEST["filters"])) {
			foreach ($_REQUEST["filters"] as $name => $value) {
				/*if (get_magic_quotes_gpc()) {
					$value = stripslashes($value);
				}*/
				if ($value != '')
					$pc->addFilter($name, $value);
				else
					$pc->removeFilter($name);
			}
		}

		//PAGE
		if (isset($pPage) && $pPage != "") {
			$pc->setPage($pPage);
		}

		if (isset($pMaxPerPage) && $pMaxPerPage != "") {
			$pc->setMaxPerPage($pMaxPerPage);
		}

		$this->list[$type] = $pc;
		return $pc;
	}

	function getPageContext($type)
	{
		if ($this->list[$type])
			return $this->list[$type];
		else
			return new PageContext();
	}
}



class Session extends SessionCore
{
	const SESSION_NAME = "Session_backend";
	var $user = null;
	var $context = null;
	var $menu = "";
	var $site = null;

	const AREA_SITE = "site";
	const AREA_CLIENT = "client";
	const AREA_SHOP = "shop";
	const AREA_ORDER = "order";
	const AREA_ADMIN = "admin";
	const AREA_KITCHEN = "kitchen";

	function __construct() {}

	function login($login, $password)
	{
		$dbUser = new DBUser();
		$this->user = $dbUser->getByLogin($login, $password);
		if (isset($this->user)) {
			$dbUser->updateLastLogin($this->user->id);
			$dbUser->addLog("Connexion", "Connexion a la plateforme", $this->user->login);
			$this->context = new Context();
		} else {
			$dbUser->addLog("Connexion", "Echec de connexion", "($login)");
		}
	}

	static function loadNoConnection()
	{
		return self::load(null, false);
	}
	static function load($pageContextName = null, $checkConnected = true)
	{
		global $pageContext;
		global $session;

		ini_set('session.gc_maxlifetime', 86400);
		session_start();
		$session = $_SESSION[self::SESSION_NAME];

		if (!$session) {
			$session = new Session();
			$_SESSION[self::SESSION_NAME] = $session;
		}


		if ($checkConnected && !$session->isConnected()) {
			$session->addMessage("danger", "Session invalide");
			self::logout();
		}

		if (!($_REQUEST["dm"] ?? false)) {
			$session->_Messages = array();
			$session->_Debug = array();
			$session->_Toasts = array();
		}

		if ($pageContextName) {
			$pageContext = $session->loadPageContext($pageContextName);
		}
	}

	function getSite()
	{
		return $this->site;
	}


	function isConnected()
	{
		return isset($this->user) && isset($this->user->id);
	}

	function loadPageContext($type)
	{
		if ($this->context)
			return $this->context->load($type);
		else
			return NULL;
	}

	function getMenu()
	{
		return $this->menu;
	}

	function setMenu($menu)
	{
		$this->menu = $menu;
	}

	static function checkRule($isOK, $message = false)
	{
		if (!$isOK) {
			Header("Location: /manager/admin/invalidPolicy.php" . ($message ? "?dm=1" : ""));
			exit();
		}
	}

	static function checkArea($area)
	{
		global $TEXT2;
		global $session;
		$areas = array(
			self::AREA_SITE => array("ruleSite" => true, "isAboValid" => true),
			self::AREA_SHOP => array("ruleShop" => true, "isAboValid" => true),
			self::AREA_ORDER => array("ruleOrder" => true, "isAboValid" => false),
			self::AREA_CLIENT => array("ruleOrder" => true, "isAboValid" => true),
			self::AREA_ADMIN => array("ruleAdmin" => true, "isAboValid" => true),
			self::AREA_KITCHEN => array("ruleKitchen" => true, "isAboValid" => true)
		);

		$user = $session->user;

		$areaDef = $areas[$area];
		if ($areaDef) {
			if (($areaDef["ruleSite"] ?? false) && !$user->ruleSite()) {
				$session->addMessage("danger", $TEXT2["msg_invalidPolicy"] . " Rule site");
				self::checkRule(false, true);
			} else if (($areaDef["ruleShop"] ?? false) && !$user->ruleShop()) {
				$session->addMessage("danger", $TEXT2["msg_invalidPolicy"] . " Rule shop");
				self::checkRule(false, true);
			} else if (($areaDef["ruleOrder"] ?? false) && !$user->ruleOrder()) {
				$session->addMessage("danger", $TEXT2["msg_invalidPolicy"] . " Rule order");
				self::checkRule(false, true);
			} else if (($areaDef["ruleAdmin"] ?? false) && !$user->ruleAdmin()) {
				$session->addMessage("danger", $TEXT2["msg_invalidPolicy"] . " Rule admin");
				self::checkRule(false, true);
			} else if (($areaDef["ruleKitchen"] ?? false) && !$user->ruleKitchen()) {
				$session->addMessage("danger", $TEXT2["msg_invalidPolicy"] . " Rule kitchen");
				self::checkRule(false, true);
			}
		} else {
			$session->addMessage("danger", $TEXT2["msg_invalidPolicy"] . " Area non definie : " . $area);
			self::checkRule(false, true);
		}
	}


	static function checkCommand($redirection)
	{
		global $command;
		$command = $_REQUEST["command"];
		if (!isset($command)) {
			Header("Location: " . $redirection);
			exit();
		}
		return $command;
	}
	static function logout()
	{
		session_start();
		session_unset();
		session_destroy();
		Header("Location: /manager/admin/index.php");
		exit();
	}
}
<?
require_once(dirname(__FILE__) . '/Configuration.php');

function GetSQLValue($theValue, $theType, $default = NULL, $escape = true)
{
	/*if (get_magic_quotes_gpc() && $escape) {
		$theValue = stripslashes($theValue);
	}*/

	$theValue = mysqli_real_escape_string(DBTools::getConnection(), $theValue);

	switch ($theType) {

		case "text":
			$theValue = ($theValue != "") ? "'" . strip_tags($theValue) . "'" : ($default ? "'" . $default . "'" : "NULL");
			break;
		case "json":
			$theValue = ($theValue != "") ? "'" . $theValue . "'" : ($default ? "'" . $default . "'" : "NULL");
			break;
		case "html":
			$theValue = ($theValue != "") ? "'" . $theValue . "'" : ($default ? "'" . $default . "'" : "NULL");
			break;
		case "date":
		case "time":
			$theValue = ($theValue != "") ? "'" . $theValue . "'" : ($default ? "'" . $default . "'" : "NULL");
			break;
		case "long":
		case "int":
			$theValue = ($theValue !== "") ? intval($theValue) : ($default ? intval($default) : "NULL");
			break;
		case "bool":
			$theValue = ($theValue == "1" || $theValue == "on" || $theValue == "true") ? "1" : "0";
			break;
		case "float":
			$theValue = ($theValue !== "") ? floatval($theValue) : ($default ? floatval($default) : "NULL");
			break;
		case "brut":
			break;
	}

	return $theValue;
}

function UTF8List($list)
{
	foreach ($list as $k => $i) {
		$list[$k] = utf8_encode($i);
	}
	return $list;
}

//////////////////////////////////////////////////////////////////
// DBTools
//////////////////////////////////////////////////////////////////
class DBTools
{

	private static $connection;

	public static function getConnection()
	{
		if (isset(self::$connection)) {
			return self::$connection;
		} else {
			self::$connection = mysqli_connect(
				Configuration::getParameter("mysql_server"),
				Configuration::getParameter("mysql_user"),
				Configuration::getParameter("mysql_password"),
				Configuration::getParameter("mysql_database"),
				NULL,
				Configuration::getParameter("mysql_socket")
			);

			if (!self::$connection) {
				die('Erreur de connexions (' . mysqli_connect_errno() . ') ' . mysqli_connect_error());
			}
			mysqli_set_charset(self::$connection, "utf8");
			return self::$connection;
		}
	}

	//////////////////////////////////////////////////////////////////
	// EXECUTE QUERY
	//////////////////////////////////////////////////////////////////
	function execute($query)
	{
		global $session;
		$t1 = microtime(true);

		$result = mysqli_query(self::getConnection(), $query);
		$t2 = microtime(true);

		if (!$result) {
			$error = mysqli_error(self::getConnection());
			$this->addLog("SQL", $query . " (" . $error . ")");
			if ($session)
				$session->addDebug("(" . number_format(($t2 - $t1) * 1000, 4, ".", " ") . "ms) " . $query . " => <font color='red'>INVALID (" . $error . ")</font>");
			return NULL;
		} else {
			if ($session)
				$session->addDebug("(" . number_format(($t2 - $t1) * 1000, 4, ".", " ") . "ms) " . $query);
			return $result;
		}
	}

	//////////////////////////////////////////////////////////////////
	// ADD LOG
	//////////////////////////////////////////////////////////////////
	function addLog($type, $description, $user = null)
	{
		global $session;
		if ($user == null) {
			if (isset($session) && isset($session->user)) {
				$user = $session->user->getFullName();
			}
			if (!isset($user)) {
				$user = "-";
			}
		}

		// Insertion du nouveau log
		$todayis = date("Y-m-j H:i:s", time());
		$insert = sprintf(
			"INSERT INTO log (user, date, type, description) VALUES (%s, %s, %s, %s)",
			GetSQLValue($user, "text"),
			"TIMESTAMP '$todayis'",
			GetSQLValue($type, "text", "", "", false),
			GetSQLValue($description, "text", "", "", false)
		);
		mysqli_query(self::getConnection(), $insert);
	}


	//////////////////////////////////////////////////////////////////
	// GET WHERE QUERY
	//////////////////////////////////////////////////////////////////
	function getWhere($filters = NULL, $sort = "id desc", $limit1 = NULL, $limit2 = NULL, $prefix = "WHERE")
	{
		$query = "";
		if (isset($filters) && count($filters) > 0) {
			$query .= " $prefix ";
			$isFirst = true;
			foreach ($filters as $k => $v) {
				if (!$isFirst)
					$query .= " AND ";
				$query .= $v;
				$isFirst = false;
			}
		}
		if (isset($sort) && $sort != "") {
			$query .= " ORDER BY $sort";
		}
		if (isset($limit1) && isset($limit2) && is_numeric($limit1) && is_numeric($limit2)) {
			$query .= " LIMIT $limit1,$limit2";
		}
		return $query;
	}

	function insertId()
	{
		return mysqli_insert_id(self::getConnection());
	}
}
<?
require_once(dirname(__FILE__).'/file.php');

///////////////////////////////////////////////////////////////////////////////////////
// UPLOADER
///////////////////////////////////////////////////////////////////////////////////////
class Uploader{
	
	static function uploadDocument($filepath, $upload=NULL, $delete=false){
		global $session;
		$filepath = Configuration::getPathUpload().$filepath;				
		$list = array('application/pdf','application/force-download');
	  	if(isset($upload) || $delete){
	  		$session->addDebug("Remove file: {$filepath}");		
			unlink($filepath);
		}
		if(isset($upload)){
			return self::upload($filepath, $upload, $list, 4000000);
		}else{
			return false;
		}			
	}	
		
	static function uploadPhoto($filepath, $upload=NULL, $delete=false){
		global $session;
		$filepath = Configuration::getPathUpload().$filepath;	
		if((isset($upload) && $upload["size"] != 0 ) || $delete){
			$session->addDebug("Remove file: {$filepath}");
	     	array_map( "unlink", glob($filepath.".*"));			
		}
		if(isset($upload)){
			$t="jpg";
			if($upload["type"]=="image/gif")
				$t="gif";
			else if($upload["type"]=="image/png")
				$t="png";			
			$filepath = $filepath.".".$t;
			
			$list = array('image/jpeg', 'image/jpg', 'image/pjpeg', 'image/png');
			return self::upload($filepath, $upload, $list, 4000000);			
		}else{
			return false;
		}	
	}	

		static function uploadMedia($filepath, $upload=NULL, $delete=false){
		global $session;
		$filepath = Configuration::getPathUpload().$filepath;	
		if((isset($upload) && $upload["size"] != 0 ) || $delete){
			$session->addDebug("Remove file: {$filepath}");
	     	array_map( "unlink", glob($filepath.".*"));			
		}
		if(isset($upload)){
			$t="jpg";
			if($upload["type"]=="image/gif")
				$t="gif";
			else if($upload["type"]=="image/png")
				$t="png";			
			else if($upload["type"]=="video/mp4")
				$t="mp4";	
			else if($upload["type"]=="video/mpeg")
				$t="mpeg";	
			else if($upload["type"]=="video/x-msvideo")
				$t="avi";
			$filepath = $filepath.".".$t;
			
			$list = array('image/jpeg', 'image/jpg', 'image/pjpeg', 'image/png', 'video/mp4', 'video/mpeg','video/x-msvideo');
			return self::upload($filepath, $upload, $list, 20000000);			
		}else{
			return false;
		}	
	}
	

	static function upload($filepath, $upload=NULL, $acceptedTypes=NULL, $maxSize=10000000){
		
		global $session;
	  if (isset($filepath) && isset($upload) && $upload["size"] != 0 && $upload["size"]<=$maxSize) {
	    if (is_uploaded_file($upload['tmp_name'])){
				if(!$acceptedTypes || in_array($upload["type"], $acceptedTypes)) { 				
					move_uploaded_file($upload['tmp_name'], $filepath);
					$session->addDebug("Add file: {$filepath}");
					return true;
				}else{
					$session->addDebug("Refuse file: {$filepath} ".$upload["type"]);
				}
			}		
		}
		return false;
	}	
}


function deleteDir($dir, $delRoot=true){
	if (substr($dir, strlen($dir)-1, 1) != '/'){
		$dir .= '/';
	}
 	if($handle = opendir($dir)){
  	while ($obj = readdir($handle)){
			if ($obj != '.' && $obj != '..'){
				if (is_dir($dir.$obj)){
					if (!deleteDir($dir.$obj))
						return false;
				}elseif (is_file($dir.$obj)){
					if (!unlink($dir.$obj))
						return false;
				}
			}
		}
		closedir($handle);
		if($delRoot){
			if (!@rmdir($dir))
				return false;
		}
		return true;
	}
 	return false;
} 

?><?

/***************************************************************************
 * formatString
 ***************************************************************************/
function formatString($string, $max_words, $replaceBR = true)
{
	$string_array = explode(' ', strip_tags($string));
	if (count($string_array) > $max_words && $max_words > 0)
		$string = implode(' ', array_slice($string_array, 0, $max_words)) . '...';
	//$string = htmlspecialchars($string);
	if ($replaceBR)
		$string = nl2br($string);
	return $string;
}


function formatDate($sqlDate, $type = 1, $lang = "fr")
{
	if ($sqlDate) {
		$day = substr($sqlDate, 8, 2);
		$month = substr($sqlDate, 5, 2);
		$year = substr($sqlDate, 0, 4);
		$yearShort = substr($sqlDate, 0, 2);
		if ($lang == "fr") {
			$a = array("Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre");
			$b = array("Janv", "Fév", "Mars", "Avril", "Mai", "Juin", "Juil", "Août", "Sept", "Oct", "Nov", "Déc");
		} else if ($lang == "es") {
			$a = array("Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre");
			$b = array("Ene", "Feb", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Sept", "Oct", "Nov", "Dic");
		} else if ($lang == "it") {
			$a = array("Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre");
			$b = array("Gen", "Feb", "Marzo", "Apr", "Mag", "Giu", "Lug", "Ago", "Set", "Ott", "Nov", "Dic");
		} else {
			$a = array("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December");
			$b = array("Jan", "Feb", "March", "April", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec");
		}
		if ($type == 1) {
			if ($lang == "en")
				return $month . "-" . $day . "-" . $year;
			else
				return $day . "/" . $month . "/" . $year;
		} else if ($type == 2)
			return $day . " " . $a[intval($month) - 1];
		else if ($type == 3)
			return $a[intval($month) - 1] . " " . $year;
		else if ($type == 4) {
			return array($day, $b[intval($month) - 1]);
		} else if ($type == 5) {
			return intval($day) . " " . $a[intval($month) - 1] . " " . $year;
		} else if ($type == 6) {
			if ($lang == "en")
				return $month . "-" . $day . "-" . $year;
			else
				return $day . "/" . $month . "/" . $yearShort;
		} else {
			return $day . " " . $a[intval($month) - 1] . " " . $year;
		}
	}
	return "";
}

/**
 * Convert into filename by removing all accents and special characters. Useful for URL Rewriting.
 * @param $text
 * @return string
 */
function convertTextToUrl($text)
{
	// Remove all accents.
	$convertedCharacters = array(
		'À' => 'A',
		'Á' => 'A',
		'Â' => 'A',
		'Ã' => 'A',
		'Ä' => 'A',
		'Å' => 'A',
		'à' => 'a',
		'á' => 'a',
		'â' => 'a',
		'ã' => 'a',
		'ä' => 'a',
		'å' => 'a',
		'Ò' => 'O',
		'Ó' => 'O',
		'Ô' => 'O',
		'Õ' => 'O',
		'Ö' => 'O',
		'Ø' => 'O',
		'ò' => 'o',
		'ó' => 'o',
		'ô' => 'o',
		'õ' => 'o',
		'ö' => 'o',
		'ø' => 'o',
		'È' => 'E',
		'É' => 'E',
		'Ê' => 'E',
		'Ë' => 'E',
		'é' => 'e',
		'è' => 'e',
		'ê' => 'e',
		'ë' => 'e',
		'Ç' => 'C',
		'ç' => 'c',
		'Ì' => 'I',
		'Í' => 'I',
		'Î' => 'I',
		'Ï' => 'I',
		'ì' => 'i',
		'í' => 'i',
		'î' => 'i',
		'ï' => 'i',
		'Ù' => 'U',
		'Ú' => 'U',
		'Û' => 'U',
		'Ü' => 'U',
		'ù' => 'u',
		'ú' => 'u',
		'û' => 'u',
		'ü' => 'u',
		'ÿ' => 'y',
		'Ñ' => 'N',
		'ñ' => 'n'
	);

	$text = strtr($text, $convertedCharacters);

	// Put the text in lowercase.
	$text = mb_strtolower($text, 'utf-8');

	// Remove all special characters.
	$text = preg_replace('#[^a-z0-9\-]#', '-', $text);

	// Remove two consecutive dashes (that's not very pretty).
	$text = preg_replace('/--/U', '-', $text);
	$text = preg_replace('/--/U', '-', $text);
	return $text;
}

function formatStars($num)
{

	$html = "";
	for ($i = 1; $i <= $num; $i++) {
		$html .= "<span class='glyphicon glyphicon-star'></span> ";
	}
	return $html;
}

function minifyHtml($html)
{
	// Remove whitespace between tags, comments, and extra spaces
	$html = preg_replace('/\>[^\S ]+/s', '>', $html);
	$html = preg_replace('/[^\S ]+\</s', '<', $html);
	$html = preg_replace('/(\s)+/s', '\\1', $html);
	$html = preg_replace('/<!--.*?-->/s', '', $html); // Remove comments
	return trim($html);
}
