<?php

class ProductHandler extends Handler{

	var $product;
	var $category;
	var $productsUrl = array();
	var $productsName = array();
	var $productsNavName = array();
	var $categoriesUrl = array();
	var $categoriesName = array();

	function __construct() {
		parent::__construct('ProductHandler');
	}
	
	function getItemList($request=array('full' => 1)) {
		$result = array();
//		$result = $this->DB->SelectArray(array('parentitem'),'id,name,itemtype,sort_order,(\'now\'::date - date_changed::date) AS unmodified,date_changed,access_flag,date_locked',array(),'sort_order asc,id asc');
		$result = $this->DB->SelectArray(array('parentitem'),'id,name,itemtype,sort_order,TIMESTAMPDIFF(day,date_changed,NOW())  AS unmodified,date_changed,access_flag,date_locked',array(),'sort_order asc,id asc');
		if($request['full']) {
			$presets = array();
			$selected = $this->DB->SelectAny('SELECT id, name FROM preset');
			$presets_count = count($selected);
			for($i = 0; $i < $presets_count; $i++) $presets[$selected[$i]['id']] = $selected[$i]['name'];
			$packages = array();
			$hostpaths = array();
			$usernames = array();
			$count = count($result);
			for($i = 0; $i < $count; $i++){
				$date_changed = explode('.', $result[$i]['date_changed']);
				$result[$i]['date_changed'] = $date_changed[0];
				$date_locked = explode('.', $result[$i]['date_locked']);
				$result[$i]['date_locked'] = $date_locked[0];
				$result[$i]['username'] = $result[$i]['access_flag'] ? $this->getUserName(array('type' => 1, 'userid' => $result[$i]['access_flag'])) : '';
				$result[$i]['publish'] = array();
				$query = 'SELECT packagepublish.id, packagepublish.ownerid as package_id, packagepublish.host, packagepublish.userid, packagepublish.date_published FROM packagepublish WHERE packagepublish.type = 1 AND packagepublish.successful = 1 AND packagepublish.date_published > \''.$result[$i]['date_changed'].'\' AND packagepublish.ownerid IN (SELECT DISTINCT packageitem.ownerid FROM packageitem WHERE packageitem.type = 17 AND packageitem.object = \''.$result[$i]['id'].'\') ORDER BY packagepublish.date_published DESC';
				$packagepublish = $this->DB->SelectAny($query);
				$presets_unique = array();
				$c = count($packagepublish);
				$index = 0;
				for($j = 0; $j < $c; $j++){
					if(isset($presets_unique[$packagepublish[$j]['host']])) continue;
					$presets_unique[$packagepublish[$j]['host']] = true;
					$result[$i]['publish'][$index] = $packagepublish[$j];
					$date_published = explode ('.', $packagepublish[$j]['date_published']);
					$result[$i]['publish'][$index]['date_published'] = $date_published[0];
					if(!isset($packages[$packagepublish[$j]['package_id']])){
						$sel = $this->DB->SelectAny('SELECT name FROM package WHERE id = '.$packagepublish[$j]['package_id'].' LIMIT 1');
						$packages[$packagepublish[$j]['package_id']] = empty($sel) ? '[deleted]' : $sel[0]['name'];
					}
					$result[$i]['publish'][$index]['package_name'] = $packages[$packagepublish[$j]['package_id']];
					if(!isset($hostpaths[$packagepublish[$j]['host']])){
						$sel = $this->DB->SelectAny('SELECT name FROM preset WHERE id = '.$packagepublish[$j]['host'].' LIMIT 1');
						$hostpaths[$packagepublish[$j]['host']] = empty($sel) ? '[unknown]' : $sel[0]['name'];
					}
					$result[$i]['publish'][$index]['hostpath'] = $hostpaths[$packagepublish[$j]['host']];
					if(!isset($usernames[$packagepublish[$j]['userid']])){
						$sel = $this->DB->SelectAny('SELECT username FROM member WHERE id = '.$packagepublish[$j]['userid'].' LIMIT 1');
						$usernames[$packagepublish[$j]['userid']] = empty($sel) ? '[unknown]' : $sel[0]['username'];
					}
					$result[$i]['publish'][$index]['username'] = $usernames[$packagepublish[$j]['userid']];
					$index++;
				}
				$result[$i]['published_count'] = count($result[$i]['publish']).'/'.$presets_count;
			}
		}
		return $result;
	}

	function getUserName($request = array()){
		$selected = $this->DB->SelectAny('SELECT username FROM '.($request['type'] == 1 ? 'member' : 'publisher_user').' WHERE id = '.$request['userid'].' LIMIT 1');
		$username = empty($selected) ? '[undefined]' : $selected[0]['username'];
		return $username;
	}

	function getLock($request = array()){
		$table = '';
		$id = 0;
		empty($request['category']) and $request['category'] = 0;
		!empty($request['category']) and $table = 'category' and $id = $request['category'];
		empty($request['product']) and $request['product'] = 0;
		!empty($request['product']) and $table = 'product' and $id = $request['product'];
		empty($request['parentitem']) and $request['parentitem'] = 0;
		!empty($request['parentitem']) and $table = 'parentitem' and $id = $request['parentitem'];
		empty($request['member']) and $request['member'] = 0;
		if(!empty($request['member']) && (!empty($request['category']) || !empty($request['product'])  || !empty($request['parentitem']))) {
			$query='select t.id, t.access_flag, t.date_locked, u.username from '.$table.' t, member u where t.id='.$id.' and t.access_flag=u.id';
			$selected = $this->DB->SelectAny($query);
		}		
		return !empty($selected[0])? $selected[0] : array();
	}

	function makeLock($request = array()) {
		$table = '';
		$id = 0;
		empty($request['category']) and $request['category'] = 0;
		!empty($request['category']) and $table = 'category' and $id = $request['category'];
		empty($request['product']) and $request['product'] = 0;
		!empty($request['product']) and $table = 'product' and $id = $request['product'];
		empty($request['parentitem']) and $request['parentitem'] = 0;
		!empty($request['parentitem']) and $table = 'parentitem' and $id = $request['parentitem'];
		empty($request['member']) and $request['member'] = 0;
		switch($table) {
			case 'category': $entity = 23; break;
			case 'parentitem': $entity = 24; break;
			case 'product': $entity = 25; break;
		}
		if(!empty($request['member']) && (!empty($request['category']) || !empty($request['product'])  || !empty($request['parentitem']))) {
			$this->DB->begin();
			$this->DB->update($table,array('access_flag' => $request['member'],'date_locked' => 'now()'),array('id' => $id),0);
			$this->setLogEvent(5,$entity,3,'Lock '.ucfirst($table).' ['.$id.']',$id);
			$this->DB->commit();
		}
		return $request;
	}

	function makeUnLock($request = array()) {
		$table = '';
		$id = 0;
		empty($request['category']) and $request['category'] = 0;
		!empty($request['category']) and $table = 'category' and $id = $request['category'];
		empty($request['product']) and $request['product'] = 0;
		!empty($request['product']) and $table = 'product' and $id = $request['product'];
		empty($request['parentitem']) and $request['parentitem'] = 0;
		!empty($request['parentitem']) and $table = 'parentitem' and $id = $request['parentitem'];
		empty($request['member']) and $request['member'] = 0;
		switch($table) {
			case 'category': $entity = 23; break;
			case 'parentitem': $entity = 24; break;
			case 'product': $entity = 25; break;
		}
		if(!empty($request['member']) && (!empty($request['category']) || !empty($request['product'])  || !empty($request['parentitem']))) {
			$this->DB->begin();
			$this->DB->update($table,array('access_flag' => 0),array('id' => $id));
			$this->setLogEvent(5,$entity,4,'UnLock '.ucfirst($table).' ['.$id.']',$id);
			$this->DB->commit();
		}
		return $request;
	}

	function selectParentItemComments($request = array()){
		if(empty($request['fields'])) $request['fields']='pic.*,m.username as member';
		if(empty($request['sortColumn'])) { $request['sortColumn']='pic.version'; $request['sortType']='desc';}
		$request['conditions']['m.id']=array('='=>'pic.member');
		$request['conditions']['pic.ownerid']=array('='=>$request[1]);
		foreach($request['conditions'] as $k=>$v) $rels[]='and';
		if(empty($request['curPageNumber'])) $request['curPageNumber']=1;
		if(empty($request['pageRecordsQty'])) $request['pageRecordsQty']=10;
		$selected=$this->DB->SelectArray(Array('member m','parentitemcomment pic'),'count(*) as qty',$request['conditions'],0,0,0,array(),'CND_COMPLEX',$rels);
		$request['recordsTotal']=$selected[0]['qty'];
		$request['pagesTotal'] = ceil($request['recordsTotal']/$request['pageRecordsQty']);
		$request['curPage']=$this->DB->SelectArray(Array('member m','parentitemcomment pic'),$request['fields'],$request['conditions'],$this->getOrderBy($request),$this->getLimit($request),0,array(),'CND_COMPLEX',$rels);
		return $request;
	}

	function selectProductComments($request = array()){
		if(empty($request['fields'])) $request['fields']='pc.*,m.username as member';
		if(empty($request['sortColumn'])) { $request['sortColumn']='pc.version'; $request['sortType']='desc';}
		$request['conditions']['m.id']=array('='=>'pc.member');
		$request['conditions']['pc.ownerid']=array('='=>$request[1]);
		foreach($request['conditions'] as $k=>$v) $rels[]='and';
		if(empty($request['curPageNumber'])) $request['curPageNumber']=1;
		if(empty($request['pageRecordsQty'])) $request['pageRecordsQty']=10;
		$selected=$this->DB->SelectArray(Array('member m','productcomment pc'),'count(*) as qty',$request['conditions'],0,0,0,array(),'CND_COMPLEX',$rels);
		$request['recordsTotal']=$selected[0]['qty'];
		$request['pagesTotal'] = ceil($request['recordsTotal']/$request['pageRecordsQty']);
		$request['curPage']=$this->DB->SelectArray(Array('member m','productcomment pc'),$request['fields'],$request['conditions'],$this->getOrderBy($request),$this->getLimit($request),0,array(),'CND_COMPLEX',$rels);
		return $request;
	}


	function selectCategoryComments($request = array()){
		if(empty($request['fields'])) $request['fields']='cc.*,m.username as member';
		if(empty($request['sortColumn'])) { $request['sortColumn']='cc.version'; $request['sortType']='desc';}
		$request['conditions']['m.id']=array('='=>'cc.member');
		$request['conditions']['cc.ownerid']=array('='=>$request[1]);
		foreach($request['conditions'] as $k=>$v) $rels[]='and';
		if(empty($request['curPageNumber'])) $request['curPageNumber']=1;
		if(empty($request['pageRecordsQty'])) $request['pageRecordsQty']=10;
		$selected=$this->DB->SelectArray(Array('member m','categorycomment cc'),'count(*) as qty',$request['conditions'],0,0,0,array(),'CND_COMPLEX',$rels);
		$request['recordsTotal']=$selected[0]['qty'];
		$request['pagesTotal'] = ceil($request['recordsTotal']/$request['pageRecordsQty']);
		$request['curPage']=$this->DB->SelectArray(Array('member m','categorycomment cc'),$request['fields'],$request['conditions'],$this->getOrderBy($request),$this->getLimit($request),0,array(),'CND_COMPLEX',$rels);
		return $request;
	}

	function sortAccessories($request = array()) {
		empty($request) and $request = array();
		$this->DB->begin();
		foreach($request as $key => $value) {
			$this->DB->update('product',array('sort_order' => (intval($value['sort_order']) > 0? intval($value['sort_order']) : 1)),array('id' => $key));
		}
		$this->setLogEvent(5,25,15,'Sort accessories');
		$this->DB->commit();
		return array();
	}


	function sortProducts($request = array()) {
		empty($request) and $request = array();
		$this->DB->begin();
		foreach($request as $key => $value) {
//			$this->DB->update('product',array('sort_order' => (intval($value['sort_order']) > 0? intval($value['sort_order']) : 1)),array('id' => $key));
			$this->DB->update('product',array('sort_order' => (intval($value['sort_order']) > 0? intval($value['sort_order']) : 0)),array('id' => $key));
		}
		$this->setLogEvent(5,25,15,'Sort products');
		$this->DB->commit();
		return array();
	}

	function sortParentItems($request = array()) {
		empty($request) and $request = array();
		$this->DB->begin();
		foreach($request as $key => $value) {
			$this->DB->update('parentitem',array('sort_order' => (intval($value['sort_order']) > 0? intval($value['sort_order']) : 1)),array('id' => $key));
		}
		$this->setLogEvent(5,24,15,'Sort parent items');
		$this->DB->commit();
		return array();
	}

	function sortCategories($request = array()) {
		empty($request) and $request = array();
		$this->DB->begin();
		foreach($request as $key => $value) {
			$this->DB->update('category',array('sort_order' => (intval($value['sort_order']) > 0? intval($value['sort_order']) : 1)),array('id' => $key));
		}
		$this->setLogEvent(5,23,15,'Sort categories');
		$this->DB->commit();
		return array();
	}

function sortCatProducts($request = array()) {
//printArray ($request);exit;
	empty($request['cartlineitems']) and $request['cartlineitems'] = array();
	foreach($request['cartlineitems'] as $key => $value) {
		if(is_numeric($value['sort_order'])) {
			$cli = new CategoryLineItem();
			$cli->id = $key;
			$cli->sort_order = $value['sort_order'];
			$this->DB->processObject($cli);
			$this->DB->commit();
		}
	}
//-------
	/*empty($request['categories']) and $request['categories'] = array();
	foreach($request['categories'] as $key => $value) {
		if(is_numeric($value['sort_order'])) {
			$cat = new Category();
			$cat->id = $key;
			$cat->sort_order = $value['sort_order'];
			$this->DB->processObject($cat);
			$this->DB->commit();
		}
	}*/
//-------
	return $request;
}


	function getProductCollection($request=array()) {   
		$categories = $this->DB->SelectArray('categorylineitem','ownerid,item',array('1' => '1'),'id');
		$generation = $this->DB->SelectAny('select * from generation order by sort_order');
		$files = $this->DB->SelectAny('select * from productfile where filetype in (2,8)');
		$result = $collection = array();
		$result = $this->DB->SelectAny('select p.id, p.name, p.generation, p.product_class, p.path, p.path2, p.pid, pr.value as price, pr.current, p.full_desc, i.itemtype from product p, price pr, parentitem i where p.item=i.id and p.id=pr.ownerid and pr.value > 0 order by p.id asc, pr.current desc');
		foreach($result as $key => $value) {
			if(is_numeric($value['price']) && (double)$value['price'] > 0) {
				if(empty($collection[$value['id']])) {
					$collection[$value['id']] = array(
						'id' => $value['id'],
						'name' => strip_tags($value['name']),
						'product_class' => strip_tags($value['product_class']),
						'pid' => $value['pid'],
						'price' => number_format($value['price'],2,'.',''),
						'generation' => '',
						'itemtype' => $value['itemtype'],
					);
					foreach($generation as $k => $v) {
						if($v['id']==$value['generation']) {
							$collection[$value['id']]['generation'] = $v['id']==10? '' : $v['name'].($v['gen_type']==2? ' International ' : ' ').'Generation';
						}
					}
					foreach($categories as $k => $v) {
						if($v['item']==$value['id']) {
							$collection[$value['id']]['path'] = !empty($value['path2'])? '/'.$value['path2'] : $this->getCategoryPath($v['ownerid']).($value['itemtype']==1? '/'.$value['path'] : '#'.$value['id']);
							continue;
						}
					}
					foreach($files as $k => $v) {
						if($v['ownerid']==$value['id']) {
							if($value['itemtype']==1 && $v['filetype']==2) {
								$collection[$value['id']]['image'] = !empty($v['image_link'])? $v['image_link'] : $value['id'];
							}
							else if($value['itemtype']==2 && $v['filetype']==8) {
								$collection[$value['id']]['image'] = !empty($v['image_link'])? $v['image_link'] : $value['id'];
							}
						}
					}
					$desc = explode('.',$value['full_desc']);
					$collection[$value['id']]['desc'] = str_replace(array("\r\n", "\n", "\r"),'',@$desc[0].'.'.@$desc[1]);
				}
			}
			else unset($result[$key]);
		}
		return $collection;
	}

	function getProductList($request=array('full' => 1)) {
		$categories = $this->DB->SelectArray('categorylineitem, category' , 'name, categorylineitem.ownerid,categorylineitem.item', array( 'categorylineitem.ownerid' => 'category.id'),'categorylineitem.id');
		$result = array();
//		$result = $this->DB->SelectArray(array('product p, parentitem i'),'p.path,p.path2,p.id,p.name,i.itemtype,p.sort_order,(\'now\'::date - p.date_changed::date) AS unmodified,p.date_changed,p.access_flag,p.date_locked',array('p.item' => 'i.id','i.itemtype' => 1),'p.sort_order asc,p.id asc');
//		$result = $this->DB->SelectArray(array('product p, parentitem i'),'p.path,p.path2,p.id,p.name,i.itemtype,p.sort_order,(\'now\'::date - p.date_changed::date) AS unmodified,p.date_changed,p.access_flag,p.date_locked',array('p.item' => 'i.id','i.itemtype' => 1),' p.sort_order asc,p.id asc  ');
		$result = $this->DB->SelectArray(array('product p, parentitem i'),'p.path,p.path2,p.id,p.nav_name as name,i.itemtype,p.sort_order, TIMESTAMPDIFF(day,p.date_changed,NOW()) AS unmodified,p.date_changed,p.access_flag,p.date_locked',array('p.item' => 'i.id','i.itemtype' => 1),'p.id asc');
//printArray ($result);printArray ($categories);exit;
		foreach($result as $key => $value) {
			foreach($categories as $k => $v) {
				if($v['item']==$value['id'] && !stristr($v['name'], 'Accessories') ) {
					$result[$key]['path'] = !empty($value['path2'])? '/'.$value['path2'] : $this->getCategoryPath($v['ownerid']).'/'.$value['path'];
					$result[$key]['category'] = $v['name'];
					continue;
				}
			}
		}
		if($request['full']) {
			$presets = array();
			$selected = $this->DB->SelectAny('SELECT id, name FROM preset');
			$presets_count = count($selected);
			for($i = 0; $i < $presets_count; $i++) $presets[$selected[$i]['id']] = $selected[$i]['name'];
			$packages = array();
			$hostpaths = array();
			$usernames = array();
			$count = count($result);
			for($i = 0; $i < $count; $i++){
				$date_changed = explode('.', $result[$i]['date_changed']);
				$result[$i]['date_changed'] = $date_changed[0];
				$date_locked = explode('.', $result[$i]['date_locked']);
				$result[$i]['date_locked'] = $date_locked[0];
				$result[$i]['username'] = $result[$i]['access_flag'] ? $this->getUserName(array('type' => 1, 'userid' => $result[$i]['access_flag'])) : '';
				$result[$i]['publish'] = array();
				$query = 'SELECT packagepublish.id, packagepublish.ownerid as package_id, packagepublish.host, packagepublish.userid, packagepublish.date_published FROM packagepublish WHERE packagepublish.type = 1 AND packagepublish.successful = 1 AND packagepublish.date_published > \''.$result[$i]['date_changed'].'\' AND packagepublish.ownerid IN (SELECT DISTINCT packageitem.ownerid FROM packageitem WHERE packageitem.type = 18 AND packageitem.object = \''.$result[$i]['id'].'\') ORDER BY packagepublish.date_published DESC';
				$packagepublish = $this->DB->SelectAny($query);
				$presets_unique = array();
				$c = count($packagepublish);
				$index = 0;
				for($j = 0; $j < $c; $j++){
					if(isset($presets_unique[$packagepublish[$j]['host']])) continue;
					$presets_unique[$packagepublish[$j]['host']] = true;
					$result[$i]['publish'][$index] = $packagepublish[$j];
					$date_published = explode ('.', $packagepublish[$j]['date_published']);
					$result[$i]['publish'][$index]['date_published'] = $date_published[0];
					if(!isset($packages[$packagepublish[$j]['package_id']])){
						$sel = $this->DB->SelectAny('SELECT name FROM package WHERE id = '.$packagepublish[$j]['package_id'].' LIMIT 1');
						$packages[$packagepublish[$j]['package_id']] = empty($sel) ? '[deleted]' : $sel[0]['name'];
					}
					$result[$i]['publish'][$index]['package_name'] = $packages[$packagepublish[$j]['package_id']];
					if(!isset($hostpaths[$packagepublish[$j]['host']])){
						$sel = $this->DB->SelectAny('SELECT name FROM preset WHERE id = '.$packagepublish[$j]['host'].' LIMIT 1');
						$hostpaths[$packagepublish[$j]['host']] = empty($sel) ? '[unknown]' : $sel[0]['name'];
					}
					$result[$i]['publish'][$index]['hostpath'] = $hostpaths[$packagepublish[$j]['host']];
					if(!isset($usernames[$packagepublish[$j]['userid']])){
						$sel = $this->DB->SelectAny('SELECT username FROM member WHERE id = '.$packagepublish[$j]['userid'].' LIMIT 1');
						$usernames[$packagepublish[$j]['userid']] = empty($sel) ? '[unknown]' : $sel[0]['username'];
					}
					$result[$i]['publish'][$index]['username'] = $usernames[$packagepublish[$j]['userid']];
					$index++;
				}
				$result[$i]['published_count'] = count($result[$i]['publish']).'/'.$presets_count;
			}
		}
		return $result;
	}

	function getAccessoriesList($request=array('full' => 1)) {
		$result = array();
//		$result1 = $this->DB->SelectArray(array('product p, parentitem i'),'p.id,p.header,p.name,i.itemtype,p.sort_order,(\'now\'::date - p.date_changed::date) AS unmodified,p.date_changed,p.access_flag,p.date_locked',array('p.item' => 'i.id','i.itemtype' => 2),'p.id');
//		$result2 = $this->DB->SelectArray(array('product p, parentitem i'),'p.id,p.header,p.name,i.itemtype,p.sort_order,(\'now\'::date - p.date_changed::date) AS unmodified,p.date_changed,p.access_flag,p.date_locked',array('p.item' => 'i.id','i.itemtype' => 3),'p.sort_order asc,p.name asc');
//		$result = mergeArrays($result1,$result2);
$result = $this->DB->SelectAny(" select p.id,p.header,p.name,i.itemtype,p.sort_order, TIMESTAMPDIFF(day,p.date_changed,NOW()) AS unmodified, p.date_changed,p.access_flag,p.date_locked from product p, parentitem i where p.item = i.id and (i.itemtype = 3 or i.itemtype = 2) order by p.sort_order asc,p.name asc ");
//printArray($result);exit;
		if($request['full']) {
			$presets = array();
			$selected = $this->DB->SelectAny('SELECT id, name FROM preset');
			$presets_count = count($selected);
			for($i = 0; $i < $presets_count; $i++) $presets[$selected[$i]['id']] = $selected[$i]['name'];
			$packages = array();
			$hostpaths = array();
			$usernames = array();
			$count = count($result);
			for($i = 0; $i < $count; $i++){
				$date_changed = explode('.', $result[$i]['date_changed']);
				$result[$i]['date_changed'] = $date_changed[0];
				$date_locked = explode('.', $result[$i]['date_locked']);
				$result[$i]['date_locked'] = $date_locked[0];
				$result[$i]['username'] = $result[$i]['access_flag'] ? $this->getUserName(array('type' => 1, 'userid' => $result[$i]['access_flag'])) : '';
				$result[$i]['publish'] = array();
				$query = 'SELECT packagepublish.id, packagepublish.ownerid as package_id, packagepublish.host, packagepublish.userid, packagepublish.date_published FROM packagepublish WHERE packagepublish.type = 1 AND packagepublish.successful = 1 AND packagepublish.date_published > \''.$result[$i]['date_changed'].'\' AND packagepublish.ownerid IN (SELECT DISTINCT packageitem.ownerid FROM packageitem WHERE packageitem.type = 18 AND packageitem.object = \''.$result[$i]['id'].'\') ORDER BY packagepublish.date_published DESC';
				$packagepublish = $this->DB->SelectAny($query);
				$presets_unique = array();
				$c = count($packagepublish);
				$index = 0;
				for($j = 0; $j < $c; $j++){
					if(isset($presets_unique[$packagepublish[$j]['host']])) continue;
					$presets_unique[$packagepublish[$j]['host']] = true;
					$result[$i]['publish'][$index] = $packagepublish[$j];
					$date_published = explode ('.', $packagepublish[$j]['date_published']);
					$result[$i]['publish'][$index]['date_published'] = $date_published[0];
					if(!isset($packages[$packagepublish[$j]['package_id']])){
						$sel = $this->DB->SelectAny('SELECT name FROM package WHERE id = '.$packagepublish[$j]['package_id'].' LIMIT 1');
						$packages[$packagepublish[$j]['package_id']] = empty($sel) ? '[deleted]' : $sel[0]['name'];
					}
					$result[$i]['publish'][$index]['package_name'] = $packages[$packagepublish[$j]['package_id']];
					if(!isset($hostpaths[$packagepublish[$j]['host']])){
						$sel = $this->DB->SelectAny('SELECT name FROM preset WHERE id = '.$packagepublish[$j]['host'].' LIMIT 1');
						$hostpaths[$packagepublish[$j]['host']] = empty($sel) ? '[unknown]' : $sel[0]['name'];
					}
					$result[$i]['publish'][$index]['hostpath'] = $hostpaths[$packagepublish[$j]['host']];
					if(!isset($usernames[$packagepublish[$j]['userid']])){
						$sel = $this->DB->SelectAny('SELECT username FROM member WHERE id = '.$packagepublish[$j]['userid'].' LIMIT 1');
						$usernames[$packagepublish[$j]['userid']] = empty($sel) ? '[unknown]' : $sel[0]['username'];
					}
					$result[$i]['publish'][$index]['username'] = $usernames[$packagepublish[$j]['userid']];
					$index++;
				}
				$result[$i]['published_count'] = count($result[$i]['publish']).'/'.$presets_count;
			}
		}
		return $result;
	}

	function getShipMethod($request = array()) {
		return $this->DB->SelectGuide(array('shipcosttype'));
	}

	function getShoppingStatus($request = array()) {
		global $Server;
		$handler = $Server->getHandler(10);
		return $handler->getShoppingStatus($request);
	}

	function getModulesTree($request = array('lang' => 1,'parent' => 0),$categoriesTree = array()){
		if(empty($request['lang'])) $request['lang'] = 1;
		if(empty($request['parent'])) $request['parent'] = 0;
		$selected = $this->DB->SelectArray(array('category c','category_lang cl'),'c.id,c.sys_name,c.ownerid,c.cat_type,cl.name',array('c.id' => 'cl.ownerid','lang' => $request['lang']),($request['parent']=='75' || $request['parent']=='77'? 'c.sort_order asc,c.sys_name desc' : 'c.sort_order asc,c.id asc'));
		if(!empty($selected)) $categoriesTree = $this->makeRegistryTree($selected,$request['parent']);
		foreach($categoriesTree as $key => $value) {
			if(count($value['url']) > 1) array_shift($value['url']);
			$modulesTree[$value['id']]['path'] = implode('/',$value['url']);
			$modulesTree[$value['id']]['id'] = '1';
			$modulesTree[$value['id']]['item'] = $value['id'];
		}
		return $modulesTree;
	}

	function getParentName($id,$array,$sys_name = array(),$name = array()) {
		foreach($array as $key => $value) {
			if($value['id'] == $id) {
				if($value['ownerid'] != 0) $name = $this->getParentUrl($value['ownerid'],$array);
				$name[$value['id']] = trim($value['name']);
			}
		}
		if(!empty($sys_name)) $name = mergeArrays($name,$sys_name);
		return $name;
	}

	function getParentUrl($id,$array,$sys_name = array(),$url = array()) {
		foreach($array as $key => $value) {
			if($value['id'] == $id) {
				if($value['ownerid']!=0) $url = $this->getParentUrl($value['ownerid'],$array);
				$url[$value['id']] = trim($value['sys_name']);
			}
		}
		if(!empty($sys_name)) $url = mergeArrays($url,$sys_name);
		return $url;
	}

	function makeRegistryTree($array = array(),$parent = 0,$root = 0,$tree = array()) {
		//uasort($array,'by_owner');
		foreach($array as $value) {
			if($value['ownerid'] == $parent) {
				$tree[$value['id']] = array(
					'id' => $value['id'],
					'name' => $this->getParentName($value['ownerid'],$array,array($value['id'] => $value['name'])),
					'url' => $this->getParentUrl($value['ownerid'],$array,array($value['id'] => $value['sys_name'])),
				);
				$tree = mergeArrays($tree,$this->makeRegistryTree($array,$value['id'],1));
			}
		}
		return $tree;
	}

	function getCategoriesTreeforAcc($request = array('full' => 1,'parent' => 1,'admin' => 0,'type' => 0),$categoriesTree = array()){
		if(empty($request['parent'])) $request['parent'] = 1;
		if(empty($request['admin'])) $request['admin'] = 0;
		if(empty($request['full'])) $request['full'] = 0;
		if(empty($request['type'])) $request['type'] = 0;
		if(!empty($request['type'])) $where = 'cat_type in (1,3)';
				else $where = '';
		$result = array();
//		if(!empty($where)) $result = $this->DB->SelectAny('select id,ownerid,cat_type,name,is_chart,is_active,sort_order,(\'now\'::date - date_changed::date) AS unmodified,date_changed,access_flag,date_locked from category WHERE '.$where.' order by ownerid asc, id asc, sort_order asc');
//				else $result = $this->DB->SelectArray(array('category'),'id,ownerid,cat_type,name,is_chart,is_active,sort_order,(\'now\'::date - date_changed::date) AS unmodified,date_changed,access_flag,date_locked',array(),'sort_order asc,id asc');
		if(!empty($where)) $result = $this->DB->SelectAny('select id,ownerid,cat_type,name,is_chart,is_active,sort_order, TIMESTAMPDIFF(day,date_changed,NOW()) AS unmodified,date_changed,access_flag,date_locked from category WHERE '.$where.' order by ownerid asc, id asc, sort_order asc');
				else $result = $this->DB->SelectArray(array('category'),'id,ownerid,cat_type,name,is_chart,is_active,sort_order, TIMESTAMPDIFF(day,date_changed,NOW()) AS unmodified,date_changed,access_flag,date_locked',array(),'sort_order asc,id asc');
		if($request['full']) {
			$presets = array();
			$selected = $this->DB->SelectAny('SELECT id, name FROM preset');
			$presets_count = count($selected);
			for ($i = 0; $i < $presets_count; $i++) $presets[$selected[$i]['id']] = $selected[$i]['name'];
			$packages = array();
			$hostpaths = array();
			$usernames = array();
			$count = count($result);
			for($i = 0; $i < $count; $i++){
				$date_changed = explode('.', $result[$i]['date_changed']);
				$result[$i]['date_changed'] = $date_changed[0];
				$date_locked = explode('.', $result[$i]['date_locked']);
				$result[$i]['date_locked'] = $date_locked[0];
				$result[$i]['username'] = $result[$i]['access_flag'] ? $this->getUserName(array('type' => 1, 'userid' => $result[$i]['access_flag'])) : '';
				$result[$i]['publish'] = array();
				$query = 'SELECT packagepublish.id, packagepublish.ownerid as package_id, packagepublish.host, packagepublish.userid, packagepublish.date_published FROM packagepublish WHERE packagepublish.type = 1 AND packagepublish.successful = 1 AND packagepublish.date_published > \''.$result[$i]['date_changed'].'\' AND packagepublish.ownerid IN (SELECT DISTINCT packageitem.ownerid FROM packageitem WHERE packageitem.type = 16 AND packageitem.object = \''.$result[$i]['id'].'\') ORDER BY packagepublish.date_published DESC';
				$packagepublish = $this->DB->SelectAny($query);
				$presets_unique = array();
				$c = count($packagepublish);
				$index = 0;
				for($j = 0; $j < $c; $j++){
					if(isset($presets_unique[$packagepublish[$j]['host']])) continue;
					$presets_unique[$packagepublish[$j]['host']] = true;
					$result[$i]['publish'][$index] = $packagepublish[$j];
					$date_published = explode ('.', $packagepublish[$j]['date_published']);
					$result[$i]['publish'][$index]['date_published'] = $date_published[0];
					if(!isset($packages[$packagepublish[$j]['package_id']])){
						$sel = $this->DB->SelectAny('SELECT name FROM package WHERE id = '.$packagepublish[$j]['package_id'].' LIMIT 1');
						$packages[$packagepublish[$j]['package_id']] = empty($sel) ? '[deleted]' : $sel[0]['name'];
					}
					$result[$i]['publish'][$index]['package_name'] = $packages[$packagepublish[$j]['package_id']];
					if(!isset($hostpaths[$packagepublish[$j]['host']])){
						$sel = $this->DB->SelectAny('SELECT name FROM preset WHERE id = '.$packagepublish[$j]['host'].' LIMIT 1');
						$hostpaths[$packagepublish[$j]['host']] = empty($sel) ? '[unknown]' : $sel[0]['name'];
					}
					$result[$i]['publish'][$index]['hostpath'] = $hostpaths[$packagepublish[$j]['host']];
					if(!isset($usernames[$packagepublish[$j]['userid']])){
						$sel = $this->DB->SelectAny('SELECT username FROM member WHERE id = '.$packagepublish[$j]['userid'].' LIMIT 1');
						$usernames[$packagepublish[$j]['userid']] = empty($sel) ? '[unknown]' : $sel[0]['username'];
					}
					$result[$i]['publish'][$index]['username'] = $usernames[$packagepublish[$j]['userid']];
					$index++;
				}
				$result[$i]['published_count'] = count($result[$i]['publish']).'/'.$presets_count;
			}
		}
		if(!empty($result)) {
			if(!empty($request['type'])) {
				$categoriesTree = array();
				$this->access_count = array();
				$count = count($result);
				for($i = 0; $i < $count; $i++) {
					if(!empty($result[$i]) && !in_array($result[$i]['id'],$this->access_count)) {
						$res_array = $this->makeCatTree($request['admin'],$result,0,1);
						$categoriesTree = mergeArrays($categoriesTree,$res_array);
						$res_array = $this->makeCatTree($request['admin'],$result,$result[$i]['ownerid'],1);
						$categoriesTree = mergeArrays($categoriesTree,$res_array);
					}
				}
			}
			else $categoriesTree = $this->makeCatTree($request['admin'],$result,$request['parent']);
		}
		return $categoriesTree;
	}	
	
	function getCategoriesTree($request = array('full' => 1,'parent' => 1,'admin' => 0,'type' => 0),$categoriesTree = array()){
		if(empty($request['parent'])) $request['parent'] = 1;
		if(empty($request['admin'])) $request['admin'] = 0;
		if(empty($request['full'])) $request['full'] = 0;
		if(empty($request['type'])) $request['type'] = 0;
		if(!empty($request['type'])) $where = 'cat_type in (1,4)';
				else $where = '';
		$result = array();
//		if(!empty($where)) $result = $this->DB->SelectAny('select id,ownerid,cat_type,name,is_chart,is_active,sort_order,(\'now\'::date - date_changed::date) AS unmodified,date_changed,access_flag,date_locked from category WHERE '.$where.' order by ownerid asc, id asc, sort_order asc');
//				else $result = $this->DB->SelectArray(array('category'),'id,ownerid,cat_type,name,is_chart,is_active,sort_order,(\'now\'::date - date_changed::date) AS unmodified,date_changed,access_flag,date_locked',array(),'sort_order asc,id asc');
		if(!empty($where)) $result = $this->DB->SelectAny('select id,ownerid,cat_type,name,is_chart,is_active,sort_order, TIMESTAMPDIFF(day,date_changed,NOW()) AS unmodified,date_changed,access_flag,date_locked from category WHERE '.$where.' order by ownerid asc, id asc, sort_order asc');
				else $result = $this->DB->SelectArray(array('category'),'id,ownerid,cat_type,name,is_chart,is_active,sort_order, TIMESTAMPDIFF(day,date_changed,NOW()) AS unmodified,date_changed,access_flag,date_locked',array(),'sort_order asc,id asc');
		if($request['full']) {
			$presets = array();
			$selected = $this->DB->SelectAny('SELECT id, name FROM preset');
			$presets_count = count($selected);
			for ($i = 0; $i < $presets_count; $i++) $presets[$selected[$i]['id']] = $selected[$i]['name'];
			$packages = array();
			$hostpaths = array();
			$usernames = array();
			$count = count($result);
			for($i = 0; $i < $count; $i++){
				$date_changed = explode('.', $result[$i]['date_changed']);
				$result[$i]['date_changed'] = $date_changed[0];
				$date_locked = explode('.', $result[$i]['date_locked']);
				$result[$i]['date_locked'] = $date_locked[0];
				$result[$i]['username'] = $result[$i]['access_flag'] ? $this->getUserName(array('type' => 1, 'userid' => $result[$i]['access_flag'])) : '';
				$result[$i]['publish'] = array();
				$query = 'SELECT packagepublish.id, packagepublish.ownerid as package_id, packagepublish.host, packagepublish.userid, packagepublish.date_published FROM packagepublish WHERE packagepublish.type = 1 AND packagepublish.successful = 1 AND packagepublish.date_published > \''.$result[$i]['date_changed'].'\' AND packagepublish.ownerid IN (SELECT DISTINCT packageitem.ownerid FROM packageitem WHERE packageitem.type = 16 AND packageitem.object = \''.$result[$i]['id'].'\') ORDER BY packagepublish.date_published DESC';
				$packagepublish = $this->DB->SelectAny($query);
				$presets_unique = array();
				$c = count($packagepublish);
				$index = 0;
				for($j = 0; $j < $c; $j++){
					if(isset($presets_unique[$packagepublish[$j]['host']])) continue;
					$presets_unique[$packagepublish[$j]['host']] = true;
					$result[$i]['publish'][$index] = $packagepublish[$j];
					$date_published = explode ('.', $packagepublish[$j]['date_published']);
					$result[$i]['publish'][$index]['date_published'] = $date_published[0];
					if(!isset($packages[$packagepublish[$j]['package_id']])){
						$sel = $this->DB->SelectAny('SELECT name FROM package WHERE id = '.$packagepublish[$j]['package_id'].' LIMIT 1');
						$packages[$packagepublish[$j]['package_id']] = empty($sel) ? '[deleted]' : $sel[0]['name'];
					}
					$result[$i]['publish'][$index]['package_name'] = $packages[$packagepublish[$j]['package_id']];
					if(!isset($hostpaths[$packagepublish[$j]['host']])){
						$sel = $this->DB->SelectAny('SELECT name FROM preset WHERE id = '.$packagepublish[$j]['host'].' LIMIT 1');
						$hostpaths[$packagepublish[$j]['host']] = empty($sel) ? '[unknown]' : $sel[0]['name'];
					}
					$result[$i]['publish'][$index]['hostpath'] = $hostpaths[$packagepublish[$j]['host']];
					if(!isset($usernames[$packagepublish[$j]['userid']])){
						$sel = $this->DB->SelectAny('SELECT username FROM member WHERE id = '.$packagepublish[$j]['userid'].' LIMIT 1');
						$usernames[$packagepublish[$j]['userid']] = empty($sel) ? '[unknown]' : $sel[0]['username'];
					}
					$result[$i]['publish'][$index]['username'] = $usernames[$packagepublish[$j]['userid']];
					$index++;
				}
				$result[$i]['published_count'] = count($result[$i]['publish']).'/'.$presets_count;
			}
		}
//printArray( $result);		
		if(!empty($result)) {
			if(!empty($request['type'])) {
				$categoriesTree = array();
				$this->access_count = array();
				$count = count($result);
				for($i = 0; $i < $count; $i++) {
					if(!empty($result[$i]) && !in_array($result[$i]['id'],$this->access_count)) {
						$res_array = $this->makeCatTree($request['admin'],$result,0,1);
						$categoriesTree = mergeArrays($categoriesTree,$res_array);
						$res_array = $this->makeCatTree($request['admin'],$result,$result[$i]['ownerid'],1);
						$categoriesTree = mergeArrays($categoriesTree,$res_array);
					}
				}
			}
			else $categoriesTree = $this->makeCatTree($request['admin'],$result,$request['parent']);
		}
		return $categoriesTree;
	}

	function makeCatTree($admin = 0,$array = array(),$parent = 1,$root = 0,$tree = array()) {
		if(!$root)
			foreach($array as $value){
				if($value['id'] == $parent) {
					if($admin || $value['is_active']) {
						$tree['parent'] = $value;
						$tree['parent']['subcat'] = array();
					}
				}
			}
		foreach($array as $value) {
			if($value['ownerid'] == $parent) {
				if($admin || ($value['is_active'] && $value['is_chart'])) {
					$tree[$value['id']] = $value;
					$this->access_count[$value['id']] = $value['id'];
					$tree[$value['id']]['subcat'] = $this->makeCatTree($admin,$array,$value['id'],1);
				}
			}
		}
		return $tree;
	}

	function getTree($categoriesTree = array()) {
		$selected = $this->DB->SelectArray(array('category c'),'id,sys_name,ownerid,cat_type,name',array(),($request['parent']=='75' || $request['parent']=='77'? 'sort_order asc,sys_name desc' : 'sort_order asc,id asc'));
		if(!empty($selected)) $categoriesTree = $this->makeTree($selected,0);
		return $categoriesTree;
	}

	function makeTree($array = array(),$parent = 1,$tree = array()) {
		foreach($array as $key => $value) {
			if($value['ownerid'] == $parent)
				$tree[$value['id']] = $this->makeTree($array,$value['id']);
		}
		return $tree;
	}

	function getProductsCount($request = array('lang' => 1,'parent' => 0),$categoriesTree = array()){
		$countTree = $this->getCategoriesTree($request);
		foreach($countTree as $key => $value) $this->getCount($countTree[$key]);
		foreach($countTree as $key => $value) $countTree[$key]['count'] = $this->sumCount($countTree[$key]);
		return $countTree;
	}

	function getCount(&$cat) {
		if(!empty($cat['subcat'])) foreach($cat['subcat'] as $key => $value) $this->getCount($cat['subcat'][$key]);
		else $cat['count'] = $this->DB->SelectSingle(array('categorylineitem cli','product p'),'count(distinct cli.item)',array('cli.ownerid' => $cat['id'],'cli.item' => 'p.id','p.active' => 't'));
	}

	function getModules($request) {
		global $Server;
		$handler = $Server->getHandler('5');
		return $handler->modules;
	}

	function sumCount($cat) {
		empty($cat['count']) and $cat['count'] = 0;
		if(!empty($cat['subcat'])) foreach($cat['subcat'] as $key => $value) $cat['count'] += $this->sumCount($cat['subcat'][$key]);
		return $cat['count'];
	}

	function getColor($request = array()) {
		empty($request['0']) and $request['0'] = '';
		empty($request['1']) and $request['1'] = '';
		empty($request['2']) and $request['2'] = '';
		switch($request['0']) {
			case 'Product':
				if(!empty($request['1']))
					$color[0] = $this->DB->SelectSingle(array('product p','item i','itemcolor ic'),'ic.name',array('p.id' => intval($request['1']),'p.ownerid' => 'i.id','i.color::int' => 'ic.id'));
			break;
			case 'ArmasightFullProductChart':
				if(equals(@$request['1'],'Category') && !empty($request['2']))
					$color[0] = $this->DB->SelectSingle(array('category c','itemcolor ic'),'ic.name',array('c.id' => intval($request['2']),'c.color::int' => 'ic.id'));
			break;
			case 'HowNightVisionWorks': $color[0] = 'green'; break;
			case 'DayOpticsQuality': $color[0] = 'blue'; break;
			default: $color[0] = 'neitral'; break;
		}
		return empty($color[0])? array('neitral') : $color;
	}

	function getDownloadChart($request = array('lang' => 1,'parent' => 1,'desc' => FALSE),$chart = array()) {
		if(empty($request['parent'])) $request['parent'] = 0;
		if(empty($request['lang'])) $request['lang'] = 1;
		if(empty($request['desc'])) $request['desc'] = FALSE;
		$chart = $this->makeDownloadChart($this->getCategoriesTree($request),$request['parent'],$request['desc']);
		if(empty($chart)) {
			$chart = $this->createDownloadCategory();
			$chart->_error = '4';
		}
		return $chart;
	}

	function getXMLChart($request = array('lang' => 1,'parent' => 0,'desc' => FALSE),$chart = array()) {
		if(empty($request['parent'])) $request['parent'] = 0;
		if(empty($request['lang'])) $request['lang'] = 1;
		if(empty($request['desc'])) $request['desc'] = FALSE;
		$chart = $this->makeXMLChart($this->getCategoriesTree($request),$request['parent'],$request['desc']);
		if(empty($chart)) {
			$chart = $this->createXMLCategory();
			$chart->_error = '4';
		}
		return $chart;
	}

	function makeXMLChart($tree = array(),$parent = 1,$desc = FALSE) {
		empty($tree) and $tree = array();
		foreach($tree as $key => $value) {
			$top_parent = (empty($value['subcat']) && $value['id']!=$parent) || count($tree)==1? false : true;
			$category = $this->createXMLCategory($top_parent,$desc);
			$category->id = $value['id'];
			$this->DB->initObject($category);
			$category->cat_type = $value['cat_type'];
			if($value['id']==$parent) {
				$handler = new ContentHandler();
				$module = $handler->openSection(array('path' => 'Download'));
			}
			if(!empty($value['subcat']) && $category->cat_type != 1 && $category->cat_type != 4) $category->subcat = $this->makeXMLChart($value['subcat'],1,$desc);
			if($category->cat_type != 1 && $category->cat_type != 4) $tree[$key] = $category;
		}
		return $tree;
	}

	function makeDownloadChart($tree = array(),$parent = 1,$desc = FALSE) {
		empty($tree) and $tree = array();
		foreach($tree as $key => $value) {
			$top_parent = (empty($value['subcat']) && $value['id']!=$parent) || count($tree)==1? false : true;
			$category = $this->createDownloadCategory($top_parent,$desc);
			$category->id = $value['id'];
			$this->DB->initObject($category);
			$category->cat_type = $value['cat_type'];
			if($value['id']==$parent) {
				$handler = new ContentHandler();
				$module = $handler->openSection(array('path' => 'Download'));
				$category->links = $module->links;
				$category->desc_langs = $module->contents;
			}
			if(!empty($value['subcat']) && $category->cat_type != 1 && $category->cat_type != 4) $category->subcat = $this->makeDownloadChart($value['subcat'],1,$desc);
			if($category->cat_type != 1 && $category->cat_type != 4) $tree[$key] = $category;
		}
		return $tree;
	}

	function getChart($request = array('parent' => 1),$chart = array()) {
		if(empty($request['parent'])) $request['parent'] = 1;
		if(empty($request['full'])) $request['full'] = 0;
//printObject($this->getCategoriesTree($request),$request['parent']);exit;
		$chart = $this->makeChart($this->getCategoriesTree($request),$request['parent']);
		if(empty($chart)) {
			$chart = $this->createCategory();
			$chart->_error = '4';
		}
		else if($chart['parent']->id == 1) {
			foreach($chart as $key => $value) if($value->cat_type==1 || $value->cat_type==4) unset($chart[$key]);
		}

		return $chart;
	}

/*		function getFullSiteMapChart($request = array('parent' => 1),$chart = array()) {
			if(empty($request['parent'])) $request['parent'] = 1;
			if(empty($request['full'])) $request['full'] = 0;
			$chart = $this->makeFullAccChart($this->getCategoriesTree(array('full' => 0,'admin' => 1,'parent' => 1)),$request['parent']);
			if(empty($chart)) {
				$chart = $this->createCategory();
				$chart->_error = '4';
			}
			else if($chart['parent']->id == 1) {
				foreach($chart as $key => $value) if($value->cat_type==1 || $value->cat_type==4) unset($chart[$key]);
			}
			return $chart;
	}*/
	
	function getFullChart($request = array('parent' => 1),$chart = array()) {
		if(empty($request['parent'])) $request['parent'] = 1;
		if(empty($request['full'])) $request['full'] = 0;
		$chart = $this->makeFullAccChart($this->getCategoriesTree($request),$request['parent']);
//printObject($chart);exit;
		if(empty($chart)) {
			$chart = $this->createCategory();
			$chart->_error = '4';
		}
		else if($chart['parent']->id == 1) {
			foreach($chart as $key => $value) if($value->cat_type==1 || $value->cat_type==4) unset($chart[$key]);
		}
		return $chart;
	}
	
	function makeFullAccChart($tree = array(),$parent = 1) {
		global $REGISTRY;
		empty($tree) and $tree = array();
		foreach($tree as $key => $value) {
			$category = $this->createCategory($value['cat_type'],($value['id']==$parent? true : false),((empty($value['subcat']) && $value['id']!=$parent) || count($tree)==1? false : true));
			$category->id = $value['id'];
			$this->DB->initObject($category);
//printObject ($category);			
			foreach((!empty($category->categorylineitems->data)? $category->categorylineitems->data : array()) as $k => $v) {
				if(!$category->categorylineitems->data[$k]->item->is_active)
					unset($category->categorylineitems->data[$k]);
				else if($category->cat_type == 0 || $category->cat_type == 2 || $category->cat_type == 3 || $category->cat_type == 5) {
					//------
							foreach($REGISTRY['VirtualSlotTarget']['main'] as $path => $handler) {
								$query = explode('?',$handler);
								$target = explode(':',array_shift($query));
								$properties = array_shift($query);
								$pair = explode('=',$properties);
								$name = array_shift($target);
								if($name=='ProductView' && $category->categorylineitems->data[$k]->item->id == $pair[1]) {
									$category->categorylineitems->data[$k]->item->url = $path;
									break;
								}
							}
					//------
//					$category->categorylineitems->data[$k]->item->url = !empty($v->item->path2)? '/'.$v->item->path2 : $this->getCategoryPath($category->id).'/'.$v->item->path;
					if($category->cat_type == 5) $selected = $this->DB->SelectAny('SELECT id,filetype,image_link FROM productfile WHERE ownerid = '.$category->categorylineitems->data[$k]->item->id.' AND filetype in (1,6,7)');
						else $selected = $this->DB->SelectAny('SELECT id,filetype,image_link FROM productfile WHERE ownerid = '.$category->categorylineitems->data[$k]->item->id.' AND filetype in (1,2,8)');
					if(!empty($selected))
						foreach($selected as $fv) $category->categorylineitems->data[$k]->item->files[] = $fv;
					else $category->categorylineitems->data[$k]->item->files = array();
					$selected = $this->DB->SelectAny('SELECT id,current,value FROM price WHERE ownerid = '.$category->categorylineitems->data[$k]->item->id);
					if(!empty($selected)) {
						foreach($selected as $fv) $category->categorylineitems->data[$k]->item->prices[] = $fv;
					}
					else $category->categorylineitems->data[$k]->item->prices = array();

					if($category->cat_type == 2) {
						$selected = $this->DB->SelectAny('SELECT id FROM productlineitem WHERE forsale=1 AND optional=1 AND ownerid = '.$category->categorylineitems->data[$k]->item->id);
						if(!empty($selected)) {
							$category->categorylineitems->data[$k]->item->productlineitems = new ObjectsList();
							$category->categorylineitems->data[$k]->item->productlineitems->type = $this->createProductLineItem();
							foreach($selected as $pli) {
								$pli_obj = $this->createProductLineItem();
								$pli_obj->id = $pli['id'];
								$this->DB->initObject($pli_obj);
								$category->categorylineitems->data[$k]->item->productlineitems->data[] = clone $pli_obj;
							}
						}
					}
					else if($category->cat_type == 3) {
						$selected = $this->DB->SelectAny('SELECT id FROM productlineitem WHERE optional=1 AND ownerid = '.$category->categorylineitems->data[$k]->item->id);
						if(!empty($selected)) {
							$category->categorylineitems->data[$k]->item->productlineitems = new ObjectsList();
							$category->categorylineitems->data[$k]->item->productlineitems->type = $this->createProductLineItem();
							foreach($selected as $pli) {
								$pli_obj = $this->createProductLineItem();
								$pli_obj->id = $pli['id'];
								$this->DB->initObject($pli_obj);
								$category->categorylineitems->data[$k]->item->productlineitems->data[] = clone $pli_obj;
							}
						}
						else unset($category->categorylineitems->data[$k]);
					}
					
					else if($category->cat_type == 0) {
						$selected = $this->DB->SelectAny('SELECT id,lineitem FROM recomenduselineitem WHERE ownerid = '.$category->categorylineitems->data[$k]->item->id);
						if(!empty($selected))
							$category->categorylineitems->data[$k]->item->recomenduselineitems = $selected;
					}
				}
				else if($category->cat_type == 1 || $category->cat_type == 4) {
					$selected = $this->DB->SelectAny('SELECT id,filetype,image_link FROM productfile WHERE ownerid = '.$category->categorylineitems->data[$k]->item->id.' AND filetype in (8)');
					if(!empty($selected))
						foreach($selected as $fv) $category->categorylineitems->data[$k]->item->files[] = $fv;
					else $category->categorylineitems->data[$k]->item->files = array();
					$selected = $this->DB->SelectAny('SELECT id,current,value FROM price WHERE ownerid = '.$category->categorylineitems->data[$k]->item->id);
					if(!empty($selected))
						foreach($selected as $fv) $category->categorylineitems->data[$k]->item->prices[] = $fv;
					else $category->categorylineitems->data[$k]->item->prices = array();
					
					$category->categorylineitems->data[$k]->item->applicableitems = $this->DB->SelectAny('SELECT p.id, p.is_active, p.name FROM product p left join productlineitem pli on p.id = pli.ownerid WHERE pli.optional=1 and lineitem = '.$category->categorylineitems->data[$k]->item->id);
					foreach((!empty($category->categorylineitems->data[$k]->item->applicableitems)? $category->categorylineitems->data[$k]->item->applicableitems : array() ) as $a_k => $a_v) {
						if(!$a_v['is_active'])
							unset($category->categorylineitems->data[$k]->item->applicableitems[$a_k]);
						else {
							foreach($REGISTRY['VirtualSlotTarget']['main'] as $path => $handler) {
								$query = explode('?',$handler);
								$target = explode(':',array_shift($query));
								$properties = array_shift($query);
								$pair = explode('=',$properties);
								$name = array_shift($target);
								if($name=='ProductView' && $category->categorylineitems->data[$k]->item->applicableitems[$a_k]['id'] == $pair[1]) {
									$category->categorylineitems->data[$k]->item->applicableitems[$a_k]['url'] = $path;
									break;
								}
							}
						}
					}
				}
			}
			foreach((!empty($category->links->data)? $category->links->data : array()) as $k => $v)
				if($v->moduletype != 1) unset($category->links->data[$k]);
			$category->cat_type = $value['cat_type'];
			if(!empty($value['subcat'])) $category->subcat = $this->makeFullAccChart($value['subcat']);
			$tree[$key] = $category;
		}
		return $tree;
	}
	
	
	function makeChart($tree = array(),$parent = 1) {
		global $REGISTRY;
		empty($tree) and $tree = array();
		foreach($tree as $key => $value) {
			$category = $this->createCategory($value['cat_type'],($value['id']==$parent? true : false),((empty($value['subcat']) && $value['id']!=$parent) || count($tree)==1? false : true));
			$category->id = $value['id'];
			$this->DB->initObject($category);
			foreach((!empty($category->categorylineitems->data)? $category->categorylineitems->data : array()) as $k => $v) {
				if(!$category->categorylineitems->data[$k]->item->is_active)
					unset($category->categorylineitems->data[$k]);
//				else if($category->cat_type == 0 || $category->cat_type == 2 || $category->cat_type == 3 || $category->cat_type == 5) {
					else if($category->cat_type == 0 || $category->cat_type == 2 || $category->cat_type == 5) {
					$category->categorylineitems->data[$k]->item->url = !empty($v->item->path2)? '/'.$v->item->path2 : $this->getCategoryPath($category->id).'/'.$v->item->path;
					if($category->cat_type == 5) $selected = $this->DB->SelectAny('SELECT id,filetype,image_link FROM productfile WHERE ownerid = '.$category->categorylineitems->data[$k]->item->id.' AND filetype in (1,6,7)');
						else $selected = $this->DB->SelectAny('SELECT id,filetype,image_link FROM productfile WHERE ownerid = '.$category->categorylineitems->data[$k]->item->id.' AND filetype in (1,2,8)');
					if(!empty($selected))
						foreach($selected as $fv) $category->categorylineitems->data[$k]->item->files[] = $fv;
					else $category->categorylineitems->data[$k]->item->files = array();
					$selected = $this->DB->SelectAny('SELECT id,current,value FROM price WHERE ownerid = '.$category->categorylineitems->data[$k]->item->id);
					if(!empty($selected)) {
						foreach($selected as $fv) $category->categorylineitems->data[$k]->item->prices[] = $fv;
					}
					else $category->categorylineitems->data[$k]->item->prices = array();

					if($category->cat_type == 2) {
						$selected = $this->DB->SelectAny('SELECT id FROM productlineitem WHERE forsale=1 AND optional=1 AND ownerid = '.$category->categorylineitems->data[$k]->item->id);
						if(!empty($selected)) {
							$category->categorylineitems->data[$k]->item->productlineitems = new ObjectsList();
							$category->categorylineitems->data[$k]->item->productlineitems->type = $this->createProductLineItem();
							foreach($selected as $pli) {
								$pli_obj = $this->createProductLineItem();
								$pli_obj->id = $pli['id'];
								$this->DB->initObject($pli_obj);
								$category->categorylineitems->data[$k]->item->productlineitems->data[] = clone $pli_obj;
							}
						}
					} 		
					/*else if($category->cat_type == 3) {
						$selected = $this->DB->SelectAny('SELECT id FROM productlineitem WHERE optional=1 AND ownerid = '.$category->categorylineitems->data[$k]->item->id);
						if(!empty($selected)) {
							$category->categorylineitems->data[$k]->item->productlineitems = new ObjectsList();
							$category->categorylineitems->data[$k]->item->productlineitems->type = $this->createProductLineItem();
							foreach($selected as $pli) {
								$pli_obj = $this->createProductLineItem();
								$pli_obj->id = $pli['id'];
								$this->DB->initObject($pli_obj);
								$category->categorylineitems->data[$k]->item->productlineitems->data[] = clone $pli_obj;
							}
						}
						else unset($category->categorylineitems->data[$k]);
					}*/
					
					else if($category->cat_type == 0) {
						$selected = $this->DB->SelectAny('SELECT id,lineitem FROM recomenduselineitem WHERE ownerid = '.$category->categorylineitems->data[$k]->item->id);
						if(!empty($selected))
							$category->categorylineitems->data[$k]->item->recomenduselineitems = $selected;
					}
				}
				//else if($category->cat_type == 1 || $category->cat_type == 4) {
				else if($category->cat_type == 1 || $category->cat_type == 4 || $category->cat_type == 3 ) {
					$selected = $this->DB->SelectAny('SELECT id,filetype,image_link FROM productfile WHERE ownerid = '.$category->categorylineitems->data[$k]->item->id.' AND filetype in (8)');
					if(!empty($selected))
						foreach($selected as $fv) $category->categorylineitems->data[$k]->item->files[] = $fv;
					else $category->categorylineitems->data[$k]->item->files = array();
					$selected = $this->DB->SelectAny('SELECT id,current,value FROM price WHERE ownerid = '.$category->categorylineitems->data[$k]->item->id);
					if(!empty($selected))
						foreach($selected as $fv) $category->categorylineitems->data[$k]->item->prices[] = $fv;
					else $category->categorylineitems->data[$k]->item->prices = array();
					
					$category->categorylineitems->data[$k]->item->applicableitems = $this->DB->SelectAny('SELECT p.id, p.is_active, p.name FROM product p left join productlineitem pli on p.id = pli.ownerid WHERE pli.optional=1 and lineitem = '.$category->categorylineitems->data[$k]->item->id);
					foreach((!empty($category->categorylineitems->data[$k]->item->applicableitems)? $category->categorylineitems->data[$k]->item->applicableitems : array() ) as $a_k => $a_v) {
						if(!$a_v['is_active'])
							unset($category->categorylineitems->data[$k]->item->applicableitems[$a_k]);
						else {
							foreach($REGISTRY['VirtualSlotTarget']['main'] as $path => $handler) {
								$query = explode('?',$handler);
								$target = explode(':',array_shift($query));
								$properties = array_shift($query);
								$pair = explode('=',$properties);
								$name = array_shift($target);
								if($name=='ProductView' && $category->categorylineitems->data[$k]->item->applicableitems[$a_k]['id'] == $pair[1]) {
									$category->categorylineitems->data[$k]->item->applicableitems[$a_k]['url'] = $path;
									break;
								}
							}
						}
					}
				}
			}
			foreach((!empty($category->links->data)? $category->links->data : array()) as $k => $v)
				if($v->moduletype != 1) unset($category->links->data[$k]);
			$category->cat_type = $value['cat_type'];
			if(!empty($value['subcat'])) $category->subcat = $this->makeChart($value['subcat']);
			$tree[$key] = $category;
		}
		return $tree;
	}

	function getProductIdByPath($request=array()) {
		if(empty($request['path'])) $request['path'] = '';
		if(empty($request['path2'])) $request['path2'] = '';
		$selected = $this->DB->SelectAny('select id from product where path = \''.$request['path'].'\' OR path2 =  \''.$request['path2'].'\'');
		if (count($selected) >1) {
			foreach($selected as $k => $v) {
				$cat=$this->DB->SelectAny("select c.ownerid from category c left join categorylineitem cl on c.id = cl.ownerid where c.ownerid <>27 and cl.item =".$v['id']);
				if(!empty($cat)) return array('id' => $v['id']);
			}
		}
		if(!empty($selected)) return array('id' => $selected[0]['id']);
		return array();
	}

	function getCategoryByPath($request=array()) {
		global $REGISTRY;
		if(empty($request['path'])) $request['path'] = '/';
		foreach($REGISTRY['VirtualSlotTarget']['main'] as $path => $handler) {
			if($request['path']==strval($path)) {
				$query = explode('?',$handler);
				$target = explode(':',array_shift($query));
				$properties = array_shift($query);
				$pair = explode('=',$properties);
				$name = array_shift($target);
				if($name=='StoreView') {
					$category = new Category();
					$category->id = $pair[1];
					$category->color = new Color();
					$this->DB->initObject($category);
					return $category;
				}
			}
		}
		return array('color' => array('name' => 'green'));
	}

	function getProductUrl($id) {
		foreach($this->productsUrl as $key => $value) {
			if(!empty($this->productsUrl[$key][$id])) return $this->productsUrl[$key][$id];
		}
		return '/Product/'.$id;
	}

	function getCategoryForAccessory($request = array()) {
		/*$categories = $this->DB->SelectGuide(array('category g'),array('g.id','g.cat_type as name'),array('1' => '1'));
		foreach($categories as $key => $value)
			if($value) return array('category' => $key);
		return array('category' => 0);*/
		return array('category' => 27);
	}

	function saveAccessory($request) { //printArray($request);exit;
		global $Server, $REGISTRY, $TOOLS_PATH;
		$this->undo = '';
		if(!empty($request['id']) || !empty($request['duplicate_id'])) {
			$old_product = new Product();
			$old_product->files = new ObjectsList();
			$old_product->files->type = new ProductFile();
			$old_product->id = !empty($request['duplicate_id'])? $request['duplicate_id'] : $request['id'];
			$this->DB->initObject($old_product);
		}
		$product = $this->createAccessoryOrKit(TRUE);
		if(!empty($request['id']) || !empty($request['duplicate_id'])) {
			$product->files = clone $old_product->files;
			foreach($old_product->files->data as $value) {
				$product->_files[] = array(
					'imagetype' => $value->imagetype,
					'filetype' => $value->filetype,
					'date_uploaded' => $value->date_uploaded,
					'image_link' => $value->image_link,
					'number' => $value->number,
				);
			}
		}
		$this->parseRequest($request,$product);
		if(!empty($request['prew'])) $this->saveImage($product,$request['prew'],1);
		if(!empty($product->_error)) {
			$this->DB->good = FALSE;
			return $product;
		}
		if(!empty($request['middle'])) $this->saveImage($product,$request['middle'],8);
		if(!empty($product->_error)) {
			$this->DB->good = FALSE;
			return $product;
		}
		$product->files->data = array_values($product->files->data);
		//$selected = $this->DB->SelectAny('SELECT id FROM product WHERE name = \''.$product->name.'\''.(empty($product->id)? '' : ' AND id != '.$product->id));
		//if(!empty($selected)) {
		//	$this->DB->good = FALSE;
		//	$product->_error = 'Accessory with such name already exists';
		//	return $product;
		//}
		$this->DB->begin();
		$product->access_flag = 0;
		$product->ownerid = $product->item->id;
		// �������� ���������� ������
		if(!empty($product->id)) {
			$Undo_field= array('type' => 18,'id' => $product->id,'undo' => 1);
			include($TOOLS_PATH.'\undo.php');
			$this->undo = $undo_handler->arr_obj;
		}
		if(empty($product->id)) {
			$product->uid = $this->getUID('product');
			$max = $this->DB->SelectSingle(array('product'),'max(sort_order)',array());
			$product->sort_order = $max+10;
			$product->date_created = 'now';
		}
		else $product->sort_order = $this->DB->SelectSingle(array('product'),'sort_order',array('id' => $product->id));
		if(!empty($request['duplicate_id'])) $this->DB->update('product',array('access_flag' => 0),array('id' => $request['duplicate_id']));
		$product->date_changed = 'now';
		if(empty($product->id)) $this->setLogEvent(5,25,11,'Add accessory "'.$product->name);
		else $this->setLogEvent(5,25,12,'Edit accessory "'.$product->name.'" ['.$product->id.']',$product->id);
		$this->DB->processObject($product);
		unset($old_product);
		if(empty($product->uid)) {
			$selected = $this->DB->SelectAny('SELECT uid FROM product WHERE id = '.$product->id.' LIMIT 1');
			if(!empty($selected) && !empty($selected[0]['uid'])) $this->DB->delete('deleted', array('uid' => $selected[0]['uid'], 'type' => 18));
		}
		else $this->DB->delete('deleted', array('uid' => $product->uid, 'type' => 18));
		$this->DB->delete('categorylineitem',array('item' => $product->id));
		$categories = $this->DB->SelectGuide(array('category g'),array('g.id','g.cat_type as name'),array('1' => '1'));
		$true = 0;
		foreach($product->prices->data as $key => $value)
			if(!empty($value->value) && floatval($value->value) > 0) $true++;
		/*if($true) {
			foreach($product->applicableitems->data as $key => $value)
				if(!empty($value->product->id)) $true++;
		}*/
		foreach((!empty($request['categorylineitems'])? $request['categorylineitems'] : array()) as $key => $value) {
			/*if($categories[$value['id']]==1) {
				if($true >= 2) $this->DB->insert('categorylineitem',array('ownerid' => $value['id'],'item' => $product->id));
			}
			else if($categories[$value['id']]==4) $this->DB->insert('categorylineitem',array('ownerid' => $value['id'],'item' => $product->id));*/
			$this->DB->insert('categorylineitem',array('ownerid' => $value['id'],'item' => $product->id));
		}
		$productcomment= new ProductComment();
		$productcomment->version = 1;
		$productcomment->value = 'Accessory has been created';
		$selected = $this->DB->SelectAny("select version from productcomment where ownerid = ".$product->id." order by date desc LIMIT 1 OFFSET 0");
		if(!empty($selected[0]['version']) && isset($request['comment'])) {
			$productcomment->version=++$selected[0]['version'];
			$productcomment->value = (!empty($request['_undo_'])? 'Accessory has been undone up to '.$request['_undo_']." version<br>\r\n" : '').htmlspecialchars($request['comment']);
		}
		$productcomment->ownerid = $product->id;
		$productcomment->member = empty($request['id_user']) ? $this->Security->currentuser->id : $request['id_user'];
		$productcomment->date = 'now';
		$this->DB->processObject($productcomment,'save',array(),array(),TRUE);
		if(!empty($request['_undo_'])) {
			$this->setLogEvent(5,25,10,'Accessory "'.$product->name.'" ('.$product->path.') ['.$product->id.'] has been undone up to '.$request['_undo_'].' version',$product->id);
		}
		$this->DB->commit();
		clearCache();
		if($this->DB->good) {
			if(!empty($this->undo)) {
				$undo_handler->GetArrayInFile($this->undo, "Undo_object", $ROOT_PATH."/undo/".$pub_type[0]['name']."/".$Undo_field['id']."/".($productcomment->version>1? $productcomment->version-1 : 1).".inc");
			}
		}
		return $product;
	}

	function deleteAccessory($request) {
		global $Server, $REGISTRY;
		$product = $this->createAccessoryOrKit(TRUE);
		$product->id = $request['id'];
		$this->DB->initObject($product);
		//image_link
		$selected = $this->DB->SelectAny('SELECT id FROM productfile WHERE image_link = '.$product->id.' AND ownerid != '.$product->id);
		if(!empty($selected)) {
			$this->DB->good = FALSE;
			$product->_error = 'Accessory can\'t be deleted as its images are being used for other accessories';
			return $product;
		}
		
/*		//orderlineitem
		$selected = $this->DB->SelectAny('SELECT id FROM orderlineitem WHERE product = '.$product->id);
		if(!empty($selected)) {
			$this->DB->good = FALSE;
			$product->_error = 'Accessory can\'t be deleted as some orders refer to it';
			return $product;
		}
		//products
		$selected = $this->DB->SelectAny('SELECT id FROM productlineitem WHERE lineitem = '.$product->id);
		if(!empty($selected)) {
			$this->DB->good = FALSE;
			$product->_error = 'Accessory can\'t be deleted as it is being used as an optional/include accessory for some products';
			return $product;
		}*/
		$this->DB->begin();
		$this->DB->SelectAny('delete from orderlineitem WHERE product = '.$product->id);
		$this->DB->SelectAny('delete from productlineitem WHERE lineitem = '.$product->id);
		$product->access_flag = 0;
		$presets = $this->DB->SelectGuide(array('preset g'),'*',array());
		foreach($presets as $prekey => $prevalue) $this->DB->insert('deleted',array('uid' => $product->uid,'preset' => $prekey,'type' => 18));
		$this->setLogEvent(5,25,13,'Delete accessory "'.$product->name.'" ['.$product->id.']',$product->id);
		$this->DB->processObject($product,'delete',array(),array(),TRUE);
		$this->DB->delete('changedurl', array('ownerid' => $product->id));
		//productcomment
		$this->DB->delete('productcomment',array('ownerid' => $product->id));
		//categorylineitem
		$this->DB->delete('categorylineitem',array('item' => $product->id));
		$this->DB->commit();
		return $product;
	}

	function deleteImages($request) {
		$this->product = new Product();
		$this->product->images = new ObjectsList();
		$this->product->images->type = new ItemPhoto();
		$this->product->id = $request['id'];
		$this->DB->initObject($this->product);
		if(!empty($request['number']) && validate((int)$request['number']) && (int)$request['number'] <= count($this->product->images->data)) {
			foreach($this->product->images->data as $key => $value) {
				if($value->number==$request['number']) {
					$this->product->images->data[$key]->image_type = '';
					$this->product->images->data[$key]->uploaded_date = '';
				}
			}
			foreach($this->product->images->data as $key =>$value) {
				if($value->number > $request['number']) {
					$this->product->images->data[$key-1]->image_type = $value->image_type;
					$this->product->images->data[$key-1]->uploaded_date = $value->uploaded_date;
				}
				if($value->number == count($this->product->images->data)) {
					$this->product->images->data[$key]->image_type = '';
					$this->product->images->data[$key]->uploaded_date = '';
				}
			}
			foreach($this->product->images->data as $key =>$value) {
				if(empty($this->product->images->data[$key]->uploaded_date))
					unset($this->product->images->data[$key]);
			}
			$this->DB->processObject($this->product);
			$this->DB->commit();
		}
		return $this->product;
	}

	function saveImages($object,$request = array(),$type = 3) { //printArray($request); exit;
		$images = array();
		//$col = $type==3? 'image' : '3d';
		if ($type==3)
			$col = 'image';
			elseif ($type==7) $col = 'userguide'; 
				else $col = '3d';
		
		if(empty($object->files->data)) {
			$i = 1;
			foreach($request[$col] as $key => $value) {
				$images[$key] = new ProductFile();
				$images[$key]->number = $i;
				$images[$key]->filetype = $type;
				$images[$key]->date_uploaded = 'now';
				$images[$key]->imagetype = !empty($value['image_type'])? $value['image_type'] : 'jpg';
				$images[$key]->sort_order = isset($value['sort_order'])?$value['sort_order']:$i;
				$images[$key]->description = isset($value['description'])?$value['description']:"";
				$i++;
			}
		}
		else { //printObject($object->files->data);exit;
			foreach($object->files->data as $key => $value) {
				if($value->filetype == $type) {
					if(!empty($request[$col][$value->number])) {
						$images[$value->number] = clone $value;
						$images[$value->number]->sort_order = $request[$col][$value->number]['sort_order'];
						if (isset($request[$col][$value->number]['description'])) // images does not have description
							$images[$value->number]->description = $request[$col][$value->number]['description'];
						unset($object->files->data[$key]);
					}
					else unset($object->files->data[$key]);
				}
			}
		}
		//print '<li>Do<br>';printObject($images); exit;
		empty($request[$col]) and $request[$col] = array();
		$count = !empty($request[$col])? array_max(array_keys($request[$col])) : 0;
		for($i = 1; $i <= $count; $i++) {
			if(!empty($request[$col][$i])) {
				if(!empty($request[$col][$i]['_tmp_name'])) {
					if(!empty($images[$i])) $images[$i]->date_uploaded = 'now';
					else {
						$images[$i] = new ProductFile();
						$images[$i]->number = $i;
//						$images[$i]->sort_order = $i;
					$images[$i]->sort_order = isset($request[$col][$i]['sort_order'])?$request[$col][$i]['sort_order']:$i;  //$request[$col][$i]['sort_order'];
						$images[$i]->filetype = $type;
						$images[$i]->date_uploaded = 'now';
						$images[$i]->imagetype = !empty($request[$col][$i]['image_type'])? $request[$col][$i]['image_type'] : ' ';
						$images[$i]->description = isset($request[$col][$i]['description'])?$request[$col][$i]['description']:$i;
					}
				}
			}
			else if(!empty($images[$i])) unset($images[$i]);
		}
		//print '<li>Posle<br>';printObject($images); exit;
		$i = 1;
		foreach($images as $key => $value) {
			//$value->number = $value->sort_order = $i;
			$value->number = $i;
			$object->files->data[] = clone $value;
			$i++;
		}
		//print '<li>Result<br>';printObject($object->files->data);exit;
	}

	function saveImage($object,$request = array(),$type = 1) {
		if(!empty($request['image_link'])) {
			$selected = $this->DB->SelectAny('SELECT id,image_link FROM productfile WHERE ownerid = '.$request['image_link'].' AND filetype = '.$type);
			if(empty($selected) || !empty($selected[0]['image_link'])) {
				switch($type) {
					case 1: $name = 'Preview Image'; break;
					case 2: $name = 'Big Image'; break;
					case 8: $name = 'Middle Image'; break;
				}
				$object->_error = ' The product can\'t use image of specified product with ID#'.$request['image_link'].' as a '.$name.', because this product also uses an image of other product.';
			}
		}
		foreach($object->files->data as $key => $value)
			if($value->filetype == $type) unset($object->files->data[$key]);
		$image = new ProductFile();
		$image->imagetype = $request['image_type'];
		$image->filetype = $type;
		$image->date_uploaded = 'now';
		$image->image_link = $request['image_link'];
		$object->files->data[] = clone $image;
	}

	function deleteProductFile($request = array()) {
		empty($request['id']) and $request['id'] = 0;
		empty($request['type']) and $request['type'] = 0;
		$selected = $this->DB->SelectAny('SELECT id,imagetype FROM productfile WHERE ownerid = '.$request['id'].' AND filetype = '.$request['type']);
		if(!empty($selected)) {
			switch($request['type']) {
				case 5: $name = 'Hi-Res. Image'; $file = 'hi.tif'; break;
				case 6: $name = 'Specification Sheet'; $file = 'ss.pdf'; break;
				case 7: $name = 'User\'s Guide'; $file = 'ug.pdf'; break;
			}
			$this->DB->begin();
			$this->DB->delete('productfile', array('id' => $selected[0]['id']));
			$this->setLogEvent(5,25,12,'Delete file "'.$name.'" from product ['.$request['id'].']',$request['id']);
			$product = new Product();
			$product->id = $request['id'];
			$this->DB->initObject($product);
			$product->date_changed = 'now';
			$this->DB->processObject($product,'save',array(),array(),TRUE);
			//$this->DB->rollback();
			$this->DB->commit();
			return array('id' => $request['id'],'file' => $file);
		}
		else return array('_error' => ' ');
	}

		/* *******************************/
		
	function uploadImages($files, $arrayName, $fileName){ 		
		GLOBAL $ROOT_PATH;			
		$duplicateArray = array();		
		$uploaddir   = $ROOT_PATH.'/images/thermal/';
		$uploaddirDB = '/images/thermal/';
		$ext='';
		//printArray($this->fileType);	
		
		if(!empty($files)){
			foreach($files as $key=>$value){
				foreach ($value as $keyIn => $valueIn ) {
					foreach ($valueIn as $i=>$row){			
						if ( $key == 'tmp_name' && !empty($row) ) {														
							if ( !file_exists($uploaddir.$arrayName.'/'.$keyIn) ){
								mkdir( $uploaddir.$arrayName, 0775 );
								mkdir( $uploaddir.$arrayName.'/'.$keyIn, 0775 );								
							}
							
							if ( is_dir($uploaddir.$arrayName.'/'.$keyIn ) ) {
								if (file_exists($uploaddir.$arrayName.'/'.$keyIn.'/'.$fileName.'.gif') )  { unlink($uploaddir.$arrayName.'/'.$keyIn.'/'.$fileName.'.gif');  } 
								if (file_exists($uploaddir.$arrayName.'/'.$keyIn.'/'.$fileName.'.jpeg'))  { unlink($uploaddir.$arrayName.'/'.$keyIn.'/'.$fileName.'.jpeg'); }
								if (file_exists($uploaddir.$arrayName.'/'.$keyIn.'/'.$fileName.'.jpg') )  { unlink($uploaddir.$arrayName.'/'.$keyIn.'/'.$fileName.'.jpg');  }
								if (file_exists($uploaddir.$arrayName.'/'.$keyIn.'/'.$fileName.'.png') )  { unlink($uploaddir.$arrayName.'/'.$keyIn.'/'.$fileName.'.png');  }
																
								copy( $row, $uploaddir.$arrayName.'/'.$keyIn.'/'.$fileName.'.'.strtolower($ext[1]) ); // str_to_lower
								//echo  $uploaddirDB.$arrayName.'/'.$keyIn.'/'.$fileName.'.'.strtolower($ext[1]).'<br />'.$keyIn.'<br /><br />---'.$fileName.'--<br />';
//								$this->DB->update('product', array('device_simulator_image' => $uploaddirDB.$arrayName.'/'.$keyIn.'/'.$fileName.'.'.strtolower($ext[1]) ) , array( 'id' => $fileName ) );
							}														
						} 						
						if ( $key == 'type' && !empty($row) ) {						
							$ext = explode('/',$row);												
							//$fileName[$arrayName.'_'.$keyIn.'_'.$fileName] = $uploaddirDB.$arrayName.'_'.$keyIn.'_'.$fileName.'.'.strtolower($ext[1]);							
						}					
					}
				}				
			}						
		}
		if (!empty($fileName)) return $fileName; //return $fileName = array_unique($fileName);
		else return false;
	} 
	/*************************************/

	function saveProduct($request = array()) {
//	printArray($request);exit;
		global $Server, $REGISTRY, $TOOLS_PATH;

		$this->undo = '';
		if(!empty($request['id']) || !empty($request['duplicate_id'])) {
			$old_product = new Product();
			$old_product->files = new ObjectsList();
			$old_product->files->type = new ProductFile();
			$old_product->id = !empty($request['duplicate_id'])? $request['duplicate_id'] : $request['id'];
			$this->DB->initObject($old_product);
		}
		$product = $this->createProduct(TRUE);
		if(!empty($request['id']) || !empty($request['duplicate_id'])) {
			$product->files = clone $old_product->files;
			foreach($old_product->files->data as $value) {
				$product->_files[] = array(
					'imagetype' => $value->imagetype,
					'filetype' => $value->filetype,
					'date_uploaded' => $value->date_uploaded,
					'image_link' => $value->image_link,
					'number' => $value->number,
					'description' => $value->description,
				);
			}
		}
		$this->parseRequest($request,$product);
		$links = $product->links->data;
		$product->links = '';
		if(!empty($request['image'])) 
			$this->saveImages($product,$request,3);
				else if(!empty($request['id']) || !empty($request['duplicate_id'])) {
					foreach($product->files->data as $key => $value) {
						if($value->filetype == 3) unset($product->files->data[$key]);
					}
				}
				
		if(!empty($request['userguide']))
			$this->saveImages($product,$request,7);
				else if(!empty($request['id']) || !empty($request['duplicate_id'])) {
					foreach($product->files->data as $key => $value) {
						if($value->filetype == 7) unset($product->files->data[$key]);
					}
				}
		
				
		/*if(!empty($request['3d'])) 
			$this->saveImages($product,$request,4);
				else if(!empty($request['id']) || !empty($request['duplicate_id'])) {
					foreach($product->files->data as $key => $value) {
						if($value->filetype == 4) unset($product->files->data[$key]);
					}
				}*/
		if(!empty($request['hi'])) $this->saveImage($product,$request['hi'],5);
		if(!empty($request['ss'])) $this->saveImage($product,$request['ss'],6);
		if(!empty($request['ug'])) $this->saveImage($product,$request['ug'],7);
		if(!empty($request['prew'])) $this->saveImage($product,$request['prew'],1);
		if(!empty($product->_error)) {
			$this->DB->good = FALSE;
			return $product;
		}
		if(!empty($request['big'])) $this->saveImage($product,$request['big'],2);
		if(!empty($product->_error)) {
			$this->DB->good = FALSE;
			return $product;
		}
		if(!empty($request['middle'])) $this->saveImage($product,$request['middle'],8);
		if(!empty($product->_error)) {
			$this->DB->good = FALSE;
			return $product;
		}
		$product->files->data = array_values($product->files->data);
		$product->path = strtolower($product->path);
		/*$selected = $this->DB->SelectAny('SELECT id FROM product WHERE access_flag=0 and (lower(path) = \''.$product->path.'\' OR lower(path2) = \''.$product->path.'\')'.(empty($product->id)? '' : ' AND id != '.$product->id) );
		if(!empty($selected)) {
			$this->DB->good = FALSE;
			$product->_error = 'Product with such Path already exists(Existing Product ID:'.$selected[0]['id'].')';
			return $product;
		}
		else {*/
	 		foreach($request['categorylineitems'] as $key => $value) {
				$new_slot = $this->getCategoryPath($value['id']).'/'.$product->path;
				foreach($REGISTRY['VirtualSlotTarget']['main'] as $path => $handler) {
					if($new_slot==strval($path) && $handler != 'ProductView:object?id='.$product->id) {
						$this->DB->good = FALSE;
						$product->_error = 'Category or Page with such Path already exists';
						return $product;
					}
				}
				//----add color (for compare)
				$rootcategory = $this->DB->SelectAny('SELECT ownerid FROM category WHERE id = '.$value['id']);
				if($value['id'] != 27 &&  !empty($rootcategory) && $rootcategory[0]['ownerid'] != 27) {
					//print $rootcategory[0]['ownerid'];exit;
						$color = $this->DB->SelectAny('SELECT id FROM color WHERE ownerid = '.$rootcategory[0]['ownerid']);
						$product->color->id = $color[0]['id'];
						$this->DB->initObject($product->color);
				}
			}
		//}
		
		if(!empty($product->path2)) {
			$product->path2 = strtolower($product->path2);
			$selected = $this->DB->SelectAny('SELECT id FROM product WHERE (lower(path) = \''.$product->path2.'\' OR lower(path2) = \''.$product->path2.'\')'.(empty($product->id)? '' : ' AND id != '.$product->id));
			if(!empty($selected)) {
				$this->DB->good = FALSE;
				$product->_error = 'Product with such Root Path already exists';
				return $product;
			}
			else {
				foreach($request['categorylineitems'] as $key => $value) {
					$new_slot = $this->getCategoryPath($value['id']).'/'.$product->path2;
					foreach($REGISTRY['VirtualSlotTarget']['main'] as $path => $handler) {
						if(($new_slot==strval($path) || '/'.$product->path2==strval($path)) && $handler != 'ProductView:object?id='.$product->id) {
							$this->DB->good = FALSE;
							$product->_error = 'Category or Page with such Root Path already exists';
							return $product;
						}
					}
				}
			}
		}
		$this->DB->begin();
		$product->access_flag = 0;
		$changed_url = false;
		$product->ownerid = $product->item->id;
		if(!empty($product->id)) {
			$selected = $this->DB->SelectAny('SELECT path, path2 FROM product WHERE id = '.$product->id.' LIMIT 1');
			if(!empty($selected)){
				if($selected[0]['path'] != $product->path) $changed_url = true;
				if($selected[0]['path2'] != $product->path2) $changed_url = true;
				$Undo_field= array('type' => 18,'id' => $product->id,'undo' => 1);
				include($TOOLS_PATH.'\undo.php');
				$this->undo = $undo_handler->arr_obj;
			}
		}
		if(empty($product->id)) {
			$product->uid = $this->getUID('product');
			$max = $this->DB->SelectSingle(array('product'),'max(sort_order)',array());
			$product->sort_order = $max+10;
			$product->date_created = 'now';
		}
		else $product->sort_order = $this->DB->SelectSingle(array('product'),'sort_order',array('id' => $product->id));
		if(!empty($request['duplicate_id'])) $this->DB->update('product',array('access_flag' => 0),array('id' => $request['duplicate_id']));
		$product->date_changed = 'now';
		if(isset($request['autochange']) && $request['autochange']=='true') {
			$old_slot = array();
			$selected = $this->DB->SelectAny('SELECT ownerid FROM categorylineitem WHERE item = '.$product->id);
			if(!empty($selected)) {
				$count = count($selected);
				for($i = 0; $i < $count; $i++){
					$old_slot[$selected[$i]['ownerid']] = $this->getCategoryPath($selected[$i]['ownerid']).'/'.$old_product->path;
				}
			}
		}
		
		//---remove all accessories that are NOT existed in DB
		//printArray($request['productlineitems']);exit;
		foreach($request['productlineitems'] as $key_acc => $value_acc) {
			$acc = $this->DB->SelectAny('SELECT id FROM product WHERE id = '.$value_acc['lineitem']['id']);
			if(empty($acc) || empty($acc[0]['id'])) unset ($request['productlineitems'][$key_acc] );
		}
		
		if(empty($product->id)) $this->setLogEvent(5,25,11,'Add product "'.$product->name.'" ('.$product->path.')');
			else $this->setLogEvent(5,25,12,'Edit product "'.$product->name.'" ('.$product->path.') ['.$product->id.']',$product->id);
		//print '<li>Full Result<br>';printObject($product);
		$product->layout = 2;
		$this->DB->processObject($product);
		
		if(!empty($request['id'])) {	
				$old_path2 = $old_product->path2;
				unset($old_product);
		}
		if(empty($product->uid)) {
			$selected = $this->DB->SelectAny('SELECT uid FROM product WHERE id = '.$product->id.' LIMIT 1');
			if(!empty($selected) && !empty($selected[0]['uid'])) $this->DB->delete('deleted', array('uid' => $selected[0]['uid'], 'type' => 18));
		}
		else $this->DB->delete('deleted', array('uid' => $product->uid, 'type' => 18));
		$this->DB->delete('link',array('ownerid' => $product->id,'moduletype' => 2));
		$i = 1;
		foreach($links as $key => $value) {
			$link = new Link();
			$this->parseRequest($value,$link);
			$link->ownerid = $product->id;
			$link->sort_order = $i*10;
			$this->DB->processObject($link);
			$i++;
		}
		if($changed_url){
			$selected = $this->DB->SelectAny('SELECT id FROM preset');
			$count = count($selected);
			for ($i = 0; $i < $count; $i++){
				$record_exists = $this->DB->SelectAny('SELECT id FROM changedurl WHERE ownerid = '.$product->id.' AND preset = '.$selected[$i]['id'].' LIMIT 1');
				if(empty($record_exists)) $this->DB->insert('changedurl', array('ownerid' => $product->id, 'preset' => $selected[$i]['id']));
			}
		}
		$slot = array();
		$this->DB->delete('categorylineitem',array('item' => $product->id));
		foreach((!empty($request['categorylineitems'])? $request['categorylineitems'] : array()) as $key => $value) {
			$this->DB->insert('categorylineitem',array('ownerid' => $value['id'],'item' => $product->id));
			$slot[$value['id']] = $this->getCategoryPath($value['id']).'/'.$product->path;
		}
		
//printArray($slot);exit;
		$productcomment= new ProductComment();
		$productcomment->version = 1;
		$productcomment->value = 'Product has been created';
		$selected = $this->DB->SelectAny("select version from productcomment where ownerid = ".$product->id." order by date desc LIMIT 1 OFFSET 0");
		if(!empty($selected[0]['version'])) {
			$productcomment->version=++$selected[0]['version'];
			$productcomment->value = (!empty($request['_undo_'])? 'Product has been undone up to '.$request['_undo_']." version<br>\r\n" : '').htmlspecialchars($request['comment']);
		}
		$productcomment->ownerid = $product->id;
		$productcomment->member = empty($request['id_user']) ? $this->Security->currentuser->id : $request['id_user'];
		$productcomment->date = 'now';
		$this->DB->processObject($productcomment,'save',array(),array(),TRUE);
		if(!empty($request['_undo_'])) {
			$this->setLogEvent(5,25,10,'Product "'.$product->name.'" ('.$product->path.') ['.$product->id.'] has been undone up to '.$request['_undo_'].' version',$product->id);
		}
		//$this->DB->rollback();
		$this->DB->commit();
		if($this->DB->good) {
			foreach($REGISTRY['VirtualSlotTarget']['main'] as $path => $handler) {
				if($handler == 'ProductView:object?id='.$product->id) {
					unset($REGISTRY['VirtualSlotTarget'][''][$path]);
					unset($REGISTRY['VirtualSlotTarget']['main'][$path]);
					unset($REGISTRY['VirtualSlotTarget'][''][$path.'.xml']);
					unset($REGISTRY['VirtualSlotTarget']['main'][$path.'.xml']);
				}
			}
			if(!empty($request['id'])) {
				unset($REGISTRY['VirtualSlotTarget'][''][$old_path2]);
				unset($REGISTRY['VirtualSlotTarget']['main'][$old_path2]);
				unset($REGISTRY['VirtualSlotTarget'][''][$old_path2.'.xml']);
				unset($REGISTRY['VirtualSlotTarget']['main'][$old_path2.'.xml']);
			}
			if(!empty($product->path2)) {
				$REGISTRY['VirtualSlotTarget']['']['/'.$product->path2] = $product->layout;
				$REGISTRY['VirtualSlotTarget']['main']['/'.$product->path2] = 'ProductView:object?id='.$product->id;
				$REGISTRY['VirtualSlotTarget']['']['/'.$product->path2.'.xml'] = 'ProductRSSView:object?id='.$product->id;
				$REGISTRY['VirtualSlotTarget']['main']['/'.$product->path2.'.xml'] = 'ProductRSSView:object?id='.$product->id;
			}
			else {
				foreach($slot as $key => $value) {
					$REGISTRY['VirtualSlotTarget'][''][$value] = $product->layout;
					$REGISTRY['VirtualSlotTarget']['main'][$value] = 'ProductView:object?id='.$product->id;
					$REGISTRY['VirtualSlotTarget'][''][$value.'.xml'] = 'ProductRSSView:object?id='.$product->id;
					$REGISTRY['VirtualSlotTarget']['main'][$value.'.xml'] = 'ProductRSSView:object?id='.$product->id;
				}
			}
			$REGISTRY['VirtualSlotTarget']['main']['?'] = 'DescribeView:object?id=10';
			$Server->saveRegistry();
			// ���������� ���������� ������
			if(!empty($this->undo)) {
				$undo_handler->GetArrayInFile($this->undo, "Undo_object", $ROOT_PATH."/undo/".$pub_type[0]['name']."/".$Undo_field['id']."/".($productcomment->version>1? $productcomment->version-1 : 1).".inc");
			}
			// Autochange URL
			if(isset($request['autochange']) && $request['autochange'] == 'true') {
				include($TOOLS_PATH.'/autochangeURL.inc');
				//print '<li>OLD SLOT - '.$old_slot;
				//print '<li>NEW SLOT - '.$slot;
				foreach($old_slot as $key => $value) {
					if(!empty($slot[$key]) && $value != $slot[$key]) {
						autochangeURL($value, $slot[$key], (is_object($this->Security) ? $this->Security->currentuser->id : $this->currentuser->id));
						$this->setLogEvent(5,25,9, 'Allover content Autochange URL from "'.$value.'" to "'.$slot[$key].'" complete', $product->id);
					}
					else if(empty($slot[$key])) {
						autochangeURL($value, $this->getCategoryPath(1), (is_object($this->Security) ? $this->Security->currentuser->id : $this->currentuser->id));
						$this->setLogEvent(5,25,9, 'Allover content Autochange URL from "'.$value.'" to "'.$this->getCategoryPath(1).'" complete', $product->id);
					}
				}
				$this->DB->commit();
			}
			//--- clear this product's pages + all category pages with this product
 			foreach($request['categorylineitems'] as $key => $value) {
 				$cat_url = $this->getCategoryPath($value['id']);
				$url = $cat_url.'/'.$product->path;
				foreach($REGISTRY['VirtualSlotTarget']['main'] as $path => $handler) {
					if($url==strval($path) && $handler == 'ProductView:object?id='.$product->id) {
						clearCacheByURL($url);
						clearCacheByURL($cat_url);
						clearCacheByURL("/sitemap");
					}
				}
			}
		}
		//if(!$this->DB->good) $product->_error = ' ';
		return $product;
	}

	function deleteProduct($request) {
		global $Server, $REGISTRY;
		$product = $this->createProduct(TRUE);
		$product->id = $request['id'];
		$this->DB->initObject($product);
		$product->links = '';
		//image_link
		$selected = $this->DB->SelectAny('SELECT id FROM productfile WHERE image_link = '.$product->id.' AND ownerid != '.$product->id);
		if(!empty($selected)) {
			$this->DB->good = FALSE;
			$product->_error = 'Product can\'t be deleted as its images are being used for other products';
			return $product;
		}
		//special
		$selected = $this->DB->SelectAny('SELECT id FROM special WHERE item = '.$product->id);
		if(!empty($selected)) {
			$this->DB->good = FALSE;
			$product->_error = 'Product can\'t be deleted as it is used as featured product';
			return $product;
		}
		// �������� �� dynamic previews ???
		//orderlineitem
		$selected = $this->DB->SelectAny('SELECT id FROM orderlineitem WHERE product = '.$product->id);
		if(!empty($selected)) {
			$this->DB->good = FALSE;
			$product->_error = 'Product can\'t be deleted as some orders refer to it';
			return $product;
		}
		$this->DB->begin();
		$slots = array();
		$selected = $this->DB->SelectAny('SELECT ownerid FROM categorylineitem WHERE item = '.$product->id);
		if(!empty($selected)) {
			$count = count($selected);
			for($i = 0; $i < $count; $i++){
				$slots[$selected[$i]['ownerid']] = $this->getCategoryPath($selected[$i]['ownerid']).'/'.$product->path;
			}
		}
		$product->access_flag = 0;
		$presets = $this->DB->SelectGuide(array('preset g'),'*',array());
		foreach($presets as $prekey => $prevalue) $this->DB->insert('deleted',array('uid' => $product->uid,'preset' => $prekey,'type' => 18));
		$this->setLogEvent(5,25,13,'Delete product "'.$product->name.'" ('.$product->path.') ['.$product->id.']',$product->id);
		$this->DB->processObject($product,'delete',array(),array(),TRUE);
		/* ��������� ��������� */$this->DB->delete('changedurl', array('ownerid' => $product->id));
		//meta
		$this->DB->delete('meta',array('ownerid' => $product->id,'moduletype' => 3));
		//menulineitem other
		foreach($slots as $key => $value) $this->DB->query('delete from "menulineitem" where path=\''.$value.'\'');
		//productcomment
		$this->DB->delete('productcomment',array('ownerid' => $product->id));
		//links
		$this->DB->delete('link',array('ownerid' => $product->id,'moduletype' => 2));
		//categorylineitem
		$this->DB->delete('categorylineitem',array('item' => $product->id));
		//applicable
		$this->DB->delete('applicable',array('product' => $product->id));
		$this->DB->commit();
		if($this->DB->good) {
			foreach($REGISTRY['VirtualSlotTarget']['main'] as $path => $handler) {
				if($handler == 'ProductView:object?id='.$product->id || $handler == 'ProductRSSView:object?id='.$product->id) {
					unset($REGISTRY['VirtualSlotTarget'][''][$path]);
					unset($REGISTRY['VirtualSlotTarget']['main'][$path]);
				}
			}
			$Server->saveRegistry();
		}
		//$this->DB->rollback();
		return $product;
	}

	function getProductName($request = array('id' => 0)) {
		$this->product = new Product();
		$this->parseRequest($request,$this->product);
		$this->DB->initObject($this->product);
		return $this->product;
	}

	function openMailProduct($request = array('id' => 0)) {
		$this->product = $this->createMailProduct();
		$this->parseRequest($request,$this->product);
		$this->DB->initObject($this->product);
		$this->product->item->id = $this->product->ownerid;
		$this->DB->initObject($this->product->item);
		if(empty($this->product->active)) $this->product->_error = '1'; // Net Takogo
		elseif($this->product->active=='f') $this->product->_error = '6'; // Ne Aktiven
		elseif($this->product->item->itemtype->id!=1) $this->product->_error = '5'; // Ne Produkt
		return $this->product;
	}

	function openAccessory($request = array('id' => 0,'ship' => 0,'catid' => 0)) {
		if(empty($request['ship'])) $request['ship'] = 0;
		global $TOOLS_PATH;
		if(!empty($request['undo'])) {
			$Undo_field= array('type' => 18,'id' => $request['id'],'undo' => 0,'version' => $request['undo']);
			include($TOOLS_PATH.'\undo.php');
			$selected = $this->DB->SelectAny('SELECT path FROM product WHERE id = '.$request['id'].' LIMIT 1');
			$print_arr['old_url'] = @$selected[0]['path'];
			return $print_arr;
		}
		$product = $this->createAccessoryOrKit($request['ship']);
		$this->parseRequest($request,$product);
		$this->DB->initObject($product);
		if(!empty($product->files->data)) {
			uasort($product->files->data,'by_index');
			$product->files->data = array_values($product->files->data);
		}
		if(!empty($product->shipcosts->data)) {
			uasort($product->shipcosts->data,'by_shipcosttype');
			$product->shipcosts->data = array_values($product->shipcosts->data);
		}
		return $product;
	}

	function openParentItem($request = array('id' => 0)) {
		global $TOOLS_PATH;
		if(!empty($request['undo'])) {
			$Undo_field= array('type' => 17,'id' => $request['id'],'undo' => 0,'version' => $request['undo']);
			include($TOOLS_PATH.'\undo.php');
			return $print_arr;
		}
		$parentitem = new ParentItem();;
		$this->parseRequest($request,$parentitem);
		$this->DB->initObject($parentitem);
		return $parentitem;
	}

	function saveParentItem($request = array()) {
		global $Server, $REGISTRY, $TOOLS_PATH;
		$this->undo = '';
		$parentitem = new ParentItem();
		$this->parseRequest($request,$parentitem);
		$selected = $this->DB->SelectAny('SELECT id FROM parentitem WHERE name = \''.$parentitem->name.'\''.(empty($parentitem->id)? '' : ' AND id != '.$parentitem->id));
		if(!empty($selected)) {
			$this->DB->good = FALSE;
			$parentitem->_error = 'Parent Item with such name already exists';
			return $parentitem;
		}
		$this->DB->begin();
		$parentitem->access_flag = 0;
		// �������� ���������� ������ / �������� �� ��������� ����
		if(!empty($parentitem->id)) {
			$selected = $this->DB->SelectAny('SELECT name,itemtype FROM parentitem WHERE id = '.$parentitem->id.' LIMIT 1');
			if(!empty($selected)){
				$Undo_field= array('type' => 17,'id' => $parentitem->id,'undo' => 1);
				include($TOOLS_PATH.'\undo.php');
				$this->undo = $undo_handler->arr_obj;
				if($selected[0]['itemtype']!=$parentitem->itemtype) {
					$selected = $this->DB->SelectAny('SELECT id FROM product WHERE item = '.$parentitem->id);
					if(!empty($selected)) {
						$this->DB->good = FALSE;
						$parentitem->_error = 'It is not possible to change type of item\'s parent as it is already a parent for some products or accessories';
						return $parentitem;
					}
				}
			}
		}
		if(empty($parentitem->id)) {
			$parentitem->uid = $this->getUID('parentitem');
			$max = $this->DB->SelectSingle(array('parentitem'),'max(sort_order)',array());
			$parentitem->sort_order = $max+10;
			$parentitem->date_created = 'now';
		}
		else $parentitem->sort_order = $this->DB->SelectSingle(array('parentitem'),'sort_order',array('id' => $parentitem->id));
		if(!empty($request['duplicate_id'])) $this->DB->update('parentitem',array('access_flag' => 0),array('id' => $request['duplicate_id']));
		$parentitem->date_changed = 'now';
		if(empty($parentitem->id)) $this->setLogEvent(5,24,11,'Add parent item "'.$parentitem->name.'"');
		else $this->setLogEvent(5,24,12,'Edit Parent Item "'.$parentitem->name.'" ['.$parentitem->id.']',$parentitem->id);
		$this->DB->processObject($parentitem, 'save', array(), array(), TRUE);
		if(empty($category->uid)) {
			$selected = $this->DB->SelectAny('SELECT uid FROM parentitem WHERE id = '.$parentitem->id.' LIMIT 1');
			if(!empty($selected) && !empty($selected[0]['uid'])) $this->DB->delete('deleted', array('uid' => $selected[0]['uid'], 'type' => 17));
		}
		else $this->DB->delete('deleted', array('uid' => $parentitem->uid, 'type' => 17));
		$parentitemcomment= new ParentItemComment();
		$parentitemcomment->version = 1;
		$parentitemcomment->value = 'Parent Item has been created';
		$selected = $this->DB->SelectAny("select version from parentitemcomment where ownerid = ".$parentitem->id." order by date desc LIMIT 1 OFFSET 0");
		if(!empty($selected[0]['version'])) {
			$parentitemcomment->version=++$selected[0]['version'];
			$parentitemcomment->value = (!empty($request['_undo_'])? 'Parent Item has been undone up to '.$request['_undo_']." version<br>\r\n" : ''). (isset($request['comment'])?htmlspecialchars($request['comment']):'' )   ;
		}
		$parentitemcomment->ownerid = $parentitem->id;
		$parentitemcomment->member = empty($request['id_user']) ? $this->Security->currentuser->id : $request['id_user'];
		$parentitemcomment->date = 'now';
		$this->DB->processObject($parentitemcomment,'save',array(),array(),TRUE);
		if(!empty($request['_undo_'])) {
			$this->setLogEvent(5,24,10,'Parent Item "'.$parentitem->name.'" ['.$parentitem->id.'] has been undone up to '.$request['_undo_'].' version',$parentitem->id);
		}
		$this->DB->commit();
		clearCache();
		if($this->DB->good) {
			// ���������� ���������� ������
			if(!empty($this->undo))
				$undo_handler->GetArrayInFile($this->undo, "Undo_object", $ROOT_PATH."/undo/".$pub_type[0]['name']."/".$Undo_field['id']."/".($parentitemcomment->version>1? $parentitemcomment->version-1 : 1).".inc");
		}
		return $parentitem;
	}

	function deleteParentItem($request = array()) {
		global $Server, $REGISTRY;
		$parentitem = new ParentItem();
		$parentitem->id = $request['id'];
		$this->DB->initObject($parentitem);
		$selected = $this->DB->SelectAny("select id from product where item = ".$parentitem->id);
		if(!empty($selected)) {
			$this->DB->good = FALSE;
			$parentitem->_error = 'The Parent Item is not a subject removals as is the parent for products';
			return $parentitem;
		}
		$this->DB->begin();
		$parentitem->access_flag = 0;
		$presets = $this->DB->SelectGuide(array('preset g'),'*',array());
		foreach($presets as $prekey => $prevalue) $this->DB->insert('deleted',array('uid' => $parentitem->uid,'preset' => $prekey,'type' => 17));
		$this->setLogEvent(5,24,13,'Delete parent item "'.$parentitem->name.'" ['.$parentitem->id.']',$parentitem->id);
		$this->DB->processObject($parentitem,'delete',array(),array(),TRUE);
		//parentitemcomment
		$this->DB->delete('parentitemcomment',array('ownerid' => $parentitem->id));
		$this->DB->commit();
		return $parentitem;
	}

	function openCategory($request = array('id' => 0)) {
		global $TOOLS_PATH;
		if(!empty($request['undo'])) {
			$Undo_field= array('type' => 16,'id' => $request['id'],'undo' => 0,'version' => $request['undo']);
			include($TOOLS_PATH.'\undo.php');
			$selected = $this->DB->SelectAny('SELECT sys_name FROM category WHERE id = '.$request['id'].' LIMIT 1');
			$print_arr['old_url'] = @$selected[0]['sys_name'];
			return $print_arr;
		}
		empty($request['getlinks']) and $request['getlinks'] = 1;
		empty($request['parent']) and $request['parent'] = 1;
		empty($request['meta']) and $request['meta'] = 0;
		$category = $this->createCategory(0,$request['getlinks'],$request['parent'],$request['meta']);
		$this->parseRequest($request,$category);
		$this->DB->initObject($category);
		foreach((!empty($category->reviews->data)? $category->reviews->data : array()) as $key => $value) {
			if($value->moduletype != 2) unset($category->reviews->data[$key]);
		}
		$category->reviews->data = array_values($category->reviews->data);
		if(!empty($category->reviews->data)) {
			usort($category->reviews->data,'by_index');
			$category->reviews->data = array_values($category->reviews->data);
		}
		foreach((!empty($category->customerreviewitems->data)? $category->customerreviewitems->data : array()) as $key => $value) {
			if($value->moduletype != 2) unset($category->customerreviewitems->data[$key]);
		}
		if(!empty($category->customerreviewitems->data)) $category->customerreviewitems->data = array_values($category->customerreviewitems->data);
		if(!empty($category->customerreviewitems->data)) {
			usort($category->customerreviewitems->data,'by_index');
			$category->customerreviewitems->data = array_values($category->customerreviewitems->data);
		}
		foreach((!empty($category->links->data)? $category->links->data : array()) as $k => $v) {
			if($v->moduletype != 1) unset($category->links->data[$k]);
		}
		$category->links->data = array_values($category->links->data);
		foreach((!empty($category->metas->data)? $category->metas->data : array()) as $key => $value) {
			if($value->moduletype != 2) unset($category->metas->data[$key]);
		}
		if(!empty($category->metas->data)) $category->metas->data = array_values($category->metas->data);
		return $category;
	}

	function deleteCategory($request = array()) {
		global $Server, $REGISTRY;
		$category = $this->createCategory(0,false,true);
		$category->id = $request['id'];
		$this->DB->initObject($category);
		$category->links = '';
		$selected = $this->DB->SelectAny("select id from category where ownerid = ".$category->id);
		if(!empty($selected)) {
			$this->DB->good = FALSE;
			$category->_error = 'The Category is not a subject removals as is the parent for other categories';
			return $category;
		}
		else {
			// �������� ��������� - categorylineitems
			$selected = $this->DB->SelectAny("select id from categorylineitem where ownerid = ".$category->id);
			if(!empty($selected)) {
				$this->DB->good = FALSE;
				$category->_error = 'The Category is not a subject removals it contains products';
				return $category;
			}
		}
		$this->DB->begin();
		$slot = $this->getCategoryPath($category->id);
		//category
		$category->access_flag = 0;
		$presets = $this->DB->SelectGuide(array('preset g'),'*',array());
		foreach($presets as $prekey => $prevalue) $this->DB->insert('deleted',array('uid' => $category->uid,'preset' => $prekey,'type' => 16));
		$this->setLogEvent(5,23,13,'Delete category "'.$category->name.'" ('.$category->sys_name.') ['.$category->id.']',$category->id);
		$this->DB->processObject($category,'delete',array(),array(),TRUE);
		/* ��������� ��������� */$this->DB->delete('changedurl', array('ownerid' => $category->id));
		//meta
		$this->DB->delete('meta',array('ownerid' => $category->id,'moduletype' => 2));
		//menulineitem other
		$this->DB->query('delete from "menulineitem" where path=\''.$slot.'\'');
		//categorycomment
		$this->DB->delete('categorycomment',array('ownerid' => $category->id));
		//links
		$this->DB->delete('link',array('ownerid' => $category->id,'moduletype' => 1));
		$this->DB->commit();
		//$this->DB->rollback();
		if($this->DB->good) {
			foreach($REGISTRY['VirtualSlotTarget']['main'] as $path => $handler) {
				if($handler == 'StoreView:object?id='.$category->id) {
					unset($REGISTRY['VirtualSlotTarget'][''][$path]);
					unset($REGISTRY['VirtualSlotTarget']['main'][$path]);
				}
			}
			$Server->saveRegistry();
		}
		return $category;
	}

	function saveCategory($request = array()) {
		global $Server, $REGISTRY, $TOOLS_PATH, $Paths;
		$this->undo = '';
		$category = $this->createCategory(0,true,true);
		$this->parseRequest($request,$category);
		$links = $category->links->data;
		$category->links = '';
		$category->sys_name = strtolower($category->sys_name);
		$selected = $this->DB->SelectAny('SELECT id FROM category WHERE lower(sys_name) = \''.$category->sys_name.'\' AND ownerid = '.$category->ownerid.(empty($category->id)? '' : ' AND id != '.$category->id));
		if(!empty($selected)) {
			$this->DB->good = FALSE;
			$category->_error = 'Category with such Path already exists';
			return $category;
		}
		else {
			$new_slot = $this->getCategoryPath($category->ownerid).'/'.$category->sys_name;
			foreach($REGISTRY['VirtualSlotTarget']['main'] as $path => $handler) {
				if($path == $new_slot && $handler != 'StoreView:object?id='.$category->id) {
					$this->DB->good = FALSE;
					$category->_error = 'Category, Product or Page with such Path already exists';
					return $category;
				}
			}
		}
		if(!empty($category->path2)) {
			$category->path2 = strtolower($category->path2);
			$selected = $this->DB->SelectAny('SELECT id FROM category WHERE (lower(sys_name) = \''.$category->path2.'\' OR lower(path2) = \''.$category->path2.'\')'.(empty($category->id)? '' : ' AND id != '.$category->id));
			if(!empty($selected)) {
				$this->DB->good = FALSE;
				$category->_error = 'Category with such Root Path already exists';
				return $category;
			}
			else {
				foreach($REGISTRY['VirtualSlotTarget']['main'] as $path => $handler) {
					if($path == '/'.$category->path2 && $handler != 'StoreView:object?id='.$category->id) {
						$this->DB->good = FALSE;
						$category->_error = 'Category, Product or Page with such Root Path already exists';
						return $category;
					}
				}
			}
		}
		$this->DB->begin();
		$category->access_flag = 0;
		$changed_url = false;
		empty($category->id) and $request['autochange'] = 'false';
		if(!empty($category->id)) {
			$selected = $this->DB->SelectAny('SELECT sys_name, path2 FROM category WHERE id = '.$category->id.' LIMIT 1');
			if(!empty($selected)){
				if($selected[0]['sys_name'] != $category->sys_name) $changed_url = true;
				if($selected[0]['path2'] != $category->path2) $changed_url = true;
				$Undo_field= array('type' => 16,'id' => $category->id,'undo' => 1);
				include($TOOLS_PATH.'\undo.php');
				$this->undo = $undo_handler->arr_obj;
			}
		}
		if(empty($category->id)) {
			$category->uid = $this->getUID('category');
			$max = $this->DB->SelectSingle(array('category'),'max(sort_order)',array('ownerid' => $category->ownerid));
			$category->sort_order = $max+10;
			$category->date_created = 'now';
		}
		else {
			$parent = $this->DB->SelectSingle(array('category'),'ownerid',array('id' => $category->id));
			if($parent==$category->ownerid) $category->sort_order = $this->DB->SelectSingle(array('category'),'sort_order',array('id' => $category->id));
			else {
				$max = $this->DB->SelectSingle(array('category'),'max(sort_order)',array('ownerid' => $category->ownerid));
				$category->sort_order = $max+10;
			}
		}
		if(!empty($request['duplicate_id'])) $this->DB->update('category',array('access_flag' => 0),array('id' => $request['duplicate_id']));
		$category->date_changed = 'now';
		if(isset($request['autochange']) && $request['autochange']=='true') $old_slot = $this->getCategoryPath($category->id);
		//??  categoryjszones   ??//
		if(empty($category->id)) $this->setLogEvent(5,23,11,'Add category "'.$category->name.'" ('.$category->sys_name.')');
		else $this->setLogEvent(5,23,12,'Edit category "'.$category->name.'" ('.$category->sys_name.') ['.$category->id.']',$category->id);
		$category->layout = 180;
		$this->DB->processObject($category, 'save', array(), array(), TRUE);
		if(empty($category->uid)) {
			$selected = $this->DB->SelectAny('SELECT uid FROM category WHERE id = '.$category->id.' LIMIT 1');
			if(!empty($selected) && !empty($selected[0]['uid'])) $this->DB->delete('deleted', array('uid' => $selected[0]['uid'], 'type' => 16));
		}
		else $this->DB->delete('deleted', array('uid' => $category->uid, 'type' => 16));
		$this->DB->delete('link',array('ownerid' => $category->id,'moduletype' => 1));
		$i = 1;
		foreach($links as $key => $value) {
			$link = new Link();
			$this->parseRequest($value,$link);
			$link->ownerid = $category->id;
			$link->sort_order = $i*10;
			$this->DB->processObject($link);
			$i++;
		}
		
		if($changed_url){
			$selected = $this->DB->SelectAny('SELECT id FROM preset');
			$count = count($selected);
			for ($i = 0; $i < $count; $i++){
				$record_exists = $this->DB->SelectAny('SELECT id FROM changedurl WHERE ownerid = '.$category->id.' AND preset = '.$selected[$i]['id'].' LIMIT 1');
				if(empty($record_exists)) $this->DB->insert('changedurl', array('ownerid' => $category->id, 'preset' => $selected[$i]['id']));
			}
		}
		$categorycomment= new CategoryComment();
		$categorycomment->version = 1;
		$categorycomment->value = 'Category has been created';
		$selected = $this->DB->SelectAny("select version from categorycomment where ownerid = ".$category->id." order by date desc LIMIT 1 OFFSET 0");
		if(!empty($selected[0]['version']) && isset ($request['comment'])) {
			$categorycomment->version=++$selected[0]['version'];
			$categorycomment->value = (!empty($request['_undo_'])? 'Category has been undone up to '.$request['_undo_']." version<br>\r\n" : '').htmlspecialchars($request['comment']);
		}
		$categorycomment->ownerid = $category->id;
		$categorycomment->member = empty($request['id_user']) ? $this->Security->currentuser->id : $request['id_user'];
		$categorycomment->date = 'now';
		$this->DB->processObject($categorycomment,'save',array(),array(),TRUE);
		if(!empty($request['_undo_'])) {
			$this->setLogEvent(5,23,10,'Category "'.$category->name.'" ('.$category->sys_name.') ['.$category->id.'] has been undone up to '.$request['_undo_'].' version',$category->id);
		}
		$this->DB->commit();
		if($this->DB->good) {
			$Paths = array();
			$slot = $this->getCategoryPath($category->id);
			//print '<li>'.$slot;
			foreach($REGISTRY['VirtualSlotTarget']['main'] as $path => $handler) {
				if($handler == 'StoreView:object?id='.$category->id) {
					unset($REGISTRY['VirtualSlotTarget'][''][$path]);
					unset($REGISTRY['VirtualSlotTarget']['main'][$path]);
					unset($REGISTRY['VirtualSlotTarget'][''][$path.'.xml']);
					unset($REGISTRY['VirtualSlotTarget']['main'][$path.'.xml']);
				}
			}
			$REGISTRY['VirtualSlotTarget'][''][$slot] = $category->layout;
			$REGISTRY['VirtualSlotTarget']['main'][$slot] = 'StoreView:object?id='.$category->id;
			$REGISTRY['VirtualSlotTarget'][''][$slot.'.xml'] = 'StoreRSSView:object?id='.$category->id;
			$REGISTRY['VirtualSlotTarget']['main'][$slot.'.xml'] = 'StoreRSSView:object?id='.$category->id;
			$REGISTRY['VirtualSlotTarget']['main']['?'] = 'DescribeView:object?id=10';
			$Server->saveRegistry();
			if(!empty($this->undo)) {
				$undo_handler->GetArrayInFile($this->undo, "Undo_object", $ROOT_PATH."/undo/".$pub_type[0]['name']."/".$Undo_field['id']."/".($categorycomment->version>1? $categorycomment->version-1 : 1).".inc");
			}
			// Autochange URL
			if(isset($request['autochange']) && $request['autochange'] == 'true') {
				include($TOOLS_PATH.'/autochangeURL.inc');
				//print '<li>OLD SLOT - '.$old_slot;
				//print '<li>NEW SLOT - '.$slot;
				autochangeURL($old_slot, $slot, (is_object($this->Security) ? $this->Security->currentuser->id : $this->currentuser->id));
				$this->setLogEvent(5,23,9, 'Allover content Autochange URL from "'.$old_slot.'" to "'.$slot.'" complete', $category->id);
				$this->DB->commit();
			}
			clearCache();
		}
		return $category;
	}

	function openMetaInfo($request = array('module' => 3,'item' => 0,'content_type' => 1)) {
		global $Server;
		if(empty($request['module'])) $request['module'] = 3;
		if(empty($request['item'])) $request['item'] = 0;
		if(empty($request['content_type'])) $request['content_type'] = 1;
		$handler = &$Server->getHandler(14);
		return $handler->getMetaInfo($request);
	}

	function openDownloadProduct($request = array('id' => 0,'catid' => 0)) {
		global $REGISTRY;
		$product = $this->createZipProduct();
		$this->parseRequest($request,$product);
		$this->DB->initObject($product);
		if(!$product->is_active) $product->_error = '6'; // Ne Aktiven
		else if($product->item->itemtype->id!=1) $product->_error = '5'; // Ne Produkt
		if(!empty($product->files->data)) {
			uasort($product->files->data,'by_index');
			$product->files->data = array_values($product->files->data);
		}
		foreach((!empty($product->item->children->data)? $product->item->children->data : array()) as $key => $value) {
			if(!$value->is_active) unset($product->item->children->data[$key]);
			else if($value->id!=$product->id) {
				foreach($REGISTRY['VirtualSlotTarget']['main'] as $path => $handler) {
					if($handler == 'ProductView:object?id='.$value->id) {
						$product->item->children->data[$key]->url = $path;
						continue;
					}
				}
			}
		}
		uasort($product->item->children->data,'by_generation');
		return $product;
	}

	function saveMetaInfo($request = array()) {
		global $Server, $REGISTRY, $TOOLS_PATH, $ROOT_PATH;
		$this->undo = '';
		$meta = new Meta();
		$js = $request['js_type']=='product'? new ProductJSZone() : new CategoryJSZone();
		$this->DB->begin();
		$Undo_field= array('type' => ($request['js_type']=='product'? 18 : 16),'id' => $request['ownerid'],'undo' => 1);
		include($TOOLS_PATH.'\undo.php');
		$this->undo = $undo_handler->arr_obj;
		$this->DB->delete('meta',array('ownerid' => $request['ownerid'],'moduletype' => $request['moduletype']));
		foreach($request['meta'] as $key => $value) {
			$meta->ownerid = $request['ownerid'];
			$meta->moduletype = $request['moduletype'];
			$meta->module = $request['ownerid'];
			$meta->value = $value;
			switch($key) {
				case 'title': $meta->metatype->id = 1; $meta->sort_order = 1; break;
				case 'description': $meta->metatype->id = 2; $meta->sort_order = 2; break;
				case 'keywords': $meta->metatype->id = 3; $meta->sort_order = 3; break;
			}
			$this->DB->processObject($meta,'save',array(),array(),TRUE);
			$meta->id = '';
		}
		$this->DB->delete($request['js_type'].'jszone',array('ownerid' => $request['ownerid']));
		foreach($request['js'] as $key => $value) {
			if(!empty($value)) {
				$js->ownerid = $request['ownerid'];
				$js->value = $value;
				$js->use_default = 0;
				switch($key) {
					case 'head':
						$js->type = 1;
						!empty($request['js']['head_use_default']) and $js->use_default = $request['js']['head_use_default'];
					break;
					case 'body_before':
						$js->type = 2;
						!empty($request['js']['before_use_default']) and $js->use_default = $request['js']['before_use_default'];
					break;
					case 'body_after':
						$js->type = 3;
						!empty($request['js']['after_use_default']) and $js->use_default = $request['js']['after_use_default'];
					break;
				}
				if($key!='head_use_default'
					&& $key!='before_use_default'
						&& $key!='after_use_default')
							$this->DB->processObject($js,'save',array(),array(),TRUE);
				$js->id = '';
			}
		}
		//$this->DB->rollback();
		$comment= $request['js_type']=='product'? new ProductComment() : new CategoryComment();
		$comment->version = 1;
		$comment->value = 'Meta Information & JS-Zones has been created';
		$selected = $this->DB->SelectAny("select version from ".$request['js_type']."comment where ownerid = ".$request['ownerid']." order by date desc LIMIT 1 OFFSET 0");
		if(!empty($selected[0]['version'])) {
			$comment->version=++$selected[0]['version'];
			$comment->value = !empty($request['_undo_'])? 'Meta Information & JS-Zones has been undone up to '.$request['_undo_']." version<br>\r\n" : 'Meta Information & JS-Zones has been changes';
		}
		$comment->ownerid = $meta->module;
		$comment->member = $Server->getHandler(3)->currentuser->id;
		$comment->date = 'now';
		$this->DB->processObject($comment,'save',array(),array(),TRUE);
		if(!empty($request['_undo_']))
			$this->setLogEvent(5,($request['js_type']=='product'? 25 : 23),10,'Meta Information & JS-Zones has been undone up to '.$request['_undo_'].' version',$request['ownerid']);
		if(!empty($this->undo)) {
			$undo_handler->GetArrayInFile($this->undo, "Undo_object", $ROOT_PATH."/undo/".$pub_type[0]['name']."/".$Undo_field['id']."/".($comment->version>1? $comment->version-1 : 1).".inc");
		}
		$module = $request['js_type']=='product'? new Product() : new Category();
		$module->id = $request['ownerid'];
		$this->DB->initObject($module);
		$module->date_changed = 'now';
		$module->access_flag = 0;
		$this->DB->processObject($module,'save',array(),array(),TRUE);
		$this->setLogEvent(5,($request['js_type']=='product'? 25 : 23),12,'Edit meta information & js zones for page "'.$module->name.'" ['.$request['ownerid'].']', $request['ownerid']);
		$this->DB->commit();
		clearCache();
		return $meta;
	}

	/* makes product list in distance chart for thermal devices*/	
	function getChartProductList($id){
		$url =  $this->DB->SelectAny("select path, path2, distance_chart_activity from product where id = $id" );
		$result['show_on_site'] =  $url['0']['distance_chart_activity'];
		$url = $url['0']['path'];		
		if ( $result['show_on_site'] == 0 || empty($result['show_on_site']) ) return false; 
		$url_int = $this->DB->SelectAny("SELECT ownerid from category where id in (SELECT ownerid FROM categorylineitem WHERE item = $id) AND ownerid = 33");		
		$url_int = $url_int[0]['ownerid'];
		
		$international = 'not';
		if ( $url_int )  $international = '';
		
		$result['id'] = $id;		
		if ( preg_match('/thor/', $url) )  $result['series'] = 'thor';
		if ( preg_match('/odin/', $url) )  $result['series'] = 'odin';
		if ( preg_match('/ots-x/', $url) ) $result['series'] = 'ots-x';
		
		$result['product_list'] = $this->DB->SelectAny("
			select id, name, path
			from product 
			where LOWER( name ) like '%$result[series]%'
			AND is_active = 1
			and LOWER(path2) not like '%archive%' AND LOWER(path) not like '%archive%'
			and LOWER(path2) $international like '%international%' AND LOWER(path) $international like '%international%'
			and LOWER(path2) not like '%sale%' AND LOWER(path) not like '%sale%'
			AND distance_chart_activity = 1
			ORDER BY name");			
		return $result;		
	}

	function openProduct($request = array('id' => 0,'ship' => 0,'catid' => 0,'children' => 0,'meta' => 0)) {
		if(empty($request['ship'])) $request['ship'] = 0;
		if(empty($request['children'])) $request['children'] = 0;
		if(empty($request['meta'])) $request['meta'] = 0;
		global $TOOLS_PATH;
		if(!empty($request['undo'])) {
			$Undo_field= array('type' => 18,'id' => $request['id'],'undo' => 0,'version' => $request['undo']);
			include($TOOLS_PATH.'\undo.php');
			$selected = $this->DB->SelectAny('SELECT path FROM product WHERE id = '.$request['id'].' LIMIT 1');
			$print_arr['old_url'] = @$selected[0]['path'];
			return $print_arr;
		}
		$this->product = $this->createProduct($request['ship'],$request['children'],$request['meta']);
		$this->parseRequest($request,$this->product);
		$this->DB->initObject($this->product);
//printObject($this->product);exit;	
		// distance chart results 
//		$this->product->distanceChart = $this->getChartProductList ( $this->product->id );		
		
		foreach((!empty($this->product->customerreviewitems->data)? $this->product->customerreviewitems->data : array()) as $key => $value) {
			if($value->moduletype != 3) unset($this->product->customerreviewitems->data[$key]);
		}
		if(!empty($this->product->customerreviewitems->data)) $this->product->customerreviewitems->data = array_values($this->product->customerreviewitems->data);
		if(!empty($this->product->customerreviewitems->data)) {
			usort($this->product->customerreviewitems->data,'by_index');
			$this->product->customerreviewitems->data = array_values($this->product->customerreviewitems->data);
		}
		foreach((!empty($this->product->metas->data)? $this->product->metas->data : array()) as $key => $value) {
			if($value->moduletype != 3) unset($this->product->metas->data[$key]);
		}
		if(!empty($this->product->metas->data)) $this->product->metas->data = array_values($this->product->metas->data);
		foreach((!empty($this->product->links->data)? $this->product->links->data : array()) as $key => $value) {
			if($value->moduletype != 2) unset($this->product->links->data[$key]);
		}
		$this->product->links->data = array_values($this->product->links->data);
		if(!empty($this->product->parameters->data)) {
			usort($this->product->parameters->data,'by_index');
			$this->product->parameters->data = array_values($this->product->parameters->data);
		}
		if(!empty($this->product->features->data)) {
			usort($this->product->features->data,'by_index');
			$this->product->features->data = array_values($this->product->features->data);
		}
		foreach((!empty($this->product->reviews->data)? $this->product->reviews->data : array()) as $key => $value) {
			if($value->moduletype != 3) unset($this->product->reviews->data[$key]);
		}
		$this->product->reviews->data = array_values($this->product->reviews->data);
		if(!empty($this->product->reviews->data)) {
			usort($this->product->reviews->data,'by_index');
			$this->product->reviews->data = array_values($this->product->reviews->data);
		}
		if(!empty($this->product->files->data)) {
			usort($this->product->files->data,'by_index');
			$this->product->files->data = array_values($this->product->files->data);
		}
		if(!empty($this->product->shipcosts->data)) {
			usort($this->product->shipcosts->data,'by_shipcosttype');
			$this->product->shipcosts->data = array_values($this->product->shipcosts->data);
		}
		if(!empty($this->product->item->children->data)) {
			usort($this->product->item->children->data,'by_children_index');
			$this->product->item->children->data = array_values($this->product->item->children->data);
		}
		return $this->product;
	}

	function getRecurseUrl($id,$tree,$url = '') {
		foreach($tree as $key => $value) {
			if(empty($url)) {
				if(!empty($this->productsUrl[$key][$id])) $url = $this->productsUrl[$key][$id];
				elseif(!empty($tree[$key])) $url = $this->getRecurseUrl($id,$tree[$key]);
			}
		}
		return $url;
	}

	function getParentCat($id,$tree,$parent,$return = '') {
		foreach($tree as $key => $value) {
			if(empty($return)) {
				if(!empty($value) && array_key_exists($id,$value)) $return = !empty($parent)? $parent : $key;
				elseif(!empty($tree[$key])) $return = $this->getParentCat($id,$tree[$key],(!empty($parent)? $parent : $key));
			}
		}
		return $return;
	}

	function saveNewItems($request) {
		$this->newitems = $this->createFeaturedProduct();
		$this->parseRequest($request,$this->newitems);
		$links = $this->newitems->links->data;
		$this->newitems->links = '';
		$this->DB->processObject($this->newitems);
		$this->DB->delete('link',array('ownerid' => $this->newitems->id,'moduletype' => 2));
		foreach($links as $key =>$value) {
			$link = new Link();
			$link->linktype = new LinkType();
			$link->moduletype = new ModuleType();
			$this->parseRequest($value,$link);
			$link->ownerid = $this->newitems->id;
			$this->DB->processObject($link);
		}
		$this->DB->commit();
		return $this->newitems;
	}

	function openNewItems($request) {
		$this->newitems = $this->createFeaturedProduct();
		$selected = $this->DB->SelectArray(array('product p','item i'),'p.id',array('p.ownerid' => 'i.id','i.itemtype' => 5));
		if(!empty($selected)) {
			$this->newitems->id = $selected[0]['id'];
			$this->DB->initObject($this->newitems);
			foreach((!empty($this->newitems->links->data)? $this->newitems->links->data : array()) as $key => $value) {
				if($value->moduletype->id != 2) unset($this->newitems->links->data[$key]);
			}
			foreach((!empty($this->newitems->links->data)? $this->newitems->links->data : array()) as $key => $value)
				$links[] = $value;
			$this->newitems->links->data = !empty($links)? $links : array();
			$this->newitems->item->id = $this->newitems->ownerid;
			$this->DB->initObject($this->newitems->item);
			if(empty($this->newitems->productlineitems->data)){
				$this->newitems->_error = '2'; // Net Featured Produktov
			}
			else {
				foreach($this->newitems->productlineitems->data as $key => $value) {
					if($this->newitems->productlineitems->data[$key]->lineitem->active=='f' || $this->newitems->productlineitems->data[$key]->lineitem->mail=='t')
						unset($this->newitems->productlineitems->data[$key]);
					else {
						$this->newitems->productlineitems->data[$key]->lineitem->item->id = $this->newitems->productlineitems->data[$key]->lineitem->ownerid;
						$this->newitems->productlineitems->data[$key]->lineitem->url = $this->getProductUrl($this->newitems->productlineitems->data[$key]->lineitem->id);
						$this->DB->initObject($this->newitems->productlineitems->data[$key]->lineitem->item);
					}
				}
				uasort($this->newitems->productlineitems->data,'by_index');
				foreach($this->newitems->productlineitems->data as $key => $value) $data[] = $value;
				$this->newitems->productlineitems->data = $data;
			}
		}
		else $this->newitems->_error = '3'; // Net Featured Voobsche
		return $this->newitems;
	}

	function saveFeaturedProduct($request) {
		$this->featured = $this->createFeaturedProduct();
		$this->parseRequest($request,$this->featured);
		$links = $this->featured->links->data;
		$this->featured->links = '';
		$this->DB->processObject($this->featured);
		$this->DB->delete('link',array('ownerid' => $this->featured->id,'moduletype' => 2));
		foreach($links as $key =>$value) {
			$link = new Link();
			$link->linktype = new LinkType();
			$link->moduletype = new ModuleType();
			$this->parseRequest($value,$link);
			$link->ownerid = $this->featured->id;
			$this->DB->processObject($link);
		}
		$this->DB->commit();
		return $this->featured;
	}

	function openFeaturedProduct($request) {
		$this->featured = $this->createFeaturedProduct();
		$selected = $this->DB->SelectArray(array('product p','item i'),'p.id',array('p.ownerid' => 'i.id','i.itemtype' => 4));
		if(!empty($selected)) {
			$this->featured->id = $selected[0]['id'];
			$this->DB->initObject($this->featured);
			foreach((!empty($this->featured->links->data)? $this->featured->links->data : array()) as $key => $value) {
				if($value->moduletype->id != 2) unset($this->featured->links->data[$key]);
			}
			foreach((!empty($this->featured->links->data)? $this->featured->links->data : array()) as $key => $value)
				$links[] = $value;
			$this->featured->links->data = !empty($links)? $links : array();
			$this->featured->item->id = $this->featured->ownerid;
			$this->DB->initObject($this->featured->item);
			if(empty($this->featured->productlineitems->data)){
				$this->featured->_error = '2'; // Net Featured Produktov
			}
			else {
				foreach($this->featured->productlineitems->data as $key => $value) {
					if($this->featured->productlineitems->data[$key]->lineitem->active=='f' || $this->featured->productlineitems->data[$key]->lineitem->mail=='t')
						unset($this->featured->productlineitems->data[$key]);
					else {
						$this->featured->productlineitems->data[$key]->lineitem->item->id = $this->featured->productlineitems->data[$key]->lineitem->ownerid;
						$this->featured->productlineitems->data[$key]->lineitem->url = $this->getProductUrl($this->featured->productlineitems->data[$key]->lineitem->id);
						$this->DB->initObject($this->featured->productlineitems->data[$key]->lineitem->item);
					}
				}
				uasort($this->featured->productlineitems->data,'by_index');
				foreach($this->featured->productlineitems->data as $key => $value) $data[] = $value;
				$this->featured->productlineitems->data = $data;
			}
		}
		else $this->featured->_error = '3'; // Net Featured Voobsche
		return $this->featured;
	}

	function getCategoryPath($id, $p = ''){
		global $Paths;
		$selected = $this->DB->SelectAny('SELECT path2 FROM category where id='.$id);
		if(empty($selected[0]['path2'])) {
			if(empty($Paths)) {
				$selected = $this->DB->SelectAny('SELECT id, sys_name, ownerid, path2 FROM category');
				foreach($selected as $value)
					$Paths[$value['id']] = array(
						'path' => $value['sys_name'],
						'parent' => $value['ownerid'],
						'path2' => $value['path2'],
					);
			}
			while(1){
				if(empty($Paths[$id])) return null;
				//if(empty($Paths[$id]['parent'])) { return '/'.$Paths[$id]['path'].$p;     }
				if(empty($Paths[$id]['parent']))   { return $p;     }
				if(!empty($Paths[$id]['path2'])) { return '/'.$Paths[$id]['path2'].$p;    }
				$p = '/'.$Paths[$id]['path'].$p;
				$id = $Paths[$id]['parent'];
			}
		}	else return '/'.$selected[0]['path2'];
	}


	function createFeaturedProduct() {
		$product = new Product();
		$product->item = new Item();
		$product->item->itemtype = new ItemType();
		$product->links = new ObjectsList();
		$product->links->type = new Link();
		$product->links->type->linktype = new LinkType();
		$product->links->type->moduletype = new ModuleType();
		$product->productlineitems = new ObjectsList();
		$product->productlineitems->type = $this->createFeaturedLineItem();
		return $product;
	}

	function createFeaturedLineItem() {
		$lineitem = new ProductLineItem();
		$lineitem->lineitem = new Product();
		$lineitem->lineitem->item = new Item();
		$lineitem->lineitem->item->itemtype = new ItemType();
		$lineitem->lineitem->generation = new Generation();
		$lineitem->lineitem->warranty = new Warranty();
		$lineitem->lineitem->prices = new ObjectsList();
		$lineitem->lineitem->prices->type = new Price();
		$lineitem->lineitem->productlineitems = new ObjectsList();
		$lineitem->lineitem->productlineitems->type = $this->createProductLineItem();
		return $lineitem;
	}

	function createPreviewProduct() {
		$product = new Product();
		$product->generation = new Generation();
		//$product->prices = new ObjectsList();
		//$product->prices->type = new Price();
		//$product->files = new ObjectsList();
		//$product->files->type = new ProductFile();
		return $product;
	}

	function createDownloadProduct() {
		$product = new Product();
		$product->generation = new Generation();
		$product->prices = new ObjectsList();
		$product->prices->type = new Price();
		return $product;
	}

	function createPreviewAccessory($ship = FALSE) {
		$product = new Product();
//		$product->applicableitems = new ObjectsList();
	//	$product->applicableitems->type = new Applicable();
		//$product->applicableitems->type->product = new Product();
		if($ship) {
			$product->shipcosts = new ObjectsList();
			$product->shipcosts->type = new ShipCost();
			$product->shipcosts->type->type = new ShipCostType();
		}
		return $product;
	}

	function createAccessoryOrKit($ship = FALSE) {
		$product = new Product();
		$product->warranty = new Warranty();
		$product->prices = new ObjectsList();
		$product->prices->type = new Price();
//		$product->applicableitems = new ObjectsList();
	//	$product->applicableitems->type = new Applicable();
		//$product->applicableitems->type->product = new Product();
		$product->item = new ParentItem();
		$product->item->itemtype = new ItemType();
		$product->files = new ObjectsList();
		$product->files->type = new ProductFile();
		$product->export_restriction = new Export();
		if($ship) {
			$product->shipcosts = new ObjectsList();
			$product->shipcosts->type = new ShipCost();
			$product->shipcosts->type->type = new ShipCostType();
		}
		return $product;
	}

	function createZipProduct() { 
		$product = new Product();
		$product->item = new ParentItem();
		$product->item->itemtype = new ItemType();
		$product->item->children = new ObjectsList();
		$product->item->children->type = new Product();
		$product->item->children->type->generation = new Generation();
		$product->generation = new Generation();
		$product->files = new ObjectsList();
		$product->files->type = new ProductFile();
		return $product;
	}

	function createProduct($ship = FALSE,$children = FALSE,$meta = FALSE) {
		$product = new Product();
		$product->item = new ParentItem();
		$product->color = new Color();
		$product->item->itemtype = new ItemType();
		if($children) {
			$product->item->children = new ObjectsList();
			$product->item->children->type = new Product();
			$product->item->children->type->generation = new Generation();
			$product->item->children->type->prices = new ObjectsList();
			$product->item->children->type->prices->type = new Price();
		}
		$product->files = new ObjectsList();
		$product->files->type = new ProductFile();
		$product->generation = new Generation();
		$product->rate = new Rate();
		$product->level = new Level();
		$product->policy = new Policy();
		$product->core = new Core();
		$product->lens = new Lens();
		$product->brand = new Brand();
		$product->export_restriction = new Export();
		$product->warranty = new Warranty();
		$product->parameters = new ObjectsList();
		$product->parameters->type = new Parameter();
		$product->features = new ObjectsList();
		$product->features->type = new Feature();
		$product->reviews = new ObjectsList();
		$product->reviews->type = new Review();
		$product->customerreviewitems = new ObjectsList();
		$product->customerreviewitems->type = new CustomerReviewItem();
		$product->prices = new ObjectsList();
		$product->prices->type = new Price();
		$product->productlineitems = new ObjectsList();
		$product->productlineitems->type = $this->createProductLineItem();
		$product->links = new ObjectsList();
		$product->links->type = new Link();
		$product->technologylineitems = new ObjectsList();
		$product->technologylineitems->type = new TechnologyLineItem();
		$product->technologylineitems->type->lineitem = new Technology();
		$product->recomenduselineitems = new ObjectsList();
		$product->recomenduselineitems->type = new RecomendUseLineItem();
		$product->recomenduselineitems->type->lineitem = new RecomendUse();

		$product->relatedlineitems = new ObjectsList();
		$product->relatedlineitems->type = new RelatedLineItem();
		$product->relatedlineitems->type->lineitem = new Product();
		$product->relatedlineitems->type->lineitem->generation = new Generation();
		$product->relatedlineitems->type->lineitem->prices = new ObjectsList();
		$product->relatedlineitems->type->lineitem->prices->type = new Price();
	
		
		$product->articlelineitems = new ObjectsList();
		$product->articlelineitems->type = new ArticleLineItem();
		$product->articlelineitems->type->lineitem = new Article();
		if($ship) {
			$product->shipcosts = new ObjectsList();
			$product->shipcosts->type = new ShipCost();
			$product->shipcosts->type->type = new ShipCostType();
		}
		if($meta) {
			$product->metas = new ObjectsList();
			$product->metas->type = new Meta();
			$product->productjszones = new ObjectsList();
			$product->productjszones->type = new ProductJSZone();
		}
		return $product;
	}

	function createMailProduct() {
		$product = new Product();
		$product->item = new Item();
		$product->item->itemtype = new ItemType();
		$product->generation = new Generation();
		$product->warranty = new Warranty();
		$product->parameters = new ObjectsList();
		$product->parameters->type = new Parameter();
		$product->prices = new ObjectsList();
		$product->prices->type = new Price();
		return $product;
	}

	function createProductLineItem() {
		$lineitem = new ProductLineItem();
		$lineitem->lineitem = new Product();
		$lineitem->lineitem->prices = new ObjectsList();
		$lineitem->lineitem->prices->type = new Price();
		$lineitem->lineitem->files = new ObjectsList();
		$lineitem->lineitem->files->type = new ProductFile();
		return $lineitem;
	}

	function createCategory($type = 0,$getlinks = false,$parent = false,$meta = false) {
		$category = new Category();
		if(!$parent) {
			$category->categorylineitems = new ObjectsList();
			$category->categorylineitems->type = new CategoryLineItem();
			$category->categorylineitems->type->item = $type==1 || $type==4? $this->createPreviewAccessory(true) : $this->createPreviewProduct();
		}
		if($getlinks) {
			$category->links = new ObjectsList();
			$category->links->type = new Link();
		}
		if($meta) {
			$category->metas = new ObjectsList();
			$category->metas->type = new Meta();
			$category->categoryjszones = new ObjectsList();
			$category->categoryjszones->type = new CategoryJSZone();
		}
		$category->reviews = new ObjectsList();
		$category->reviews->type = new Review();
		$category->customerreviewitems = new ObjectsList();
		$category->customerreviewitems->type = new CustomerReviewItem();
		$category->color = new Color();
		
		$category->price_range = new ObjectsList(); 
		$category->price_range->type = new Price_Range();
		
		return $category;
	}

	function createDownloadCategory($parent = false,$desc = false) {
		$category = new Category();
		if(!$parent) {
			$category->categorylineitems = new ObjectsList();
			$category->categorylineitems->type = new CategoryLineItem();
			$category->categorylineitems->type->item = $this->createDownloadProduct();
			if($desc) {
				$category->categorylineitems->type->item->description_langs = new ObjectsList();
				$category->categorylineitems->type->item->description_langs->type = new Description();
			}
		}
		return $category;
	}

	function createXMLCategory($parent = false,$desc = false) {
		$category = new Category();
		if(!$parent) {
			$category->categorylineitems = new ObjectsList();
			$category->categorylineitems->type = new CategoryLineItem();
			$category->categorylineitems->type->item = $this->createXMLProduct();
		}
		return $category;
	}

	function createXMLProduct() {
		$product = new Product();
		return $product;
	}
}
?>