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




Class LoadsModule extends Module {
	/**
	* @template  layout for module
	*/
	public $template = 'loads';
	/**
	* @module_title  title of module
	*/
	public $module_title = 'Каталог файлов';
	/**
	* @module module indentifier
	*/
	public $module = 'loads';
	
	/**
	* @module module indentifier
	*/
	public $attached_files_path = 'loads';
	
	
	
	public function __construct($params) {
		parent::__construct($params);
		$this->attached_files_path = R . 'sys/files/loads/';
	}
	
	
	
	/**
	 * Wrong extention for download files
	 */
	private $denyExtentions = array('.php', '.phtml', '.php3', '.html', '.htm', '.pl', '.PHP', '.PHTML', '.PHP3', '.HTML', '.HTM', '.PL', '.js', '.JS');
	
	

	/**
	* default action ( show main page )
	*/
	function index() {
		//turn access
		$this->ACL->turn(array('loads', 'view_list'));
		
		
		//формируем блок со списком  разделов
		$this->_getCatsTree();
		
		
		if ($this->cached && $this->Cache->check($this->cacheKey)) {
			$html = $this->Cache->read($this->cacheKey);
		} else {
		
		
			//Узнаем кол-во материалов в БД (!we need to know whether to show hidden )
			if ($this->ACL->turn(array('other', 'can_see_hidden'), false)) {
				$total = $this->DB->select('loads', DB_COUNT);
			} else {
				$total = $this->DB->select('loads', DB_COUNT, array('cond' => array('available' => '1')));
			}
			$cntPages = ceil( $total / Config::read('per_page', 'loads') );
			if ( isset($_GET['page']) ) {
				$page = (int)$_GET['page'];
				if ( $page < 1 ) $page = 1;
			} else {
				$page = 1;
			}
			if ( $page > $cntPages ) $page = $cntPages;
			$pages = ($cntPages > 1) ? pagination($page, $cntPages, '/loads/') : '&nbsp;';
			
			
			//navigation panel
			$navi = array();
			$navi['{ADD_LINK}'] = ($this->ACL->turn(array('loads', 'add_materials'), false)) ? 
				get_link(__('Add material'), '/loads/add_form/') : '';
			$navi['{NAVIGATION}'] = $this->_buildBreadCrumbs();
			$navi['{PAGINATION}'] = $pages;
			$navi['{META}'] = __('Count all material') . $total;
			$this->_globalize($navi);
			
			if ($total == 0) {
				$html = __('Materials not found');
				return $this->_view($html);
			}
			

			$html = '';
			// get data 
			$conditions = array();
			if (!$this->ACL->turn(array('other', 'can_see_hidden'), false)) $conditions['`a`.`available`'] = '1';
			$sql = $this->DB->select('loads', DB_ALL, array(
				'joins' => array(
					array(
						'table' => 'loads_sections',
						'type' => 'LEFT',
						'alias' => 'b',
						'cond' => 'a.`category_id` = b.`id`',
					),
					array(
						'table' => 'users',
						'type' => 'LEFT',
						'alias' => 'd',
						'cond' => 'd.`id` = a.`author_id`',
					),
				),
				'fields' => array('a.*', 'b.`title` as category_name','d.`name` AS author'
				, 'd.`status` AS author_status'),
				'alias' => 'a',
				'cond' => $conditions,
				'order' => getOrderParam(__CLASS__),
				'page' => $page,
				'limit' => Config::read('per_page', 'loads'),
			));
			// Additional fields
			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.')')));
			
			
			//ITERATION RECORDS
			foreach ($sql as $result) {
				$markets = array();
				$result = $this->Parser->quoteTags($result);
				$_SESSION['current_vars'] = $result;
				$htmlloads = $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, 
					Config::read('announce_lenght', 'loads'), $result);
				$markets['{ANNOUNCE}'] = $this->Parser->quoteTags($announce);
				
				
				foreach ($result as $key=>$value) {
					$markets['{'.strtoupper($key).'}'] = h($value);  
				}
				
				$markets['{LOADS}'] = $result['downloads'];
				$markets['{PROFILE_URL}'] = getProfileUrl($result['author_id']);
				$markets['{CATEGORY_URL}'] = get_url('/loads/category/' . $result['category_id']);
				$html .= $this->_replaceMarkets($markets, $htmlloads);


				//prepear cache tags
				$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);

			if ($this->cached)
				$this->Cache->write($html, $this->cacheKey, $this->cacheTags);
		}
		return $this->_view($html);
	}


	

	/**
	* action view category of loads
	*/
	function category($id = null) {
		//turn access
		$this->ACL->turn(array('loads', 'view_list'));
		$id = intval($id);
		if (empty($id) || $id < 1) redirect('/loads/');
	
	
		$catinfo = $this->DB->select('loads_sections', DB_FIRST, array('cond' => array('id' => $id)));
		if (count($catinfo) < 1)
			return showInfoMessage(__('Can not find category'), '/loads/');
		if (!$this->ACL->checkCategoryAccess($catinfo[0]['no_access'])) 
			return showInfoMessage(__('Permission denied'), '/loads/');
	

		//формируем блок со списком  разделов
		$this->_getCatsTree($id);
		
		
		if ($this->cached && $this->Cache->check($this->cacheKey)) {
			$html = $this->Cache->read($this->cacheKey);
		} else {
		
		
			$conditions = array('category_id' => $id);
			//(!we need to know whether to show hidden )
			if (!$this->ACL->turn(array('other', 'can_see_hidden'), false)) $conditions['available'] = '1';
			$total = $this->DB->select('loads', DB_COUNT, array('cond' => $conditions));
			$cntPages = ceil($total / Config::read('per_page', 'loads'));
			if (isset($_GET['page'])) {
				$page = (int)$_GET['page'];
				if ($page < 1) $page = 1;
			} else {
				$page = 1;
			}
			if ($page > $cntPages) $page = $cntPages;
			$pages = ($cntPages > 1) ? pagination($page, $cntPages, '/loads/category/' . $id) : '&nbsp;';
			
			
			
			//navigation panel
			$navi = array();
			$navi['{ADD_LINK}'] = ($this->ACL->turn(array('loads', 'add_materials'), false)) ? 
				get_link(__('Add material'), '/loads/add_form/') : '';
			$navi['{NAVIGATION}'] = $this->_buildBreadCrumbs($id);	
			$navi['{PAGINATION}'] = $pages;
			$navi['{META}'] = __('Count material in cat') . $total;
			$this->_globalize($navi);
			
			
			if ($total == 0) {
				$html = __('Materials not found');
				return $this->_view($html);
			}
			

			$html = '';
			$conditions = array('`a`.`category_id`' => $id);
			if (!$this->ACL->turn(array('other', 'can_see_hidden'), false)) $conditions['`a`.`available`'] = '1';
			$sql = $this->DB->select('loads', DB_ALL, array(
				'joins' => array(
					array(
						'table' => 'loads_sections',
						'type' => 'LEFT',
						'alias' => 'b',
						'cond' => 'a.`category_id` = b.`id`',
					),
					array(
						'table' => 'users',
						'type' => 'LEFT',
						'alias' => 'd',
						'cond' => 'd.`id` = a.`author_id`',
					),
				),
				'fields' => array('`a`.*', '`b`.`title` as category_name'
				, '`d`.`name` AS author', '`d`.`status` AS author_status'),
				'alias' => 'a',
				'cond' => $conditions,
				'order' => getOrderParam(__CLASS__),
				'page' => $page,
				'limit' => Config::read('per_page', 'loads'),
			));
			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.')')));
			
			
			//ITERATION RECORDS
			foreach ($sql as $result) {
				$markets = array();
				$result = $this->Parser->quoteTags($result);
				$_SESSION['current_vars'] = $result;
				$htmlloads = $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, 
					Config::read('announce_lenght', 'loads'), $result);
				$markets['{ANNOUNCE}'] = $this->Parser->quoteTags($announce);
				
				foreach ($result as $key => $value) {
				   if ($key != 'announce') $markets['{'.strtoupper($key).'}'] = h($value);
				}
				
				$markets['{LOADS}'] = $result['downloads'];
				$markets['{CATEGORY_URL}'] = get_url('/loads/category/' . $result['category_id']);
				$markets['{PROFILE_URL}'] = getProfileUrl($result['author_id']);
				$html .= $this->_replaceMarkets($markets, $htmlloads);
				
				//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 into cache
			if ($this->cached)
				$this->Cache->write($html, $this->cacheKey, $this->cacheTags);
		}
		return $this->_view($html);
	}
	  
	  


	/**
	 * show page with load info
	 * @ page title
	 * @ categories
	 *
	 * @param int $id
	 */
	function view ($id = null) {
		//turn access
		$this->ACL->turn(array('loads', 'view_materials'));
		$id = intval($id);
		if (empty($id) || $id < 1) redirect('/');


		// извлекаем из БД информацию материала
		$sql = $this->DB->select('loads', DB_FIRST, array(
			'joins' => array(
				array(
					'table' => 'loads_sections',
					'type' => 'LEFT',
					'alias' => 'b',
					'cond' => 'a.`category_id` = b.`id`',
				),
				array(
					'table' => 'users',
					'type' => 'LEFT',
					'alias' => 'd',
					'cond' => 'd.`id` = a.`author_id`',
				),
			),
			'fields' => array('`a`.*', '`b`.`title` as category_name', 'b.`no_access` as no_access'
			, '`d`.`name` AS author', '`d`.`status` AS author_status'),
			'alias' => 'a',
			'cond' => array('`a`.`id`' => $id),
		));
		//if no record - redirect ( info message )
		if (count($sql) < 1) return showInfoMessage(__('Some error occurred'), '/loads/');
		if ($sql[0]['available'] == 0 && !$this->ACL->turn(array('other', 'can_see_hidden'), false)) 
			return showInfoMessage(__('Permission denied'), '/loads/');
		if (!$this->ACL->checkCategoryAccess($sql[0]['no_access'])) 
			return showInfoMessage(__('Permission denied'), '/loads/');
		
		
		// Additional fields
		if (is_object($this->AddFields) && count($sql) > 0) {
			$sql = $this->AddFields->mergeRecords($sql);
		}
		$result = $this->Parser->quoteTags($sql[0]);
		$_SESSION['current_vars'] = $result;
		
		
		//  в другом случае извлекаем шаблон отображения материала
		$html = $this->Parser->getAndParse('vievmat.html');
		
		$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;
		
		
		// crumbs
		$navi = array();
		$navi['{CATEGORY_URL}'] = get_url('/loads/category/' . $result['category_id']);
		$navi['{CATEGORY_NAME}'] = h($result['category_name']);
		$navi['{NAVIGATION}'] = $this->_buildBreadCrumbs($result['category_id']);
		$this->_globalize($navi);



		//если админ, выводим админбар
		$markets = array();
		$markets['{MODER_PANEL}'] = $this->_getAdminBar($result);
		
		
		
		if(!empty($result['download']) and is_file(R . 'sys/files/loads/'.$result['download'])) {
		  $attach_serv = '<a target="_blank" href="' . get_url('/loads/download_file/' 
		  . $result['id']) . '">Скачать с сервера ('.
		  ( getFileSize( R . 'sys/files/loads/'.$result['download'] ) ).' Кб)</a>';
		} else {
			$attach_serv  = '';
		}
		
		if( !empty($result['download_url_size'])) {
			$attach_rem_size = ' ('.$result['download_url_size'].')';
		} else {
			$attach_rem_size  = '';
		}

		if(!empty($result['download_url'])) {
		  $attach_rem_url = '<a target="_blank" href="' . get_url('/loads/download_file_url/' 
		  . $result['id']) . '">Скачать удалённо' . $attach_rem_size . '</a>';
		} else {
			$attach_rem_url = '';
		}
		$markets['{ATTACHMENT}'] = '[ ' . $attach_serv . ' ' . $attach_rem_url . ' ]';
		
		$text_load = $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_load = str_replace('{IMAGE'.$attach['attach_number'].'}'
					, '[img]' . get_url('/sys/files/'.$this->module.'/'.$attach['filename']).'[/img]'
					, $text_load);
				}
			}
		}
		$text_load = $this->Textarier->print_page($text_load, $result['author_status'], $result['title']);
		$markets['{MAIN_TEXT}'] = $this->Parser->quoteTags($text_load);
		
		foreach ($result as $key=>$value) {
		   $markets['{'.strtoupper($key).'}'] = h($value);
		}
		
		$markets['{PROFILE_URL}'] = getProfileUrl($result['author_id']);
		$html = $this->_replaceMarkets($markets, $html);

		$this->DB->save('loads', array('views' => ($result['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']);
		
		/* COMMENT BLOCK */
		if (Config::read('comment_active', 'loads') == 1 
		&& $this->ACL->turn(array('loads', 'view_comments'), false) && $result['commented'] == 1) {
			if ($this->ACL->turn(array('loads', 'add_comments'), false)) 
				$this->comments  = $this->_add_comment_form($id);
			$this->comments  = $this->_get_comments($id) . $this->comments;
		}
		
		
		//prepear cache tags
		$this->setCacheTag(array(
			'user_id_' . $result['author_id'],
			'record_id_' . $result['id'],
		));
		
		
		//формируем блок со списком  разделов
		$this->_getCatsTree($result['category_id']);
		
		return $this->_view($html);
	}


	
	
	/*
	 * return form to add 
	 */
	function add_form () {
		//turn access
		$this->ACL->turn(array('loads', 'add_materials'));
		$writer_status = (!empty($_SESSION['user']['status'])) ? $_SESSION['user']['status'] : 0;
		
		
		//формируем блок со списком  разделов
		$this->_getCatsTree();
		
		
		$markets = array();
		$html = $this->Parser->getAndParse('addform.html' );
		
		// Additional fields
		if (is_object($this->AddFields)) {
			$_addFields = $this->AddFields->getInputs();
			foreach($_addFields as $k => $field) {
				$html = str_replace('{' . strtoupper($k) . '}', $field, $html );
			}
		}
		
		
		
		$sql = $this->DB->select('loads_sections', DB_ALL);
		$cats_change = '';
		foreach ($sql as $cat) {
			if (!empty($_SESSION['FpsForm']['in_cat']) && $_SESSION['FpsForm']['in_cat'] == $cat['id'])
				$selected = ' selected="selected"';
			else if (!empty($_SESSION['viewMessage']['in_cat']) && $_SESSION['viewMessage']['in_cat'] == $cat['id'])
				$selected = ' selected="selected"';
			else
				$selected = '';
				
			$cats_change .= '<option value="' . $cat['id'] . '"'
			. $selected . ' >' . h($cat['title']) . '</option>';
		}
		
		
		//if user want preview message
		if (isset($_SESSION['viewMessage'])) {
			$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']);
			$download_url 		= h($_SESSION['viewMessage']['download_url']);
			$download_url_size 		= h($_SESSION['viewMessage']['download_url_size']);
			$commented 			= h($_SESSION['viewMessage']['commented']);
			$available 			= h($_SESSION['viewMessage']['available']);
			$available 			= h($_SESSION['viewMessage']['in_cat']);
			unset( $_SESSION['viewMessage'] );
		}
		
		// Errors
		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']);
			$download_url	= h($_SESSION['FpsForm']['download_url']);
			$download_url_size	= h($_SESSION['FpsForm']['download_url_size']);
			$commented	    = h($_SESSION['FpsForm']['commented']);
			$available	    = h($_SESSION['FpsForm']['available']);
			$available	    = h($_SESSION['FpsForm']['in_cat']);
			unset( $_SESSION['FpsForm'] );
		}
		
		//comments and hide
		$commented = (!empty($commented) || !isset($_POST['submitForm'])) ? 'checked="checked"' : '';
		if (!$this->ACL->turn(array('loads', 'record_comments_management'), false)) $commented .= ' disabled="disabled"';
		$available = (!empty($available) || !isset($_POST['submitForm'])) ? 'checked="checked"' : '';
		if (!$this->ACL->turn(array('loads', 'hide_material'), false)) $available .= ' disabled="disabled"';
		
		
		
		$markets['{ACTION}'] = get_url('/loads/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['{DOWNLOAD_URL}'] = (!empty($download_url)) ? $download_url : '';
		$markets['{DOWNLOAD_URL_SIZE}'] = (!empty($download_url_size)) ? $download_url_size : '';
		$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);
		
		
		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('loads', 'add_materials'));
		// Если не переданы данные формы - функция вызвана по ошибке
		if (!isset( $_POST['mainText']) 
		|| !isset( $_POST['title']) 
		|| !isset( $_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', 'download_url', 'download_url_size');
		$fields_settings = Config::read('fields', 'loads');
		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     = mb_substr( $_POST['title'], 0, 128 );
		$addLoad   = trim($_POST['mainText']);
		$title     = trim( $title );
		$in_cat    = intval($_POST['cats_selector']);
		$commented = (!empty($_POST['commented'])) ? 1 : 0;
		$available = (!empty($_POST['available'])) ? 1 : 0;
		if (!$this->ACL->turn(array('loads', 'record_comments_management'), false)) $commented = '1';
		if (!$this->ACL->turn(array('loads', 'hide_material'), false)) $available = '1';
		
		// Preview
		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, 'download_url' => null, 'download_url_size' => null, 'commented' => null, 'available' => null), $_POST);
			redirect('/loads/add_form/');
		}

		// Проверяем, заполнены ли обязательные поля
		$valobj = new Validate;  //validation data class
		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($addLoad))                    
			$error = $error . '<li>' . __('Empty field "material"') . '</li>' ."\n";
		
		if (mb_strlen($addLoad) > Config::read('max_lenght', 'loads')) 
			$error = $error .'<li>'. sprintf(__('Wery big "material"'), Config::read('max_lenght', 'loads')) .'</li>'."\n";
		if (mb_strlen($addLoad) < Config::read('min_lenght', 'loads')) 
			$error = $error .'<li>'. sprintf(__('Wery small "material"'), Config::read('min_lenght', 'loads')) .'</li>'."\n";
		
		if (Config::read('require_file', 'loads') == 1) {
			if (empty($_FILES['attach']['name'])) 
				$error = $error . '<li>' . __('Not attaches') . '</li>' . "\n";	
		}
		if (isset($_FILES['attach']['name']) 
		&& $_FILES['attach']['size'] > Config::read('max_file_size', 'loads'))
			$error = $error .'<li>'. sprintf(__('Wery big file2'), (Config::read('max_file_size', 'loads')/1024)) .'</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";
		if (!empty($download_url) && !$valobj->cha_val($download_url, V_TITLE)) 
			$error = $error. '<li>' . __('Wrong chars in "download_url"') . '</li>' ."\n";
		if (!empty($download_url_size) && !$valobj->cha_val($download_url_size, V_TITLE)) 
			$error = $error. '<li>' . __('Wrong chars in "download_url_size"') . '</li>' ."\n";
			
			
													
		$sql = $this->DB->select('loads_sections', DB_FIRST, array('cond' => array('id' => $in_cat)));
		if (empty($sql)) $error = $error . __('Can not find category')."\n";
		$info_cat = $sql[0];
		
		
		
			
		// 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, 'download_url' => null, 'download_url_size' => 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('/loads/add_form/');
		}


		//Проверяем прикрепленный файл...
		$file = '';
		if (!empty($_FILES['attach']['name'])) {
			$file = $this->__saveFile($_FILES['attach']);
		}

		// span protected
		if ( isset( $_SESSION['unix_last_post'] ) and ( time() - $_SESSION['unix_last_post'] < 30 ) ) {
			return showInfoMessage(__('Your message has been added'), '/loads/');
		}
		
		// Формируем SQL-запрос на добавление темы
		$addLoad = mb_substr($addLoad, 0, Config::read('max_lenght', 'loads'));
		$query = $this->DB->save('loads', array(
				'title' 		=> $title,
				'main' 			=> $addLoad,
				'date' 			=> new Expr('NOW()'),
				'author_id' 	=> $_SESSION['user']['id'],
				'category_id' 	=> $in_cat,
				'download' 		=> $file,
				'description'   => $description,
				'tags'          => $tags,
				'sourse'  	    => $sourse,
				'sourse_email'  => $sourse_email,
				'sourse_site'   => $sourse_site,
				'download_url'   => $download_url,
				'download_url_size'   => $download_url_size,
				'commented'     => $commented,
				'available'     => $available,
				'view_on_home' 	=> $info_cat['view_on_home'],
		));
		// 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);
		
		//clear cache
		$this->Cache->clean(CACHE_MATCHING_ANY_TAG, array('module_load'));
		$this->DB->cleanSqlCache();
		if ($this->Log) $this->Log->write('adding load', 'load id(' . $last_id . ')');
		return showInfoMessage(__('Material successful added'), '/loads/' );					  
	}




	/**
	 * 
	 * Create form and fill his data from record which ID
	 * transfered into function. Show errors if an exists
	 * after unsuccessful attempt.
	 * 
	 */
	function edit_form($id = null) {
		$idLoad = (int)$id;
		if ($idLoad < 1 || empty($idLoad)) redirect('/');
		$writer_status = (!empty($_SESSION['user']['status'])) ? $_SESSION['user']['status'] : 0;

		
		// Получаем из БД информацию о редактируемой теме
		$res = $this->DB->select('loads', DB_FIRST, array(
			'joins' => array(
				array(
					'table' => 'loads_sections',
					'type' => 'LEFT',
					'alias' => 'b',
					'cond' => 'a.`category_id` = b.`id`',
				),
				array(
					'table' => 'users',
					'type' => 'LEFT',
					'alias' => 'd',
					'cond' => 'd.`id` = a.`author_id`',
				),
			),
			'fields' => array('`a`.*', '`b`.`title` as category_name', 'd.`status` AS author_status'
			, '`d`.`name` AS author', 'b.`no_access` as no_access'),
			'alias' => 'a',
			'cond' => array('`a`.`id`' => $id),
		));
		if (count($res) == 0) redirect('/loads/');
		
		// 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);
		}
		
		
		$load = $res[0];
		$this->page_title .= __('Material editing');
		$html = '';
		$markets = array();
		
		
		if (!$this->ACL->turn(array('loads', 'edit_materials'), false) 
		&& (empty($_SESSION['user']['id']) || $load['author_id'] != $_SESSION['user']['id'] 
		|| !$this->ACL->turn(array('loads', 'edit_mine_materials'), false))) {
			return showInfoMessage(__('Permission denied'), '/loads/' );
		}
		
		$_SESSION['current_vars'] = $load;

		//формируем блок со списком  разделов
		$this->_getCatsTree($load['category_id']);
		// Preview
		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               = $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']);
			$download_url 		= h($_SESSION['viewMessage']['download_url']);
			$download_url_size 	= h($_SESSION['viewMessage']['download_url_size']);
			$commented 			= h($_SESSION['viewMessage']['commented']);
			$available 			= h($_SESSION['viewMessage']['available']);
			unset( $_SESSION['viewMessage'] );
		}
		
		
		// Errors
		if (isset($_SESSION['FpsForm'])) {
			$info = $this->Parser->getAndParse('infomessage.html' );
			$info = str_replace( '{INFO_MESSAGE}', $_SESSION['FpsForm']['error'], $info );
			$html = $html . $info . "\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']);
			$download_url 		= h($_SESSION['FpsForm']['download_url']);
			$download_url_size 	= h($_SESSION['FpsForm']['download_url_size']);
			$commented 			= h($_SESSION['FpsForm']['commented']);
			$available 			= h($_SESSION['FpsForm']['available']);
			unset($_SESSION['FpsForm']);
		} else {
			$title    			= h($load['title']);
			$edit   			= h($load['main']);
			$description		= h($load['description']);
			$tags 				= h($load['tags']);
			$sourse 			= h($load['sourse']);
			$sourse_email 		= h($load['sourse_email']);
			$sourse_site 		= h($load['sourse_site']);
			$download_url 		= h($load['download_url']);
			$download_url_size 	= h($load['download_url_size']);
			$commented 			= h($load['commented']);
			$available 			= h($load['available']);
		}
		//comments and hide
		$commented = (!empty($commented)) ? 'checked="checked"' : '';
		if (!$this->ACL->turn(array('loads', 'record_comments_management'), false)) $commented .= ' disabled="disabled"';
		$available = (!empty($available)) ? 'checked="checked"' : '';
		if (!$this->ACL->turn(array('loads', 'hide_material'), false)) $available .= ' disabled="disabled"';
		
		
		$cats = $this->DB->select('loads_sections', DB_ALL);
		$cats_change = '';
		foreach ($cats as $cat) {
			if($load['category_id'] == $cat['id']) {
				$cats_change .= "<option value=\"" . $cat['id'] . "\" selected=\"selected\">" 
				. h($cat['title']) . "</option>";
			} else {
				$cats_change .= "<option value=\"" . $cat['id'] . "\">" 
				. h($cat['title']) . "</option>";
			}
		}

		
		// Считываем в переменную файл шаблона, содержащего форму для редактирования темы
		$tpl = $this->Parser->getAndParse('editform.html' );
		$markets['{ACTION}'] = get_url('/loads/update/' . $idLoad);
		$markets['{TITLE}'] = $title;
		$markets['{CATS_SELECTOR}'] = $cats_change;
		$markets['{AUTHOR}'] = h($load['author']);
		$markets['{MAIN_TEXT}'] = $edit;
		$markets['{DESCRIPTION}'] = $description;
		$markets['{TAGS}'] = $tags;
		$markets['{SOURSE}'] = $sourse;
		$markets['{SOURSE_EMAIL}'] = $sourse_email;
		$markets['{SOURSE_SITE}'] = $sourse_site;
		$markets['{DOWNLOAD_URL}'] = $download_url;
		$markets['{DOWNLOAD_URL_SIZE}'] = (!empty($download_url_size)) ? $download_url_size : '';
		$markets['{COMMENTED}'] = $commented;
		$markets['{AVAILABLE}'] = $available;
		foreach ($load 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}'] = $this->_buildBreadCrumbs($load['category_id']);
		$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) or
		   !isset($_POST['title']) or
		   !isset($_POST['mainText']))
		{
			redirect('/');
		}
		$idLoad = (int)$id;
		if ( $idLoad < 1 ) redirect('/loads/');


		
		$target = $this->DB->select('loads', DB_FIRST, array('cond' => array('id' => $idLoad)));
		if (count($target) < 1) redirect('/loads/');
		$load = $target[0];
		
		if (!$this->ACL->turn(array('loads', 'edit_materials'), false) 
		&& (empty($_SESSION['user']['id']) || $load['author_id'] != $_SESSION['user']['id'] 
		|| !$this->ACL->turn(array('loads', 'edit_mine_materials'), false))) {
			return showInfoMessage(__('Permission denied'), '/loads/' );
		}

		$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', 'download_url', 'download_url_size');
		$fields_settings = Config::read('fields', 'loads');
		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));
		$editLoad   = trim($_POST['mainText']);
		$in_cat 	= intval($_POST['cats_selector']);
		$commented = (!empty($_POST['commented'])) ? 1 : 0;
		$available = (!empty($_POST['available'])) ? 1 : 0;
		if (!$this->ACL->turn(array('loads', 'record_comments_management'), false)) $commented = '1';
		if (!$this->ACL->turn(array('loads', 'hide_material'), false)) $available = '1';
		
		// Preview
		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, 'download_url' => null, 'download_url_size' => null, 'commented' => null, 'available' => null), $_POST);
			redirect('/loads/edit_form/' . $id);
		}
		
		if (mb_strlen($editLoad) > Config::read('max_lenght', 'loads')) 
			$error = $error . '<li>' . sprintf(__('Wery big "material"'), Config::read('max_lenght', 'loads')).'</li>'."\n";
		if (mb_strlen($editLoad) < Config::read('min_lenght', 'loads')) 
			$error = $error .'<li>' . sprintf(__('Wery small "material"'), Config::read('min_lenght', 'loads')).'</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( $editLoad ) ) 
			$error = $error.'<li>' . __('Empty field "material"') .'</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";
		if (!empty($download_url) && !$valobj->cha_val($download_url, V_TITLE)) 
			$error = $error.'<li>' . __('Wrong chars in "download_url"') .'</li>'."\n";
		if (!empty($download_url_size) && !$valobj->cha_val($download_url_size, V_TITLE)) 
			$error = $error.'<li>' . __('Wrong chars in "download_url_size"') .'</li>'."\n";
		
		$sql = $this->DB->select('loads_sections', DB_COUNT, array('cond' => array('id' => $in_cat)));
		if (empty($sql)) $error = $error .'<li>' . __('Can not find category') .'</li>'."\n";
		$info_cat = $sql[0];
		
		
		
		// Delete attached file if an exists and we get flag from editor
		if (!empty($_POST['delete_file']) || !empty($_FILES['attach']['name'])) {
			if (!empty($load['download']) && file_exists($this->attached_files_path . $load['download'])) {
				_unlink($this->attached_files_path . $load['download']);
			}
		}
		
		//Проверяем прикрепленный файл...
		$file = '';
		if (!empty($_FILES['attach']['name'])) {
			$file = $this->__saveFile($_FILES['attach']);
		}
		
		
		
		// Errors
		if (!empty($error)) {
			$_SESSION['FpsForm'] = array_merge(array('title' => null, 'mainText' => null, 
				'description' => null, 'tags' => null, 'sourse' => null, 'sourse_email' => null, 'in_cat' => $in_cat,
				'sourse_site' => null, 'download_url' => null, 'download_url_size' => 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('/loads/edit_form/' . $idLoad );
		}
		
		
		// Запрос на обновление новости
		$this->DB->save('loads', array(
			'id' 		   => $idLoad,
			'title' 	   => $title,
			'main' 		   => $editLoad,
			'category_id'  => $in_cat,
			'description'  => $description,
			'tags'         => $tags,
			'sourse'  	   => $sourse,
			'sourse_email' => $sourse_email,
			'sourse_site'  => $sourse_site,
			'download_url'  => $download_url,
			'download_url_size'  => $download_url_size,
			'commented'    => $commented,
			'available'    => $available,
			'download'     => $file,
		));
		// Save additional fields if they is active
		if (is_object($this->AddFields)) {
			$this->AddFields->save($idLoad, $_addFields);
		}
		
		//clear cache
		$this->Cache->clean(CACHE_MATCHING_TAG, array('record_id_' . $idLoad, 'module_load'));
		$this->DB->cleanSqlCache();
		if ($this->Log) $this->Log->write('editing load', 'load id(' . $idLoad . ')');
		return showInfoMessage(__('Operation is successful'), getReferer());

	}






	// Функция удаляет тему; ID темы передается методом GET
	function delete($id = null) {
		$idLoad = (int)$id;
		if ( $idLoad < 1 ) {
			redirect('/');
		}

		$sql = $this->DB->select('loads', DB_ALL, array('cond' => array('id' => $idLoad)));
		$result = $sql[0];
		
		if (!$this->ACL->turn(array('loads', 'delete_materials'), false) 
		&& (empty($_SESSION['user']['id']) || $result['author_id'] != $_SESSION['user']['id'] 
		|| !$this->ACL->turn(array('loads', 'delete_mine_materials'), false))) {
			return showInfoMessage(__('Permission denied'), '/loads/' );
		}
		
		$this->Cache->clean(CACHE_MATCHING_ANY_TAG, array('module_load'));
		
		if ( !empty( $result['download'] ) and is_file( R . 'sys/files/loads/' . $result['download'] ) )
			unlink(R . 'sys/files/loads/' . $result['download'] );
			
		// Delete records from data base. Also delete additional fields data
		$this->DB->query("DELETE FROM `" . $this->DB->getFullTableName('loads') . "` WHERE `id` = '" . $idLoad . "'");
		$this->DB->query("DELETE FROM `" . $this->DB->getFullTableName('news_add_content') . "` WHERE `entity_id` = '" . $idLoad . "'");
		
		$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 . "'");
		
		$this->DB->cleanSqlCache();
		if ($this->Log) $this->Log->write('delete load', 'load id(' . $idLoad . ')');
		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');
	}	
	




	function download_file($id = null, $mimetype = 'application/octet-stream') {
		
		if (empty($id)) redirect('/');
		$id = intval($id);
		//clear cache
		$this->Cache->clean(CACHE_MATCHING_TAG, array('record_id_' . $id, 'module_load'));
		
		$res = $this->DB->select('loads', DB_FIRST, array('cond' => array('id' => $id)));
		if (count($res) < 1) return showInfoMessage(__('File not found'), '/loads/' );
		$result = $res[0];
		
		$this->DB->save('loads', array(
			'`downloads` = `downloads` + 1',
			'id' => $id,
		));
		$this->DB->cleanSqlCache();
		$name = $result['download'];
		$filename = R . 'sys/files/loads/'.$result['download'];

		if (!file_exists($filename))
			return showInfoMessage(__('File not found'), '/loads/' );
		$from=0;
		$size=filesize($filename);
		$to=$size;
		if (isset($_SERVER['HTTP_RANGE'])) {
			if (preg_match ('#bytes=-([0-9]*)#',$_SERVER['HTTP_RANGE'],$range)) {// если указан отрезок от конца файла
				$from=$size-$range[1];
				$to=$size;
			} elseif(preg_match('#bytes=([0-9]*)-#',$_SERVER['HTTP_RANGE'],$range)) {// если указана только начальная метка

				$from=$range[1];
				$to=$size;
			} elseif(preg_match('#bytes=([0-9]*)-([0-9]*)#',$_SERVER['HTTP_RANGE'],$range)) {// если указан отрезок файла

				$from=$range[1];
				$to=$range[2];
			}
			header('HTTP/1.1 206 Partial Content');

			$cr='Content-Range: bytes '.$from .'-'.$to.'/'.$size;
		} else
			header('HTTP/1.1 200 Ok');
		
		$etag=md5($filename);
		$etag=substr($etag, 0, 8) . '-' . substr($etag, 8, 7) . '-' . substr($etag, 15, 8);
		header('ETag: "'.$etag.'"');
		header('Accept-Ranges: bytes');
		header('Content-Length: ' .($to-$from));
		if (isset($cr))header($cr);
			header('Connection: close');
			
		header('Content-Type: ' . $mimetype);
		header('Last-Modified: ' . gmdate('r', filemtime($filename)));
		header("Last-Modified: ".gmdate("D, d M Y H:i:s", filemtime($filename))." GMT");
		header("Expires: ".gmdate("D, d M Y H:i:s", time() + 3600)." GMT");
		$f=fopen($filename, 'rb');


		if (preg_match('#^image/#',$mimetype))
			header('Content-Disposition: filename="'.$name.'";');
		else
			header('Content-Disposition: attachment; filename="'.$name.'";');

		fseek($f, $from, SEEK_SET);
		$size=$to;
		$downloaded=0;
		while(!feof($f) and ($downloaded<$size)) {
			$block = min(1024*8, $size - $downloaded);
			echo fread($f, $block);
			$downloaded += $block;
			flush();
		}
		fclose($f);
	}


	function download_file_url($id = null, $mimetype = 'application/octet-stream') {
	
		$res = $this->DB->select('loads', DB_FIRST, array('cond' => array('id' => $id)));
		$result = $res[0];
	
		$this->DB->save('loads', array(
			'`downloads` = `downloads` + 1',
			'id' => $id,
		));
		$this->DB->cleanSqlCache();
	
		header('Location: ' . $result['download_url'] . '');
	}
	
	
	/**
	* @param int $id - record ID
	*
	* update date by record also up record in recods list
	*/
	public function upper($id) {
		$this->ACL->turn(array('loads', 'up_materials'));
		$id = (int)$id;
		if ($id < 1) {
			redirect('/');
		}
		$this->DB->save('loads', array('id' => $id, 'date' => new Expr('NOW()')));
		return showInfoMessage(__('Operation is successful'), '/loads/');
	}

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

	
	/**
	 * Try Save file
	 * 
	 * @param array $file (From POST request)
	 */
	private function __saveFile($file) {
		// Массив недопустимых расширений файла вложения
		$extentions = $this->denyExtentions;
		// Извлекаем из имени файла расширение
		$ext = strrchr( $file['name'], "." );
		
		
		// Формируем путь к файлу
		if (in_array($ext, $extentions)) {
			$path = md5(uniqid(rand(), true)) . '-' . date("YmdHis", time()) . '.txt';
		} else {

			$path = md5(uniqid(rand(), true)) . '-' . date("YmdHis", time()) . $ext;
		}
		// Перемещаем файл из временной директории сервера в директорию files
		if (move_uploaded_file($file['tmp_name'], R . 'sys/files/loads/' . $path)) {
			chmod( R . 'sys/files/loads/' . $path, 0644 );
		}
		
		return $path;
	}
	


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

?>
