clsCatItem(TRUE); //call parent constructor
          $this->tablename=GetTablePrefix()."Link";
          $this->type=TYPE_LINK;
          $this->BasePermission ="LINK";
          $this->id_field = "LinkId";
          $this->TagPrefix = "link";
          $this->TitleField = 'Name';
          $this->ReviewSortOrder = trim($objConfig->Get("Link_ReviewsSort")." ".$objConfig->Get("Link_ReviewsOrder"));
          $this->ReviewSortOrder .= trim(",".$objConfig->Get("Link_ReviewsSort2")." ".$objConfig->Get("Link_ReviewsOrder2"));
          $this->Reviews->PerPage = $objConfig->Get("Perpage_LinkReviews");
          /* keyword highlighting */
          $this->OpenTagVar = "Link_Highlight_OpenTag";
          $this->CloseTagVar = "Link_Highlight_CloseTag";
          if(isset($LinkId))
            $this->LoadFromDatabase($LinkId);
          if($objSession->HasSystemPermission("DEBUG.ITEM"))
          {
            $this->SetDebugLevel(1);
          }
    }
  function DetectChanges($name, $value)
  {
  	global $objSession;
	if (!isset($this->Data[$name]) ) return false;
  	//echo "class: ".get_class($this)."
";
	if ($this->Data[$name] != $value && $value != '') {
		//echo "$name Modified tt ".$this->Data[$name]." : $value
";
		if ($objSession->GetVariable("HasChanges") != 1) {
			$objSession->SetVariable("HasChanges", 2);
		}
	}
  }
    function ClearCacheData()
    {
       DeleteModuleTagCache('inlink');
    	/*$cats = explode(",",$this->CategoryMemberList());
       if(is_array($cats))
       {
         foreach($cats as $c)
         {
           if(is_numeric($c))
           {
             $evar = "'%:m".$c."%'";
             DeleteTagCache("l_list_links","",$evar);
             DeleteTagCache("l_link_more","",$evar);
           }
         }
       }
       DeleteTagCache("l_link_modified%","");
       DeleteTagCache("LinkPopValue","","");
       DeleteTagCache("LinkHotValue","","");
       DeleteTagCache("LinkNewValue","","");*/
    }
    function Delete()
    {
        parent::Delete();
        if($this->tablename==GetTablePrefix()."Link")
        {
            $this->ClearCacheData();
      //    DeleteTagCache("m_itemcount","Link%");
        }
    }
    function Update($UpdatedBy = null)
    {
        parent::Update($UpdatedBy);
        if($this->tablename == GetTablePrefix().'Link') $this->ClearCacheData();
    }
    function Create()
    {
        parent::Create();
        if($this->tablename == GetTablePrefix().'Link') $this->ClearCacheData();
    }
    function SetNewItem()
    {
        global $objConfig;
        $value = $this->Get("CreatedOn");
        $cutoff = adodb_date("U") - ($objConfig->Get("Link_NewDays") * 86400);
        $this->IsNew = FALSE;
        if($value>$cutoff)
            $this->IsNew = TRUE;
        return $this->IsNew;
    }
    function SetPopItem()
    {
        global $objConfig, $objLinkList;
        $cutoff = $objLinkList->GetPopValue();
        $this->IsPop = FALSE;
        if($cutoff>0)
        {
          if($this->Get('CachedRating') >= $cutoff
          		&& $this->Get('CachedVotesQty') >= $objConfig->Get('Link_MinVotes'))
          {
            $this->IsPop = TRUE;
          }
        }
        return $this->IsPop;
    }
    function SetHotItem()
    {
        global $objConfig, $objLinkList, $objSession;
        $this->IsHot = FALSE;
        $cutoff = $objLinkList->GetHotValue();
        if($cutoff>0)
        {
            if($this->Get("Hits")>=$cutoff) {
              $this->IsHot = TRUE;
            }
        }
        return $this->IsHot;
    }
	function Approve()
	{
      if($this->Get("Status")==-2)
      {
          $this->SendUserEventMail("LINK.MODIFY.APPROVE",$this->Get("CreatedById"));
          $this->SendAdminEventMail("LINK.MODIFY.APPROVE");
      }
      else
      {
        $this->SendUserEventMail("LINK.APPROVE",$this->Get("CreatedById"));
        $this->SendAdminEventMail("LINK.APPROVE");
      }
	  $this->Set("Status", 1);
	  $this->Update();
	}
    function Deny()
    {
        if($this->Get("Status")==-2)
        {
            $this->SendUserEventMail("LINK.DENY.PENDING",$this->Get("CreatedById"));
            $this->SendAdminEventMail("LINK.DENY.PENDING");
            $this->Delete();
        }
        else
        {
          $this->SendUserEventMail("LINK.DENY",$this->Get("CreatedById"));
          $this->SendAdminEventMail("LINK.DENY");
          $this->Set("Status", 0);
          $this->Update();
        }
    }
    function Validate()
    {
		global $objSession, $Errors;
        $dataValid = true;
        if(!strlen($this->Get("Name")))
        {
            $Errors->AddError("error.fieldIsRequired",'Name',"","",get_class($this),"Validate");
            $dataValid = false;
        }
//        if(!isset($this->m_Url))
//        {
//            $Errors->AddError("error.fieldIsRequired",'Url',"","",get_class($this),"Validate");
//            $dataValid = false;
//        }
        if(!(int)$this->Get("CreatedOn"))
        {
            $Errors->AddError("error.fieldIsRequired",'CreatedOn',"","",get_class($this),"Validate");
            $dataValid = false;
        }
        if(!(int)$this->Get("CreatedById"))
        {
            $Errors->AddError("error.fieldIsRequired",'CreatedBy',"","",get_class($this),"Validate");
            $dataValid = false;
        }
        return $dataValid;
    }
    function LoadFromDatabase($Id)
    {
		global $objSession,$Errors;
        if(!isset($Id))
        {
            $Errors->AddError("error.AppError",NULL,'Internal error: LoadFromDatabase id',"",get_class($this),"LoadFromDatabase");
            return false;
        }
        $sql = sprintf("SELECT * FROM ".$this->tablename." WHERE LinkId = '%s'",$Id);
        $result = $this->adodbConnection->Execute($sql);
        if ($result === false)
        {
            $Errors->AddError("error.DatabaseError",NULL,$this->adodbConnection->ErrorMsg(),"",get_class($this),"LoadFromDatabase");
            return false;
        }
        $data = $result->fields;
		if(is_array($data))
          $this->SetFromArray($data);
        $this->Clean();
        return TRUE;
    }
    function LoadFromResourceId($Id)
    {
        global $objSession, $Errors;
        if(!isset($Id))
        {
            $Errors->AddError("error.AppError",NULL,'Internal error: LoadFromDatabase id',"",get_class($this),"LoadFromResourceId");
            return false;
        }
        $sql = sprintf("SELECT * FROM ".$this->tablename." WHERE ResourceId = '%s'",$Id);
        $result = $this->adodbConnection->Execute($sql);
        if ($result === false)
        {
            $Errors->AddError("error.DatabaseError",NULL,$adodbConnection->ErrorMsg(),"",get_class($this),"LoadFromResourceId");
            return false;
        }
        $data = $result->fields;
        if(is_array($data))
        {
            $this->SetFromArray($data);
            $this->Clean();
        }
        return TRUE;
    }
    function ReviewCount($TodayOnly = FALSE)
    {
//       if($TodayOnly==FALSE && is_numeric($this->Get("CachedReviewsQty")))
//           return (int)$this->Get("CachedReviewsQty"); //this is a performance boost
       if(!is_object($this->Reviews))
       {
           $this->Reviews= new clsItemReviewList($this->Get("ResourceId"));
       }
       else
       {
           $this->Reviews->itemID=$this->Get("ResourceId");
       }
       return $this->Reviews->GetItemReviewCount($TodayOnly);
    }
    function StatusIcon()
    {
       global $rootURL;
       $ret = $rootURL."/in-link/admin/images/";
       switch(abs($this->Get("Status")))
       {
         case STATUS_DISABLED:
           $ret .= "icon16_link_disabled.gif";
           break;
         case STATUS_PENDING:
           $ret .= "icon16_link_pending.gif";
           break;
         case STATUS_ACTIVE:
           $img = "icon16_link.gif";
           if($this->IsPopItem())
               $img = "icon16_link_pop.gif";
           if($this->IsHotItem())
               $img = "icon16_link_hot.gif";
           if($this->IsNewItem())
               $img = "icon16_link_new.gif";
           if($this->Is("EditorsPick"))
               $img = "icon16_link_pick.gif";
           $ret .= $img;
           break;
       }
       return $ret;
    }
    function ItemURL($Template=NULL,$SetCat=FALSE,$Action=NULL)
    {
    	global $var_list_update,$var_list,$l_var_list_update,$m_var_list_update;
    	$url_params = Array();
    	$var_list_update['t'] = $Template ? $Template : $var_list['t'];
    	//if($SetCat)
    	//{
    		$cat = $this->Get("CategoryId");
    		if( !is_numeric($cat) ) $cat = $this->GetPrimaryCategory();
    		$m_var_list_update["cat"] = $cat;
    	//}
    	$l_var_list_update["id"] = $this->Get("LinkId");
    	if( isset($Action) && $Action ) $url_params['Action'] = $Action;
    	$ret = HREF_Wrapper('', $url_params);
    	unset($l_var_list_update["id"], $var_list_update["t"],$m_var_list_update["cat"]);
    	return $ret;
    }
    function ParseObject($element)
    {
    	/* when updating this function, update the comments at the top of the file */
        global $objConfig, $objCatList, $rootURL, $var_list, $var_list_update,
               $l_var_list_update, $m_var_list_update, $objSession, $objUsers;
        $extra_attribs = ExtraAttributes($element->attributes);
        if(strtolower($element->name)==$this->TagPrefix)
        {
            $field = strtolower($element->attributes["_field"]);
            switch($field)
            {
				case 'pending_approval':
            		$ret = $this->isPending() ? true : '';
            		if ($element->GetAttributeByName('_Not')) {
            			$ret = $ret ? '' : true;
            		}
            		break;
            	/*
				@field:link.url
				@description:Returns link URL or default value if URL is empty
				*/
				case 'url':
					$ret = $this->Get('Url');
					$default = $element->GetAttributeByName('_default');
					if( empty($ret) && !empty($default) )
					{
						$ret = language($default);
					}
					break;
      	case 'additional_params':
      		$ret = '';
      		if( $objConfig->Get('Link_UrlStatus') )
      		{
      			$link_url = addslashes( htmlspecialchars( $this->Get('Url') ) );
      			$ret = ' onmouseover="window.status = \''.$link_url.'\'; return true;" onmouseout="window.status = \'\';"';
      		}
      		break;
      	case "name":
	      	/*
	      	@field:link.name
	      	@description:Returns the link name
	      	*/
	      	//echo "test";
	                $ret= $this->HighlightField("Name");
	         break;
            case "description":
            	/*
            	@field:link.description
            	@description:Link Description
            	@attrib:_maxlength:int:Maximum number of characters to return
            	@attrib:_wordchop:bool:If truncating the description, setting wordchop causes the result to be truncated at the last space before the split
            	*/
                $ret = inp_unescape(($this->Get("Description")));
                $len = (int)$element->GetAttributeByName('_maxlength');
                if($len>0 && strlen($ret)>$len)
                {
                    $ret = substr($ret,0,$len);
                    $wordchop = $element->GetAttributeByName('_wordchop');
                    if(strlen($wordchop)==0 || $wordchop = "1")
                    {
                        if(substr($wordchop,-1)!=" ")
                        {
                          $pos = strrpos($ret," ");
                          $ret = substr($ret,0,$pos);
                        }
                    }
                    $ret .= " ..";
                }
                $ret = $this->HighlightText($ret);
            break;
            case "createdby":
								/*
								@field:link.createdby
								@description:parse a user field of the user that created the link
			  				@attrib:_usertag::User field to return (defaults to login ID)
			  				*/
                $field = $element->attributes["_usertag"];
                if(!strlen($field))
                {
                    $field = "user_login";
                }
                $userId = $this->Get("CreatedById");
                if (!empty($userId) && ($userId > 0))
                {
	                $u =& $objUsers->GetItem($userId);
	                if (is_object($u))
	                {
	                	$ret = $u->parsetag($field);
	                }
                }
	            else
	            	$ret = " ";
            break;
            case "date":
            	/*
  				@field:link.date
  				@description:Returns the date/time the link was created
  				@attrib:_tz:bool:Convert the date to the user's local time
  				@attrib:_part::Returns part of the date.  The following options are available: month,day,year,time_24hr,time_12hr
            	*/
                $d = $this->Get("CreatedOn");
                $ret = $this->ParseTimeStamp($d,$element->attributes);
            break;
            case "modified":
                /*
 			    @field:link.modified
 			    @description:Returns the date/time the link was last modified
  			    @attrib:_tz:bool:Convert the date to the user's local time
  			    @attrib:_part::Returns part of the date.  The following options are available: month,day,year,time_24hr,time_12hr
                */
                $d = $this->Get("Modified");
                if($d<=0)
                    $d = $this->Get("CreatedOn");
                $ret = $this->ParseTimeStamp($d,$element->attributes);
            break;
            case "expire":
                /*
 			    @field:link.expire
 			    @description:Returns the date/time the link suppose to expire.
  			    @attrib:_tz:bool:Convert the date to the user's local time
  			    @attrib:_part::Returns part of the date.  The following options are available: month,day,year,time_24hr,time_12hr
  			    @attrib:_dataexists:bool: Used with opeing/closing tags to exclude the whole block when expiration date is not set.
  			    @attrib:_noexpirelabel:lang:Returns language tag when link is immortal (expire set to 0).
                */
                $d = $this->Get("Expire");
                if($d == 0)
                {
                	if($element->attributes['_datenotset'] == 1)
                	{
                		$ret = 1;
                		break;
                	}
                	if(strlen($element->attributes['_noexpirelabel']))
                		$ret = language($element->attributes['_noexpirelabel']);
                	else
                		$ret = "";
                }
                elseif ($d > 0)
                {
                	$ret = $this->ParseTimeStamp($d, $element->attributes);
                }
                else
                	$ret = "";
            break;
            case "delete_link":
                /*
                @field:link.delete_link
                @description:Returns a URL to delete the link
  				@attrib:_template:tpl:Template URL should point to
  				*/
                $catid = $this->GetPrimaryCategory();
                if($objSession->HasCatPermission("LINK.DELETE",$catid) ||
                   ($objSession->Get("PortalUserId")==$this->Get("CreatedById") && $objSession->HasCatPermission("LINK.OWNER.DELETE",$catid)))
                {
                  $t = $element->attributes["_template"];
                	if(!strlen($t))
                  	 $t = $var_list["t"];
                	$ret = $this->ItemURL($t);
                }
            break;
            case "edit_link":
                /*
                @field:link.edit_link
                @description:Returns a URL to edit the link
  				@attrib:_template:tpl:Template URL should point to
  				*/
                $catid = $this->GetPrimaryCategory();
                if(($objSession->HasCatPermission("LINK.MODIFY",$catid) || $objSession->HasCatPermission("LINK.MODIFY.PENDING",$catid)) ||
                   (($objSession->Get("PortalUserId")==$this->Get("CreatedById") && $objSession->HasCatPermission("LINK.OWNER.MODIFY",$catid)) || ($objSession->Get("PortalUserId")==$this->Get("CreatedById") && $objSession->HasCatPermission("LINK.OWNER.MODIFY.PENDING",$catid))))
                {                
                  $t = $element->attributes["_template"];
                	if(!strlen($t))
                  	 $t = $var_list["t"];
                	$ret = $this->ItemURL($t);
                }
            break;
            case 'is_enhanced':
				if (!class_exists('kApplication') || $this->isPending() ) {
					return '';
				}
				
				$application =& kApplication::Instance();
				$l_tag_processor =& $application->recallObject('l_TagProcessor');
				$application->SetVar('l_id', $this->Get('LinkId'));
				$res = $l_tag_processor->LinkIsEnhanced( Array() );
				$ret = getArrayValue($element->attributes, '_not') ? !$res : $res;
				return $ret ? 1 : '';
				break;
            case "redirect":
            	/*
            	@field:link.redirect
            	@description:Returns a URL to redirect the browser to the link's URL
            	*/
                $ret =  $rootURL."in-link/inlink_redirect.php?env=". BuildEnv()."&linkid=".$this->Get("LinkId");
                break;
            case "add_favorite_link":
                /*
              	@field:link.add_favorite_link
              	@description:Returns a URL to add this link to the user's favorites
  				@attrib:_template:tpl:Template URL should point to
  				*/
                $t = $element->attributes["_template"];
                if(!strlen($t))
                    $t = $var_list["t"];
                $ret = $this->ItemURL($t,FALSE,"l_add_favorite");
            break;
            case "del_favorite_link":
                /*
              	@field:link.del_favorite_link
              	@description:Returns a URL to remove this link from the user's favorites
  				@attrib:_template:tpl:Template URL should point to
  				*/
                $t = $element->attributes["_template"];
                if(!strlen($t))
                    $t = $var_list["t"];
                $ret = $this->ItemURL($t,FALSE,"l_del_favorite");
            break;
			/*
				@field:link.favorite_toggle
				@description: Returns a link to set or reset the favorite flag for the current user
				@attrib: _template:tpl:Template to link to if user has the FAVORITES permission (defaults to current template)
				@attrib: _denytemplate:tpl: Template to link to if user does not have favorites permission (ie Guest)  Defaults to current template
				@attrib: _addlabel:lang:Language tag to display if link is to add favorite
				@attrib: _addimage::Image url to include in link if adding favorite
				@attrib: _dellabel:lang:Language tag to display if link is already a favorite
				@attrib: _delimage::Image url to include in link if removing the favorite
			*/
            case "favorite_toggle":
            		$catid = $this->GetPrimaryCategory();
            		$unregister=false;
                	if($objSession->HasCatPermission("FAVORITES", $catid))
                	{
                		$t = $element->GetAttributeByName('_template');
                	}
                	else
                	{
                		$t = $element->GetAttributeByName('_denytemplate');
                		RegisterEnv("dest", $element->GetAttributeByName('_denytemplate'));
                		$unregister = true;
                	}
//                	echo "RES: ".$unregister;
                	if(!strlen($t))
                    	$t = $var_list["t"];
                	if(!$this->IsFavorite($objSession->Get("PortalUserId"), $this->GetPrimaryCategory()))
                	{
                		$action = "l_add_favorite";
                		if( $element->GetAttributeByName('_addlabel') )
                		{
                			$label = language($element->attributes["_addlabel"]);
                		}
                		else
                		{
                			if(strlen($element->attributes["_addimage"]))
                			{
                				$result = MakeHTMLTag($element,'_img');
                				$label = '';
                			}
                		}
                	}
                	else
                	{
                  		$action = "l_del_favorite";
                  		if(strlen($element->attributes["_dellabel"]))
                  		{
                  			$label = language($element->attributes["_dellabel"]);
                  		}
                  		else
                  		{
                			if(strlen($element->attributes["_delimage"]))
                			{
                				$result = MakeHTMLTag($element,'_img');
                				$label = '
';
                			}
                  		}
                	}
                	$action = $unregister? NULL : $action;
                 	$ret = "ItemURL($t,FALSE,$action)."\">$label";
                 	if ($unregister)
                 		UnregisterEnv("dest");
            break;
/*
          	@field:link.hits
           	@description:Returns number of hits for item
*/
            case "hits":
                $ret= round($this->Get("Hits"));
            break;
/*
            	@field:link.votes
            	@description:Returns number of votes for item rating
*/
/*
  				@field:link.cat_link
            	@description:Returns a URL setting the link to the current link and the link's category to the current category
  				@attrib:_template:tpl:Template URL should point to
*/
/*
  				@field:link.link
  				@description:Returns a URL setting the link to the current link
  				@attrib:_template:tpl:Template URL should point to
*/
/*
            	  @field:link.rating
            	  @description:Displays the links rating
  				  @attrib:_displaymode:: How the rating should be displayed