<?php

class clsItem extends clsParsedItem
{
	var $type;
	var $Reviews;
	var $Related;
	var $Images;
	var $PrimaryCat;
	var $IsNew = FALSE;
	var $IsHot = FALSE;
	var $IsPop = FALSE;
	var $Keywords;
	var $OpenTagVar;
	var $CloseTagVar;
	var $AdminParser;
	var $CustomFields;
	var $FieldClass;
	var $CustomLoaded=0;
	var $ReviewSortOrder;
	var $ReviewPerPageVar;

	var $TitleField = '';
	
	function clsItem($FullItem=FALSE)
	{
		$this->clsParsedItem();
		if($FullItem==TRUE)
		{
			$this->Reviews = new clsItemReviewList();
			$this->Related = new clsRelationshipList();
		}
		$this->Images = new clsImageList();
		$this->CustomFields = array();
		$this->FieldClass = new clsCustomFieldList();
	}

	function ClearCacheData()
	{
		DeleteModuleTagCache('kernel');
		DeleteModuleTagCache('inlink');
		DeleteModuleTagCache('innews');
		DeleteModuleTagCache('inbulletin');
	}

	/* item reviews */
	function &GetItemReviews($Page=1)
	{
		$res_id = $this->Get("ResourceId");
		$this->Reviews->itemID=$res_id;
		$this->Reviews->PerPageVar = $this->ReviewPerPageVar;
		$this->Reviews->Page = $Page;
		$this->Reviews->GetReviewList("Status=1",$this->ReviewSortOrder);
		return $this->Reviews;
	}

	function ReviewCount($TodayOnly=FALSE)
	{

		if(is_numeric($this->Get("CachedReviewsQty")) && !$TodayOnly)
		return (int)$this->Get("CachedReviewsQty");

		$this->Reviews->itemID=$this->Get("ResourceId");
		return (int)$this->Reviews->GetItemReviewCount($TodayOnly);
	}

	function ReviewsLoaded()
	{
		if($this->Reviews->itemID==$this->Get("ResourceId"))
		{
			return $this->Reviews->ItemCount();
		}
		else
		return 0;
	}

	function &AddReview($createdBy,$reviewText,$isPending,$ip=NULL,$ForceIP=0, $Module="", $CreatedOn = 0)
	{
		$this->Reviews->itemID=$this->Get("ResourceId");
		
		if($ip == NULL)
			$ip = $_SERVER["REMOTE_ADDR"];

		if(!$CreatedOn)
			$CreatedOn = mktime(0,0,0,adodb_date("m"),adodb_date("d"),adodb_date("Y"));
		$Status = 1;
		if($isPending)
		$Status = 2;

		$AutoModule = GetModuleByAction(); // determine module name by action
		if( $Module && ($AutoModule != $Module) ) $AutoModule = $Module;

		$r = $this->Reviews->AddReview($CreatedOn,$reviewText,$Status,$ip,0,$this->Get("ResourceId"),$this->type,$createdBy,0,$AutoModule);
		$this->Increment("CachedReviewsQty");
		return $r;
	}

	function ReviewIPExists($ip)
	{
		return ip_exists($ip,$this->Get("ResourceId"),$this->Reviews->SourceTable);
	}

	function DeleteReview($reviewID)
	{
		$r = $this->Reviews->GetReview($reviewID);
		if(is_object($r))
		{
			$r->Delete();
			$this->Decrement("CachedReviewsQty");
		}
	}

	function DeleteReviews()
	{ 
		$res_id = $this->Get("ResourceId");
		if($res_id)
		{
			$sql = "DELETE FROM ".GetTablePrefix()."ItemReview WHERE ItemId=$res_id";
			$this->adodbConnection->Execute($sql);
			unset($this->Reviews);
			$this->Reviews = new clsItemReviewList($res_id);
		}
	}

	/* item custom fields */

	function LoadCustomFields($force = null)
	{		
		if((!is_null($force) || !$this->CustomLoaded) && $this->Get("ResourceId")>0)
		{
			$this->FieldClass = new clsCustomFieldList();
			$this->FieldClass->Type = $this->type;
			$this->FieldClass->LoadFieldsAndValues($this->Get("ResourceId"));
			foreach($this->FieldClass->Items as $f)
			{
				if (strlen($f->Get("ValueList") && (($f->Get("ElementType") == "select") || ($f->Get("ElementType") == "radio"))))
				{
					if ($f->HasField('Value'))
					{	
						$ValueList = explode(",", $f->Get("ValueList"));
						if (is_array($ValueList))
						{
							foreach ($ValueList as $curr => $value)
							{
								$c_data = explode("=", $value);
								if ($c_data[0] == $f->Get('Value'))
								{
									$this->CustomFields[$f->Get("FieldName")]['value'] = $f->Get('Value');	
									$this->CustomFields[$f->Get("FieldName")]['lang_value'] = language($c_data[1]);	
								}
							}
						}
						else
						{
							$this->CustomFields[$f->Get("FieldName")]['value'] = $f->HasField('Value') ? $f->Get('Value') : '';	
							$this->CustomFields[$f->Get("FieldName")]['lang_value'] = null;						
						}																
					}
					else
					{
						$this->CustomFields[$f->Get("FieldName")]['value'] = strlen($f->HasField('Value')) ? $f->Get('Value') : '';
						$this->CustomFields[$f->Get("FieldName")]['lang_value'] = null;
					}
				}
				else
				{
					$this->CustomFields[$f->Get("FieldName")]['value'] = strlen($f->HasField('Value')) ? $f->Get('Value') : '';
					$this->CustomFields[$f->Get("FieldName")]['lang_value'] = null;
															
				}
			}
			$this->CustomLoaded = 1;
		}
	}
	
	function SetCustomField($fieldname,$value)
	{
		// echo "Setting CF [<b>$fieldname</b>] = [$value]<br>";
		if(!$this->CustomLoaded)
		$this->LoadCustomFields();
		$this->CustomFields[$fieldname] = $value;
	}

	function SaveCustomFields()
	{
		//echo "Saving CFs<br>";
		if(!(int)$this->Get("ResourceId"))
		return TRUE;

		if(!$this->CustomLoaded)
		return TRUE;

		$data = new clsCustomDataList();
		$data->LoadResource($this->Get("ResourceId"));
		foreach($this->FieldClass->Items as $f)
		{
			$value = $this->CustomFields[$f->Get("FieldName")];
			$data->SetFieldValue($f->Get("CustomFieldId"),$this->Get("ResourceId"),$value);
		}
		$data->SaveData();
		unset($data);
	}

	/*
	function GetCustomFieldValue($fieldname,$default="")
	{
		if(!$this->CustomLoaded)
		$this->LoadCustomFields();
		$fieldname=strtolower($fieldname);
		foreach($this->CustomFields as $k=>$v)
			if(strtolower($k)==$fieldname)
				return $v;
		return $default;

		if(isset($this->CustomFields[$fieldname]))
		{
			$ret = $this->CustomFields[$fieldname];
		}
		elseif(isset($this->CustomFields[$fieldname=strtolower($fieldname)]))
		{
			$ret = $this->CustomFields[$fieldname];
		}
		else
		$ret = $default;
		return $ret;
	}
	*/
	
	function GetCustomFieldValue($fieldname, $default="", $ListValue = 0)
	{
		if(!$this->CustomLoaded)
			$this->LoadCustomFields(null);		
		elseif (is_array($this->CustomFields) && empty($this->CustomFields))
			$this->LoadCustomFields(1);		
			
		$fieldname = strtolower($fieldname);
		
		foreach($this->CustomFields as $k => $v)
		{
			if(strtolower($k) == $fieldname)
			{					
				return $ListValue? $v['lang_value'] : $v['value'];
			}				
		}
		
		return $default;		
	}
	
	function DeleteCustomData()
	{
		$cdata = new clsCustomDataList();
		$cdata->DeleteResource($this->Get("ResourceId"));
	}

	function Delete($RecordOnly=FALSE)
	{
		global $objFavorites;
		
		if($RecordOnly==FALSE)
		{
			$this->DeleteReviews();
			$this->DeleteRelations();
			$this->DeleteCustomData();
			if($this->NoResourceId==0)
			{
				if($this->UsingTempTable()==FALSE)
				{
					if(is_object($this->Images))
					$this->Images->DeleteResource($this->Get("ResourceId"));
					$objFavorites->DeleteItem($this->Get("ResourceId"));
				}
			}
		}
		parent::Delete();
	}

	/* item relationships */
	function GetRelatedItems()
	{
		global $objConfig;

		$where = "SourceId = ".$this->Get("ResourceId");
		$where .= " OR (TargetId=".$this->Get("ResourceId")." AND Type=1)";
		$orderBy = $objConfig->Get("Relation_Sortfield")." ".$objConfig->Get("Relation_Sortorder");
		$orderBy = trim($orderBy);
		$this->Related->Clear();
		$res = $this->Related->LoadRelated($where,$orderBy);
		return $res;
	}

	function &RelationObject()
	{
		return $this->Related;
	}

	function DeleteRelations()
	{ 
		$res_id = $this->Get("ResourceId");
		if($res_id)
		{
			$sql = "DELETE FROM ".GetTablePrefix()."Relationship WHERE SourceId=$res_id OR TargetId=$res_id";
			$this->adodbConnection->Execute($sql);
			unset($this->Reviews);
			$this->Related = new clsRelationshipList($res_id);
		}
	}


	/* keyword highlighting for searches */

	function HighlightField($field)
	{
		global $objConfig;

		if(/*!strlen($OpenTag) || !strlen($CloseTag) ||*/ !is_array($this->Keywords))
		{
			//echo "Missing something<br>\n";
			return $this->Get($field);
		}

		if(strlen($this->OpenTagVar))
		$OpenTag = $objConfig->Get($this->OpenTagVar);
		if(strlen($this->CloseTagVar))
		$CloseTag = $objConfig->Get($this->CloseTagVar);

		$k = array_merge($this->Keywords["required"],$this->Keywords["normal"]);
		if(count($k))
		{
			$result = HighlightKeywords($k, $this->Get($field), $OpenTag, $CloseTag);
		}
		else
		{
			$result = $this->Get($field);
			//echo "No Keywords<br>\n";
		}
		return $result;
	}
  
	function HighlightText($text)
	{
		global $objConfig;

		if(strlen($this->OpenTagVar))
		$OpenTag = $objConfig->Get($this->OpenTagVar);
		if(strlen($this->CloseTagVar))
		$CloseTag = $objConfig->Get($this->CloseTagVar);

		if(!strlen($OpenTag) || !strlen($CloseTag) || !is_array($this->Keywords)) {
			return $text;
		}
		$k = array_merge($this->Keywords["required"],$this->Keywords["normal"]);
		if(count($k))
		{
			$result = HighlightKeywords($k,$text, $OpenTag, $CloseTag);
		}
		else
		$result = $text;

		return $result;
	}

	/* item status functions */

	function Is($name)
	{
		$var = "m_" . $name;
		return ( isset($this->$var) && $this->$var ) ? true : false;
	}

	function IsHotItem()
	{
		switch($this->Get("HotItem"))
		{
			case ALWAYS:
			return TRUE;
			break;
			case NEVER:
			return FALSE;
			break;
			case AUTO:
			return $this->IsHot;
			break;
		}
	}

	function SetHotItem()
	{
		$this->IsHot = FALSE;
	}

	function IsNewItem()
	{
		switch($this->Get("NewItem"))
		{
			case ALWAYS:
			return TRUE;
			break;
			case NEVER:
			return FALSE;
			break;
			case AUTO:
			return $this->IsNew;
			break;
		}
	}

	function SetNewItem()
	{
		$this->IsNew = FALSE;
	}

	function IsPopItem()
	{
		switch($this->Get("PopItem"))
		{
			case ALWAYS:
			return TRUE;
			break;
			case NEVER:
			return FALSE;
			break;
			case AUTO:
			return $this->IsPop;
			break;
		}
	}

	function SetPopItem()
	{
		$this->IsPop = FALSE;
	}

	function SetFromArray($data, $dirty = false)
	{
		parent::SetFromArray($data, $dirty);
		if(is_array($data))
		{
			if(array_key_exists("NewItem",$data))
			{
				$this->SetNewItem();
			}
			if(array_key_exists("HotItem",$data))
			{
				$this->SetHotItem();
			}
			if(array_key_exists("PopItem",$data))
			{
				$this->SetPopItem();
			}
		}
	}

	function Validate()
	{
		/* skeleton*/
		return true;
	}

	function LoadFromDatabase($Id, $IdField = null) // custom IdField by Alex)
	{
		/* skeleton */
		parent::LoadFromDatabase($Id, $IdField);
	}



	//Changes priority
	function MoveDown()
	{
		$this->Decrement("Priority");
	}

	function MoveUp()
	{
		$this->Increment("Priority");
	}

	function CheckPermission($permissionName)
	{
		//Check permission and if needs approval set approval
		global $objSession,$objCatList;

		$perm = $this->BasePermission;
		if(strlen($perm)>0)
		$perm .= ".";
		$perm .= $permissionName;

		//get an instance of the forum category
		$cat =& $objCatList->GetCategory($this->Get("CategoryId"));
		if(!is_object($cat))
		{
			return FALSE;
		}
		else
		{
			return ($cat->HasPermission($perm,$objSession->Get("GroupId")));
		}
	}

	function SubmitVote($voteRating, $voteNotes)
	{
		global $Errors;
		global $REMOTE_ADDR;
		//echo "Submitting vote<br>";
/*		if($this->rating_ip_exists($REMOTE_ADDR))
		{
			//            $Errors->AddError("error.already_voted","","","",get_class($this),"SubmitVote");
			return false;
		}*/
		$vote = new  clsItemRating(NULL);
		$vote->Set("ItemId",$this->UniqueId());
		$vote->Set("RatingValue",$voteRating);
		if(!$vote->Create()) {
			//echo "Submitting Failed<br>";
			return false;
		}

		$NumVotes = (int)$this->Get('CachedVotesQty');
		$CurrentRating = $this->Get('CachedRating');

		$Rating = (($NumVotes * $CurrentRating) + $voteRating)/($NumVotes+1);
		$this->Set("CachedRating",$Rating);
		$this->Update();
		$this->Increment("CachedVotesQty");
		//echo "Submitting Done<br>";
	}

	function rating_ip_exists($ip)
	{
		$count = 0;
		$id = $this->Get("ResourceId");
		$sql = "SELECT count(*) as DupCount FROM ".GetTablePrefix()."ItemRating WHERE IPAddress='$ip' and ItemId=$id";
		$adodbConnection = &GetADODBConnection();
		$rs = $adodbConnection->Execute($sql);
		if($rs)
		{
			$count = $rs->fields["DupCount"];
		}
		return ($count>0);
		//return FALSE;
	}

	function PurgeRatings()
	{
		global $objConfig;

		$expired=time()-86400*$objConfig->Get("Timeout_Rating");
		$query="DELETE FROM ".GetTablePrefix()."ItemRating WHERE CreatedOn<$expired";
		$this->adodbConnection->Execute($query);
	}

	function GetThumbnailImage()
	{
		if($this->Images->NumItems()==0)
		$this->Images->GetResourceImages($this->Get("ResourceId"));
		return $this->Images->GetResourceThumbnail($this->Get("ResourceId"));
	}

	function GetImage($number)
	{
		return $this->Images->GetImageByResource($this->Get("ResourceId"),$number);
	}

	function GetImageByName($name)
	{
		if(!is_object($this->Images))
		$this->Images = new clsImageList();
		return $this->Images->GetImageByName($this->Get("ResourceId"),$name);
	}

	function &GetDefaultImage()
	{
		return $this->Images->GetDefaultImage($this->Get("ResourceId"));
	}
	
	function &GetAvatarImage()
	{
		return $this->Images->GetAvatarImage($this->Get("ResourceId"));
	}

	function CreatePendingCopy()
	{
		$OrgId = $this->IdField();
		$this->Dirty();
		$this->Set("OrgId",$OrgId);
		$this->UnsetIdField();
		$this->Set("ResourceId",0);
		$this->Set("Status",-2);
		$this->Create();
	}

	function AddFavorite($PortalUserId=NULL)
	{
		global $objSession, $objFavorites;

		$res = FALSE;
		
		// user can be added to favorites, but they have no primary category :)
		$category_id = method_exists($this, 'GetPrimaryCategory') ? $this->GetPrimaryCategory() : $GLOBALS['m_var_list']['cat'];
		
		if( $objSession->HasCatPermission("FAVORITES", $category_id) )
		{
			if(!$PortalUserId)
			$PortalUserId = $objSession->Get("PortalUserId");
			if($PortalUserId==$objSession->Get("PortalUserId") || $objSession->HasSystemPermission("ADMIN"))
			{
				$objFavorites->AddFavorite($PortalUserId,$this->Get("ResourceId"), $this->type);
				$res = TRUE;
			}
		}
		return $res;
	}

	function DeleteFavorite($PortalUserId=NULL)
	{
		global $objSession, $objFavorites;

		$res = FALSE;

		// user can be added to favorites, but they have no primary category :)
		$category_id = method_exists($this, 'GetPrimaryCategory') ? $this->GetPrimaryCategory() : $GLOBALS['m_var_list']['cat'];
		
		if( $objSession->HasCatPermission("FAVORITES", $category_id) )
		{
			if(!$PortalUserId)
			$PortalUserId = $objSession->Get("PortalUserId");
			//echo $PortalUserId." ".$objSession->Get("PortalUserId");
			if($PortalUserId==$objSession->Get("PortalUserId") || $objSession->HasSystemPermission("ADMIN"))
			{
				$objFavorites->DeleteFavorite($PortalUserId,$this->Get("ResourceId"));
				$res = TRUE;
			}
		}
		return $res;
	}

	function IsFavorite($PortalUserId=NULL, $cat_id=NULL)
	{
		global $objSession, $objFavorites;

		$res = FALSE;

		if($objSession->HasCatPermission("FAVORITES", $cat_id))
		{
			if(!$PortalUserId)
			$PortalUserId = $objSession->Get("PortalUserId");

			if($PortalUserId==$objSession->Get("PortalUserId") || $objSession->HasSystemPermission("ADMIN"))
			{
				$i = $objFavorites->GetFavoriteObject($PortalUserId,$this->Get("ResourceId"));

				if(is_object($i))
				{
					$res = TRUE;
				}
				else
				$res = FALSE;
			}
		}

		return $res;
	}

	function CheckBanned()
	{
		global $objBanList;

		$objBanList->LoadItemRules($this->type);
		$found = FALSE;
		$MatchedRule = 0;
		foreach($objBanList->Items as $b)
		{
			$field = $b->Get("ItemField");
			if($this->FieldExists($field))
			{
				$ThisValue = strtolower($this->Get($field));
				$TestValue = strtolower($b->Get("ItemValue"));
				switch($b->Get("ItemVerb"))
				{
					case 0: /* any */
					$found = TRUE;
					break;
					case 1: /* is */
					if($ThisValue==$TestValue)
					$found = TRUE;
					break;
					case 2: /* is not */
					if($ThisValue != $TestValue)
					$found = TRUE;
					break;
					case 3: /* contains */
					if(strstr($ThisValue,$TestValue))
					$found = TRUE;
					break;
					case 4: /* not contains */
					if(!strstr($ThisValue,$TestValue))
					$found = TRUE;
					break;
					case 5: /* Greater Than */
					if($TestValue > $ThisValue)
					$found = TRUE;
					break;
					case 6: /* Less Than */
					if($TestValue < $ThisValue)
					$found = TRUE;
					break;
					case 7: /* exists */
					if(strlen($ThisValue)>0)
					$found = TRUE;
					break;
					case 8: /* unique */
					if($this->ValueExists($field,$ThisValue))
					$found = TRUE;
					break;
				}
			}
			if($found)
			{
				if($b->Get("RuleType")==0)
				{
					$MatchedRule = $b->Get("RuleId");
				}
				else
				{
					$MatchedRule = 0;
				}
				break;
			}
		}
		return $MatchedRule;
	}
} /* clsItem */

class clsCatItem extends clsItem
{
	function clsCatItem($FullItem=FALSE)
	{
		$this->clsItem($FullItem);
	}

	function Delete($RecordOnly=FALSE)
	{ 
		global $objFavorites;

		parent::Delete($RecordOnly);
		if($RecordOnly==FALSE)
		{
			$this->RemoveFromAllCategories();
		}
	}
	/* category membership functions */

	function AssignPrimaryCategory($SourceTable)
	{
		$catid = 0;
		$sql = "SELECT * FROM $SourceTable WHERE ItemResourceId=".$this->Get("ResourceId")." LIMIT 1";
		$rs = $this->adodbConnection->Execute($sql);
		if($rs && !$rs->EOF)
		{
			$catid = $rs->fields["CategoryId"];
			$this->SetPrimaryCategory($catid,$SourceTable);
		}
		return $catid;
	}

	function GetPrimaryCategory($SourceTable = "")
	{
		if(is_numeric($this->PrimaryCat))
		return $this->PrimaryCat;

		$this->PrimaryCat="";
		if( strlen($SourceTable) == 0 ) $SourceTable = GetTablePrefix()."CategoryItems";
		$res_id = $this->HasField('ResourceId') ? $this->Get('ResourceId') : 0;
		$sql = "SELECT * FROM $SourceTable WHERE ItemResourceId=".$res_id." AND PrimaryCat=1";
		$rs = $this->adodbConnection->Execute($sql);
		if($rs && !$rs->EOF)
		{
			$this->PrimaryCat=$rs->fields["CategoryId"];
			return $this->PrimaryCat;
		}
		else
		{
			$this->AssignPrimaryCategory($SourceTable);
			return $this->PrimaryCat;
		}
	}

	function SetPrimaryCategory($CategoryId,$SourceTable = "")
	{
		if(strlen($SourceTable)==0)
		$SourceTable = GetTablePrefix()."CategoryItems";

		$rs = $this->adodbConnection->Execute('SELECT * FROM '.$SourceTable.' WHERE CategoryId='.$CategoryId.' AND ItemResourceId='.$this->Get("ResourceId"));
		$this->adodbConnection->Execute("UPDATE $SourceTable SET PrimaryCat=0 WHERE ItemResourceId=".$this->Get("ResourceId"));
		$this->adodbConnection->Execute("UPDATE $SourceTable SET PrimaryCat=1 WHERE CategoryId=$CategoryId AND ItemResourceId=".$this->Get("ResourceId"));

		$this->PrimaryCat=$CategoryId;
	}

	function CategoryMemberCount($SourceTable="")
	{
		if(strlen($SourceTable)==0)
		$SourceTable = GetTablePrefix()."CategoryItems";

		$sql = "SELECT count(*) as CatCount FROM $SourceTable WHERE ItemResourceId=".$this->Get("ResourceId");
		if($this->debuglevel)
		echo $sql."<br>\n";

		$rs = $this->adodbConnection->Execute($sql);
		$count = 0;
		if($rs && !$rs->EOF)
		$count = $rs->fields["CatCount"];
		return $count;
	}

	/**
	 * Return comma separated CategoryId list,
	 * where this item is member (will be shown there)
	 *
	 * @param string $SourceTable
	 * @return string
	 */
	function CategoryMemberList($SourceTable="")
	{
		$cats = array();
		if(strlen($SourceTable)==0)
		$SourceTable = GetTablePrefix()."CategoryItems";

		$sql = "SELECT * FROM $SourceTable WHERE ItemResourceId=".$this->Get("ResourceId");

		if($this->debuglevel)
		echo $sql."<br>\n";

		$rs = $this->adodbConnection->Execute($sql);
		while($rs && !$rs->EOF)
		{
			$cats[] = $rs->fields["CategoryId"];
			$rs->MoveNext();
		}
		$catlist = implode(",",$cats);
		return $catlist;
	}

	function AddToCategory($CatId,$SourceTable="",$PrimaryValue=NULL)
	{
		global $objSession, $objCatList;

		if(!$SourceTable)
		$SourceTable = GetTablePrefix()."CategoryItems";

		if($this->type>0)
		{
			$Primary = 0;
			if(is_numeric($PrimaryValue))
			{
				$Primary = $PrimaryValue;
				if($Primary==1)
				$this->PrimaryCat = $CatId;
			}
			else
			{
				if(!is_numeric($this->GetPrimaryCategory()))
				{
					$Primary =1;
					$this->PrimaryCat = $CatId;
				}
			}

			// check if not exists

			$db =& $this->adodbConnection;
			$sql = sprintf('SELECT * FROM %s WHERE CategoryId = %s AND ItemResourceId = %s', $SourceTable, (int)$CatId, $this->Get("ResourceId"));
			$rs = $db->Execute($sql);

			if (is_object($rs)) {
				if($rs->RecordCount() == 0 )
				{
					$sql = "INSERT INTO $SourceTable (CategoryId,ItemResourceId, PrimaryCat) VALUES (".(int)$CatId.",'".$this->Get("ResourceId")."',$Primary)";
					if($this->debuglevel)
						echo $sql."<br>\n";
					$this->adodbConnection->Execute($sql);
				}
			}

			$c = $objCatList->GetCategory($CatId);
		}
	}

	function RemoveFromCategory($CatId,$SourceTable="",$Force=0)
	{
        if(!is_numeric($CatId)) return; 
		global $objSession, $objCatList;
		if(strlen($SourceTable)==0)
			$SourceTable = GetTablePrefix()."CategoryItems";

		if($this->type>0)
		{
			$primary = $this->GetPrimaryCategory();
			if(($primary==$CatId && $this->CategoryMemberCount($SourceTable)>1) || ($primary != $CatId) || $Force)
			{
				$sql = "DELETE FROM $SourceTable WHERE CategoryId=$CatId AND ItemResourceId=".$this->Get("ResourceId");
				if($objSession->HasSystemPermission("DEBUG.LIST"))
				echo $sql."<br>\n";

				$this->adodbConnection->Execute($sql);
				$c = $objCatList->GetCategory($CatId);
				$c->ClearCacheData();
			}
		}
	}

	function MoveToCategory($OldCatId,$NewCatId,$SourceTable="")
	{
		if(strlen($SourceTable)==0)
		$SourceTable = GetTablePrefix()."CategoryItems";

		$sql = "UPDATE $SourceTable SET CategoryId=$NewCatId WHERE CategoryId=$OldCatId AND ItemResourceId=".$this->Get("ResourceId");
		if($this->debuglevel)
			echo $sql."<br>\n";

		$this->adodbConnection->Execute($sql);
	}

	function DeleteCategoryItems($CatId,$SourceTable = "")
	{ 
		if(strlen($SourceTable)==0)
			$SourceTable = GetTablePrefix()."CategoryItems";

		$CatCount = $this->CategoryMemberCount($SourceTable);
		if($CatCount>1)
		{ 
			$this->RemoveFromCategory($CatId,$SourceTable);
			$this->ClearCacheData();
		}
		else
		{ 
			$this->Delete();
			$sql = "DELETE FROM $SourceTable WHERE CategoryId=$CatId AND ItemResourceId=".$this->Get("ResourceId");
			if($this->debuglevel)
				echo $sql."<br>\n";

			$this->adodbConnection->Execute($sql);
		}
	}
	function RemoveFromAllCategories($SourceTable = "")
	{ 
		if(strlen($SourceTable)==0)
			$SourceTable = GetTablePrefix()."CategoryItems";

		if($this->type>0)
		{
			$sql = "SELECT * FROM $SourceTable WHERE ItemResourceId=".$this->Get("ResourceId");
			$rs = $this->adodbConnection->Execute($sql);
			while ($rs && !$rs->EOF)
			{
				$CategoryId = $rs->fields["CategoryId"];
				$rs->MoveNext();
			}
			$sql = "DELETE FROM $SourceTable WHERE ItemResourceId=".$this->Get("ResourceId");
			if($this->debuglevel)
				echo $sql."<br>\n";

			$this->adodbConnection->Execute($sql);
		}
	}

	function CopyToNewResource($TargetCat = NULL,$NameField="Name")
	{
		global $objSession;

		$CatList = $this->CategoryMemberList();

		$Cats = explode(",",$CatList);
		//echo "Target: $TargetCat<br>";
		$OldId = $this->Get("ResourceId");
		$this->UnsetIdField();
		$this->Dirty();
		if(!is_numeric($this->Get("OrgId")))
		$this->UnsetField("OrgId");
		$this->UnsetField("ResourceId");
		if(is_numeric($TargetCat) && strlen($NameField))
		{
			$OldName = $this->Get($NameField);
			if(substr($OldName,0,5)=="Copy ")
			{
				$parts = explode(" ",$OldName,4);
				if($parts[2]=="of" && is_numeric($parts[1]))
				{
					$Name = $parts[3];
				}
				else
				if($parts[1]=="of")
				{
					$Name = $parts[2]." ".$parts[3];
				}
				else
				$Name = $OldName;
			}
			else
			$Name = $OldName;
			$Names = CategoryItemNameCount($TargetCat,$this->tablename,$NameField,$Name);
			if(count($Names)>0)
			{
				$NameCount = count($Names);
				$found = FALSE;
				$NewName = "Copy of $Name";

				if(!in_array("Copy of $Name",$Names))
				{
					$found = TRUE;
				}
				else
				{
					for($x=2;$x<$NameCount+2;$x++)
					{

						$NewName = "Copy ".$x." of ".$Name;
						if(!in_array($NewName,$Names))
						{
							$found = TRUE;
							break;
						}

					}
				}
				if(!$found)
				{
					$NameCount++;
					$NewName = "Copy $NameCount of $Name";
				}
				$this->Set($NameField,$NewName);
			}
		}
		$this->Create();
		// copy relationships
		$NewId = $this->Get("ResourceId");
		$reldata = new clsRelationshipList($TargetCat,$this->IdField());
		$reldata->CopyToResource($OldId,$NewId);

		// copy reviews
		$rdata = new clsItemReviewList();
		$rdata->CopyToItemId($OldId,$NewId);
		unset($rdata);

		// copy custom fields
		$cdata = new clsCustomDataList();
		$cdata->CopyResource($OldId,$NewId);
		unset($cdata);

		// copy images
		if(is_object($this->Images))
		$this->Images->CopyResource($OldId,$NewId);

		$this->AddToCategory($TargetCat, '', 0); // insert (but with duplicate records check)
		//echo "ok";
		if(is_numeric($TargetCat))
		{
			if(is_array($Cats))
			{
				if(!in_array($TargetCat,$Cats))
				{
					$this->AddToCategory($TargetCat, 0); // insert
				}
			}
			$this->SetPrimaryCategory($TargetCat); // 2 updates
		}
	}
	
	function refreshLastUpdate($cat_id = null)
	{
		$db =& GetADODBConnection();
		$prefix = GetTablePrefix();
		
		// 1,2,3,4 - set lastupdate date to item's primary category as recent
		// change date of all items in this category of same type as this item
		
		// 1. get item category or use passed one
		if(!isset($cat_id)) $cat_id = $this->GetPrimaryCategory();
		if($cat_id == 0) return false;
		
		// 2. get all item ResourceIds in that category
		$sql = 'SELECT ItemResourceId FROM '.$prefix.'CategoryItems WHERE CategoryId = '.$cat_id;
		$item_rids = $db->GetCol($sql);
		if($item_rids)
		{
			$item_rids = implode(',',$item_rids);
		
			// 2a. get LastUpdate date based on all item in $cat_id category
			$sql = 'SELECT MAX(IF(Modified=0,CreatedOn,Modified)) FROM '.$this->tablename.' WHERE ResourceId IN ('.$item_rids.')';
			$item_last_update = $db->GetOne($sql);
		}
		else 
		{
			$item_last_update = 0;
		}
		
		// 3. get LastUpdate date based on all $cat_id subcategories
		$sql = 'SELECT MAX(IF(Modified=0,CreatedOn,Modified)) FROM '.$prefix.'Category WHERE ParentId = '.$cat_id;
		$cat_last_update = $db->GetOne($sql);
		
		$last_update = max($item_last_update,$cat_last_update);
		
		// 4. set $last_update date to $cat_id category
		$sql = 'UPDATE '.$prefix.'Category SET Modified = '.$last_update.' WHERE CategoryId = '.$cat_id;
		$db->Execute($sql);
		
		// 5. get $cat_id parent CategoryId
		$sql = 'SELECT ParentId FROM '.$prefix.'Category WHERE CategoryId = '.$cat_id;
		if($cat_id > 0) $this->refreshLastUpdate( $db->GetOne($sql) );
	}
	
	function StripDisallowed($string)
	{
		$not_allowed = Array(' ', '\\', '/', ':', '*', '?', '"', '<', '>', '|');
     	$string = str_replace($not_allowed, '_', $string);
     	$string = preg_replace('/(_+)/', '_', $string);
     	
     	while( preg_match('/(.*)_([\d]+)$/', $string, $rets) )
		{
			$string = $rets[1];
		}
     	
     	return $string;
	}

	function GenerateFilename()
	{
		if ( !$this->Get('AutomaticFilename') && $this->Get('Filename') ) return false;
		$name = $this->StripDisallowed( $this->Get($this->TitleField) );
		if ( $name != $this->Get('Filename') ) $this->Set('Filename', $name);
	}
     
	function Update($UpdatedBy = null)
    {
        $this->GenerateFilename();
    	parent::Update($UpdatedBy);
    
    }

    function Create()
    {
    	$this->GenerateFilename();
        parent::Create();
    }

}
?>