<?php
/*
=====================================================
 Модуль создал: REZER (http://rezer.net)
=====================================================
 Файл: board.class.php
=====================================================
 Данный код защищен авторскими правами
=====================================================
 Назначение: класс для работы с модулем
=====================================================
*/

if( !defined( "DATALIFEENGINE" ) ) die( "Hacking attempt!" );

class Board {
	
	var $Config = array();
	var $AllowOptionsType = array( "category", "country", "city", "currency", "board_type", "banners", "blocks" );
	var $Field = false;
	
	var $EchoCatOk = array();
	var $SpeedBar = array();
	var $ThreadCatForSql = array();
	var $Navigation = false;
	var $CacheDir = null;
	var $CacheSkin = null;
	var $AltUrl = false;
	var $LoadCityOk = array();
	var $JsCatSelect = false;
	var $EmailClass = false;
	var $EmailTpl = array();
	var $AllowSendEmail = array();
	
	//------------------------------------------------=-=-=-=-=
	//	Инициализация класса
	//------------------------------------------------=-=-=-=-=
	
	function Start(){
		global $is_logged, $member_id, $config;
		
		require( ENGINE_DIR."/data/board.config.php" );
		include( ENGINE_DIR."/data/board/cron.php" );
		
		$this->Config = $BoardConfig;
		$this->Cron = $BoardCronConfig;
		$this->CacheDir = ENGINE_DIR."/data/board/cache/";
		$this->CacheSkin = $config['skin'];
		$this->AllowSendEmail = $this->Config['echo_post_author_email'] ? explode( ",", $this->Config['echo_post_author_email'] ) : array();
		
		$this->AllowEditPost = ( in_array( $member_id['user_group'], explode( ",", $this->Config['post_groups_edit'] ) ) ) ? true : false;
		$this->AllowEditAllPost = ( in_array( $member_id['user_group'], explode( ",", $this->Config['post_groups_edit_all'] ) ) ) ? true : false;
		$this->AllowAddPost = ( in_array( $member_id['user_group'], explode( ",", $this->Config['post_groups_add'] ) ) ) ? true : false;
		$this->AllowAddPostCaptcha = ( in_array( $member_id['user_group'], explode( ",", $this->Config['post_groups_captcha'] ) ) ) ? true : false;
		$this->AllowAddPostNoDel = ( in_array( $member_id['user_group'], explode( ",", $this->Config['post_groups_no_del'] ) ) ) ? true : false;
		
		$this->AltUrl = $config['allow_alt_url'] == "yes" ? true : false;
		
		if( $this->Config['region_on'] != "on" )
			{
				unset( $this->AllowOptionsType[1] );
				unset( $this->AllowOptionsType[2] );
			}
			
		foreach( $this->AllowOptionsType as $type )
			{
				if( !file_exists( ENGINE_DIR."/data/board/{$type}.php" ) ) $this->CreateDB();
				include_once( ENGINE_DIR."/data/board/{$type}.php" );
			}
		
		$this->StartField();
		$this->Cron( 120, "cron_time", "CleareAllCache" );
	}
	
	//----------------------------------------------------------=-=-=-=-=
	//	Запуск класса доп. полей блогов
	//----------------------------------------------------------=-=-=-=-=
	
	function StartField( $Necessarily = false ){
		
		if( ( $this->Field === false && $this->Config['field_on'] == "on" ) || ( $Necessarily === true ) )
			{
				include( ENGINE_DIR."/inc/board/field.class.php" );
				$this->Field = new BoardField( ENGINE_DIR."/data/board/fields.board.db" );
			}
	}
	
	//------------------------------------------------=-=-=-=-=
	//	Сохранение конфигов
	//------------------------------------------------=-=-=-=-=
	
	function SaveConfig( $Opt = array(), $LastOpt, $NameOpt, $File, $title = "(Powered by REZER)", $Ajax = false ){
		
		$save_con = $Opt + $LastOpt;
		$handler = fopen( $File, "w" );
		fwrite( $handler, "<?php \n\n//{$title}\n\n{$NameOpt} = array (\n" );
		foreach( $save_con as $name => $value )
			{
				if( is_array( $value ) ) $value = implode( ",", $value );
				if( $Ajax === true && function_exists( "CharsetConvert" ) ) $value = CharsetConvert( $value );
				$value = addslashes( stripslashes( trim( str_replace( "\n", "<br />", str_replace( "\r", "", $value ) ) ) ) );
				fwrite( $handler, "\t\"{$name}\" => \"{$value}\",\n" );
			}
		fwrite( $handler, ");\n\n?>" );
		fclose( $handler );
	}
	
	//------------------------------------------------=-=-=-=-=
	//	Создание кэша альбомов (без фоток)
	//------------------------------------------------=-=-=-=-=
	
	function CreateDB(){
		global $db;
		
		foreach( $this->AllowOptionsType as $type ) @unlink( ENGINE_DIR."/data/board/{$type}.php" );
		$this->ClearCache( "../city/" );
		
		$AllowCity = array();
		$result = $db->query( "SELECT * FROM ".PREFIX."_board_options ORDER BY `sort`" );
		if( $db->num_rows( $result ) > 0 )
			{
				while( $row = $db->get_row( $result ) )
					{
						$ThisOpt = "";
						$id = $row['id'];
						$type = $row['type'];
						$sort = $row['sort'] > 0 ? intval( $row['sort'] ) : 1;
						$options = array();
						$alt_name = "";
						$ForArray = "";
						if( !in_array( $type, $this->AllowOptionsType ) ) continue;
						
						if( $row['options'] )
							{
								$row['options'] = explode( "|||", $row['options'] );
								foreach( $row['options'] as $opt )
									{
										$opt = explode( "=", $opt );
										$opt[0] = $this->FiletrForDb( $opt[0], "read" );
										$opt[1] = $this->FiletrForDb( $opt[1], "read" );
										$options[ $opt[0] ] = $opt[1];
									}
							}
								else
							{
								$options = array();
							}
							
						if( $options['alt_name'] ) $alt_name = addslashes( stripslashes( $options['alt_name'] ) );
						if( $alt_name ) $alt_name = "\n\$this->DBIndex['{$type}']['{$alt_name}'] = \"{$id}\";";
								
						if( $type == "city" && $options['country'] )
							{
								$options['country'] = intval( $options['country'] );
								$ForArray = "['".intval( $options['country'] )."']";
								//$AllowType[ $type ] .= "\n\$this->DBIndex['{$type}']['{$id}'] = \"{$options['country']}\";";
							}
							
						if( $type == "banners" ) $alt_name = "\n\$this->DBIndex['{$type}']['{$row['sort']}']['{$id}'] = \"{$id}\";";
						
						$ThisOpt .= "\t\"id\" => \"{$id}\",\n";
						$ThisOpt .= "\t\"type\" => \"{$type}\",\n";
						$ThisOpt .= "\t\"sort\" => \"{$sort}\",\n";
						foreach( $options as $name => $value )
							{
								$name = addslashes( stripslashes( $name ) );
								$value = addslashes( stripslashes( $value ) );
								$value = str_replace( "\$", "\\\$", $value );
								
								$ThisOpt .= "\t\"{$name}\" => \"{$value}\",\n";
							}
						
						if( $type == "city" )
							{
								$AllowCity[ $options['country'] ] .= "\$this->DB['{$type}']{$ForArray}['{$id}'] = array(\n{$ThisOpt});{$alt_name}\n\n";
							}
								else
							{
								$AllowType[ $type ] .= "\$this->DB['{$type}']{$ForArray}['{$id}'] = array(\n{$ThisOpt});{$alt_name}\n\n";
							}
					}
			}
		
		foreach( $this->AllowOptionsType as $type )
			{
				$Text = "<?php\n\nif( !defined( \"DATALIFEENGINE\" ) ) die( \"Hacking attempt!\" );\n\n".$AllowType[ $type ]."?>";
				$fp = fopen( ENGINE_DIR."/data/board/{$type}.php", "w+" );
				fwrite( $fp, $Text );
				fclose( $fp );
			}
			
		foreach( $AllowCity as $country_id => $row )
			{
				$Text = "<?php\n\nif( !defined( \"DATALIFEENGINE\" ) ) die( \"Hacking attempt!\" );\n\n".$AllowCity[ $country_id ]."?>";
				$fp = fopen( ENGINE_DIR."/data/board/city/city_{$country_id}.php", "w+" );
				fwrite( $fp, $Text );
				fclose( $fp );
			}
		
		unset( $AllowType );
		unset( $AllowCity );
	}
	
	function LoadListCity( $country_id ){
		
		if( $this->Config['region_on'] != "on" ) return false;
		$country_id = intval( $country_id );
		if( $country_id && !$this->LoadCityOk[ $country_id ] )
			{
				unset( $this->DB['city'][ $country_id ] );
				$file = ENGINE_DIR."/data/board/city/city_{$country_id}.php";
				if( file_exists( $file ) ) require( $file );
			}
	}
	
	//------------------------------------------------=-=-=-=-=
	// Отправка письма на почту
	//------------------------------------------------=-=-=-=-=
	
	function SendEmail( $template, $subject, $emailFrom, $emailTo, $options = array() ){
		global $db, $config;
		
		$template = $db->safesql( $template );
		if( !$this->EmailClass )
			{
				include( ENGINE_DIR."/classes/mail.class.php" );
				include( ENGINE_DIR."/data/board/tpl.email.php" );
				$this->EmailClass = new dle_mail( $config );
				$this->EmailTpl = $BoardEmail;
				if( $emailFrom != "" ) $this->EmailClass->from = $emailFrom;
			}
			
		if( empty( $template ) ) return false;
		if( empty( $subject ) ) return false;
		if( empty( $emailTo ) ) return false;
		
		$Template = stripslashes( $this->EmailTpl[ $template ] );
		if( empty( $Template ) ) return "Template not found";
		
		$options['domain'] = $_SERVER['HTTP_HOST'];
		foreach( $options as $name => $value ) $Template = str_replace( "%{$name}%", $value, $Template );
		$this->EmailClass->send( $emailTo, $subject, $Template );
		
		if( $this->EmailClass->send_error )
			return $this->EmailClass->smtp_msg;
		else
			return true;
	}
	
	//------------------------------------------------=-=-=-=-=
	//	Фильтр данный для сохранения в БД
	//------------------------------------------------=-=-=-=-=
	
	function FiletrForDb( $text, $type = "save" ){
		
		if( $type == "save" )
			{
				$text = str_replace( "\r", "", $text );
				$text = str_replace( "\n", "&567&", $text );
				$text = str_replace( "=", "&744&", $text );
				$text = str_replace( "|", "&421&", $text );
			}
				else
			{
				$text = str_replace( "&567&", "\n", $text );
				$text = str_replace( "&744&", "=", $text );
				$text = str_replace( "&421&", "|", $text );
			}
		
		return $text;
	}
	
	function ReplacePrice( $price ){
		
		$return = "";
		$price = str_replace( " ", "", $price );
		$price = "{$price}";
		if( strlen( $price ) < 4 ) return $price;
		
		$c = 0;
		for( $i = strlen( $price ); $i > 0; $i-- )
			{
				if( $c == 3 )
					{
						$return = $price[ ( $i - 1 ) ]." {$return}";
						$c = 1;
					}
						else
					{
						$return = $price[ ( $i - 1 ) ].$return;
						$c++;
					}
			}
		
		return $return;
	}
	
	function UpdateViews( $id ){
		global $db;
		
		$id = intval( $id );
		if( !$id ) return false;
		if( $this->Config['full_cache_views'] == "yes" )
			{
				$fp = fopen( ENGINE_DIR."/data/board/post.views.db", "a" );
				fwrite( $fp, "{$id}\n" );
				fclose( $fp );
				@chmod( ENGINE_DIR."/data/board/post.views.db", 0666 );
			}
				else
			{
				$db->query( "UPDATE ".PREFIX."_board_post SET `views`=views+1 WHERE `id`='{$id}'" );
			}
		
		return true;
	}
	
	function LastCommentsBlock(){
		global $db, $config, $lang, $tpl, $_TIME;
		
		$return = $this->OpenCache( "", "block.last_comm.tmp" );
		if( !$return )
			{
				$template = file_get_contents( $tpl->dir."/board/main/last.comments.tpl" );
				$result = $db->query( "SELECT ".PREFIX."_board_comments.id as com_id, ".PREFIX."_board_comments.board_id, ".PREFIX."_board_comments.author_id, ".PREFIX."_board_comments.author, ".PREFIX."_board_comments.text, ".PREFIX."_board_comments.ip, ".PREFIX."_board_comments.date, ".PREFIX."_board_post.id, ".PREFIX."_board_post.title, ".PREFIX."_board_post.alt_name, ".PREFIX."_board_post.category FROM ".PREFIX."_board_comments LEFT JOIN ".PREFIX."_board_post ON ".PREFIX."_board_comments.board_id=".PREFIX."_board_post.id WHERE ".PREFIX."_board_comments.del!='1' ORDER BY `date` DESC LIMIT 0,15" );
				if( $db->num_rows( $result ) > 0 )
					{
						while( $row = $db->get_row( $result ) )
							{
								$id = $row['id'];
								$title = stripslashes( $row['title'] );
								$alt_name = $row['alt_name'];
								$category = $row['category'];
								$author = stripslashes( $row['author'] );
								$author_id = intval( $row['author_id'] );
								$text = stripslashes( $row['text'] );
								$date = strtotime( $row['date'] );
								$full_link = $this->ReturnLinkPost( $id, $alt_name, $category );
								$authorLink = $config['allow_alt_url'] == "yes" ? "/user/".urldecode( $author )."/" : "/index.php?subaction=userinfo&user={$author}";
								
								// Работаем с датой
								if( date( "Ymd", $date ) == date( "Ymd", $_TIME ) )
									$date = $lang['time_heute'].langdate( ", H:i", $date );
								elseif( date( "Ymd", $date ) == date( "Ymd", ( $_TIME - 86400 ) ) )
									$date = $lang['time_gestern'].langdate( ", H:i", $date );
								else
									$date = langdate( $config['timestamp_comment'], $date );
								
								$forReturn = $template;
								$forReturn = str_replace( "{title}", $title, $forReturn );
								$forReturn = str_replace( "{author}", $author, $forReturn );
								$forReturn = str_replace( "{authorLink}", $authorLink, $forReturn );
								$forReturn = str_replace( "{text}", $text, $forReturn );
								$forReturn = str_replace( "{date}", $date, $forReturn );
								$forReturn = str_replace( "{full_link}", $full_link, $forReturn );
								
								$return .= $forReturn;
							}
					}
						else
					{
						$return = "Нет комментариев";	
					}
				
				$this->CreateCache( "", "block.last_comm.tmp", $return );
			}
		
		return $return;
	}
	
	function SetBanners( $type = "short", $position ){
		
		$return = "";
		if( $type == "short" )
			{
				if( count( $this->DBIndex['banners'][ $position ] ) > 0 )
					{
						foreach( $this->DBIndex['banners'][ $position ] as $id )
							{
								$code = stripslashes( $this->DB['banners'][ $id ]['code'] );
								$return .= $code;	
							}	
					}
			}
		
		return $return;
	}
	
	//------------------------------------------------=-=-=-=-=
	//	Разрешён ли тип для категории
	//------------------------------------------------=-=-=-=-=
	
	function notTypeForCat( $cat_id ){
		$noTypeForCat = true;
		foreach( $this->DB['board_type'] as $typeID => $typeRow )
			{
				$AllowCats = explode( ",", $typeRow['AllowCats'] );
				if( in_array( $cat_id, $AllowCats ) ) return false;
			}	
		
		return true;
	}
	
	function AllowTypeInCats( $type, $cat_id ){
		
		if( !$this->DB['board_type'][ $type ] ) return false;
		if( $this->DB['board_type'][ $type ]['AllowCats'] == "all" ) return true;
		
		$AllowCats = explode( ",", $this->DB['board_type'][ $type ]['AllowCats'] );
		if( in_array( $cat_id, $AllowCats ) ) return true;
		
		return false;		
	}
	
	//------------------------------------------------=-=-=-=-=
	//	Создание индекса всех категорий (кто в какой находится)
	//------------------------------------------------=-=-=-=-=
	
	function SetCategoryIndex(){
		
		$this->CategoryIndex = array();
		$this->CategoryOurIndex = array();
		if( count( $this->DB['category'] ) < 1 ) return false;
		foreach( $this->DB['category'] as $id => $row )
			{
				if( $row['cat'] != "" && $this->DB['category'][ $row['cat'] ] )
					{
						$this->CategoryIndex[ $row['cat'] ][] = $id;
						$this->CategoryOurIndex[ $id ] = true;
					}
			}
	}
	
	//------------------------------------------------=-=-=-=-=
	//	Проверка, находится ли какая-то категория, в другой категории (неограниченная вложенность)
	//------------------------------------------------=-=-=-=-=
	
	function InCat( $id, $not ){
		
		if( $id && $this->DB['category'][ $id ] )
			{
				if( $this->DB['category'][ $id ]['cat'] == $not )
					{
						return true;
					}
						else
					{
						if( $this->DB['category'][ $id ]['cat'] )
							{
								if( $this->InCat( $this->DB['category'][ $id ]['cat'], $not ) === true ) return true;
							}
					}					
			}
		
		return false;
	}
	
	//------------------------------------------------=-=-=-=-=
	//	Возвращение самой главной категории подкатегории
	//------------------------------------------------=-=-=-=-=
	
	function MainCat( $id ){
		if( $this->DB['category'][ $id ]['cat'] ) return $this->MainCat( $this->DB['category'][ $id ]['cat'] );
		return $id;
	}
	
	//------------------------------------------------=-=-=-=-=
	//	Возвращение списка категорий для выбора (<select>)
	//------------------------------------------------=-=-=-=-=
	
	function JSSelectCategory( $select = "" ){
		
		$return = "";
		$returnJS = "";
		if( count( $this->DB['category'] ) < 1 ) return false;
		if( !is_array( $this->CategoryIndex ) ) $this->SetCategoryIndex();
		
		foreach( $this->DB['category'] as $id => $row )
			{
				if( in_array( $id, $this->EchoCatOk ) ) continue;
				if( !$this->CategoryOurIndex[ $id ] )
					{
						$this->EchoCatOk[] = $id;
						$name = htmlspecialchars( stripslashes( $this->DB['category'][ $id ]['name'] ) );
						$returnJS .= "<div id=\"InCat_{$id}\" style=\"display: none;\"><select name=\"category\" id=\"BoardSelectCategory\" onkeyup=\"CategorySelect();\" onkeydown=\"CategorySelect();\" onchange=\"CategorySelect();\">".$this->SelectCategory( $select, "", -1, $id )."</select></div>";
						
						$selected = ( $this->JsCatSelect === true || $select == $id ) ? "selected=\"selected\"" : "";
						$this->JsCatSelect = false;
						
						$return .= "<option value=\"{$id}\" {$selected}>{$name}</option>";
					}
			}
		
		$JSFunction = <<<HTML
		
		var BoardAddStart = true;
		function BoardInCat(){
			var SelectCat = document.getElementById( "mainCat" ).value;
			if( SelectCat > 0 )
				{
					if( document.getElementById( "InCat_" + SelectCat ).innerHTML != "" )
						{
							document.getElementById( "BoardTextForInCat" ).innerHTML = document.getElementById( "InCat_" + SelectCat ).innerHTML;
						}
					
					if( BoardAddStart == true )
						BoardAddStart = false;
					else
						CategorySelect();
					return;
				}
			
			document.getElementById( "BoardTextForInCat" ).innerHTML = "";
		}
		
		BoardInCat();
			
HTML;
		
		$return = <<<HTML
		
		<select name="MainCategory" id="mainCat" onkeyup="BoardInCat();" onkeydown="BoardInCat();" onchange="BoardInCat();">
			{$return}
		</select>
		<span id="BoardTextForInCat">&nbsp;</span>
		
HTML;
		
		return array(
			"main"	=>	$return,
			"js"	=>	"{$returnJS}<script language=\"javascript\" type=\"text/javascript\">{$JSFunction}</script>",
		);
	}
	
	function SelectCategory( $selected = "", $not = "", $nbsp = "", $id = "", $all = false ){
		
		$return = "";
		if( count( $this->DB['category'] ) < 1 ) return false;
		if( !is_array( $this->CategoryIndex ) ) $this->SetCategoryIndex();
		
		if( !$id )
			{
				$this->EchoCatOk = array();
				
				if( $all === true )
					{
						if( !$selected || count( $selected ) == 0 )
							{
								$okSelected = "selected=\"selected\"";
							}
								else
							{
								if( is_array( $selected ) )
									$okSelected = ( in_array( "all", $selected ) ) ? "selected=\"selected\"" : "";
								else
									$okSelected = ( $selected == "all" ) ? "selected=\"selected\"" : "";
							}
						
						$return = "<option value=\"all\" {$okSelected}> - Все - </option>";
					}
					
				foreach( $this->DB['category'] as $id => $row )
					{
						if( in_array( $id, $this->EchoCatOk ) ) continue;
						if( !$this->CategoryOurIndex[ $id ] )
							{
								$return .= $this->SelectCategory( $selected, $not, $nbsp, $id );
							}
					}
			}
				else
			{
				if( is_array( $not ) )
					{
						foreach( $not as $SId )
							{
								if( $id == $SId ) return;
								if( $this->InCat( $id, $SId ) === true ) return;	
							}
					}
						else
					{
						if( $not == $id ) return;
						if( $not && $this->InCat( $id, $not ) === true ) return;
					}
					
				if( !$this->DB['category'][ $id ] ) return;
				
				if( !in_array( $id, $this->EchoCatOk ) )
					{
						$echoNbsp = "";
						for( $i = 0; $i < ( $nbsp * 4 ); $i++ ) $echoNbsp .= "&nbsp;";
						$echoNbsp = $echoNbsp ? "{$echoNbsp} " : "";
						
						if( is_array( $selected ) )
							$okSelected = ( in_array( $id, $selected ) ) ? "selected=\"selected\"" : "";
						else
							$okSelected = ( $selected == $id ) ? "selected=\"selected\"" : "";
						
						if( $okSelected != "" ) $this->JsCatSelect = true;
						$name = htmlspecialchars( stripslashes( $this->DB['category'][ $id ]['name'] ) );
						$return .= "<option value=\"{$id}\" {$okSelected}>{$echoNbsp}{$name}</option>";
						$this->EchoCatOk[] = $id;
					}
				
				if( count( $this->CategoryIndex[ $id ] ) > 0 )
					{
						foreach( $this->CategoryIndex[ $id ] as $NewID )
							{
								if( in_array( $NewID, $this->EchoCatOk ) ) continue;
								$return .= $this->SelectCategory( $selected, $not, ( $nbsp + 1 ), $NewID );
							}
					}
			}
		
		return $return;
	}
	
	//------------------------------------------------=-=-=-=-=
	//	Вывод всех категорий для админцентра
	//------------------------------------------------=-=-=-=-=
	
	function ReturnAdminCat( $nbsp = 0, $id = "" ){
		
		$return = "";
		if( count( $this->DB['category'] ) < 1 ) return false;
		if( !is_array( $this->CategoryIndex ) ) $this->SetCategoryIndex();
		
		if( !$id )
			{
				$this->EchoCatOk = array();
				foreach( $this->DB['category'] as $id => $row )
					{
						if( in_array( $id, $this->EchoCatOk ) ) continue;
						if( !$this->CategoryOurIndex[ $id ] )
							{
								$return .= $this->ReturnAdminCatForm( $row, $nbsp );
								if( count( $this->CategoryIndex[ $id ] ) > 0 ) $return .= $this->ReturnAdminCat( ( $nbsp + 1 ), $id );
							}
					}
			}
				else
			{
				if( count( $this->CategoryIndex[ $id ] ) < 1 ) return;
				foreach( $this->CategoryIndex[ $id ] as $NewID )
					{
						if( in_array( $NewID, $this->EchoCatOk ) ) continue;
						$return .= $this->ReturnAdminCatForm( $this->DB['category'][ $NewID ], $nbsp );
						if( count( $this->CategoryIndex[ $NewID ] ) > 0 ) $return .= $this->ReturnAdminCat( ( $nbsp + 1 ), $NewID );
					}
			}
			
		return $return;
	}
	
	function ReturnAdminCatForm( $row, $nbsp = 0 ){
		
		$return = "";
		$echoNbsp = "";
		for( $i = 0; $i < ( $nbsp * 4 ); $i++ )	$echoNbsp .= "-";
		$echoNbsp = $echoNbsp ? "{$echoNbsp} " : "";
		
		$id = $row['id'];
		$name = htmlspecialchars( stripslashes( $row['name'] ) );
		$alt_name = htmlspecialchars( stripslashes( $row['alt_name'] ) );
		$template = $row['template'] ? htmlspecialchars( stripslashes( $row['template'] ) ) : "---";
		$sort = intval( $row['sort'] );
		$link = $this->ReturnLinkCategory( $id );
		$BgColor = !$echoNbsp ? "#FCFDE3" : "#FFFFFF";
		$count_post = intval( $row['count_post'] );
				
$return = <<<HTML

<div id="del_Category_{$id}">
	<table width="100%" border="0">
		<tr height="30px" onmouseover="this.bgColor='#F1F7FE'" onmouseout="this.bgColor='{$BgColor}'" bgcolor="{$BgColor}">
			<td width="70px" align="center" id="StatusCategory_{$id}">{$id}</td>
			<td>
				{$echoNbsp}
				<a href="javascript:void(0);" onclick="EditCategory( '{$id}' ); return false;" title="Редактировать категорию" onmouseover="showhint( '<strong>Альт. имя:</strong> {$alt_name}<br /><strong>Шаблон:</strong> {$template}<br />', this, event, '250px')">{$name} ({$count_post})</a>
				<a href="{$link}" target="_blank" title="Перейти в категорию"><img src="engine/inc/board/style/images/next.png" alt="&rarr;" class="ImgNextLink" /></a>
			</td>
			<td width="100px" align="center">
				<input type="text" name="sort[{$id}]" value="{$sort}" style="text-align: center; width: 50px;" class="edit" />
			</td>
			<td width="100px" align="center">
				<a onclick="return dropdownmenu( this, event, MenuCategory( '{$id}' ), '120px')" href="javascript:void(0);">
					<img src="engine/skins/images/browser_action.gif" border="0">
				</a>
			</td>
			<td width="30px">
				<input type="checkbox" name="CheckCategory[]" value="{$id}" />
			</td>
		</tr>
		<tr>
			<td colspan="10" background="engine/skins/images/mline.gif" height="1"></td>
		</tr>
	</table>
</div>

HTML;
		$this->EchoCatOk[] = $id;
		return $return;
	}
	
	//------------------------------------------------=-=-=-=-=
	//	Возвращает ссылку на категорию
	//------------------------------------------------=-=-=-=-=
	
	function ReturnLinkCategory( $id, $onlyCat = false ){
		
		if( $this->AltUrl === false )
			{
				if( $this->DB['category'][ $id ]['alt_name'] )
					{
						$alt_name = $this->DB['category'][ $id ]['alt_name'];
						return "/index.php?do=board&action=boardcat&boardcat={$alt_name}";	
					}
						else
					{
						return "/index.php?do=board";	
					}
			}
		
		if( !$onlyCat )
			{
				$return = "/board/";
				$this->LinkCategory = array();
				$this->ReturnLinkCategory( $id, true );
				if( count( $this->LinkCategory ) > 0 )
					{
						$Cat = array();
						for( $i = ( count( $this->LinkCategory ) -1 ); $i >= 0; $i-- )
							{
								$Cat[] = $this->LinkCategory[ $i ];
							}
							
						$Cat = implode( "/", $Cat );
						$return .= "{$Cat}/";
					}
			}
				else
			{
				$return = "";
				if( $this->DB['category'][ $id ] ) $this->LinkCategory[] = $this->DB['category'][ $id ]['alt_name'];
				if( $this->DB['category'][ $id ]['cat'] && $this->DB['category'][ $this->DB['category'][ $id ]['cat'] ] ) $this->ReturnLinkCategory( $this->DB['category'][ $id ]['cat'], true );
			}
			
		return $return;		
	}
	
	//------------------------------------------------=-=-=-=-=
	//	Возвращает ссылку на категорию с уже сгенерированными html тегами
	//------------------------------------------------=-=-=-=-=
	
	function ReturnLinkHrefCategory( $id ){
		
		if( !$this->DB['category'][ $id ] ) return false;
		$CatName = htmlspecialchars( stripslashes( $this->DB['category'][ $id ]['name'] ) );
		$CatLink = $this->ReturnLinkCategory( $id );
		$return = "<a href=\"{$CatLink}\">{$CatName}</a>";
		
		return $return;
	}
	
	//------------------------------------------------=-=-=-=-=
	//	Возвращает ссылку на объявление
	//------------------------------------------------=-=-=-=-=
	
	function ReturnLinkPost( $id, $alt_name, $cat_id ){
		
		if( $this->AltUrl === true )
			{
				$cat_link = $this->ReturnLinkCategory( $cat_id );
				$return = "{$cat_link}{$id}-{$alt_name}.html";
			}
				else
			{
				$alt_name = $this->DB['category'][ $cat_id ]['alt_name'];
				$return = "/index.php?do=board&boardcat={$alt_name}&action=post&id={$id}";
			}
			
		return $return;
	}
	
	//------------------------------------------------=-=-=-=-=
	//	Возвращает ссылку на добавление объявления
	//------------------------------------------------=-=-=-=-=
	
	function ReturnLinkAddPost(){
		
		if( $this->AltUrl === true )
			{
				$return = $this->ReturnLinkCategory( $this->RequestCat )."add";
			}
				else
			{
				$alt_name = $this->DB['category'][ $this->RequestCat ]['alt_name'];
				$return = "/index.php?do=board&boardcat={$alt_name}&action=add";
			}
			
		return $return;
	}
	
	//------------------------------------------------=-=-=-=-=
	//	Генерация вывода категорий на главной модуля
	//------------------------------------------------=-=-=-=-=
	
	function ListAllCategory( $MainTemplate, $ThreadTemplate, $Columns = 1, $id = "" ){
		
		$i = 1;
		$return = "";
		$TdWidth = intval( 100 / $Columns );
		if( count( $this->DB['category'] ) < 1 ) return false;
		if( !is_array( $this->CategoryIndex ) ) $this->SetCategoryIndex();
		
		$this->EchoCatMainTemplate = $MainTemplate;
		$this->EchoCatThreadTemplate = $ThreadTemplate;
		
		foreach( $this->DB['category'] as $id => $row )
			{
				if( !$this->CategoryOurIndex[ $id ] )
					{
						$return .= "<td width=\"{$TdWidth}%\">".$this->GenerateTemplateCat( $id )."</td>";
						if( $i % $Columns == 0 ) $return .= "</tr><tr>";
						$i++;
					}
			}
				
		$return = "<table width=\"100%\" class=\"BoardMainCats\"><tr>{$return}</tr></table>";			
		return $return;
	}
	
	function GenerateTemplateCat( $id, $thread = false ){
		
		$return = "";
		if( !$thread )
			{
				$link = $this->ReturnLinkCategory( $id );
				$title = htmlspecialchars( stripslashes( $this->DB['category'][ $id ]['name'] ) );
				$icon = htmlspecialchars( stripslashes( $this->DB['category'][ $id ]['icon'] ) );
				$count_boards = intval( $this->DB['category'][ $id ]['count_post'] );
				
				$return = str_replace( "{link}", $link, $this->EchoCatMainTemplate );
				$return = str_replace( "{title}", $title, $return );
				$return = str_replace( "{count_boards}", $count_boards, $return );
				
				if( $icon )
					{
						$return = preg_replace( "#\\[icon\\](.+?)\\[/icon\\]#is", "\\1", $return );
						$return = str_replace( "{icon}", "{THEME}/board/style/{$icon}", $return );
					}
						else
					{
						$return = preg_replace( "#\\[icon\\](.+?)\\[/icon\\]#is", "", $return );
					}
				
				$countThread = count( $this->CategoryIndex[ $id ] );
				if( $countThread > 0 )
					{
						$return = preg_replace( "#\\[thread\\](.+?)\\[/thread\\]#is", "\\1", $return );
						$return = str_replace( "{content}", $this->GenerateTemplateCat( $id, true ), $return );					
					}
						else
					{
						$return = preg_replace( "#\\[thread\\](.+?)\\[/thread\\]#is", "", $return );
					}
			}
				else
			{
				$countThread = count( $this->CategoryIndex[ $id ] );
				$maxThread = intval( $this->Config['main_page_max_echo_thread_cats'] );
				if( $countThread )
					{
						if( $maxThread > 0 && $countThread >= $maxThread )
							{
								$Comma = array();
								foreach( $this->CategoryIndex[ $id ] as $NewId )
									{
										$title = htmlspecialchars( stripslashes( $this->DB['category'][ $NewId ]['name'] ) );
										$link = $this->ReturnLinkCategory( $NewId );
										$count_boards = intval( $this->DB['category'][ $NewId ]['count_post'] );
										$Comma[] = "<a href=\"{$link}\">{$title}</a> <span>({$count_boards})</span>";
									}
									
								$Comma = ( count( $Comma ) > 0 ) ? implode( ", ", $Comma ) : "";
								$return = $Comma;
							}
								else
							{
								foreach( $this->CategoryIndex[ $id ] as $NewId )
									{
										$ForReturn = "";
										$link = $this->ReturnLinkCategory( $NewId );
										$title = htmlspecialchars( stripslashes( $this->DB['category'][ $NewId ]['name'] ) );
										$icon = htmlspecialchars( stripslashes( $this->DB['category'][ $NewId ]['icon'] ) );
										$count_boards = intval( $this->DB['category'][ $NewId ]['count_post'] );
										
										$ForReturn = str_replace( "{link}", $link, $this->EchoCatThreadTemplate );
										$ForReturn = str_replace( "{title}", $title, $ForReturn );
										$ForReturn = str_replace( "{count_boards}", $count_boards, $ForReturn );
										
										if( $icon )
											{
												$ForReturn = preg_replace( "#\\[icon\\](.+?)\\[/icon\\]#is", "\\1", $ForReturn );
												$ForReturn = str_replace( "{icon}", "{THEME}/board/style/{$icon}", $ForReturn );
											}
												else
											{
												$ForReturn = preg_replace( "#\\[icon\\](.+?)\\[/icon\\]#is", "", $ForReturn );
											}
											
										if( count( $this->CategoryIndex[ $NewId ] ) > 0 )
											{
												$ForReturn = preg_replace( "#\\[thread\\](.+?)\\[/thread\\]#is", "\\1", $ForReturn );
												$ForReturn = str_replace( "{content}", $this->GenerateTemplateCat( $NewId, true ), $ForReturn );
											}
												else
											{
												$ForReturn = preg_replace( "#\\[thread\\](.+?)\\[/thread\\]#is", "", $ForReturn );
											}
											
										$return .= $ForReturn;
									}
							}
					}
			}
		
		return $return;
	}
	
	//------------------------------------------------=-=-=-=-=
	//	Генерация подкатегорий просматриваемой категории
	//------------------------------------------------=-=-=-=-=
	
	function GenerateTemplateThreadCat( $MainTemplate, $listTemplate, $id, $Columns = 3, $BoardType = "", $allReady = false ){
		
		if( !$id ) return false;
		if( !is_array( $this->CategoryIndex ) ) $this->SetCategoryIndex();
		
		$allCat = $this->Config['short_echo_category'] == "default" ? false : true;
		
		if( $this->Config['short_echo_category'] == "all_main_cat" && $allReady !== true ) $id = $this->MainCat( $id );
		if( $this->Config['short_echo_category'] == "all_cat" && $allReady !== true ) $id = $this->DB['category'][ $id ]['cat'] ? $this->DB['category'][ $id ]['cat'] : $id;
		
		if( $this->DB['category'][ $id ] )
			{
				$return = array();
				if( count( $this->CategoryIndex[ $id ] ) > 0 )
					{
						$i = 1;
						
						if( $allCat === true && $allReady !== true )
							{
								$CategoryIndex = array( $id );
								foreach( $this->CategoryIndex[ $id ] as $NewId ) $CategoryIndex[] = $NewId;
							}
								else
							{
								$CategoryIndex = $this->CategoryIndex[ $id ];
							}
						
						foreach( $CategoryIndex as $NewId )
							{
								if( $BoardType && $allCat === true && $this->AllowTypeInCats( $BoardType, $NewId ) !== true ) continue;
								$link = $this->ReturnLinkCategory( $NewId );
								$title = $id == $NewId ? "Все" : htmlspecialchars( stripslashes( $this->DB['category'][ $NewId ]['name'] ) );
								$count_boards = intval( $this->DB['category'][ $NewId ]['count_post'] );
								if( $BoardType && $allCat === true ) $link .= "type-{$BoardType}/";
								
								$ForReturn = str_replace( "{link}", $link, $listTemplate );
								$ForReturn = str_replace( "{title}", $title, $ForReturn );
								$ForReturn = str_replace( "{count_boards}", $count_boards, $ForReturn );
								
								$ForReturn = preg_replace( "#\\[active\\](.*?)\\[/active\\]#is", ( $NewId == $this->RequestCat ? "\\1" : "" ), $ForReturn );
								$ForReturn = preg_replace( "#\\[not-active\\](.*?)\\[/not-active\\]#is", ( $NewId == $this->RequestCat ? "" : "\\1" ), $ForReturn );
								
								if( $allCat === true && $id != $NewId )
									$ForReturn = str_replace( "{inCat}", $this->GenerateTemplateThreadCat( $MainTemplate, $listTemplate, $NewId, $Columns, $BoardType, true ), $ForReturn );
								else
									$ForReturn = str_replace( "{inCat}", "", $ForReturn );
								
								if( $allCat === true && $allReady !== true )
									{
										if( !is_array( $return[ $i ] ) ) $return[ $i ] = array();
										$return[ $i ][] = $ForReturn;
									}
										else
									{
										if( !$return[ $i ] ) $return[ $i ] = "";
										$return[ $i ] .= $ForReturn;
									}
								
								$i = ( $i == $Columns ) ? 1 : ( $i + 1 );
							}
						
						if( $allReady !== true )
							{
								$NewReturn = "";
								$TdWidth = intval( 100 / $Columns );
								
								if( $allCat === true )
									{
										$i = 1;
										foreach( $return as $array )
											{
												foreach( $array as $value )
													{
														$value = str_replace( "{list}", $value, $MainTemplate );
														$NewReturn .= "<td width=\"{$TdWidth}%\">{$value}</td>";
														if( $i % $Columns == 0 ) $NewReturn .= "</tr><tr>";
														$i++;
													}
											}
									}
										else
									{
										foreach( $return as $value )
											{
												$value = str_replace( "{list}", $value, $MainTemplate );
												$NewReturn .= "<td width=\"{$TdWidth}%\">{$value}</td>";
											}
									}
								
								$return = "<table width=\"100%\" border=\"0\"><tr>{$NewReturn}</tr></table>";
							}
								else
							{
								$return = implode( "", $return );
								$return = str_replace( "{list}", $return, $MainTemplate );
							}
					}
						else
					{
						$return = "";	
					}
			}
		
		return $return;
	}
	
	//------------------------------------------------=-=-=-=-=
	//	Возвращает готовый текст для сохранения в БД
	//------------------------------------------------=-=-=-=-=
	
	function CompileOpt( $opt ){
		
		unset( $opt['id'] );
		unset( $opt['type'] );
		unset( $opt['sort'] );
		
		$ReturnOpt = array();
		foreach( $opt as $name => $value )
			{
				$name = $this->FiletrForDb( $name );
				$value = $this->FiletrForDb( $value );
						
				$ReturnOpt[] = "{$name}={$value}";
			}
				
		$ReturnOpt = implode( "|||", $ReturnOpt );
		return $ReturnOpt;
	}
	
	//------------------------------------------------=-=-=-=-=
	//	Обновляет опции в БД
	//------------------------------------------------=-=-=-=-=
	
	function SaveBoardOpt( $row, $newRow, $id = "" ){
		global $db;
		
		$id = $id != "" ? intval( $id ) : intval( $row['id'] );
		if( !$id ) return false;
		
		$newRow = $newRow + $row;
		$SqlOpt = $db->safesql( $this->CompileOpt( $newRow ) );
		$db->query( "UPDATE ".PREFIX."_board_options SET `options`='{$SqlOpt}' WHERE `id`='{$id}' LIMIT 1" );
	}
	
	//------------------------------------------------=-=-=-=-=
	//	Возвращает список стран для выбора
	//------------------------------------------------=-=-=-=-=
	
	function ReturnSelectCountry( $select = "" ){
		
		$return = "";
		if( count( $this->DB['country'] ) > 0 )
			{
				foreach( $this->DB['country'] as $id => $row )
					{
						$name = htmlspecialchars( stripslashes( $row['name'] ) );
						$selected = ( $select == $id ) ? "selected=\"selected\"" : "";
						
						$return .= "<option value=\"{$id}\" {$selected}>{$name}</option>";
					}
			}
		
		return $return;
	}
	
	//------------------------------------------------=-=-=-=-=
	//	Возвращает список городов для выбора
	//------------------------------------------------=-=-=-=-=
	
	function ReturnSelectCity( $CountryID, $select = "" ){
		
		$return = "";
		if( count( $this->DB['city'][ $CountryID ] ) > 0 )
			{
				foreach( $this->DB['city'][ $CountryID ] as $id => $row )
					{
						$name = htmlspecialchars( stripslashes( $row['name'] ) );
						$selected = ( $select == $id ) ? "selected=\"selected\"" : "";
						
						$return .= "<option value=\"{$id}\" {$selected}>{$name}</option>";
					}
			}
		
		return $return;
	}
	
	//------------------------------------------------=-=-=-=-=
	//	Возвращает список типов предложений для выбора и добавлении объявления
	//------------------------------------------------=-=-=-=-=
	
	function JSType(){
		
		$JSReturn = "var BoardTypeCat = [];\nvar BoardTypeName = [];\n";
		$TypeName = array();
		if( count( $this->DB['category'] ) < 1 ) return false;
		if( count( $this->DB['board_type'] ) < 0 ) return false;
		foreach( $this->DB['category'] as $catID => $row )
			{
				$forJS = array();
				foreach( $this->DB['board_type'] as $id => $row )
					{
						if( $this->AllowTypeInCats( $id, $catID ) !== true ) continue;
						$forJS[] = $id;
						if( !$TypeName[ $id ] ) $TypeName[ $id ] = htmlspecialchars( stripslashes( $row['name'] ) );
					}
				
				$forJS = implode( ",", $forJS );
				$JSReturn .= "BoardTypeCat['{$catID}'] = [{$forJS}];\n";
			}
		
		$JSTypeName = "";
		foreach( $TypeName as $id => $name ) $JSTypeName .= "BoardTypeName[{$id}] = \"{$name}\";\n";		
		return "<script language=\"javascript\" type=\"text/javascript\">{$JSReturn}\n{$JSTypeName}\nBoardTypeSetCategory();</script>";
	}
	
	//------------------------------------------------=-=-=-=-=
	//	Возвращает список типов предложений для выбора
	//------------------------------------------------=-=-=-=-=
	
	function ReturnSelectBoardType( $select = "", $catID = "" ){
		
		$return = "";

		if( count( $this->DB['board_type'] ) > 0 )
			{
				foreach( $this->DB['board_type'] as $id => $row )
					{
						if( $catID != "" )
							{
								if( $this->AllowTypeInCats( $id, $catID ) !== true ) continue;	
							}
						
						$name = htmlspecialchars( stripslashes( $row['name'] ) );
						$selected = ( $select == $id ) ? "selected=\"selected\"" : "";
						
						$return .= "<option value=\"{$id}\" {$selected}>{$name}</option>";
					}
			}
		
		return $return;
	}
	
	//------------------------------------------------=-=-=-=-=
	//	Возвращает список валют для выбора
	//------------------------------------------------=-=-=-=-=
	
	function ReturnSelectCurrency( $select = "" ){
		
		$return = "";
		if( count( $this->DB['currency'] ) > 0 )
			{
				foreach( $this->DB['currency'] as $id => $row )
					{
						$name = htmlspecialchars( stripslashes( $row['name'] ) );
						$symbol = htmlspecialchars( stripslashes( $row['symbol'] ) );
						$selected = ( $select == $id ) ? "selected=\"selected\"" : "";
						
						$return .= "<option value=\"{$id}\" {$selected}>{$name} ({$symbol})</option>";
					}
			}
		
		return $return;
	}
	
	//------------------------------------------------=-=-=-=-=
	//	Определение ID просматриваемой категории
	//------------------------------------------------=-=-=-=-=
	
	function DefinitionCat(){
		
		$cat = $_REQUEST['boardcat'];
		if( $cat )
			{
				$cat = explode( "/", $cat );
				$cat = end( $cat );
				if( $this->DBIndex['category'][ $cat ] )
					{
						$this->RequestCat = $this->DBIndex['category'][ $cat ];
						return true;
					}
			}
		
		return false;
	}
	
	//------------------------------------------------=-=-=-=-=
	//	Возвращает информацию для генерации метатитлов и спидбара просматриваемой категории
	//------------------------------------------------=-=-=-=-=
	
	function SpeedBarCat( $id, $Clear = true ){
		
		if( $Clear === true ) $this->SpeedBar = array();
		if( $this->DB['category'][ $id ] )
			{
				$title = htmlspecialchars( stripslashes( $this->DB['category'][ $id ]['name'] ) );
				$link = $this->ReturnLinkCategory( $id );
				$this->SpeedBar[] = array(
					"title"		=> $title,
					"link"		=> $link,
					"id"		=> $id							
				);
						
				if( $this->DB['category'][ $id ]['cat'] && $this->DB['category'][ $this->DB['category'][ $id ]['cat'] ] ) $this->SpeedBarCat( $this->DB['category'][ $id ]['cat'], false );
			}
		
		return $this->SpeedBar;
	}
	
	//------------------------------------------------=-=-=-=-=
	//	Возвращает массив с ID всех подкатегорий просматриваемой категории
	//------------------------------------------------=-=-=-=-=
	
	function SqlThreadCat( $id ){
		
		if( !$id ) return false;
		if( !is_array( $this->CategoryIndex ) ) $this->SetCategoryIndex();
		if( $this->DB['category'][ $id ] )
			{
				$this->ThreadCatForSql[] = $id;
				if( count( $this->CategoryIndex[ $id ] ) > 0 )
					{
						foreach( $this->CategoryIndex[ $id ] as $NewID )
							{
								$this->SqlThreadCat( $NewID );
							}
					}
			}
		
		return $this->ThreadCatForSql;
	}
	
	//------------------------------------------------=-=-=-=-=
	//	Фильтрация текста для начала поиска
	//------------------------------------------------=-=-=-=-=
	
	function FilterSearchText( $text ){
		$quotes = array( "\x27", "\x22", "\x60", "\t", "\n", "\r", "'", ",", "/", "¬", ";", ":", "@", "~", "[", "]", "{", "}", "=", ")", "(", "*", "&", "^", "%", "$", "<", ">", "?", "!", '"', "|" );
		$goodquotes = array( "-", "+", "#" );
		$repquotes = array( "\-", "\+", "\#" );
		$text = stripslashes( $text );
		$text = trim( strip_tags( $text ) );
		$text = str_replace( $quotes, "", $text );
		$text = str_replace( $goodquotes, $repquotes, $text );
		return $text;
	}
	
	//----------------------------------------------------------=-=-=-=-=
	//	Генерация ссылок для навигации
	//----------------------------------------------------------=-=-=-=-=
	
	function CreateNavigation( $url, $page, $total, $tpl = "navigation.tpl", $ajax = "", $result = "board" ){
		
		if( !$this->Navigation )
			{
				require( ENGINE_DIR."/modules/board/navigation.class.php" );
				$this->Navigation = new BoardNavigation;
			}
			
		$this->Navigation->URL = $url;
		$this->Navigation->Page = $page;
		$this->Navigation->Total = $total;
		$this->Navigation->Tpl = $tpl;
		$this->Navigation->AjaxURL = $ajax;
		$this->Navigation->Compile = $result;
		if( $ajax ) $this->Navigation->Ajax = true;	
		
		$this->Navigation->BuildNavigation();
	}
	
	function NotepadPost( $id, $span = true ){
		global $is_logged, $member_id;
		
		$return = "";
		if( $is_logged )
			{
				if( $member_id['board_notepad'] )
					{
						$Notepad = explode( ",", $member_id['board_notepad'] );
						if( in_array( $id, $Notepad ) )
							{
								$return = "<a href=\"javascript:void(0);\" onclick=\"BoardNotepad( '{$id}', 'del' ); return false;\">Удалить из блокнота</a>";
							}
					}
				
				if( !$return ) $return = "<a href=\"javascript:void(0);\" onclick=\"BoardNotepad( '{$id}', 'add' ); return false;\">Добавить в блокнот</a>";
				if( $span === true ) $return = "<span id=\"BoardPostNotepad_{$id}\">{$return}</span>";
			}
			
		return $return;
	}
	
	//----------------------------------------------------------=-=-=-=-=
	//	Генерация списка <select> из массива
	//----------------------------------------------------------=-=-=-=-=
	
	function SelectList( $list, $select = "" ){
	
		if( is_array( $list ) )
			{
				foreach( $list as $name => $value )
					{
						if( is_array( $select ) )
							{
								if( in_array( $name, $select ) ) $selected = "selected"; else $selected = "";
							}
								else
							{
								if( $name == $select ) $selected = "selected"; else $selected = "";	
							}
							
						$return .= "<option value=\"{$name}\" {$selected}>{$value}</option>\n";	
					}
					
				return $return;
			}
			
		return false;
	}
	
	function AllowEditPost( $author_id, $approve ){
		global $is_logged, $member_id;
		
		if( !$is_logged ) return false;
		if( $this->AllowEditAllPost === true ) return true;
		if( $this->AllowEditPost !== true ) return false;
		if( $author_id == $member_id['user_id'] ) return true;
		
		return false;
	}
	
	function AllowAddPost(){
		global $is_logged, $member_id;
		
		if( !$is_logged ) return false;
		if( $this->AllowAddPost === true ) return true;
		
		return false;
	}
	
	function AddPostCategory( $CategoryID ){
		
		$InCat = $this->SpeedBarCat( $CategoryID );
		
		$fp = fopen( ENGINE_DIR."/data/board/post.cat.count.db", "a" );
		foreach( $InCat as $row )
			{
				$CatID = $row['id'];
				fwrite( $fp, "{$CatID}|plus\n" );
			}
		
		fclose( $fp );
	}
	
	function DelPostCategory( $CategoryID ){
		
		$InCat = $this->SpeedBarCat( $CategoryID );
		
		$fp = fopen( ENGINE_DIR."/data/board/post.cat.count.db", "a" );
		foreach( $InCat as $row )
			{
				$CatID = $row['id'];
				fwrite( $fp, "{$CatID}|minus\n" );
			}
		
		fclose( $fp );
	}
	
	function ReplaceTagBlock( $Opt, $text, $Not ){
		global $action;
		
		if( !$Opt ) return null;
		$Opt = explode( ",", $Opt );
		return ( ( in_array( $action, $Opt ) && $Not != "Not" ) || ( !in_array( $action, $Opt ) && $Not == "Not" ) ) ? stripslashes( $text ) : null;
	}
	
	function ReplaceTagBlockCat( $Cats, $text, $Not ){
		global $action;
		
		if( !$Cats ) return null;
		$Cats = explode( ",", $Cats );
		return ( ( in_array( $this->RequestCat, $Cats ) && $Not != "Not" ) || ( !in_array( $this->RequestCat, $Cats ) && $Not == "Not" ) ) ? stripslashes( $text ) : null;
	}
	
	//------------------------------------------------=-=-=-=-=
	//	Изображение к объявлению
	//------------------------------------------------=-=-=-=-=
	
	function ParsePhotosNews( $text, $images ){
		
		if( $images )
			{
				$i = 1;
				$all = "";
				$allBig = "";
				$images = explode( "|||", $images );
				foreach( $images as $img )
					{
						$img = explode( "###", $img );	
						$Photo = "/uploads/board/post/{$img[1]}/{$img[0]}";
						$PhotoThumb = "/uploads/board/post/{$img[1]}/thumbs/{$img[0]}";
						
						$hs = "<a href=\"{$Photo}\" target=\"_blank\" onclick=\"return hs.expand(this)\"><img src=\"{$PhotoThumb}\" alt=\"\" /></a>";
						$all .= "<div class=\"BoardPhoto BoardPhoto-{$i}\">{$hs}</div>";
						$allBig .= "<div class=\"BoardPhoto BoardPhoto-{$i}\"><a href=\"{$Photo}\" target=\"_blank\" onclick=\"return hs.expand(this)\"><img src=\"{$Photo}\" alt=\"\" /></a></div>";
						$text = str_replace( "{image:{$i}}", $hs, $text );
						$text = str_replace( "{image:{$i}->link}", $Photo, $text );
						$text = str_replace( "{image:{$i}->thumb}", $PhotoThumb, $text );
						$text = preg_replace( "#\\[not-image:{$i}\\](.+?)\\[/not-image:{$i}\\]#is", "", $text );
						$text = preg_replace( "#\\[image:{$i}\\](.+?)\\[/image:{$i}\\]#is", "\\1", $text );
						$i++;
					}
					
				$text = str_replace( "{image:all}", $all, $text );
				$text = str_replace( "{image:all->big}", $allBig, $text );
				$text = preg_replace( "#\\[not-image\\](.+?)\\[/not-image\\]#is", "", $text );
				$text = preg_replace( "#\\[image\\](.+?)\\[/image\\]#is", "\\1", $text );
			}
		
		$text = str_replace( "{image:all}", "<div class=\"BoardNotImages\">Нет изображений</div>", $text );
		$text = preg_replace( "/{image:(.+?)}/i", "", $text );
		$text = preg_replace( "#\\[not-image:(.+?)\\](.+?)\\[/not-image:(.+?)\\]#is", "\\2", $text );
		$text = preg_replace( "#\\[image:(.+?)\\](.+?)\\[/image:(.+?)\\]#is", "", $text );
		$text = preg_replace( "#\\[not-image\\](.+?)\\[/not-image\\]#is", "\\1", $text );
		$text = preg_replace( "#\\[image\\](.+?)\\[/image\\]#is", "", $text );
		return $text;		
	}
	
	function CompileImages(){
		$imageArr = $this->ArrayListPhotos();
		$this->CleareOnlyDBImages();
		
		$return = array();
		if( count( $imageArr ) > 0 )
			{
				foreach( $imageArr as $img )
					{
						$return[] = "{$img[0]}###{$img[1]}";
					}
				
				$return = implode( "|||", $return );
			}
				else
			{
				$return = "";	
			}
		
		return $return;
	}
	
	function BoardNewsImages( $row, $template, $mainTemplate, $array = false, $admin = false ){
		global $member_id, $is_logged;
		
		$listImg = "";
		$CountPhotos = 0;
		$imgArray = $this->ArrayListPhotos( $row );
		if( count( $imgArray ) > 0 )
			{
				foreach( $imgArray as $img )
					{
						$Photo = "/uploads/board/post/{$img[1]}/{$img[0]}";
						$PhotoThumb = "/uploads/board/post/{$img[1]}/thumbs/{$img[0]}";
						$tpl = str_replace( "{photo}", "<a href=\"{$Photo}\" target=\"_blank\" onclick=\"return hs.expand(this)\"><img src=\"{$PhotoThumb}\" alt=\"\" /></a>", $template );
						
						$tpl = str_replace( "[del]", "<a href=\"javascript:void(0);\" onclick=\"DelBoardPhoto( '{$img[0]}', '{$row['id']}' ); return false;\">", $tpl );
						$tpl = str_replace( "[/del]", "</a>", $tpl );
						$tpl = "<div id=\"{$img[0]}\">{$tpl}</div>";
						
						$listImg .= $tpl;
						$CountPhotos++;
					}	
			}
				else
			{
				$listImg = "Нет загруженных фотографий";
			}
		
		$listImg = str_replace( "{photos}", $listImg, $mainTemplate );
		$dle_skin = $admin === true ? "" : "skin : dle_skin,";
		$admin = $admin === true ? "admin: 1," : "";
		$JSPostID = $row['id'] ? $row['id'] : "\"\"";
		$returnJS = <<<HTML
		
			<script type="text/javascript" src="/engine/ajax/board/ajaxupload.js"></script>
			<script language="javascript" type="text/javascript">
				var BoardCountPhotos = {$CountPhotos};
				function BoardUploadPhotos(){
					$(function(){
						var btnUpload = $( "#BoardUploadPhotos" );
						var status = $( "#StatusBoardUploadPhotos" );
						new AjaxUpload( btnUpload, {
							action: "/engine/ajax/board/news.photos.php",
							name: 	"Filedata",
								
							data: {
								ajax : 1,
								upload : 1,
								{$admin}
								{$dle_skin}
								PostID: {$JSPostID},
							},
					
							onSubmit: function( file, ext ){
								status.html( "Загрузка, пожалуйста подождите..." );
							},
								
							onComplete: function( file, response ){
									
								status.html( "" );
								if( BoardCountPhotos == 0 ) $( "#BoardImages" ).html( "" );
								$( "#BoardImages" ).html( document.getElementById( "BoardImages" ).innerHTML + response );
								BoardCountPhotos++;
							}
						});
							
					});
				}
					
				function DelBoardPhoto( Photo, PostID ){
						
					var Quest = confirm( "Вы уверены, что хотите удалить данную фотографию?" );
					if( Quest )
						{
							if( !PostID ) PostID = "";
							ShowLoading( "" );
							$.ajax({
								url: "/engine/ajax/board/news.photos.php",
								data: "del=1&Photo=" + Photo + "&PostID=" + PostID,
								success: function( data ){
									
									HideLoading( "" );
									if( data )
										{
											alert( data );
										}
											else
										{
											var DelElement = document.getElementById( Photo );
											DelElement.parentNode.removeChild( DelElement );
											BoardCountPhotos--;
											if( BoardCountPhotos <= 0 )
												{
													$( "#BoardImages" ).html( "Нет загруженных фотографий" );
												}
										}
								},
								dataType: "html",
								type: "POST"
							});
						}
				}
				BoardUploadPhotos();
			</script>
		
HTML;
		
		return $array === true ? array( "list" => $listImg, "js" => $returnJS ) : $listImg.$returnJS;		
	}
	
	function CountImages( $images = "" ){
		global $is_logged, $member_id;
		
		if( $images ) return count( explode( "|||", $images ) );
		
		$return = 0;
		$fileDB = ENGINE_DIR."/data/board/photos.db";
		$img = file( $fileDB );
		if( count( $img ) > 0 )
			{
				$user = !$is_logged ? $_SERVER['REMOTE_ADDR'] : $member_id['name'];
				foreach( $img as $image )
					{
						$image = explode( "==", $image );
						if( $image[0] != $user ) continue;
						$return++;
					}
			}
		
		return $return;
	}
	
	function ArrayListPhotos( $row = "" ){
		global $is_logged, $member_id;
		
		$edit = false;
		$return = array();
		if( $row['id'] )
			{
				$edit = true;
				$img = $row['photos'] != "" ? explode( "|||", $row['photos'] ) : array();
			}
				else
			{
				$fileDB = ENGINE_DIR."/data/board/photos.db";
				$img = file( $fileDB );
			}
				
		if( count( $img ) > 0 )
			{
				$user = !$is_logged ? $_SERVER['REMOTE_ADDR'] : $member_id['name'];
				foreach( $img as $image )
					{
						if( $edit === true )
							{
								$image = explode( "###", $image );
								$return[] = array( $image[0], $image[1] );
							}
								else
							{
								$image = explode( "==", $image );
								if( $image[0] != $user ) continue;
								$image[1] = explode( "|||", $image[1] );
										
								$return[] = array( $image[1][0], $image[1][1] );
							}
					}
			}
		
		return $return;
	}
	
	function AddPhotosInfoDB( $photo, $folder, $row = "" ){
		global $member_id, $is_logged, $config, $db;
		
		if( $row['id'] )
			{
				$photos = $row['photos'] != "" ? explode( "|||", $row['photos'] ) : array();
				$photos[] = "{$photo}###{$folder}";
				$photos = $db->safesql( implode( "|||", $photos ) );
				$db->query( "UPDATE ".PREFIX."_board_post SET `photos`='{$photos}' WHERE `id`='{$row['id']}'" );
				return true;
			}
		
		$added_time = time() + ( $config['date_adjust'] * 60 );
		$date = date( "Y-m-d H:i:s", $added_time );
		$fileDB = ENGINE_DIR."/data/board/photos.db";
		
		$user = !$is_logged ? $_SERVER['REMOTE_ADDR'] : $member_id['name'];
		$fp = fopen( $fileDB, "a" );
		fwrite( $fp, "{$user}=={$photo}|||{$folder}|||{$date}\n" );
		fclose( $fp );
		@chmod( $fileDB, 0666 );
	}
	
	function CleareOnlyDBImages(){
		global $member_id, $is_logged;
		
		$fileDB = ENGINE_DIR."/data/board/photos.db";
		$user = !$is_logged ? $_SERVER['REMOTE_ADDR'] : $member_id['name'];
		$file = file( $fileDB );
		$CountDBPhotos = count( $file );
		for( $i = 0; $i < $CountDBPhotos; $i++ )
			{
				$image = explode( "==", $file[ $i ] );
				if( $image[0] != $user ) continue;
				unset( $file[ $i ] );
			}	
				
		unlink( $fileDB );
		$fp = fopen( $fileDB, "a" );
		fwrite( $fp, implode( "", $file ) );
		fclose( $fp );
		@chmod( $fileDB, 0666 );
	}
	
	function CleareTimeDBImages(){
		global $config;
		
		$thisTime = time() + ( $config['date_adjust'] * 60 );
		$fileDB = ENGINE_DIR."/data/board/photos.db";
		$file = file( $fileDB );
		$CountDBPhotos = count( $file );
		for( $i = 0; $i < $CountDBPhotos; $i++ )
			{
				$image = explode( "==", $file[ $i ] );
				$image[1] = explode( "|||", $image[1] );
				$imgTime = strtotime( $image[1][2] );
								
				if( ( ( $thisTime - $imgTime ) / 60 ) < $Board->Config['add_post_photo_del'] ) continue;
				
				@unlink( ROOT_DIR."/uploads/board/post/{$image[1][1]}/{$image[1][0]}" );
				@unlink( ROOT_DIR."/uploads/board/post/{$image[1][1]}/thumbs/{$image[1][0]}" );
				
				unset( $file[ $i ] );
			}	
				
		@unlink( $fileDB );
		$fp = fopen( $fileDB, "a" );
		fwrite( $fp, implode( "", $file ) );
		fclose( $fp );
		@chmod( $fileDB, 0666 );
	}
	
	//------------------------------------------------=-=-=-=-=
	//	Работа с кэшэм
	//------------------------------------------------=-=-=-=-=
	
	// Чтение кэша
	function OpenCache( $Folder = "", $File, $Page = 0 ){
		
		$File = str_replace( "..", "", $File );
		if( $Page > $this->MaxPageCache ) return false;
		if( $Page > 1 ) $File = "page{$Page}_{$File}";
		if( !file_exists( $this->CacheDir.$Folder.$this->CacheSkin."_".$File ) ) return false;
		
		return @file_get_contents( $this->CacheDir.$Folder.$this->CacheSkin."_".$File );		
	}
	
	// Создание кэша
	function CreateCache( $Folder, $File, $Text, $Page = 0 ){
		
		$File = str_replace( "..", "", $File );
		if( empty( $Text ) ) return false;
		if( $Page > $this->MaxPageCache ) return false;
		if( $Page > 1 ) $File = "page{$Page}_{$File}";
		
		@unlink( $this->CacheDir.$File );
		$fp = fopen( $this->CacheDir.$Folder.$this->CacheSkin."_".$File, "w+");
		fwrite( $fp, $Text );
		fclose( $fp );
		@chmod( $this->CacheDir.$Folder.$this->CacheSkin."_".$File, 0666 );
	}
	
	// Очистка кэша в конкретной папке
	function ClearCache( $Folder, $FileSearch = false ){
		
		$i = 0;
		$OpenDir = opendir( $this->CacheDir.$Folder );
		while( $File = readdir( $OpenDir ) )
			{
				if( $FileSearch !== false )
					{
						if( is_array( $FileSearch ) )
							{
								foreach( $FileSearch as $StrPos )
									{
										if( is_integer( $StrPos ) ) $StrPos = (string) $StrPos;
										if( strpos( $File, $StrPos ) !== false )
											{
												if( @unlink( $this->CacheDir.$Folder.$File ) ) $i++;
												break;
											}
									}
							}
								else
							{
								if( is_integer( $FileSearch ) ) $FileSearch = (string) $FileSearch;
								if( strpos( $File, $FileSearch ) !== false )
									{
										if( @unlink( $this->CacheDir.$Folder.$File ) ) $i++;
									}
							}
					}
						else
					{
						if( @unlink( $this->CacheDir.$Folder.$File ) ) $i++;
					}
			}
		
		return $i;
	}
	
	// Обновление просмотра страниц
	function ClearCacheCountPost(){
		global $db;
		
		$FileOpen = ENGINE_DIR."/data/board/post.cat.count.db";
		if( file_exists( $FileOpen ) )
			{
				$IDView = array();
				$File = file( $FileOpen );
				foreach( $File as $value )
					{
						$value = explode( "|", trim( $value ) );
						$id = intval( $value[0] );
						$type = $value[1];
						if( $id )
							{
								$IDView[] = $id;
								$this->DB['category'][ $id ]['count_post'] = intval( $this->DB['category'][ $id ]['count_post'] );
								if( $type == "plus" )
									$this->DB['category'][ $id ]['count_post']++;
								else
									$this->DB['category'][ $id ]['count_post']--;
							}
					}
				
				if( count( $IDView ) > 0 )
					{
						foreach( $IDView as $id )
							{
								$Options = $db->safesql( $this->CompileOpt( $this->DB['category'][ $id ] ) );
								$db->query( "UPDATE ".PREFIX."_board_options SET `options`='{$Options}' WHERE `id`='{$id}' LIMIT 1" );
							}
					}
				
				unset( $IDView );
				@unlink( $FileOpen );
			}
	}
	
	// Крон ( 1 - время в минутах, 2 - уникальный префикс, 3 - папки которые необходимо очищать, 4 - запуск функции класса )
	function Cron( $Period, $CronName, $OpenMethod = "" ){
		global $db, $config;
		
		$Period = $Period * 60;
		$ThisTime = ( time() + ( $config['date_adjust'] * 60 ) );
		if( ( $this->Cron[ $CronName ] + $Period ) < $ThisTime )
			{
				if( $OpenMethod && method_exists( $this, $OpenMethod ) ) $this->$OpenMethod();
				$this->CronUpdate( array( $CronName => $ThisTime ) );
			}
	}
	
	// Обновление статистики крона
	function CronUpdate( $Update = array() ){
		
		$SaveOpt = $Update + $this->Cron;
		$fp = fopen( ENGINE_DIR."/data/board/cron.php", "w+" );
		fwrite( $fp, "<?php\n\n//Задачи кронов модуля Board (Powered by REZER)\n\n\$BoardCronConfig = array(\n" );
		foreach( $SaveOpt as $Name => $Value )
			{
				$Name = addslashes( stripslashes( $Name ) );
				$Value = addslashes( stripslashes( $Value ) );
				
				fwrite( $fp, "\t\"{$Name}\" => \"{$Value}\",\n" );
			}
		
		fwrite( $fp, ");\n\n?>" );
		fclose( $fp );
	}
	
	// Очистка всего кэша
	function CleareAllCache(){
		
		$NotDelFile = array( ".", "..", ".htaccess", "fields.board.db", "photos.db", "cron.php", "post.cat.count.db", "post.views.db", "tpl.email.php" );
		$dir = opendir( ENGINE_DIR."/data/board/" );
		while( $file = readdir( $dir ) )
			{
				if( !in_array( $file, $NotDelFile ) )
					{
						@unlink( ENGINE_DIR."/data/board/".$file );
					}
			}
		
		$this->DelAutoPost();
		$this->emailPayFunction();
		$this->UpdateVip();
		$this->UpdateSuperVip();
		$this->UpdateColor();
		$this->UpdateDBViews();
		$this->ClearCacheCountPost();
		$this->CleareTimeDBImages();
		$this->ClearCache( "" );
		$this->ClearCache( "category/" );
		$this->ClearCache( "rss/" );
		//$this->ClearCache( "../city/" );
	}
	
	function DelAutoPost(){
		global $db, $config;
		
		$added_time = time() + ( $config['date_adjust'] * 60 );
		$NowDateTime = date( "Y-m-d H:i:s", $added_time );
		
		$result = $db->query( "SELECT `id`,`category`,`alt_name`,`author_id`,`title` FROM ".PREFIX."_board_post WHERE `end_date` <= '{$NowDateTime}' AND `no_del`!='1'" );
		if( $db->num_rows( $result ) > 0 )
			{
				while( $row = $db->get_row( $result ) )
					{
						$id = $row['id'];
						$this->DelPostCategory( $row['category'] );
						$db->query( "DELETE FROM ".PREFIX."_board_comments WHERE `board_id`='{$id}'" );
						$db->query( "DELETE FROM ".PREFIX."_board_post WHERE `id`='{$id}' LIMIT 1" );
						
						if( in_array( "on_create", $this->AllowSendEmail ) )
							{
								$rowUser = $db->super_query( "SELECT `name`,`email` FROM ".USERPREFIX."_users WHERE `user_id`='{$row['author_id']}'" );
								if( $rowUser['email'] )
									{
										$this->SendEmail( "send_on_del", "Ваше объявление удалено", "", $rowUser['email'], array(
											"title"			=> stripslashes( $row['title'] ),
											"user"			=> stripslashes( $rowUser['name'] ),
										) );
									}
							}
					}
			}
	}
	
	function emailPayFunction(){
		global $db, $config;
		
		$thisTime = time() + ( $config['date_adjust'] * 60 );
		if( in_array( "on_create", $this->AllowSendEmail ) )
			{
				$result = $db->query( "
					SELECT
						p.id, p.title, p.alt_name, p.category, p.vip_date, p.super_vip_date, p.color_date,
						u.email as email, u.name as user_name
					FROM ".PREFIX."_board_post as p
					LEFT JOIN ".USERPREFIX."_users as u ON (p.author_id = u.user_id)
					WHERE ( `vip_date` < '{$thisTime}' AND `vip_date`!='' ) OR ( `super_vip_date` < '{$thisTime}' AND `vip_date`!='' ) OR ( `color_date` < '{$thisTime}' AND `vip_date`!='' )
				" );
				if( $db->num_rows( $result ) > 0 )
					{
						while( $row = $db->get_row( $result ) )
							{
								if( $row['email'] )
									{
										$payFunction = array();
										if( $row['vip_date'] && $row['vip_date'] < $thisTime ) $payFunction[] = "VIP";
										if( $row['super_vip_date'] && $row['super_vip_date'] < $thisTime ) $payFunction[] = "Super VIP";
										if( $row['color_date'] && $row['color_date'] < $thisTime ) $payFunction[] = "Выделение цветом";
										$payFunction = implode( ", ", $payFunction );
										if( !$payFunction ) continue;
										$this->SendEmail( "send_on_del_pay", "У вашего объявления сняты платные функции", "", $row['email'], array(
											"title"			=> stripslashes( $row['title'] ),
											"link"			=> "http://".$_SERVER['HTTP_HOST'].$this->ReturnLinkPost( $row['id'], $row['alt_name'], $row['category'] ),
											"user"			=> stripslashes( $row['user_name'] ),
											"function_name"	=> $payFunction,
										) );
									}
							}	
					}
			}
	}
	
	function UpdateVip(){
		global $db, $config;
		
		$thisTime = time() + ( $config['date_adjust'] * 60 );		
		$db->query( "UPDATE ".PREFIX."_board_post SET `vip_date`='' WHERE `vip_date` < '{$thisTime}'" );
	}
	
	function UpdateSuperVip(){
		global $db, $config;
		
		$thisTime = time() + ( $config['date_adjust'] * 60 );
		$db->query( "UPDATE ".PREFIX."_board_post SET `super_vip_date`='' WHERE `super_vip_date` < '{$thisTime}'" );
	}
	
	function UpdateColor(){
		global $db, $config;
		
		$thisTime = time() + ( $config['date_adjust'] * 60 );
		$db->query( "UPDATE ".PREFIX."_board_post SET `color_date`='' WHERE `color_date` < '{$thisTime}'" );
	}
	
	function UpdateDBViews(){
		global $db;
		
		$FileOpen = ENGINE_DIR."/data/board/post.views.db";
		if( file_exists( $FileOpen ) )
			{
				$IDView = array();
				$File = file( $FileOpen );
				foreach( $File as $id )
					{
						$id = intval( $id );
						if( $id ) $IDView[ $id ]++;
					}
				
				if( count( $IDView ) > 0 )
					{
						$AllowID = array();
						$SqlIDView = "";
						foreach( $IDView as $id => $count )
							{
								$SQLIDView .= "WHEN id='{$id}' THEN views + {$count} ";
								$AllowID[] = $id;
							}
						
						$AllowID = implode( ",", $AllowID );
						$db->query( "UPDATE ".PREFIX."_board_post SET views = CASE {$SQLIDView} END WHERE id IN ({$AllowID})" );
					}
				
				unset( $IDView );
				unset( $AllowID );
				unset( $SqlIDView );
				@unlink( $FileOpen );
			}
	}
}

$Board = new Board;
$Board->Start();

?>