<?php
/*
* @package LabCMS
* @copyright (c) 2006 Alexander Levin aka Loki (loki_angel@mail.ru)
* @support http://labcms.ru
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*/

function echo_mem()
{
	$current=xdebug_memory_usage();
	echo $current-$GLOBALS['usage']."<br />";
	$GLOBALS['usage']=$current;
}

//боремся с magic_quotes
function stripslashes_deep($value)
{
	if ( is_array($value) ) {
		$value = array_map('stripslashes_deep', $value);
	} elseif ( !empty($value) && is_string($value) ) {
		$value = stripslashes($value);
	}
	return $value;
}

function filterNullInSuperglobals()
{
	$_POST = filterNullRecurcive($_POST);
	$_GET = filterNullRecurcive($_GET);
	$_COOKIE = filterNullRecurcive($_COOKIE);
	$_REQUEST = filterNullRecurcive($_REQUEST);
}

function filterNullRecurcive($value)
{
	if ( is_array($value) ) {
		$value = array_map('filterNullRecurcive', $value);
	} elseif ( !empty($value) && is_string($value) ) {
		$value = str_replace("\0", '', $value);
	}
	return $value;
}

function _debug($v, $group="message", $color=null, $tip=null)
{
	Debug_HackerConsole_Main::out($v, $group, $color, $tip);
}

function _m($key, $context=null)
{
	return Lang_Generic::gettext($key, $context);
}

function _nm($key1, $key2, $key3, $num, $context=null)
{
	return Lang_Generic::ngettext($key1, $key2, $key3, $num, $context);
}

/**
 * функция определяющая права доступа к функциям
 *
 * @param string $rules
 * @return boolean
 * @author Loki
 */
function access($rules)
{
	return config::access($rules);
}


function _url($params=array(), $action='', $type='', $href='', $redirect='', $token=false)
{
	if ($token) $token=User::i()->token;
	return Url::create($params, $action, $type, $href, $redirect, $token);
}

/**
 * рекурсивно копирует каталог $sourse в  $destination
 *
 * @param text, text
 * @return
 * @author Loki
 * в настоящий момент не используется. Если не понадобится - надо удалить.
 */
function recurse_copy($sourse, $destination)
{
	$error="";
	if (!file_exists($destination)) {
		@chmod(dirname($destination), 0777);
		if (!@mkdir($destination)) return "Не удалось создать директорию $destination";
		chmod($destination, 0777);
	}
		$files = scandir($sourse);
	foreach ($files as $file) {
		if ($file!="." && $file!="..") {
			if (is_file($sourse.$file)) {
				if (!file_exists($destination.$file)) {
					if (!@copy($sourse.$file, $destination.$file)) return "Не удалось скопировать файл $destination$file";
				}
			} else {
				$error=recurse_copy($sourse.$file."/", $destination.$file."/");
				if ($error) return $error;
			}
		}
	}
}

//подсветка поисковых фраз
function highlight($word, $srchstr)
{
	if ($srchstr=="") return $word;
	if (!is_array($srchstr)) {
		$srchstr=explode(" ", preg_replace('/[\s]+/u', ' ', trim($srchstr)));
	}
	$stemmer = Factory::create('Stem_Ru');
	foreach ($srchstr as $val) {
		$val=$stemmer->stem_word($val);
		$word = preg_replace(
			'/([а-яa-z0-9]*'.preg_quote($val, "/").'[а-яa-z0-9]*)/iu', '<span class="forum_hl">\\1</span>', $word
		);
	}
	return $word;
}

function refresh($text='', $url=false, $time=0)
{
	if (!$url) $url=$_SERVER['PHP_SELF'];
	if ($text || headers_sent()) {
		echo '
			<html>
				<head>
					<meta http-equiv="refresh" content="'.$time.';url='.htmlspecialchars($url).'" />
					<style type="text/css">
						.alert-success {
							background-color: #D9EDF7;
							border-color: #BCE8F1;
							border-radius: 4px 4px 4px 4px;
							color: #3A87AD;
							font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
							font-size: 14px;
							padding: 15px;
							margin:20%;
							font-weight: bold;
						}
					</style>
				</head>
				<body>
					<div class="alert-success">'.$text.'</div>
				</body>
			</html>';
	}
	else header('Location:'.$url);
	exit;
}


/**
 * Перевод кирилицы в транслит
 *
 * @param string
 * @return string
 * @author Loki
 */
function translit($st)
{
	$rus_letters=array( 'ж',  'ц',  'ч', 'ш',  'щ',	'ь', 'ю',  'я',  'ї', 'є',
						'Ж',  'Ц',  'Ч', 'Ш',  'Щ',	'Ь', 'Ю',  'Я',  'Ї', 'Є',
						'а', 'б', 'в', 'г', 'д', 'е', 'ё', 'з', 'и', 'й', 'к',
						'л', 'м', 'н', 'о', 'п', 'р', 'с', 'т', 'у', 'ф', 'х', 'ъ', 'ы', 'э',
						'А', 'Б', 'В', 'Г', 'Д', 'Е', 'Ё', 'З', 'И', 'Й', 'К',
						'Л', 'М', 'Н', 'О', 'П', 'Р', 'С', 'Т', 'У', 'Ф', 'Х', 'Ъ', 'Ы', 'Э');
	$eng_letters=array(	'zh', 'ts', 'ch', 'sh', 'shch', '',  'yu', 'ya', 'i', 'ie',
						'ZH', 'TS', 'CH', 'SH', 'SHCH', '',  'YU', 'YA', 'I', 'IE',
						'a', 'b', 'v', 'g', 'd', 'e', 'e', 'z', 'i', 'i', 'k', 'l',
						'm', 'n', 'o', 'p', 'r', 's', 't', 'u', 'f', 'h', '',  'y', 'e',
						'A', 'B', 'V', 'G', 'D', 'E', 'E', 'Z', 'I', 'I', 'K', 'L',
						'M', 'N', 'O', 'P', 'R', 'S', 'T', 'U', 'F', 'H', '',  'Y', 'E');
	$st=str_replace($rus_letters, $eng_letters, $st);

	return $st;
}
/**
 * Приведение url в съедобный вид. 
 *
 * @param string
 * @return string
 * @author Loki
 */
function convert_url($st)
{
	$st=mb_strtolower($st);
	$st=translit($st);
	if (mb_strpos($st, "/")!==0) $st="/".$st;
	$st=trim($st);
	$st=preg_replace('#[^a-z0-9/]+#u', '_', $st);
	$st = preg_replace('%/+%', '/', $st);
	if (strlen($st)>1) $st = preg_replace('%/$%i', '', $st);
	return $st;
}

/**
* Отдает xml feed. Пока реализован rss2.0
*
* @param array
* @param string
* @author Loki
*/
function feed($feed_data)
{
	$result=genereteFeed($feed_data);
	sendXmlHeaders();
	Tpl::i()->assign('_component', $result);
	LabVars::$template='blank.tpl';
}


function sendXmlHeaders()
{
	Header("Content-Type: application/xml; charset=utf-8;");	
}

function getServerName()
{
	$protocol=($_SERVER['SERVER_PORT']==443)?'https':'http';
	$port=(!in_array($_SERVER['SERVER_PORT'], array(80, 443)))?':'.$_SERVER['SERVER_PORT']:'';
	return $protocol.'://'.$_SERVER['SERVER_NAME'].$port;
}

function genereteFeed($feed_data)
{
	//тут формируем $xml

	$rss = Factory::create(
		'Rss',
		(!empty($feed_data['title']))?$feed_data['title']:false,
		(!empty($feed_data['link']))?$feed_data['link']:false,
		(!empty($feed_data['description']))?$feed_data['description']:false,
		(!empty($feed_data['language']))?$feed_data['language']:'ru-ru',
		(!empty($feed_data['pubDate']))?$feed_data['pubDate']:false,
		(!empty($feed_data['lastBuildDate']))?$feed_data['lastBuildDate']:false,
		(!empty($feed_data['managingEditor']))?$feed_data['managingEditor']:false,
		(!empty($feed_data['webMaster']))?$feed_data['webMaster']:false
	);
	if (!isset($feed_data['allowed_tags'])) {
		$feed_data['allowed_tags']=array(
			'<b>', '<strong>', '<i>', '<u>', '<p>', '<li>', '<br>', '<ul>', '<a>', '<img>', '<blockquote>'
		);
	}
		
	if (isset($feed_data['feed']) && is_array($feed_data['feed'])) {
		foreach ($feed_data['feed'] as $tmp) {
			$tmp['description']=strip_tags($tmp['description'], implode('', $feed_data['allowed_tags']));
			$tmp['description']=preg_replace(
				'/(src|href)=("|\')?\//', "$1=$2".config::get('core.siteUrl')."/", $tmp['description']
			);
			$rss->addItem(
				(!empty($tmp['title']))?$tmp['title']:false,
				(!empty($tmp['link']))?$tmp['link']:false,
				(!empty($tmp['description']))?$tmp['description']:false,
				(!empty($tmp['pubDate']))?$tmp['pubDate']:false,
				(!empty($tmp['guid']))?$tmp['guid']:false
			);
		}
	}
	return $rss->saveXML();
}



/**
* Возвращает массив возможных начертаний логина
*
* @param string
* @return array
* @author Loki
*/
function possible_logins($login)
{
	$eng=array('a', '6', 'e', 'k', 'o', 'p', 'c', 'y', 'x', 'A', 'B', 'E', 'K', 'M', 'H', 'O', 'P', 'C', 'T', 'X');
	$rus=array('а', 'б', 'е', 'к', 'о', 'р', 'с', 'у', 'х', 'А', 'В', 'Е', 'К', 'М', 'Н', 'О', 'Р', 'С', 'Т', 'Х');
	$login=preg_replace('/\s+/', ' ', trim($login));
	$result[]=$login;
	$result[]=str_replace($eng, $rus, $login);
	$result[]=str_replace($rus, $eng, $login);
	return $result;
}

function rmdir_recurse($file)
{
	if (is_dir($file) && !is_link($file)) {
		foreach (glob($file.'/*') as $sf) {
			if (!rmdir_recurse($sf)) return false;
		}
		return rmdir($file);
	} else {
		return unlink($file);
	}
}

function getbb($string, $mode='')
{
	//класс для работы с bbcode
	$mode=explode(',', str_replace(' ', '', $mode));
	
	$bb=Factory::create('bbcode');
	if (count($mode)) foreach ($mode as $action) {
		switch($action) {
			case('nolinks'):
				// Отключаем автоматические ссылки:
				$bb->autolinks = false;
				//отключаем запрещенные теги
				unset($bb->tags['url']);
				unset($bb->tags['img']);
				//отключаем смайлики
				$bb->mnemonics=array();
				break;
			
			case('nourls'):
				// Отключаем автоматические ссылки:
				$bb->autolinks = false;
				//отключаем запрещенные теги
				unset($bb->tags['url']);
				unset($bb->tags['img']);
				break;
		}
	}
	$bb->parse($string);
	return $bb->get_html();
}

function bbcode_smiles_js($x=4, $y=4)
{
	//класс для работы с bbcode
	return bbcode::smiles_js($x, $y);
}

function get_formatted_filesize($fs)
{
	if ($fs >= 1073741824)
	$fs = round($fs / 1073741824, 2) . " "._m("Гб");
	elseif ($fs >= 1048576)
	$fs = round($fs / 1048576, 2) . " "._m("Мб");
	elseif ($fs >= 1024)
	$fs = round($fs / 1024, 2) . " "._m("Кб");
	else
	$fs = $fs . " "._m("б");
	return $fs;
}

function isNotBot($key='')
{
	if ($key) exit();
	return true;
}

/**
 * Function cuts string with the HTML tags by the specified number of chars and strips empty HTML tags from the output.
 *
 * @param string $txt text to cut
 * @param int $len number of chars to keep in the resulting string
 * @param string $delim optional string of the stop-chars,
 * @used to split the text when limit reached in the middle of the current word
 * @return string
 * @author Ilya Lebedev
 */
function breakword($txt, $len, $delim='\s;,.!?:#')
{
	$txt = preg_replace_callback(
		"#(</?[a-z]+(?:>|\s[^>]*>)|[^<]+)#mi",
		create_function(
			'$a',
			'static $len = '.$len.';'
			.'$len1 = $len-1;'
			.'$delim = \''.str_replace("#", "\\#", $delim).'\';'
			.'if ($len<=0) return "";'
			.'if ("<" == $a[0]{0}) return $a[0];'
			.'$res = preg_split("#(.{0,$len1}+(?=[$delim]))|(.{0,$len}[^$delim]*)#ms",$a[0],2,PREG_SPLIT_DELIM_CAPTURE);'
			.'if ($res[1]) { $len -= strlen($res[1])+1; $res = $res[1];}'
			.'else		 { $len -= strlen($res[2]); $res = $res[2];}'
			//.'$res = rtrim($res);/*preg_replace("#[$delim]+$#m","",$res);*/'
			.'return $res;'
		),
		$txt
	);
	while (preg_match("#<([a-z]+)[^>]*>\s*</\\1>#mi", $txt)) {
		$txt = preg_replace("#<([a-z]+)[^>]*>\s*</\\1>#mi", "", $txt);
	}
	return $txt;
}

function getFreq($time)
{
	$changefreq='always';
	if ($time<time()-3600) $changefreq='hourly';
	if ($time<time()-3600*24) $changefreq='daily';
	if ($time<time()-3600*24*7) $changefreq='weekly';
	if ($time<time()-3600*24*30) $changefreq='monthly';
	if ($time<time()-3600*24*365) $changefreq='yearly';
	return $changefreq;
}

function canonicalPath($path)
{
	// resolve relative path 
	if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $path)) {
		$_path = rtrim($cwd, '/\\') . DS . ltrim($path, '/\\'); 
	} else {
		$_path = $path; 
	} 
	// don't we all just love windows? 
	$_path = str_replace('\\', '/', $_path); 
	// resolve simples 
	$_path = preg_replace('#(/\./(\./)*)|/{2,}#', '/', $_path); 
	// resolve parents 
	while (true) {
		$_parent = strpos($_path, '/../'); 
		if ($_parent === false) {
			break;
		} elseif ($_parent === 0) {
			$_path = substr($_path, 3); 
			break;
		} 
		$_pos = strrpos($_path, '/', $_parent - strlen($_path) -1); 
		if ($_pos === false) {
			// don't we all just love windows? 
			$_pos = $_parent; 
		}
		$_path = substr_replace($_path, '', $_pos, $_parent + 3 - $_pos); 
	}
	if (DS != '/') {
		// don't we all just love windows? 
		$_path = str_replace('/', '\\', $_path); 
	}
	// this is only required for directories 
	$_path = rtrim($_path, '/\\');
	return $_path;
}

function getModulePath($module)
{
	return LabCMS::i()->getModuleNodePath($module);
}

function addBreadcrumb($name=false, $path=false, $html=false)
{
	$result=array();
	$result['path']=$path;
	if ($html) $result['name_html']=$name;
	else $result['name']=$name;
	LabVars::$breadcrumb[]=$result;
}

function real_json_encode($a=false)
{
	if (is_null($a)) return 'null';
	if ($a === false) return 'false';
	if ($a === true) return 'true';
	if (is_scalar($a)) {
		if (is_float($a)) {
			// Always use "." for floats.
			return floatval(str_replace(",", ".", strval($a)));
		}
		
		if (is_string($a)) {
			static $jsonReplaces = array(
				array("\\", "/", "\n", "\t", "\r", "\b", "\f", '"'),
				array('\\\\', '\\/', '\\n', '\\t', '\\r', '\\b', '\\f', '\"')
			);
			return '"' . str_replace($jsonReplaces[0], $jsonReplaces[1], $a) . '"';
		} else
			return $a;
	}
	$isList = true;
	for ($i = 0, reset($a); $i < count($a); $i++, next($a)) {
		if (key($a) !== $i) {
			$isList = false;
			break;
		}
	}
	$result = array();
	if ($isList) {
		foreach ($a as $v) $result[] = real_json_encode($v);
		return '[' . join(',', $result) . ']';
	} else {
		foreach ($a as $k => $v) $result[] = real_json_encode($k).':'.real_json_encode($v);
		return '{' . join(',', $result) . '}';
	}
}

function getApiModules($method)
{
	$modules=Db::i()->select("SELECT module, name FROM ?_modules ORDER BY name");
	$result=array();
	foreach ($modules as $module) {
		if (file_exists(LAB_PATH_MODULES.'/'.$module['module'].'/class.api.php')) {
			$obj=Factory::create($module['module'].'.api');
			if ($obj->isImplemented($method)) $result[$module['module']]=$module['name'];
		}
	}
	return $result;
}

function write_ini_file($file_name, $data)
{
	$ini='';
	foreach ($data as $section=>$vars) {
		if (is_array($vars)) {
			$ini.="[".$section."]\n";
			foreach ($vars as $var=>$value) {
				$ini.=$var.' = "'.$value."\";\n";
			}
		} else
			$ini.=$section.' = "'.$vars."\";\n";
	}
	if (file_put_contents($file_name, $ini)) {
		return true;
	} else {
		die("Ошибка при сохранения файла настроек!");
	}
	return false;
}

function build_cache_keys($keys, $before = '', $after = '')
{
	$result=array();
	foreach ($keys as $key => $value) {
		$result[$value] = $before . $value . $after;
	}
	return $result;
}

function array_sort_by_keys($array, $keys)
{
	$result=array();
	foreach ($keys as $key) {
		if (isset($array[$key])) {
			$result[$key] = $array[$key];
		}
	}
	return $result;
}


if (!function_exists('inet_ntop')) {
	function inet_ntop($ip)
	{
		if (strlen($ip)==4) {
			// ipv4
			list(, $ip)=unpack('N', $ip);
			$ip=long2ip($ip);
		} elseif (strlen($ip)==16) {
			// ipv6
			$ip=bin2hex($ip);
			$ip=substr(chunk_split($ip, 4, ':'), 0, -1);
			$ip=explode(':', $ip);
			$res='';
			foreach ($ip as $seg) {
				while($seg{0}=='0') $seg=substr($seg, 1);
				if ($seg!='') {
					$res.=($res==''?'':':').$seg;
				} else {
					if (strpos($res, '::')===false) {
						if (substr($res, -1)==':') continue;
						$res.=':';
						continue;
					}
					$res.=($res==''?'':':').'0';
				}
			}
			$ip=$res;
		}
		return $ip;
	}
}

if (!function_exists('inet_pton')) {
	function inet_pton($ip)
	{
		
		if (strpos($ip, '.') !== FALSE) {# ipv4
			$ip = pack('N', ip2long($ip));
		} elseif (strpos($ip, ':') !== FALSE) {# ipv6
			$ip = explode(':', $ip);
			$res = str_pad('', (4*(8-count($ip))), '0000', STR_PAD_LEFT);
			foreach ($ip as $seg) {
				$res .= str_pad($seg, 4, '0', STR_PAD_LEFT);
			}
			$ip = pack('H'.strlen($res), $res);
		}
		return $ip;
	}
}
