<?php
/*---------------------------------------------\
|											   |
| Author:       Andrey Brykin (Drunya)         |
| Version:      1.5.0                          |
| Project:      CMS                            |
| package       CMS Fapos                      |
| subpackege    News Module                    |
| copyright     ©Andrey Brykin 2010-2011       |
|----------------------------------------------|
|											   |
| any partial or not partial extension         |
| CMS Fapos,without the consent of the         |
| author, is illegal                           |
|----------------------------------------------|
| Любое распространение                        |
| CMS Fapos или ее частей,                     |
| без согласия автора, является не законным    |
\---------------------------------------------*/



Class NewsModule extends Module {

	/**
	* @module_title  title of module
	*/
	public $module_title = 'Новости';
	/**
	* @template  layout for module
	*/
	public $template = 'news';
	/**
	* @module module indentifier
	*/
	public $module = 'news';
	
	



	function index() {
		//turn access
		$this->ACL->turn(array('news', 'view_list'));

		//формируем блок со списком  разделов
		if ($this->cached && $this->Cache->check('category_' . $this->cacheKey)) {
			$this->categories = $this->Cache->read('category_' . $this->cacheKey);
			
		} else {
			$sql_cat = $this->DB->select(
				'news_sections', 
				DB_ALL, 
				array(
					'cond' => array(
						'class' => 'section'
					)
				)
			);
			foreach ($sql_cat as $result) {
				$this->categories .= '<li>' . get_link($result['title']
				, '/news/section/' . $result['id']) . '</li>';
			}
			if ($this->cached)
				$this->Cache->write($this->categories, 'category_' . $this->cacheKey
				, array('module_news', 'category_block'));
		}
		
		
		
		if ($this->cached && $this->Cache->check($this->cacheKey)) {
			$html = $this->Cache->read($this->cacheKey);
		} else {
		
			//Узнаем кол-во материалов в БД (!we need to know whether to show hidden )
			$query_params = array('cond' => array());
			if (!$this->ACL->turn(array('other', 'can_see_hidden'), false)) {
				$query_params['cond']['available'] = 1;
			}
			

			$total = $this->DB->select('news', DB_COUNT, $query_params);
			$cntPages = ceil( $total / Config::read('per_page', 'news') );
			if ( isset($_GET['page']) ) {
				$page = (int)$_GET['page'];
				if ( $page < 1 ) $page = 1;
			} else {
				$page = 1;
			}
			if ( $page > $cntPages ) $page = $cntPages;
			$pages = pagination( $page, $cntPages, '/news');
			$_SESSION['page'] = $page;
			$_SESSION['pagescnt'] = $cntPages;


			
			$navi = array();
			$navi['{ADD_LINK}'] = ($this->ACL->turn(array('news', 'add_materials'), false)) 
				? get_link(__('Add material'), '/news/add_form/') : '';
			$navi['{NAVIGATION}'] = get_link(__('Home'), '/') . __('Separator') . $this->module_title;
			$navi['{PAGINATION}'] = $pages;
			$navi['{META}'] = __('Count all material') . $total;
			$this->_globalize($navi);


			if($total <= 0) {
				$html = __('Materials not found');
				return $this->_view($html);
			}
		  
		  
			$html = '';
			//(!we need to know whether to show hidden )
			$query_params = array(
				'joins' => array(
					array(
						'table' => 'news_sections',
						'type' => 'LEFT',
						'alias' => 'b',
						'cond' => 'a.`category_id` = b.`id`',
					),
					array(
						'table' => 'news_sections',
						'type' => 'LEFT',
						'alias' => 'c',
						'cond' => 'b.`section_id` = c.`id`',
					),
					array(
						'table' => 'users',
						'type' => 'LEFT',
						'alias' => 'd',
						'cond' => 'd.`id` = a.`author_id`',
					),
				),
				'fields' => array('a.*', 'b.`title` as category_name', 'b.`section_id` as section_id', 'c.`title` as section_name', 'd.`name` AS author', 'd.`status` AS author_status'),
				'alias' => 'a',
				'page' => $page,
				'limit' => Config::read('per_page', 'news'),
			);
			if (!$this->ACL->turn(array('other', 'can_see_hidden'), false)) $query_params['cond']['`a`.`available`'] = '1';
			$order = getOrderParam(__CLASS__);
			if (!empty($order)) $query_params['order'] = $order;
			$sql = $this->DB->select('news', DB_ALL, $query_params);
			if (is_object($this->AddFields) && count($sql) > 0) {
				$sql = $this->AddFields->mergeRecords($sql);
			}
			
			
			// get ids list
			$ids = array();
			foreach ($sql as $result) {
				$ids[] = $result['id'];
			}
			$ids = implode(', ', $ids);
			$attaches = $this->DB->select($this->module . '_attaches', DB_ALL, array('cond' => array('`entity_id` IN ('.$ids.')')));
			
			
			//replace markets
			foreach ($sql as $result) {
				$markets = array();
				$result = $this->Parser->quoteTags($result);
				$_SESSION['current_vars'] = $result;
				$htmlstats = $this->Parser->getAndParse('tablemat.html');
				
				
				$rec_attaches = array();
				if (!empty($attaches) && count($attaches) > 0) {
					foreach ($attaches as $k => $attach) {
						if ($attach['entity_id'] == $result['id']) {
							$rec_attaches[] = $attach;
							unset($attaches[$k]);
						}
					}
				}
				
				
				$markets['{MODER_PANEL}'] = $this->_getAdminBar($result);
				$entry_url = get_url(entryUrl($result, $this->module));
				$markets['{ENTRY_URL}'] = $entry_url; 

				$announce = $this->Parser->unquoteTags($result['description']);
				// replace image tags in text
				if (!empty($rec_attaches) && count($rec_attaches) > 0) {
					$attachDir = R . 'sys/files/' . $this->module . '/';
					foreach ($rec_attaches as $attach) {
						if ($attach['is_image'] == 1 && file_exists($attachDir . $attach['filename'])) {
							$announce = str_replace('{IMAGE'.$attach['attach_number'].'}'
							, '[img]' . get_url('/sys/files/'.$this->module.'/'.$attach['filename']).'[/img]'
							, $announce);
						}
					}
				}
				$announce = $this->Textarier->getAnnounce($announce, $entry_url, 0, 
					$this->set['news']['announce_lenght'], $result['author_status']);
				$markets['{ANNOUNCE}'] = $this->Parser->quoteTags($announce);
				
				foreach ($result as $key => $value) {
				   $markets['{'.strtoupper($key).'}'] = h($value);
				}
				
				$markets['{CATEGORY_URL}'] = get_url('/news/category/' . $result['category_id']);
				$markets['{PROFILE_URL}'] = getProfileUrl($result['author_id']);
				$html .= $this->_replaceMarkets($markets, $htmlstats);

				//set users_id that are on this page
				$this->setCacheTag(array(
					'user_id_' . $result['author_id'],
					'record_id_' . $result['id'],
				));
			}
			
			$materials_tpl = $this->Parser->getAndParse('materials_container.html');
			$markets = array(
				'{MATERIALS}' => $html,
			);
			$html = $this->_replaceMarkets($markets, $materials_tpl);
			
			//write int cache
			if ($this->cached)
				$this->Cache->write($html, $this->cacheKey, $this->cacheTags);
		}
		
		return $this->_view($html);
	}





	/**
	 * Show materials in category. Category ID must be integer and not null.
	 */
	function category($id = null) {
		//turn access
		$this->ACL->turn(array('news', 'view_list'));
		if (!isset($id)) redirect('/');
		$id = intval($id);
		if (empty($id) || $id < 1) redirect('/');

		
		
		//формируем блок со списком  разделов
		if ($this->cached && $this->Cache->check('category_' . $this->cacheKey)) {
			$this->categories = $this->Cache->read('category_' . $this->cacheKey);
		} else {
			$sql_cat = $this->DB->select('news_sections', DB_ALL, array(
				'joins' => array(
					array(
						'table' => 'news_sections',
						'type' => '',
						'alias' => 'b',
						'cond' => '`b`.`section_id` = `a`.`section_id`',
					),
				),
				'alias' => 'a',
				'cond' => array('`a`.`id`' => $id),
			));
			//выводим поочередно все разделы, каждый с новой строки(формируем список)
			foreach ($sql_cat as $result) {
				$this->categories .= '<li>' . get_link($result['title'], '/news/category/' . $result['id']) . '</li>';
			}
			if ($this->cached)
				$this->Cache->write($this->categories, 'category_' . $this->cacheKey, array('module_news', 'category_block'));
		}
		
		
		if ($this->cached && $this->Cache->check($this->cacheKey)) {
			$html = $this->Cache->read($this->cacheKey);
		} else {
		
			$query_params = array('cond' => array('category_id' => $id));
			//(!we need to know whether to show hidden )
			if (!$this->ACL->turn(array('other', 'can_see_hidden'), false)) $query_params['cond']['available'] = '1';
			$order = getOrderParam(__CLASS__);
			if (!empty($order)) $query_params['order'] = $order;
			$total = $this->DB->select('news', DB_COUNT, $query_params);
			$cntPages = ceil( $total / Config::read('per_page', 'news') );
			// pages
			if ( isset($_GET['page']) ) {
				$page = (int)$_GET['page'];
				if ( $page < 1 ) $page = 1;
			} else {
				$page = 1;
			}
			if ( $page > $cntPages ) $page = $cntPages;
			// build page nav
			$pages = pagination( $page, $cntPages, '/news/category/' . $id);
			$_SESSION['page'] = $page;
			$_SESSION['pagescnt'] = $cntPages;

			
			
			$category_info = $this->DB->select('news_sections', DB_ALL, array(
				'joins' => array(
					array(
						'table' => 'news_sections',
						'alias' => 'b',
						'type' => 'LEFT',
						'cond' => '`b`.`id` = `a`.`section_id`',
					),
				),
				'cond' => array('`a`.`id`' => $id),
				'alias' => 'a',
				'fields' => array('a.`title` as ctitle', 'a.`id` as cid', 'b.`title` as stitle', 'b.`id` as sid'),
			));

			//navigation panel
			$navi = array();
			$navi['{ADD_LINK}'] = ($this->ACL->turn(array('news', 'add_materials'), false)) ? 
				get_link(__('Add material'), '/news/add_form/') : '';
			$navi['{NAVIGATION}'] = get_link($this->module_title, '/news/') . __('Separator') 
				. get_link($category_info[0]['stitle'], '/news/section/' . $category_info[0]['sid']) . ' &raquo; ' 
				. $category_info[0]['ctitle'];
			$navi['{PAGINATION}'] = $pages;
			$navi['{META}'] = __('Count material in cat') . $total;
			$this->_globalize($navi);

			if($total < 1) {
				$html = __('Materials not found');
				return $this->_view($html);
			}
			
			
			$html = '';
			$query_params = array(
				'joins' => array(
					array(
						'table' => 'news_sections',
						'type' => 'LEFT',
						'alias' => 'b',
						'cond' => 'a.`category_id` = b.`id`',
					),
					array(
						'table' => 'news_sections',
						'type' => 'LEFT',
						'alias' => 'c',
						'cond' => 'b.`section_id` = c.`id`',
					),
					array(
						'table' => 'users',
						'type' => 'LEFT',
						'alias' => 'd',
						'cond' => 'd.`id` = a.`author_id`',
					),
				),
				'fields' => array('`a`.*', '`b`.`title` as category_name', '`b`.`section_id` as section_id',
				'`c`.`title` as section_name', '`d`.`name` AS author', '`d`.`status` AS author_status'),
				'alias' => 'a',
				'cond' => array('`a`.`category_id`' => $id),
				'page' => $page,
				'limit' => Config::read('per_page', 'news'),
			);
			if (!$this->ACL->turn(array('other', 'can_see_hidden'), false)) $query_params['cond']['`a`.`available`'] = '1';
			if (!empty($order)) $query_params['order'] = $order;
			$sql = $this->DB->select('news', DB_ALL, $query_params);
			if (is_object($this->AddFields) && count($sql) > 0) {
				$sql = $this->AddFields->mergeRecords($sql);
			}
			
			
			// get ids list
			$ids = array();
			foreach ($sql as $result) {
				$ids[] = $result['id'];
			}
			$ids = implode(', ', $ids);
			$attaches = $this->DB->select($this->module . '_attaches', DB_ALL, array('cond' => array('`entity_id` IN ('.$ids.')')));
			
			
			//render materials
			foreach ($sql as $result) {
				$markets = array();
				$result = $this->Parser->quoteTags($result);
				$_SESSION['current_vars'] = $result;
				$template = $this->Parser->getAndParse('tablemat.html');

				
				$rec_attaches = array();
				if (!empty($attaches) && count($attaches) > 0) {
					foreach ($attaches as $k => $attach) {
						if ($attach['entity_id'] == $result['id']) {
							$rec_attaches[] = $attach;
							unset($attaches[$k]);
						}
					}
				}
				
				
				$markets['{MODER_PANEL}'] = $this->_getAdminBar($result);
				$entry_url = get_url(entryUrl($result, $this->module));
				$markets['{ENTRY_URL}'] = $entry_url;

				
				$announce = $this->Parser->unquoteTags($result['main']);
				// replace image tags in text
				if (!empty($rec_attaches) && count($rec_attaches) > 0) {
					$attachDir = R . 'sys/files/' . $this->module . '/';
					foreach ($rec_attaches as $attach) {
						if ($attach['is_image'] == 1 && file_exists($attachDir . $attach['filename'])) {
							$announce = str_replace('{IMAGE'.$attach['attach_number'].'}'
							, '[img]' . get_url('/sys/files/'.$this->module.'/'.$attach['filename']).'[/img]'
							, $announce);
						}
					}
				}
				$announce = $this->Textarier->getAnnounce($announce, $entry_url, 0, 
					$this->set['news']['announce_lenght'], $result['author_status']);
				$markets['{ANNOUNCE}'] = $this->Parser->quoteTags($announce);
				
				
				foreach ($result as $key => $value) {
					$markets['{'.strtoupper($key).'}'] = h($value);
				}
				
				$markets['{CATEGORY_URL}'] = get_url('/news/category/' . $result['category_id']);
				$markets['{PROFILE_URL}'] = getProfileUrl($result['author_id']);
				$html .= $this->_replaceMarkets($markets, $template);

				
				//prepear cache tags
				$this->setCacheTag(array(
					'user_id_' . $result['author_id'],
					'record_id_' . $result['id'],
				));
			}
			$this->setCacheTag(array('category_id_' . $id));

			
			$materials_tpl = $this->Parser->getAndParse('materials_container.html');
			$markets = array(
				'{MATERIALS}' => $html,
			);
			$html = $this->_replaceMarkets($markets, $materials_tpl);
			
			
			//write int cache
			if ($this->cached)
				$this->Cache->write($html, $this->cacheKey, $this->cacheTags);
		}
		return $this->_view($html);
	}
	  
	  
	  
	  
	  
	  
	function section($id = null) {
		//turn access
		$this->ACL->turn(array('news', 'view_list'));
		$id = intval($id);
		if (empty($id) || $id < 1) redirect('/');

		

		//формируем блок со списком  разделов
		if ($this->cached && $this->Cache->check('category_' . $this->cacheKey)) {
			$this->categories = $this->Cache->read('category_' . $this->cacheKey);
		} else {
			$sql_cat = $this->DB->select('news_sections', DB_ALL, array('cond' => array('class' => 'category', 'section_id' => $id)));
			//выводим поочередно все разделы, каждый с новой строки(формируем список)
			foreach ($sql_cat as $result) {
				$this->categories .= '<li>' . get_link($result['title'], '/news/category/'.$result['id']) . '</li>';
			}
			if ($this->cached)
				$this->Cache->write($this->categories, 'category_' . $this->cacheKey, array('module_news', 'category_block'));
		}

		
		
					
		if ($this->cached && $this->Cache->check($this->cacheKey)) {
			$html = $this->Cache->read($this->cacheKey);
		} else {
		
		
			$query_params = array('cond' => array('section_id' => $id));
			//(!we need to know whether to show hidden )
			if (!$this->ACL->turn(array('other', 'can_see_hidden'), false)) $query_params['cond']['available'] = '1';
			$order = getOrderParam(__CLASS__);
			if (!empty($order)) $query_params['order'] = $order;
			$total = $this->DB->select('news', DB_COUNT, $query_params);
			$cntPages = ceil( $total / Config::read('per_page', 'news') );
			// Проверяем передан ли номер текущей страницы (постраничная навигация)
			if ( isset($_GET['page']) ) {
				$page = (int)$_GET['page'];
				if ( $page < 1 ) $page = 1;
			} else {
				$page = 1;
			}
			if ( $page > $cntPages ) $page = $cntPages;
			// page nav
			$pages = pagination( $page, $cntPages, '/news/section/' . $id);
			$_SESSION['page'] = $page;
			$_SESSION['pagescnt'] = $cntPages;

			
			
			// Navigation panel
			$navi = array();
			$section_info = $this->DB->select('news_sections', DB_FIRST, array(
				'cond' => array(
					'id' => $id,
					'class' => 'section',
				),
			));
			$navi['{ADD_LINK}'] = ($this->ACL->turn(array('news', 'add_materials'), false)) ? 
				get_link(__('Add material'), '/news/add_form/') : '';
			$navi['{NAVIGATION}'] = get_link($this->module_title, '/news/') 
				. __('Separator') . h($section_info[0]['title']);
			$navi['{PAGINATION}'] = $pages;
			$navi['{META}'] = __('Count material in cat') . $total;
			$this->_globalize($navi);
			
			if($total < 1) {
				$html = __('Materials not found');
				return $this->_view($html);
			}
			
			
			$html = '';
			$query_params = array(
				'joins' => array(
					array(
						'table' => 'news_sections',
						'type' => 'LEFT',
						'alias' => 'b',
						'cond' => 'a.`category_id` = b.`id`',
					),
					array(
						'table' => 'news_sections',
						'type' => 'LEFT',
						'alias' => 'c',
						'cond' => 'b.`section_id` = c.`id`',
					),
					array(
						'table' => 'users',
						'type' => 'LEFT',
						'alias' => 'd',
						'cond' => 'd.`id` = a.`author_id`',
					),
				),
				'fields' => array('`a`.*', '`b`.`title` as category_name', '`b`.`section_id` as section_id',
				'`c`.`title` as section_name', '`d`.`name` AS author', '`d`.`status` AS author_status'),
				'alias' => 'a',
				'cond' => array('`b`.`section_id`' => $id),
				'order' => '`a`.`date` DESC',
				'page' => $page,
				'limit' => Config::read('per_page', 'news'),
			);
			if (!$this->ACL->turn(array('other', 'can_see_hidden'), false)) $query_params['cond']['`a`.`available`'] = '1';
			if (!empty($order)) $query_params['order'] = $order;
			$sql = $this->DB->select('news', DB_ALL, $query_params);
			if (is_object($this->AddFields) && count($sql) > 0) {
				$sql = $this->AddFields->mergeRecords($sql);
			}
			
			
			// get ids list
			$ids = array();
			foreach ($sql as $result) {
				$ids[] = $result['id'];
			}
			$ids = implode(', ', $ids);
			$attaches = $this->DB->select($this->module . '_attaches', DB_ALL, array('cond' => array('`entity_id` IN ('.$ids.')')));
			
			
			// render materials
			foreach ($sql as $result) {
				$markets = array();
				$result = $this->Parser->quoteTags($result);
				$_SESSION['current_vars'] = $result;
				$template = $this->Parser->getAndParse('tablemat.html');

				
				$rec_attaches = array();
				if (!empty($attaches) && count($attaches) > 0) {
					foreach ($attaches as $k => $attach) {
						if ($attach['entity_id'] == $result['id']) {
							$rec_attaches[] = $attach;
							unset($attaches[$k]);
						}
					}
				}
				
				
				$markets['{MODER_PANEL}'] = $this->_getAdminBar($result);
				$entry_url = get_url(entryUrl($result, $this->module));
				$markets['{ENTRY_URL}'] = $entry_url;

				
				$announce = $this->Parser->unquoteTags($result['main']);
				// replace image tags in text
				if (!empty($rec_attaches) && count($rec_attaches) > 0) {
					$attachDir = R . 'sys/files/' . $this->module . '/';
					foreach ($rec_attaches as $attach) {
						if ($attach['is_image'] == 1 && file_exists($attachDir . $attach['filename'])) {
							$announce = str_replace('{IMAGE'.$attach['attach_number'].'}'
							, '[img]' . get_url('/sys/files/'.$this->module.'/'.$attach['filename']).'[/img]'
							, $announce);
						}
					}
				}
				$announce = $this->Textarier->getAnnounce($announce, $entry_url, 0, 
					$this->set['news']['announce_lenght'], $result['author_status']);
				$markets['{ANNOUNCE}'] = $this->Parser->quoteTags($announce);
				
				
				foreach ($result as $key => $value) {
					$markets['{'.strtoupper($key).'}'] = h($value);
				}
				
				$markets['{CATEGORY_URL}'] = get_url('/news/category/' . $result['category_id']);
				$markets['{PROFILE_URL}'] = getProfileUrl($result['author_id']);
				$html .= $this->_replaceMarkets($markets, $template);


				//prepear cache tags
				$this->setCacheTag(array(
					'user_id_' . $result['author_id'],
					'record_id_' . $result['id'],
				));
			}
			$this->setCacheTag(array('section_id_' . $id));
			
			
			$materials_tpl = $this->Parser->getAndParse('materials_container.html');
			$markets = array(
				'{MATERIALS}' => $html,
			);
			$html = $this->_replaceMarkets($markets, $materials_tpl);
			
			
			//write int cache
			if ($this->cached)
				$this->Cache->write($html, $this->cacheKey, $this->cacheTags);
		}
		return $this->_view($html);
	}
	  
	  
	  




	function view ($id = null) {
		//turn access
		$this->ACL->turn(array('news', 'view_materials'));
		$id = intval($id);
		if (empty($id) || $id < 1) redirect('/');

		

		// извлекаем шаблон отображения материала
		$html = $this->Parser->getAndParse('vievmat.html');
		$sql = $this->DB->select('news', DB_FIRST, array(
			'joins' => array(
				array(
					'table' => 'news_sections',
					'type' => 'LEFT',
					'alias' => 'b',
					'cond' => 'a.`category_id` = b.`id`',
				),
				array(
					'table' => 'news_sections',
					'type' => 'LEFT',
					'alias' => 'c',
					'cond' => 'b.`section_id` = c.`id`',
				),
				array(
					'table' => 'users',
					'type' => 'LEFT',
					'alias' => 'd',
					'cond' => 'd.`id` = a.`author_id`',
				),
			),
			'fields' => array('`a`.*', '`b`.`title` as category_name', '`b`.`section_id` as section_id',
			'`c`.`title` as section_name', '`d`.`name` AS author', '`d`.`status` AS author_status'),
			'alias' => 'a',
			'cond' => array('`a`.`id`' => $id),
		));
		if (count($sql) < 1) return $this->_view(__('Some error occurred'));
		if ($sql[0]['available'] == 0 && !$this->ACL->turn(array('other', 'can_see_hidden'), false)) 
			return showInfoMessage(__('Permission denied'), '/news/');
			
		if (is_object($this->AddFields) && count($sql) > 0) {
			$sql = $this->AddFields->mergeRecords($sql);
		}
		
		
		$attaches = $this->DB->select($this->module.'_attaches', DB_ALL, array('cond' => array('entity_id' => $id)));
		$max_attaches = Config::read('max_attaches', $this->module);
		if (empty($max_attaches) || !is_numeric($max_attaches)) $max_attaches = 5;
		
		
		$result = $this->Parser->quoteTags($sql[0]);
		$_SESSION['current_vars'] = $result;
		$markets = array();
		$navi = array();
		
		
		//производим замену соответствующих участков в html шаблоне нужной информацией
		$navi['{MODULE_URL}'] = get_url('/news/');
		$navi['{SECTION_URL}'] = get_url('/news/section/' . $result['section_id']);
		$navi['{CATEGORY_URL}'] = get_url('/news/category/' . $result['category_id']);
		$navi['{SECTION_NAME}'] = h($result['section_name']);
		$navi['{CATEGORY_NAME}'] = h($result['category_name']);
		$navi['{NAVIGATION}'] = get_link($navi['{CATEGORY_NAME}'], $navi['{CATEGORY_URL}']) . __('Separator') 
		. get_link($navi['{SECTION_NAME}'], $navi['{SECTION_URL}']) . __('Separator') . h($result['title']);
		$this->_globalize($navi);


		//если админ, выводим админбар
		$markets['{MODER_PANEL}'] = $this->_getAdminBar($result);
		foreach ($result as $key => $value) {
		   $markets['{' . strtoupper($key) . '}'] = h($value);
		}
		$markets['{PROFILE_URL}'] = getProfileUrl($result['author_id']);
		
		
		$text_stat  = $this->Parser->unquoteTags($result['main']);
		// replace image tags in text
		if (!empty($attaches) && count($attaches) > 0) {
			$attachDir = R . 'sys/files/' . $this->module . '/';
			foreach ($attaches as $attach) {
				if ($attach['is_image'] == 1 && file_exists($attachDir . $attach['filename'])) {
					$text_stat = str_replace('{IMAGE'.$attach['attach_number'].'}'
					, '[img]' . get_url('/sys/files/'.$this->module.'/'.$attach['filename']).'[/img]'
					, $text_stat);
				}
			}
		}
		$text_stat  = $this->Textarier->print_page($text_stat, $result['author_status']);
		$markets['{MAIN_TEXT}']  = $this->Parser->quoteTags($text_stat);
		$html = $this->_replaceMarkets($markets, $html);
		
		
		$this->DB->save('news', array(
			'`views` = `views` + 1',
			'id' => $id,
		));
		
		$this->page_title = $this->page_title . ' - ' . h($result['title']);
		if (!empty($result['tags'])) $this->page_meta_keywords = h($result['tags']);
		if (!empty($result['description'])) $this->page_meta_description = h($result['description']);
		
		//prepear cache tags
		$this->setCacheTag(array(
			'user_id_' . $result['author_id'],
			'record_id_' . $result['id'],
			(!empty($_SESSION['user']['status'])) ? 'user_group_' . $_SESSION['user']['status'] : 'user_group_' . 'guest',
		));
		
		
		/* COMMENT BLOCK */
		if (Config::read('comment_active', 'news') == 1 
		&& $this->ACL->turn(array('news', 'view_comments'), false) 
		&& $result['commented'] == 1) {
			if ($this->ACL->turn(array('news', 'add_comments'), false)) $this->comments  = $this->_add_comment_form($id);
			$this->comments  = $this->_get_comments($id) . $this->comments;
		}
		
		//category block
		$cats = $this->DB->select('news_sections', DB_ALL, array('cond' => array('section_id' => $result['section_id'])));
		$info = '';
		foreach ($cats as $result) {
			$info.= '<li>' . get_link(h($result['title']), '/news/section/' . $result['id']) . '</li>';
		}
		
		$this->categories = $info;
		$this->DB->cleanSqlCache();
		return $this->_view($html);
	}



	 

	 
	function add_form () {
		//turn access
		$this->ACL->turn(array('news', 'add_materials'));
		$writer_status = (!empty($_SESSION['user']['status'])) ? $_SESSION['user']['status'] : 0;
		
		
		if ($this->cached && $this->Cache->check('category_' . $this->cacheKey)) {
			$this->categories = $this->Cache->read('category_' . $this->cacheKey);
		} else {
			$sql = $this->DB->select('news_sections', DB_ALL, array('cond' => array('class' => 'section')));
			//выводим поочередно все разделы, каждый с новой строки(формируем список)
			foreach ($sql as $result) {
				$this->categories .= '<li>' . get_link(h($result['title']), '/news/section/' . $result['id']) . '</li>';
			}
			if ($this->cached)
				$this->Cache->write($this->categories, 'category_' . $this->cacheKey, array('module_news', 'category_block'));
		}
		
		
		$html = $this->Parser->getAndParse('addform.html' );
		$markets = array();
		// Additional fields
		if (is_object($this->AddFields)) {
			$_addFields = $this->AddFields->getInputs();
			foreach($_addFields as $k => $field) {
				$markets['{' . strtoupper($k) . '}'] = $field;
			}
		}
		
		
		$cats_change = '';
		foreach ($sql as $fetch) {
			$cats_change .= '<option disabled="disabled">' . h($fetch['title']) . '</option>';
			$_categories   = $this->DB->select('news_sections', DB_ALL, array('cond' => array('section_id' => $fetch['id'])));
			
			foreach ($_categories as $fetch_cat) {
			
				if (!empty($_SESSION['FpsForm']['in_cat']) && $_SESSION['FpsForm']['in_cat'] == $fetch_cat['id'])
					$selected = ' selected="selected"';
				else if (!empty($_SESSION['viewMessage']['in_cat']) && $_SESSION['viewMessage']['in_cat'] == $fetch_cat['id'])
					$selected = ' selected="selected"';
				else
					$selected = '';
					
				$cats_change .= '<option value="' . $fetch_cat['id'] . '"'
				. $selected . ' >' . h($fetch_cat['title']) . '</option>';
			}
		}

		
		//предварительный просмотр
		if (isset($_SESSION['viewMessage']) and !empty($_SESSION['viewMessage']['mainText'])) {
			$view      			= $this->Parser->getAndParse('previewmessage.html');
			$view     		    = str_replace('{MESSAGE}', 
				$this->Textarier->print_page($_SESSION['viewMessage']['mainText'], $writer_status), $view);
			$html      			= $view . $html . "\n";
			$title     			= h($_SESSION['viewMessage']['title']);
			$add       			= h($_SESSION['viewMessage']['mainText']);
			$description		= h($_SESSION['viewMessage']['description']);
			$tags 				= h($_SESSION['viewMessage']['tags']);
			$sourse 			= h($_SESSION['viewMessage']['sourse']);
			$sourse_email 		= h($_SESSION['viewMessage']['sourse_email']);
			$sourse_site 		= h($_SESSION['viewMessage']['sourse_site']);
			$commented 			= h($_SESSION['viewMessage']['commented']);
			$available 			= h($_SESSION['viewMessage']['available']);
			unset($_SESSION['viewMessage']);
		}



		// Если при заполнении формы были допущены ошибки
		if (isset( $_SESSION['FpsForm'])) {
			$info           = $this->Parser->getAndParse('infomessage.html' );
			$info           = str_replace( '{INFO_MESSAGE}', $_SESSION['FpsForm']['error'], $info );
			$html           = $info . $html . "\n";
			$title    	    = h($_SESSION['FpsForm']['title']);
			$add   	  		= h($_SESSION['FpsForm']['mainText']);
			$description 	= h($_SESSION['FpsForm']['description']);
			$tags 			= h($_SESSION['FpsForm']['tags']);
			$sourse			= h($_SESSION['FpsForm']['sourse']);
			$sourse_email	= h($_SESSION['FpsForm']['sourse_email']);
			$sourse_site	= h($_SESSION['FpsForm']['sourse_site']);
			$commented	    = h($_SESSION['FpsForm']['commented']);
			$available	    = h($_SESSION['FpsForm']['available']);
			unset( $_SESSION['FpsForm'] );
		}
		
		//comments and hide
		$commented = (!empty($commented) || !isset($_POST['submitForm'])) ? 'checked="checked"' : '';
		if (!$this->ACL->turn(array('news', 'record_comments_management'), false)) $commented .= ' disabled="disabled"';
		$available = (!empty($available) || !isset($_POST['submitForm'])) ? 'checked="checked"' : '';
		if (!$this->ACL->turn(array('news', 'hide_material'), false)) $available .= ' disabled="disabled"';
		
		
		$markets['{ACTION}'] 		= get_url('/news/add/');
		$markets['{CATS_SELECTOR}'] = $cats_change;
		$markets['{TITLE}'] 		= (!empty($title)) ? $title : '';
		$markets['{MAIN_TEXT}'] 	= (!empty($add)) ? $add : '';
		$markets['{DESCRIPTION}']	= (!empty($description)) ? $description : '';
		$markets['{TAGS}'] 			= (!empty($tags)) ? $tags : '';
		$markets['{SOURSE}'] 		= (!empty($sourse)) ? $sourse : '';
		$markets['{SOURSE_EMAIL}'] 	= (!empty($sourse_email)) ? $sourse_email : '';
		$markets['{SOURSE_SITE}'] 	= (!empty($sourse_site)) ? $sourse_site : '';
		$markets['{COMMENTED}'] 	= (!empty($commented)) ? $commented : '';
		$markets['{AVAILABLE}'] 	= (!empty($available)) ? $available : '';
		$markets['{MAX_ATTACHES}'] = Config::read('max_attaches', $this->module);
		if (empty($markets['{MAX_ATTACHES}']) || !is_numeric($markets['{MAX_ATTACHES}'])) 
			$markets['{MAX_ATTACHES}'] = 5;

		$html = $this->_replaceMarkets($markets, $html);
		
		
		//navigation panel
		$navi = array();
		$navi['{NAVIGATION}'] = get_link(__('Home'), '/') . __('Separator') 
		. get_link(h($this->module_title), '/news/') . __('Separator') . __('Adding material');
		$this->_globalize($navi);

		return $this->_view($html);
	}






	/**
	 * 
	 * Validate data and create a new record into 
	 * Data Base. If an errors, redirect user to add form
	 * and show error message where speaks as not to admit 
	 * errors in the future
	 * 
	 */
	function add() {
		
		//turn access
		$this->ACL->turn(array('news', 'add_materials'));
		if (!isset($_POST['title']) || !isset($_POST['mainText']) || !isset($_POST['cats_selector'])) {
			redirect('/');
		}
		if (!is_numeric($_POST['cats_selector'])) {
			redirect('/');
		}
		$error  = '';
		
		// Check additional fields if an exists.
		// This must be doing after define $error variable.
		if (is_object($this->AddFields)) {
			$_addFields = $this->AddFields->checkFields();
			if (is_string($_addFields)) $error .= $_addFields; 
		}
		
		$fields = array('description', 'tags', 'sourse', 'sourse_email', 'sourse_site');
		$fields_settings = Config::read('fields', 'news');
		foreach ($fields as $field) {
			if (empty($_POST[$field]) && in_array($field, $fields_settings)) {
				$error = $error.'<li>' . __('Home') . ' "' . $field . '"</li>'."\n";
				$$field = null;
			} else {
				$$field = trim($_POST[$field]);
			}
		}
		// Обрезаем переменные до длины, указанной в параметре maxlength тега input
		$title  = trim(mb_substr($_POST['title'], 0, 128));
		$add 	= trim($_POST['mainText']);
		$in_cat = intval($_POST['cats_selector']);
		$commented = (!empty($_POST['commented'])) ? 1 : 0;
		$available = (!empty($_POST['available'])) ? 1 : 0;

		// Если пользователь хочет посмотреть на сообщение перед отправкой
		if ( isset( $_POST['viewMessage'] ) ) {
			$_SESSION['viewMessage'] = array_merge(array('title' => null, 'mainText' => null, 'in_cat' => $in_cat,
				'description' => null, 'tags' => null, 'sourse' => null, 'sourse_email' => null, 
				'sourse_site' => null, 'commented' => null, 'available' => null), $_POST);
			redirect('/news/add_form/');
		}

		// Check fields
		
		$valobj = new Validate;
		if (empty($in_cat))                     	
			$error = $error . '<li>' . __('Category not selected') . '</li>'."\n";
		if (empty($title))                       	
			$error = $error.'<li>' . __('Empty field "title"') . '</li>'."\n";
		elseif (!$valobj->cha_val($title, V_TITLE))  
			$error = $error.'<li>' . __('Wrong chars in "title"') . '</li>'."\n";
		if (empty($add))                    		 
			$error = $error.'<li>' . __('Empty field "material"') . '</li>'."\n";
		else if (mb_strlen($add) > Config::read('max_lenght', 'news'))
			$error = $error .'<li>'. sprintf(__('Wery big "material"'), Config::read('max_lenght', 'news')) .'</li>'."\n";
		if (!empty($tags) && !$valobj->cha_val($tags, V_TITLE)) 
			$error = $error.'<li>' . __('Wrong chars in "tags"') . '</li>'."\n";
		if (!empty($sourse) && !$valobj->cha_val($sourse, V_TITLE)) 
			$error = $error.'<li>' . __('Wrong chars in "sourse"') . '</li>'."\n";
		if (!empty($sourse_email) && !$valobj->cha_val($sourse_email, V_MAIL)) 
			$error = $error.'<li>' . __('Wrong chars in "email"') . '</li>'."\n";
		if (!empty($sourse_site) && !$valobj->cha_val($sourse_site, V_URL)) 
			$error = $error.'<li>' . __('Wrong chars in "sourse site"') . '</li>'."\n";

			
		// Check attaches size and format
		$max_attach = Config::read('max_attaches', $this->module);
		if (empty($max_attach) || !is_numeric($max_attach)) $max_attach = 5;
		$max_attach_size = Config::read('max_attaches_size', $this->module);
		if (empty($max_attach_size) || !is_numeric($max_attach_size)) $max_attach_size = 1000;
		for ($i = 1; $i <= $max_attach; $i++) {
			$attach_name = 'attach' . $i;
			if (!empty($_FILES[$attach_name]['name'])) {
			
				$img_extentions = array('.png','.jpg','.gif','.jpeg', '.PNG','.JPG','.GIF','.JPEG');
				$ext = strrchr($_FILES[$attach_name]['name'], ".");
				
				
				if ($_FILES[$attach_name]['size'] > $max_attach_size) {
					$error .= '<li>' . sprintf(__('Wery big file'), $i, round(($max_attach_size / 1000), 2)) . '</li>'."\n";
				}
				if (($_FILES[$attach_name]['type'] != 'image/jpeg'
				&& $_FILES[$attach_name]['type'] != 'image/jpg'
				&& $_FILES[$attach_name]['type'] != 'image/gif'
				&& $_FILES[$attach_name]['type'] != 'image/png')
				|| !in_array($ext, $img_extentions)) {
					$error .= '<li>' . __('Wrong file format') . '</li>'."\n";
				}
			}
		}
			
			
		// Errors
		if (!empty($error)) {
			$_SESSION['FpsForm'] = array_merge(array('title' => null, 'mainText' => null, 'in_cat' => $in_cat,
				'description' => null, 'tags' => null, 'sourse' => null, 'sourse_email' => null, 
				'sourse_site' => null, 'commented' => null, 'available' => null), $_POST);
			$_SESSION['FpsForm']['error']   = '<p class="errorMsg">' . __('Some error in form') . '</p>'.
				"\n".'<ul class="errorMsg">' . "\n" . $error . '</ul>' . "\n";
			redirect('/news/add_form/');
		}

		$sql = $this->DB->select('news_sections', DB_FIRST, array('cond' => array('id' => $in_cat)));
		$info_cat = $sql[0];
		
		if (!$this->ACL->turn(array('news', 'record_comments_management'), false)) $commented = '1';
		if (!$this->ACL->turn(array('news', 'hide_material'), false)) $available = '1';

		// Защита от того, чтобы один пользователь не добавил
		// 100 материалов за одну минуту
		if ( isset( $_SESSION['unix_last_post'] ) and ( time()-$_SESSION['unix_last_post'] < 10 ) ) {
			return showInfoMessage(__('Your message has been added'), '/news/');
		}
		
		//remove cache
		$this->Cache->clean(CACHE_MATCHING_ANY_TAG, array('module_news'));
		$this->DB->cleanSqlCache();
		// Формируем SQL-запрос на добавление темы	
		$add = mb_substr($add, 0, Config::read('max_lenght', 'news'));
		$res = $this->DB->save('news', array(
			'title'        => $title,
			'main'         => $add,
			'date'         => new Expr('NOW()'),
			'author_id'    => $_SESSION['user']['id'],
			'category_id'  => $info_cat['id'],
			'section_id'   => $info_cat['section_id'],
			'description'  => $description,
			'tags'         => $tags,
			'sourse'  	   => $sourse,
			'sourse_email' => $sourse_email,
			'sourse_site'  => $sourse_site,
			'commented'    => $commented,
			'available'    => $available,
		));
		// Get last insert ID and save additional fields if an exists and activated.
		// This must be doing only after save main(parent) material
		$last_id = mysql_insert_id();
		if (is_object($this->AddFields)) {
			$this->AddFields->save($last_id, $_addFields);
		}
		
		downloadAttaches($this->module, $last_id);
		
		
		//clean cache
		$this->Cache->clean(CACHE_MATCHING_TAG, array('module_' . $this->module));
		$this->DB->cleanSqlCache();
		if ($this->Log) $this->Log->write('adding new', 'new id(' . $last_id . ')');
		return showInfoMessage(__('Material successful added'), '/news/view/' . $last_id);				  
	}






	/**
	 * 
	 * Create form and fill his data from record which ID
	 * transfered into function. Show errors if an exists
	 * after unsuccessful attempt. Also can get data for filling
	 * from SESSION if user try preview message or create error.
	 *
	 * @param int $id material then to be edit
	 */
	function edit_form($id = null) {
		$id = (int)$id;
		if ( $id < 1 ) redirect('/');
		$writer_status = (!empty($_SESSION['user']['status'])) ? $_SESSION['user']['status'] : 0;

		
		// Получаем из БД информацию о редактируемой теме
		$res = $this->DB->select('news', DB_FIRST, array(
			'joins' => array(
				array(
					'table' => 'news_sections',
					'type' => 'LEFT',
					'alias' => 'b',
					'cond' => 'a.`category_id` = b.`id`',
				),
				array(
					'table' => 'news_sections',
					'type' => 'LEFT',
					'alias' => 'c',
					'cond' => 'b.`section_id` = c.`id`',
				),
				array(
					'table' => 'users',
					'type' => 'LEFT',
					'alias' => 'd',
					'cond' => 'd.`id` = a.`author_id`',
				),
			),
			'fields' => array('`a`.*', '`b`.`title` as category_name', '`b`.`section_id` as section_id',
			'`c`.`title` as section_name', '`d`.`name` AS author'),
			'alias' => 'a',
			'cond' => array('`a`.`id`' => $id),
		));
		if (count($res) == 0) redirect('/news/');
		
		// Merge record data with additional fields data
		// if additional fields is activated
		if (is_object($this->AddFields) && count($res) > 0) {
			$res = $this->AddFields->mergeRecords($res, true);
		}
		$stat = $this->Parser->quoteTags($res[0]);

		
		//turn access
		if (!$this->ACL->turn(array('news', 'edit_materials'), false) 
		&& (!empty($_SESSION['user']['id']) && $stat['author_id'] == $_SESSION['user']['id'] 
		&& $this->ACL->turn(array('news', 'edit_mine_materials'), false)) === false) {
			return showInfoMessage(__('Permission denied'), '/news/');
		}
		
		$_SESSION['current_vars'] = $stat;
		
		$sql = $this->DB->select('news_sections', DB_ALL, array('cond' => array('class' => 'section')));
		$cats_change = '';
		foreach ($sql as $fetch) {
			$cats_change .= "<option disabled='disabled'>" . h($fetch['title']) . "</option>";
			$categories   = $this->DB->select('news_sections', DB_ALL, array('cond' => array('section_id' => $fetch['id'])));
			foreach ($categories as $fetch_cat) {
				if($stat['category_name'] == $fetch_cat['title']) {
					$cats_change .= "<option value=\"" . $fetch_cat['id'] . "\" selected=\"selected\">" . h($fetch_cat['title']) . "</option>";
				} else {
					$cats_change .= "<option value=\"" . $fetch_cat['id'] . "\">" . h($fetch_cat['title']) . "</option>";
				}
			}
		}
		
		//forming categories list
		if ($this->cached && $this->Cache->check('category_' . $this->cacheKey)) {
			$this->categories = $this->Cache->read('category_' . $this->cacheKey);
		} else {
			foreach ($sql as $result) {
				$this->categories .= '<li>' . get_link(h($result['title']), '/news/section/'.$result['id']) . '</li>';
			}
			if ($this->cached)
				$this->Cache->write($this->categories, 'category_' . $this->cacheKey, array('module_news', 'category_block'));
		}

		
		$html = '';
		$markets = array();
		//предварительный просмотр
		if (isset($_SESSION['viewMessage']) and !empty($_SESSION['viewMessage']['mainText'])) {
			$_SESSION['viewMessage'] = $this->Parser->quoteTags($_SESSION['viewMessage']);
			$view = $this->Parser->getAndParse('previewmessage.html');
			$view = str_replace('{MESSAGE}', 
				$this->Textarier->print_page($_SESSION['viewMessage']['mainText'], $writer_status), $view);
			$html               = $html . $view . "\n";
			$title    		    = h( $_SESSION['viewMessage']['title'] );
			$edit       		= h( $_SESSION['viewMessage']['mainText'] );
			$description		= h($_SESSION['viewMessage']['description']);
			$tags 				= h($_SESSION['viewMessage']['tags']);
			$sourse 			= h($_SESSION['viewMessage']['sourse']);
			$sourse_email 		= h($_SESSION['viewMessage']['sourse_email']);
			$sourse_site 		= h($_SESSION['viewMessage']['sourse_site']);
			$commented 			= h($_SESSION['viewMessage']['commented']);
			$available 			= h($_SESSION['viewMessage']['available']);
			unset( $_SESSION['viewMessage'] );
		}
		
		
		// Если при заполнении формы были допущены ошибки
		if (isset($_SESSION['FpsForm'])) {
			$info           = $this->Parser->getAndParse('infomessage.html' );
			$info           = str_replace( '{INFO_MESSAGE}', $_SESSION['FpsForm']['error'], $info );
			$html           = $info . $html . "\n";
			$_SESSION['FpsForm'] = $this->Parser->quoteTags($_SESSION['FpsForm']);
			$title    		= h($_SESSION['FpsForm']['title']);
			$edit 			= h($_SESSION['FpsForm']['mainText']);
			$description	= h($_SESSION['FpsForm']['description']);
			$tags 			= h($_SESSION['FpsForm']['tags']);
			$sourse 		= h($_SESSION['FpsForm']['sourse']);
			$sourse_email 	= h($_SESSION['FpsForm']['sourse_email']);
			$sourse_site 	= h($_SESSION['FpsForm']['sourse_site']);
			$commented 		= h($_SESSION['FpsForm']['commented']);
			$available 		= h($_SESSION['FpsForm']['available']);
			unset($_SESSION['FpsForm']);
		} else {
			$title    		= h($stat['title']);
			$edit   		= h($stat['main']);
			$description	= h($stat['description']);
			$tags 			= h($stat['tags']);
			$sourse 		= h($stat['sourse']);
			$sourse_email 	= h($stat['sourse_email']);
			$sourse_site 	= h($stat['sourse_site']);
			$commented 		= h($stat['commented']);
			$available 		= h($stat['available']);
		}
		//comments and hide
		$commented = (!empty($commented)) ? 'checked="checked"' : '';
		if (!$this->ACL->turn(array('news', 'record_comments_management'), false)) $commented .= ' disabled="disabled"';
		$available = (!empty($available)) ? 'checked="checked"' : '';
		$action = get_url('/news/update/' . $id);

		
		// Считываем в переменную файл шаблона, содержащего форму для редактирования темы
		$tpl = $this->Parser->getAndParse('editform.html' );
		$markets['{ACTION}'] = $action;
		$markets['{TITLE}'] = $title;
		$markets['{CATS_SELECTOR}'] = $cats_change;
		$markets['{MAIN_TEXT}'] = $edit;
		$markets['{AUTHOR}'] = h($stat['author']);
		$markets['{DESCRIPTION}'] = $description;
		$markets['{TAGS}'] = $tags;
		$markets['{SOURSE}'] = $sourse;
		$markets['{SOURSE_EMAIL}'] = $sourse_email;
		$markets['{SOURSE_SITE}'] = $sourse_site;
		$markets['{COMMENTED}'] = $commented;
		$markets['{AVAILABLE}'] = $available;
		foreach ($stat as $key => $value) {
			if (preg_match('#^add_field_[\d]+$#i', $key) && is_object($this->AddFields)) {
				$markets['{' . strtoupper($key) . '}'] = $value;
			}
		}
		
		$markets = $this->Parser->quoteTags($markets);
		$html = $html . $this->_replaceMarkets($markets, $tpl);
		
		
		//navigation panel
		$navi = array();
		$navi['{NAVIGATION}']  = get_link(__('Home'), '/') . __('Separator') 
		. get_link(h($this->module_title), '/news/') . __('Separator') . __('Material editing');
		$this->_globalize($navi);


		setReferer();
		return $this->_view($html);
	}






	/**
	 * 
	 * Validate data and update record into 
	 * Data Base. If an errors, redirect user to add form
	 * and show error message where speaks as not to admit 
	 * errors in the future
	 * 
	 */
	function update($id = null) {
		// Если не переданы данные формы - функция вызвана по ошибке
		if (!isset($id) 
		|| !isset($_POST['title']) 
		|| !isset($_POST['mainText']) 
		|| !isset($_POST['cats_selector'])) {
			redirect('/');
		}
		$id = (int)$id;
		if ($id < 1) {
			redirect('/news/');
		}

		
		$target = $this->DB->select('news', DB_FIRST, array('cond' => array('id' => $id)));
		if (count($target) < 1) redirect('/news/');
		//turn access
		if (!$this->ACL->turn(array('news', 'edit_materials'), false) 
		&& (!empty($_SESSION['user']['id']) && $target[0]['author_id'] == $_SESSION['user']['id'] 
		&& $this->ACL->turn(array('news', 'edit_mine_materials'), false)) === false) {
			return showInfoMessage(__('Permission denied'), '/news/');
		}
		
		
		$error  = '';
		// Check additional fields if an exists.
		// This must be doing after define $error variable.
		if (is_object($this->AddFields)) {
			$_addFields = $this->AddFields->checkFields();
			if (is_string($_addFields)) $error .= $_addFields; 
		}
		
		$valobj = new Validate;
		$fields = array('description', 'tags', 'sourse', 'sourse_email', 'sourse_site');
		$fields_settings = Config::read('fields', 'news');
		foreach ($fields as $field) {
			if (empty($_POST[$field]) && in_array($field, $fields_settings)) {
				$error = $error.'<li>' . __('Empty field') . '"' . $field . '"</li>'."\n";
				$$field = null;
			} else {
				$$field = trim($_POST[$field]);
			}
		}
		// Обрезаем переменные до длины, указанной в параметре maxlength тега input
		$title  = trim(mb_substr($_POST['title'], 0, 128));
		$edit   = trim($_POST['mainText']);
		$commented = (!empty($_POST['commented'])) ? 1 : 0;
		$available = (!empty($_POST['available'])) ? 1 : 0;
		
		
		// Если пользователь хочет посмотреть на сообщение перед отправкой
		if (isset($_POST['viewMessage'])) {
			$_SESSION['viewMessage'] = array_merge(array('title' => null, 'mainText' => null, 
				'description' => null, 'tags' => null, 'sourse' => null, 'sourse_email' => null, 
				'sourse_site' => null, 'commented' => null, 'available' => null), $_POST);
			redirect('/news/edit_form/' . $id);
		}
		
		
		// Check fields
		if (empty($title))                   	
			$error = $error.'<li>' . __('Empty field "title"') . '</li>'."\n";
		if (!$valobj->cha_val($title, V_TITLE))  	
			$error = $error.'<li>' . __('Wrong chars in "title"') . '</li>'."\n";
		if (empty($edit))                 		
			$error = $error.'<li>' . __('Empty field "material"') . '</li>'."\n";
		else if (mb_strlen($edit) > Config::read('max_lenght', 'news'))
			$error = $error . '<li>' . sprintf(__('Wery big "material"'), Config::read('max_lenght', 'news')) .'</li>'."\n";
		if (!empty($tags) && !$valobj->cha_val($tags, V_TITLE)) 
			$error = $error.'<li>' . __('Wrong chars in "tags"') . '</li>'."\n";
		if (!empty($sourse) && !$valobj->cha_val($sourse, V_TITLE)) 
			$error = $error.'<li>' . __('Wrong chars in "sourse"') . '</li>'."\n";
		if (!empty($sourse_email) && !$valobj->cha_val($sourse_email, V_MAIL)) 
			$error = $error.'<li>' . __('Wrong chars in "email"') . '</li>'."\n";
		if (!empty($sourse_site) && !$valobj->cha_val($sourse_site, V_URL)) 
			$error = $error.'<li>' . __('Wrong chars in "sourse site"') . '</li>'."\n";


		// Errors
		if (!empty( $error )) {
			$_SESSION['FpsForm'] = array_merge(array('title' => null, 'mainText' => null, 
				'description' => null, 'tags' => null, 'sourse' => null, 'sourse_email' => null, 
				'sourse_site' => null, 'commented' => null, 'available' => null), $_POST);
			$_SESSION['FpsForm']['error']   = '<p class="errorMsg">' . __('Some error in form') . '</p>'
				."\n".'<ul class="errorMsg">'."\n".$error.'</ul>'."\n";
			redirect('/news/edit_form/' . $id);
		}
		
		$in_cat 		= intval($_POST['cats_selector']);
		$sql 			= $this->DB->select('news_sections', DB_FIRST, array('cond' => array('id' => $in_cat)));
		$info_cat 		= $sql[0];
		if (!$this->ACL->turn(array('news', 'record_comments_management'), false)) $commented = '1';
		if (!$this->ACL->turn(array('news', 'hide_material'), false)) $available = '1';
		
		
		//remove cache
		$this->Cache->clean(CACHE_MATCHING_TAG, array('module_news', 'record_id_' . $id));
		$this->DB->cleanSqlCache();
		// Запрос на обновление новости
		$edit = mb_substr($edit, 0, Config::read('max_lenght', 'news'));
		$res = $this->DB->save('news', array(
			'title' 	   => $title,
			'main' 		   => $edit,
			'category_id'  => $info_cat['id'],
			'section_id'   => $info_cat['section_id'],
			'description'  => $description,
			'tags'         => $tags,
			'sourse'  	   => $sourse,
			'sourse_email' => $sourse_email,
			'sourse_site'  => $sourse_site,
			'commented'    => $commented,
			'available'    => $available,
			'id' => $id
		));
		if (is_object($this->AddFields)) {
			$this->AddFields->save($id, $_addFields);
		}
		
		if ($this->Log) $this->Log->write('editing new', 'new id(' . $id . ')');
		return showInfoMessage(__('Operation is successful'), getReferer());
	}






	/**
	 * Check user access and if all right
	 * delete record with geting ID.
	 *
	 * @param int $id
	 */
	function delete($id = null) {
		$this->cached = false;
		$id = (int)$id;
		if ($id < 1) redirect('/');


		
		$sql = $this->DB->select('news', DB_FIRST, array('cond' => array('id' => $id)));
		if (count($sql) < 1) redirect('/');
		$result = $sql[0];
	
		//turn access
		if (!$this->ACL->turn(array('news', 'delete_materials'), false) 
		&& (!empty($_SESSION['user']['id']) && $result['author_id'] == $_SESSION['user']['id'] 
		&& $this->ACL->turn(array('news', 'delete_mine_materials'), false)) === false) {
			return showInfoMessage(__('Permission denied'), '/news/');
		}
	
		//remove cache
		$this->Cache->clean(CACHE_MATCHING_TAG, array('module_news', 'record_id_' . $id));
		$this->DB->cleanSqlCache();
		// Теперь удаляем материал 
		$this->DB->query("DELETE FROM `" . $this->DB->getFullTableName('news') 
		. "` WHERE `id` = '" . $id . "'");
		$this->DB->query("DELETE FROM `" . $this->DB->getFullTableName($this->module . '_add_content') 
		. "` WHERE `entity_id` = '" . $id . "'");
		
		$attaches = $this->DB->select($this->module . '_attaches', DB_ALL, array('cond' => array('entity_id' => $id)));
		if (count($attaches) > 0) {
			foreach ($attaches as $attach) {
				unlink(R . 'sys/files/' . $this->module . '/' . $attach['filename']);
			}
		}
		$this->DB->query("DELETE FROM `" . $this->DB->getFullTableName($this->module . '_attaches') 
		. "` WHERE `entity_id` = '" . $id . "'");
		
		
		if ($this->Log) $this->Log->write('delete new', 'new id(' . $id . ') user id('.$_SESSION['user']['id'].')');
		return showInfoMessage(__('Operation is successful'), getReferer());
	}

	
	
	/**
	* add comment to stat
	*
	* @id (int)    stat ID
	* @return      info message
	*/
	public function add_comment($id = null) {
		include_once(R . 'sys/inc/includes/add_comment.php');
	}
	
	
	/**
	* add comment form to stat
	*
	* @id (int)    stat ID
	* @return      html form
	*/
	private function _add_comment_form($id = null) {
		include_once(R . 'sys/inc/includes/_add_comment_form.php');
		return $html;
	}
	
	
	
	/**
	* edit comment form to stat
	*
	* @id (int)    comment ID
	* @return      html form
	*/
	public function edit_comment_form($id = null) {
		include_once(R . 'sys/inc/includes/edit_comment_form.php');
	}
	
	
	
	/**
	* update comment
	*
	* @id (int)    comment ID
	* @return      info message
	*/
	public function update_comment($id = null) {
		include_once(R . 'sys/inc/includes/update_comment.php');
	}
	
	
	
	/**
	* get comments for stat
	*
	* @id (int)    stat ID
	* @return      html comments list
	*/
	private function _get_comments($id = null) {
		include_once(R . 'sys/inc/includes/_get_comments.php');
		return $html;
	}
	
	
	
	/**
	* delete comment
	*
	* @id (int)    comment ID
	* @return      info message
	*/
	public function delete_comment($id = null) {
		include_once(R . 'sys/inc/includes/delete_comment.php');
	}	
	
	

	/**
	* @param int $id - record ID
	*
	* update date by record also up record in recods list
	*/
	public function upper($id) {
		//turn access
		$this->ACL->turn(array('news', 'up_materials'));
		$id = (int)$id;
		if ($id < 1) redirect('/news/');

		$this->DB->save('news', array(
			'id' => $id, 
			'date' => new Expr('NOW()'),
		));
		return showInfoMessage(__('Operation is successful'), '/news/');
	}

	
	
	/**
	* @param int $id - record ID
	*
	* allow record be on home page
	*/
	public function on_home($id) {
		//turn access
		$this->ACL->turn(array('news', 'on_home'));
		$id = (int)$id;
		if ($id < 1) redirect('/news/');

		$this->DB->save('news', array(
			'id' => $id, 
			'view_on_home' => 1,
		));
		return showInfoMessage(__('Operation is successful'), '/news/');
	}
	
	
	/**
	* @param int $id - record ID
	*
	* denied record be on home page
	*/
	public function off_home($id) {
		//turn access
		$this->ACL->turn(array('news', 'on_home'));
		$id = (int)$id;
		if ($id < 1) redirect('/news/');

		$this->DB->save('news', array(
			'id' => $id, 
			'view_on_home' => 0,
		));
		return showInfoMessage(__('Operation is successful'), '/news/');
	}
	
	
	
	/**
	* @param int $id - record ID
	*
	* fix or unfix record on top on home page
	*/
	public function fix_on_top($id) {
		$this->ACL->turn(array('news', 'on_home'));
		$id = (int)$id;
		if ($id < 1) redirect('/news/');

		$target = $this->DB->select('news', DB_FIRST, array('cond' => array('id' => $id)));
		if (empty($target[0])) redirect('/');
		$dest = ($target[0]['on_home_top'] == '1') ? '0' : '1';
		$this->DB->save('news', array('id' => $id, 'on_home_top' => $dest));
		return showInfoMessage(__('Operation is successful'), '/news/');
	}
	
	
	
	
	
	/**
	* @param array $record - assoc record array
	* @return string - admin buttons
	*
	* create and return admin bar
	*/
	protected function _getAdminBar($record) {
		$moder_panel = '';
		$id = $record['id'];
		if(isset($_SESSION['user']) and $_SESSION['user']['id'] == $record['author_id']) {
			if ($this->ACL->turn(array('news', 'edit_mine_materials'), false)) {
				$moder_panel .= get_link(get_img('/sys/img/edit_16x16.png', array('title' => __('Edit'))), '/news/edit_form/' . $id) . '&nbsp;';
			}
			
			if ($this->ACL->turn(array('news', 'up_materials'), false)) {
				$moder_panel .= get_link(get_img('/sys/img/star.png'), '/news/fix_on_top/' . $id, array('onClick' => "return confirm('" . __('Are you sure') . "')")) . '&nbsp;';
				$moder_panel .= get_link(get_img('/sys/img/up_arrow_16x16.png', array('title' => __('Up'))), 
				'/news/upper/' . $id, array('onClick' => "return confirm('" . __('Are you sure') . "')")) . '&nbsp;';
			}
			
			if ($this->ACL->turn(array('news', 'on_home'), false)) {
				if ($record['view_on_home'] == 1) {
					$moder_panel .= get_link(get_img('/sys/img/round_ok.png', array('title' => __('On home'))), 
					'/news/off_home/' . $id, array('onClick' => "return confirm('" . __('Are you sure') . "')")) . '&nbsp;';
				} else {
					$moder_panel .= get_link(get_img('/sys/img/round_not_ok.png', array('title' => __('On home'))), 
					'/news/on_home/' . $id, array('onClick' => "return confirm('" . __('Are you sure') . "')")) . '&nbsp;';
				}
			}
			
			if ($this->ACL->turn(array('news', 'delete_mine_materials'), false)) {
				$moder_panel .= get_link(get_img('/sys/img/delete_16x16.png', array('title' => __('Delete'))), 
				'/news/delete/' . $id, array('onClick' => "return confirm('" . __('Are you sure') . "')")) . '&nbsp;';
			}
			
			
		} else {
		
			if ($this->ACL->turn(array('news', 'edit_materials'), false)) {
				$moder_panel .= get_link(get_img('/sys/img/edit_16x16.png', array('title' => __('Edit'))), '/news/edit_form/' . $id) . '&nbsp;';
			}
			
			if ($this->ACL->turn(array('news', 'up_materials'), false)) {
				$moder_panel .= get_link(get_img('/sys/img/up_arrow_16x16.png', array('title' => __('Up'))), 
				'/news/upper/' . $id, array('onClick' => "return confirm('" . __('Are you sure') . "')")) . '&nbsp;';
			}
			
			if ($this->ACL->turn(array('news', 'on_home'), false)) {
				if ($record['view_on_home'] == 1) {
					$moder_panel .= get_link(get_img('/sys/img/round_ok.png', array('title' => __('On home'))), 
					'/news/off_home/' . $id, array('onClick' => "return confirm('" . __('Are you sure') . "')")) . '&nbsp;';
				} else {
					$moder_panel .= get_link(get_img('/sys/img/round_not_ok.png', array('title' => __('On home'))), 
					'/news/on_home/' . $id, array('onClick' => "return confirm('" . __('Are you sure') . "')")) . '&nbsp;';
				}
			}
			
			if ($this->ACL->turn(array('news', 'delete_materials'), false)) {
				$moder_panel .= get_link(get_img('/sys/img/delete_16x16.png', array('title' => __('Delete'))), 
				'/news/delete/' . $id, array('onClick' => "return confirm('" . __('Are you sure') . "')")) . '&nbsp;';
			}
		}
		return $moder_panel;
	}




    /**
     * RSS for news
	 *
     */
    function rss() {
		include_once R . 'sys/inc/includes/rss.php';
    }
	
	
}

?>
