<?php

define('TYPE_TOPIC', 3);
define('Locked', 3);

RegisterPrefix("clsTopic","topic","in-bulletin/topic.php");

class clsTopic extends clsCatItem
{
    function clsTopic($TopicId=NULL)
    {
        global $objSession;

        $this->clsCatItem(TRUE);
        $this->tablename=GetTablePrefix()."Topic";
        $this->type=TYPE_TOPIC;
        $this->BasePermission="TOPIC";
        $this->Prefix = 'bb';
        $this->id_field = "TopicId";
        $this->TagPrefix = "topic";
        $this->TitleField = 'TopicText';
        if(isset($TopicId))
            $this->LoadFromDatabase($TopicId);
        if($objSession->HasSystemPermission("DEBUG.ITEM"))
        {
            $this->SetDebugLevel(1);
        }

        $this->OpenTagVar = "Topic_Highlight_OpenTag";
        $this->CloseTagVar = "Topic_Highlight_CloseTag";
    }

    function ClearCacheData()
    {
		DeleteModuleTagCache('inbulletin');
    	/*       $cats = explode(",",$this->CategoryMemberList());
       if(is_array($cats))
       {
         foreach($cats as $c)
         {
           if(is_numeric($c))
           {
             $evar = "'%:m".$c."%'";
             DeleteTagCache("bb_topic_list","",$evar);
             DeleteTagCache("bb_topic_more","",$evar);
           }
         }
       }
       DeleteTagCache("bb_topic_modified%","");
       DeleteTagCache("TopicPopValue","","");
       DeleteTagCache("TopicHotValue","","");
       DeleteTagCache("TopicNewValue","","");*/
    }

    function Validate()
    {
        global $Errors;

        $dataValid = true;


        if(!strlen($this->Get("TopicText")))
        {
            $objSession->AddError("error.fieldIsRequired",'TopicText',"","",get_class($this),"Validate");
            $dataValid = false;
        }

        if(!(int)($this->Get("OwnerId")))
        {
            $Errors->AddError("error.fieldIsRequired",'Owner',"","",get_class($this),"Validate");
            $dataValid = false;
        }
        return $dataValid;
    }


    function Update($UpdatedBy=NULL,$modificationDate=null)
    {
        parent::Update($UpdatedBy,$modificationDate);
        if($this->tablename==GetTablePrefix()."Topic")
        {
            $this->ClearCacheData();
        }
    }

    function Create()
    {
        parent::Create();
        if($this->tablename==GetTablePrefix()."Topic")
        {
            $this->ClearCacheData();
            DeleteTagCache("m_itemcount","Topic%");
        }
    }

    function Delete()
    {
        global $objPostingList, $objCatList;

        $PostCount = $this->Get("Posts");
        $objPostingList->DeleteTopicPosts($this->Get("TopicId"));
      	$CategoryId = $this->Get("CategoryId");
      	if(!is_numeric($CategoryId))
        	 $CategoryId = $objCatList->CurrentCategoryID();

        if($this->tablename==GetTablePrefix()."Topic")
        {
            $this->ClearCacheData();
            DeleteTagCache("m_itemcount","Topic%");

            if($this->Get("NotifyOwnerOnChanges"))
          	{
            	$this->SendUserEventMail("TOPIC.DELETE",$this->Get('OwnerId') );
          	}
          	$this->SendAdminEventMail("TOPIC.DELETE");
        }
        parent::Delete();

        $this->refreshLastUpdate($CategoryId);

        $this->UpdateCategoryPostCount();
    }

    function UpdateModified($UserId)
	{
		$this->Set(array("Modified", "ModifiedById"), array(adodb_mktime(), $UserId));
		$this->Update();
	}

	function UpdateNumPosts()
	{
		global $objSession;

		$sql = "SELECT COUNT(PostingId) as PostCount FROM ".GetTablePrefix()."Posting WHERE TopicId=" . $this->Get("TopicId");
		$result = $this->adodbConnection->Execute($sql);

		if($result && !$result->EOF)
		{
            $sql = "UPDATE ".$this->tablename." SET Posts=".$result->fields["PostCount"]." WHERE TopicId=" . $this->Get("TopicId");
			$result = $this->adodbConnection->Execute($sql);
			if ($result === false)
			{
				$Errors->AddError("error.DatabaseError",NULL,$this->adodbConnection->ErrorMsg(),"",get_class($this),"UpdateNumPosts");
				return false;
			}
		}
	}

    function SetNewItem()
    {
        global $objConfig;

        $value = $this->Get("CreatedOn");

        $cutoff = adodb_date("U") - ($objConfig->Get("Topic_NewDays") * 86400);
        $this->IsNew = FALSE;
        if($value>$cutoff)
          $this->IsNew = TRUE;
        return $this->IsNew;
    }

    function SetPopItem()
    {
        global $objConfig, $objTopicList;

        $cutoff = $objTopicList->GetPopValue();
        if($cutoff > 0)
        {
          $this->IsPop = FALSE;
          if($this->Get('Posts') >= $cutoff)
		  {
            $this->IsPop = TRUE;
		  }
        }
        else
            $this->IsPop = FALSE;
        return $this->IsPop;
    }

    function SetHotItem()
    {
        global $objConfig, $objTopicList;

        $this->IsHot = FALSE;
        $cutoff = $objTopicList->GetHotValue();
        if($cutoff>0)
        {
            if($this->Get("Views") >= $cutoff)
              $this->IsHot = TRUE;
        }
        return $this->IsHot;
    }

	function Approve()
	{
	  $this->Set("Status", 1);
	  $this->Update();
      $this->SendUserEventMail("TOPIC.APPROVE",$this->Get("OwnerId"));
      $this->SendAdminEventMail("TOPIC.APPROVE");
	}

    function Deny()
    {
        $this->Set("Status", 0);
        $this->Update();
        $this->SendUserEventMail("TOPIC.DENY",$this->Get("OwnerId"));
        $this->SendAdminEventMail("TOPIC.DENY");
    }

    function LoadFromDatabase($Id)
    {
		global $Errors;

        if(!isset($Id))
        {
            $Errors->AddError("error.AppError",NULL,'Internal error: LoadFromDatabase id',"",get_class($this),"LoadFromDatabase");
            return false;
        }
        if($Id>0)
        {
          $sql = sprintf("SELECT * FROM ".$this->tablename." WHERE ".$this->IdField()." = '%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;

          $this->SetFromArray($data);
          return TRUE;
        }
        else
            return FALSE;
    }
    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);
    }


	function GetPostsSince($time_stamp)
	{
		global $Errors;

		$Id = $this->Get("TopicId"); //get cur cat id
		settype($time_stamp,"integer");
		$sql = "SELECT count(PostingId) as pcount FROM ".GetTablePrefix()."Posting WHERE TopicId = $Id AND Posting.ModifiedOn >= $time_stamp ";
		$result = $this->adodbConnection->Execute($sql);
		if($result && !$result->EOF)
			return $result->fields["pcount"];
		else
		{
			$Errors->AddError("error.DatabaseError",NULL,$this->adodbConnection->ErrorMsg(),"",get_class($this),"GetPostsSince");
			return false;
		}

	}

	function GetPosts()
	{
		global $Errors;

/*        if(!is_numeric($this->Get("Posts"))<1)
        {
		  $Id = $this->Get("TopicId"); //get cur cat id

		  $sql = "SELECT count(PostingId) FROM ".GetTablePrefix()."Posting WHERE TopicId = $Id";
		  $result = $this->adodbConnection->Execute($sql);
		  if($result && !$result->EOF)
			$this->Set("Posts",$result->fields[0]);
		  else
		  {
			$Errors->AddError("error.DatabaseError",NULL,$this->adodbConnection->ErrorMsg(),"","clsTopic","GetPosts");
			return false;
		  }
        }*/
        return $this->Get("Posts");
	}

    function StatusIcon()
    {
        global $rootURL;

       $ret = $rootURL."/in-bulletin/admin/images/";

       switch($this->Get("Status"))
       {
         case STATUS_DISABLED:
           $ret .= "icon16_topic_disabled.gif";
           break;
         case STATUS_PENDING:
           $ret .= "icon16_topic_pending.gif";
           break;
         case STATUS_ACTIVE:
           $img = "icon16_topic.gif";
           if($this->IsPopItem())
               $img = "icon16_topic_top.gif";
           if($this->IsHotItem())
               $img = "icon16_topic_hot.gif";
           if($this->IsNewItem())
               $img = "icon16_topic_new.gif";
           if($this->Is("EditorsPick"))
               $img = "icon16_topic_pick.gif";
           $ret .= $img;
           break;
       }
       return $ret;
    }

    function ItemURL($Template=NULL,$SetCat=FALSE,$Action=NULL)
    {
		global $var_list_update,$var_list,$bb_var_list_update,$m_var_list_update;

		$url_params = Array();
		$var_list_update["t"] = $Template ? $Template : $var_list["t"];

//        if($SetCat || (int)$this->Get("CategoryId")>0)
//        {
           $cat = $this->Get("CategoryId");
           if(!is_numeric($cat))
             $cat = $this->GetPrimaryCategory();
            $m_var_list_update["cat"] = $cat;
//        }

    	$bb_var_list_update["top"] = $this->Get("TopicId");
    	$bb_var_list_update["pp"] = 1;

        if( isset($Action) && $Action ) $url_params['Action'] = $Action;
        $ret = HREF_Wrapper('', $url_params);

        unset($m_var_list_update["cat"],$bb_var_list_update["top"],$bb_var_list_update["tp"],$bb_var_list_update["pp"], $var_list_update["t"]);
        return $ret;
    }

    function ParseObject($element)
    {
        global $objConfig, $objSession, $objUsers, $objCatList, $var_list_update, $var_list,
               $bb_var_list_update, $m_var_list_update,$objCensorList;

        //print_pre($element);

        $extra_attribs = ExtraAttributes($element->attributes);
        if(strtolower($element->name)==$this->TagPrefix)
        {
            $field = strtolower($element->attributes["_field"]);
            switch($field)
            {

            	/*
            	@field:topic.text
            	@description: Returns the topic title (or subject)
            	*/
            	case "text":
            		$topic_text = inp_unescape($objCensorList->CensorText($this->Get("TopicText")));
            		$num_chars = $element->GetAttributeByName('_numchars');
            		if ($num_chars && strlen($topic_text) > $num_chars) {
            	  	$ret = substr($topic_text, 0, $num_chars)."...";
            	  }
            	  else {
            	  	$ret = $topic_text;
            	  }
            	  $ret = $this->HighlightText($ret);
            	break;
            	/*
            	@field:topic.replies
            	@description: Returns the number of posts for the topic (The first post is not counted)
            	*/
				case "replies":
				  $ret = $this->GetPosts() - 1;
				break;
				/*
				@field:topic.views
				@description: Returns the number of times the topic has been viewed
				*/
				case "views":
					return round($this->Get("Views"));
				break;
            	/*
            	@field:topic.category
            	@description:Return a category field from the link's category
            	@attrib:_cattag::Category field to parse
            	*/

            case "lastposter":
            	/*
            	@field:topic.lastposter
            	@description:Returns the login name of the last poster in this topic
            	*/
                if(strlen($this->Get("LastPoster")))
                {
                    $ret = $this->Get("LastPoster");
                }
                else
                {
                    $id = $this->Get("LastPostId");
                    if (!is_numeric($id)) {
						$id = $this->GetLastPostId();
                    }
                    
                    if ($id) {
                      $post = new clsPosting($id);
                      if (is_object($post)) {
                        $ret = $post->Get('PosterAlias');
                        if (!$ret && ($post->Get('CreatedById') < 0)) {
                        	$ret = language('lu_Guest');
                        }
                      }
                    }
                }
            break;
            case "lastpostdate":
            	/*
  				@field:topic.lastpostdate
  				@description:Returns the date/time a post was made to this topic
  				@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("LastPostDate");
                if (!$element->GetAttributeByName('_tz')) {
                	$element->SetAttributeByName('_tz', 'auto');
                }
                $ret = $this->ParseTimeStamp($d, $element->attributes);
            break;
            	/*
 				@field:topic.image
 				@description:Return an image associated with the topic
  				@attrib:_primary:bool:If true, will return the default image if the requested image does not exist
  				@attrib:_name::Return the image with this name
  				@attrib:_thumbnail:bool:If true, return the thumbnail version of the image
  				@attrib:_imagetag:bool:If true, returns a complete image tag. exta html attributes are passed to the image tag
               */
            case "modifiedby":
				/*
				@field:topic.modifiedby
				@description:parse a user field of the user that last modified the topic
  				@attrib:_usertag::User field to return (defaults to login ID)
  				*/
                $field = $element->attributes["_usertag"];
                if(!strlen($field))
                {
                    $field = "user_login";
                }
                $u =& $objUsers->GetItem($this->Get("ModifiedById"));
                $ret = $u->parsetag($field);
            break;
            case "owner":
				/*
				@field:topic.owner
				@description:parse a user field of the user that is the topic owner
  				@attrib:_usertag::User field to return (defaults to login ID)
  				*/
                $field = $element->attributes["_usertag"];
                if(!strlen($field))
                {
                    $field = "user_login";
                }
                $u =& $objUsers->GetItem($this->Get("OwnerId"));
                $ret = $u->parsetag($field);
            break;

                /*
                @field:topic.custom
                @description:Returns a custom field
  				@attrib:_customfield::field name to return
  				@attrib:_default::default value
  				*/
            case "date":
            	/*
  				@field:topic.date
  				@description:Returns the date/time the topic 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');
                if (!$element->GetAttributeByName('_tz')) {
                	$element->SetAttributeByName('_tz', 'auto');
                }
                $ret = $this->ParseTimeStamp($d,$element->attributes);
            break;
            case "modifieddate":
            	/*
  				@field:link.modifieddate
  				@description:Returns the date/time the topic 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 (!$element->GetAttributeByName('_tz')) {
                	$element->SetAttributeByName('_tz', 'auto');
                }
                $ret = $this->ParseTimeStamp($d,$element->attributes);
            break;
            	/*
            	@field:topic.fullpath
            	@description:The full category path of the item
            	*/
            //break;
            case "locked":
            	/*
            	@field:topic.locked
            	@description: Returns a value if the topic is locked
              	@attrib:_text:lang:Language tag to display as the link text
              	@attrib:_plaintext:: Plain text to use instead of language tag
              	@attrib:image::Image URL to display
              	*/

                if($this->Get("TopicType")==0)
                {
                  $text = $element->attributes["_text"];
                  if(!strlen($text))
                  {
                    $text = $element->attributes["_plaintext"];
                    if(!strlen($text))
                    {
                    if(strlen($element->attributes["_image"]))
                    {
                            $text = "<IMG SRC=\"".$element->attributes["_image"]."\" BORDER=\"0\" alt=\"\">";
                        }
                    }
                    $ret .= $text."</A>";
                  }
                  else
                    $ret .= language($text)."</A>";
                  if(!strlen($ret)) $ret = "locked";
                }
                else {
                	$ret = '';
                }

             break;
            	/*
            	@field:topic.cat_link
            	@description:Returns a URL setting the topic to the current topic and the topic's category to the current category
  				@attrib:_template:tpl:Template URL should point to
            	*/
            	/*
  				@field:topic.link
  				@description:Returns a URL setting the topic to the current topic
  				@attrib:_template:tpl:Template URL should point to
  				*/
            case "perm_link":
				/*
				@field:topic.perm_link
				@description: Returns a link to the current topic if permissions are set for the user
				@attrib:_permission::Comma-separated permission list to check, any one permission granted to the user will create the link
				@attrib:_system:bool:Set this to true if any one permission in the list is a system permission
				@attrib:_noaccess:tpl:Template to link to if access is denied
				@attrib:_template:tpl:Tempalte to link to if access is granted
              	@attrib:_text:lang:Language tag to display as the link text
              	@attrib:_plaintext:: Plain text to use instead of language tag
              	@attrib:image::Image URL to display in the anchor tag
				*/
                $p = $element->attributes["_permission"];
                $sys = $element->attributes["_system"];
                $cat = $this->Get("CategoryId");
                if(!is_numeric($cat))
                    $cat = $this->GetPrimaryCategory();

                $HasPerm = $objSession->HasCatPermInList($p,$cat, $sys);
                if(!$HasPerm && strlen($element->attributes["_noaccess"])>0)
                {
                    $t = $element->attributes["_noaccess"];
                    $ret = $this->ItemURL($t,FALSE,"");
                }
                if($HasPerm)
                {
                    $t = $element->attributes["_template"];
                    $ret = "<A HREF=\"".$this->ItemURL($t)."\">";
                    $text = $element->attributes["_text"];
                    if(!strlen($text))
                    {
                        $text = $element->attributes["_plaintext"];
                        if(!strlen($text))
                        {
                            if(strlen($element->attributes["_image"]))
                            {
                                $text = "<IMG SRC=\"".$element->attributes["_image"]."\" BORDER=\"0\" alt=\"\">";
                            }
                        }
                        $ret .= $text."</A>";
                    }
                    else
                      $ret .= language($text)."</A>";
                }
                else
                	$ret = '';
            break;
            case "link_lock":
            	/*
              	@field:topic.link_lock
              	@description: Returns a link to lock or unlock the topic. A complete anchor tag is returned, and the tag class is set to 'topic_reply'
              	@attrib:_template:tpl:Template link should point to
              	@attrib:_text:lang:Language tag to display as the link text
              	@attrib:_plaintext:: Plain text to use instead of language tag
              	@attrib:image::Image URL to display in the anchor tag
            	*/
                $cat = $this->Get("CategoryId");
                if(!is_numeric($cat))
                    $cat = $this->GetPrimaryCategory();

                if($objSession->HasCatPermission("TOPIC.LOCK",$cat))
                {
                    $t = $element->attributes["_template"];
                    if(strlen($t))
                    {
                        $var_list_update["t"] = $t;
                    }
                    else
                        $var_list_update["t"] = $var_list["t"];

                    $bb_var_list_update["top"] = $this->Get("TopicId");
                    if($this->Get("TopicType")==1)
                    {
                        $ret = "<A HREF=\"".HREF_Wrapper('', Array('Action' => 'bb_lock_topic') )."\">";
                    }
                    else
                        $ret = "<A HREF=\"".HREF_Wrapper('', Array('Action' => 'bb_unlock_topic') )."\">";
                    $text = $element->attributes["_text"];
                    if(!strlen($text))
                    {
                        $text = $element->attributes["_plaintext"];
                        if(!strlen($text))
                        {
                            if(strlen($element->attributes["_image"]))
                            {
                                $text = "<IMG SRC=\"".$element->attributes["_image"]."\" BORDER=\"0\" alt=\"\">";
                            }
                        }
                        $ret .= $text."</A>";
                    }
                    else
                      $ret .= language($text)."</A>";
                }
                else
                    $ret = "";
                unset($bb_var_list_update["top"], $m_var_list_update["cat"],$var_list_update["t"]);
            break;

            case "link_delete":
            	/*
              	@field:topic.link_delete
              	@description: Returns a link to delete the topic.
              	@attrib:_template:tpl:Template link should point to
              	@attrib:_text:lang:Language tag to display as the link text
              	@attrib:_plaintext:: Plain text to use instead of language tag
              	@attrib:image::Image URL to display in the anchor tag
            	*/
                $cat = $this->Get("CategoryId");
                if(!is_numeric($cat))
                    $cat = $this->GetPrimaryCategory();

                $OwnerPerm = ($objSession->HasCatPermission("TOPIC.OWNER.DELETE", $cat) &&
                             $objSession->Get("PortalUserId")==$this->Get("OwnerId"));

                if($objSession->HasCatPermission("TOPIC.DELETE",$cat) || $OwnerPerm)
                {
                    $bb_var_list_update["top"] = $this->Get("TopicId");
                    $m_var_list_update["cat"] = $cat;
                    $ret = "<A CLASS=\"topic_delete\" HREF=\"".HREF_Wrapper('', Array('Action' => 'bb_topic_delete') ) ."\">";
                    $text = $element->attributes["_text"];
                    if(!strlen($text))
                    {
                        $text = $element->attributes["_plaintext"];
                        if(!strlen($text))
                        {
                            if(strlen($element->attributes["_image"]))
                            {
                                $text = "<IMG SRC=\"".$element->attributes["_image"]."\" BORDER=\"0\" alt=\"\">";
                            }
                        }
                        $ret .= $text."</A>";
                    }
                    else
                      $ret .= language($text)."</A>";
                }
                else
                    $ret = "";

                unset($bb_var_list_update["top"], $m_var_list_update["cat"]);
            break;

            case "link_edit":
            	/*
              	@field:topic.link_edit
              	@description: Rturns a link edit the topic. A complete anchor tag is returned, and the tag class is set to 'topic_reply'
              	@attrib:_template:tpl:Template link should point to
              	@attrib:_text:lang:Language tag to display as the link text
              	@attrib:_plaintext:: Plain text to use instead of language tag
              	@attrib:image::Image URL to display in the anchor tag
            	*/
                $cat = $this->Get("CategoryId");
                if (!is_numeric($cat)) {
                	$cat = $this->GetPrimaryCategory();
                }
                    
				$perms[1] = $objSession->HasCatPermission('TOPIC.MODIFY', $cat) || $objSession->HasCatPermission("TOPIC.MODIFY.PENDING", $cat);
                $perms[2] = $objSession->Get("PortalUserId") == $this->Get("OwnerId") && $objSession->HasCatPermission("TOPIC.OWNER.MODIFY", $cat);
                $perms[3] = $objSession->Get("PortalUserId") == $this->Get("OwnerId") && $objSession->HasCatPermission("TOPIC.OWNER.MODIFY.PENDING", $cat);
                 
               if ( ($perms[1] || $perms[2] || $perms[3]) && ($this->Get("TopicType") == 1) ) {
                
                    $bb_var_list_update["top"] = $this->Get("TopicId");
                    $m_var_list_update["cat"] = $cat;
                    $var_list_update["t"] = $element->attributes["_template"];
                    if(strlen($element->attributes["_template"]))
                    {
                      $ret = "<A CLASS=\"topic_edit\" HREF=\"".HREF_Wrapper()."\">";
                      $text = $element->attributes["_text"];
                      if(!strlen($text))
                      {
                        $text = $element->attributes["_plaintext"];
                        if(!strlen($text))
                        {
                            if(strlen($element->attributes["_image"]))
                            {
                                $text = "<IMG SRC=\"".$element->attributes["_image"]."\" BORDER=\"0\" alt=\"\">";
                            }
                        }
                        $ret .= $text."</A>";
                      }
                      else
                        $ret .= language($text)."</A>";
                    }
                    else
                        $ret = "[no template]";
                }
                else
                    $ret = "";
                unset($bb_var_list_update["top"], $var_list_update["t"],$m_var_list_update["cat"]);
            break;

            case "link_reply":
            	/*
              	@field:topic.link_reply
              	@description: Rturns a link to post a reply to the topic. A complete anchor tag is returned, and the tag class is set to 'topic_reply'
              	@attrib:_template:tpl:Template link should point to
              	@attrib:_text:lang:Language tag to display as the link text
              	@attrib:_plaintext:: Plain text to use instead of language tag
              	@attrib:image::Image URL to display in the anchor tag
            	*/
                if(($objSession->HasCatPermission("TOPIC.REPLY.ADD") ||
                   $objSession->Get("PortalUserId")==$this->Get("OwnerId"))
                   && $this->Get("TopicType")==1)
                {
                    $bb_var_list_update["top"] = $this->Get("TopicId");
                    $var_list_update["t"] = $element->attributes["_template"];
                    if(strlen($element->attributes["_template"]))
                    {
                      $ret = "<A CLASS=\"topic_reply\" HREF=\"".HREF_Wrapper()."\">";
                      $text = $element->attributes["_text"];
                      if(!strlen($text))
                      {
                        $text = $element->attributes["_plaintext"];
                        if(!strlen($text))
                        {
                            if(strlen($element->attributes["_image"]))
                            {
                                $text = "<IMG SRC=\"".$element->attributes["_image"]."\" BORDER=\"0\" alt=\"\">";
                            }
                        }
                        $ret .= $text."</A>";
                      }
                      else
                        $ret .= language($text)."</A>";
                    }
                    else
                        $ret = "";
                }
                else
                    $ret = "";
                unset($bb_var_list_update["top"],$var_list_update["t"]);
            break;

            case "add_favorite_link":
                /*
              	@field:topic.add_favorite_link
              	@description:Returns a URL to add this topic 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,"bb_add_favorite");
            break;
            case "del_favorite_link":
                /*
              	@field:topic.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,"bb_del_favorite");
            break;
			/*
				@field:topic.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 item is already a favorite
				@attrib: _delimage::Image url to include in link if removing the favorite
			*/
            case "favorite_toggle":

                $t = $element->attributes["_template"];
                if(!strlen($t))
                   	$t = $var_list["t"];

                if(!$this->IsFavorite())
                {
                	$action = "bb_add_favorite";
                	if (!strlen($element->attributes["_addlabel"])) {
                		$text = "<IMG SRC=\"".$element->attributes["_addimage"]."\" BORDER=\"0\" alt=\"\">";
                	}
                	else {
                		$label = $element->attributes["_addlabel"];
                	}
                }
                else
                {
                	$action = "bb_del_favorite";
                	if (!strlen($element->attributes["_dellabel"])) {
                		$text = "<IMG SRC=\"".$element->attributes["_delimage"]."\" BORDER=\"0\" alt=\"\">";
                	}
                	else {
                  	$label = $element->attributes["_dellabel"];
                  }
                }
                if (strlen($label)) {
                	$text = language($label);
                }
                $ret = "<A ".$extra_attribs." HREF=\"".$this->ItemURL($t,FALSE,$action)."\">".$text."</A>";
            break;
            case "admin_icon":
                if( $element->GetAttributeByName('_fulltag') )
                {
                    $ret = "<IMG $extra_attribs SRC=\"".$this->StatusIcon()."\" alt=\"\">";
                }
                else
                    $ret = $this->StatusIcon();
            break;
            case "admin_modified":
            	if($this->Get("Modified")<=0)
					return "-";
				return LangDate($this->Get("Modified"))."<br>".LangTime($this->Get("Modified"));
        	break;
            case "post_pagelist":
            	/*
            	@field:topic.post_pagelist
            	@description: Returns a page navigation link set for this topic, assuming the current page of the post list is page 1.  If less that one page full of posts exists, nothing is returned
            	@attrib:_DestTemplate:tpl: Template the links should point to
            	@attrib:_PagesToList:int: Number of pages listed in the bar
            	*/
                $plist = new clsPostingList();
                $plist->TopicID = $this->Get('TopicId'); //$this->TopicID;
                $where = 'TopicId = '.$this->Get('TopicId');
                $plist->QueryItemCount = $this->GetPosts();
                $plist->Page = 0;
                $t = $element->attributes['_desttemplate'];
                $PagesToList = $element->attributes['_pagestolist'];
                if (!is_numeric($PagesToList)) $PagesToList = 10;
                if ($plist->QueryItemCount > $objConfig->Get('Perpage_Postings'))
                {
					$ret = $plist->GetPageLinkList($t,'',$PagesToList, $extra_attribs);
                }
                else
                {
                    $ret = '';
                }
            break;
            case "postedby":
            	/*
            	@field:topic.postedby
            	@description:Returns the login name of the last poster in this topic
            	*/
                $ret = $this->Get("PostedBy");

                if ($ret == '') {
                	$ret = admin_language("lu_Guest");
                }
            break;
        	case "admin_cell_back":
              $ret = int_table_color_ret();
            break;
            	/*
            	  @field:topic.rating
            	  @description:Displays the topic rating
  				  @attrib:_displaymode:: How the rating should be displayed<br>
  				    	<UL>
  				    	  <LI>"Numerical": Show the decimal value
  				    	  <LI>"Text": Show the text version
  				    	  <LI>"Graphical":Show images representing the rating
  				    	</UL>
				  @attrib:_onimage::on image tick shown in graphical display mode
				  @attrib:_offimage::off image tick shown in graphical display mode
				  @attrib:_separator::In graphical display mode, this html is placed between each tick image
				*/
            	/*
            	@field:topic.reviews
            	@description:Return the number of reviews for think link
				@attrib:_today:bool:Count reviews added today only
				*/
            case "votes":
            	/*
            	@field:topic.votes
            	@description:Return the number of rating votes for this topic
				*/
                $ret = $this->Get("CachedVotesQty");
            	break;
            	
            	
            case 'icon':
            	$icons = Array();
            	$icons['new'] = $element->GetAttributeByName('_new_icon');
            	$icons['no_new'] = $element->GetAttributeByName('_no_new_icon');
            	$icons['locked'] = $element->GetAttributeByName('_locked_icon');

				
            	if ($this->Get('TopicType') == 0 || $objSession->Get('PortalUserId') <= 0) {
            		$ret = $icons['locked'];
            		break;
            	}

            	$topic_modified = $this->Get('Modified');
            	if (!$topic_modified) {
            		$topic_modified = $this->Get('CreatedOn');
            	}

            	$last_login = $objSession->GetPersistantVariable('LastLogin');

            	if ($last_login < $topic_modified) {
            		$ret = $icons['new'];
            	}
            	else {
            		$ret = $icons['no_new'];
            	}
            	break;

            	/*
 				@field:topic.new
 				@description:returns text if topic's status is "new"
  				@attrib:_label:lang: Text to return if status is new
  				*/
            	/*
 				@field:topic.pop
 				@description:returns text if topic's status is "popular"
  				@attrib:_label:lang: Text to return if status is popular
  				*/
            	/*
 				@field:topic.hot
 				@description:returns text if topic's status is "hot"
  				@attrib:_label:lang: Text to return if status is "hot"
  				*/
            	/*
 				@field:topic.pick
 				@description:returns text if topic's status is "hot"
  				@attrib:_label:lang: Text to return if status is "hot"
  				*/
            }
            if(!isset($ret))
              $ret = parent::ParseObject($element);
        }
        else
        {
            $ret = $this->parsetag($element->name);
        }
        return $ret;
    }

    function parsetag($tagname)
    {
     global $objConfig, $objSession, $objUsers, $var_list_update, $bb_var_list_update, $bb_var_list;

     switch($tagname)
	 {
	 	case "topic_admin_icon":
	 		return $this->StatusIcon();
	 	break;
		case "topic_id":
			return $this->Get("TopicId");
			break;
        case "topic_resourceid":
          return $this->Get("ResourceId");
          break;
		case "topic_modified":
			if ($this->Get('Modified') <= 0) {
				return '';
			}
			return LangDate($this->Get('Modified'), 0, true);
			break;
			
        case "topic_modified_time":
            if ($this->Get('Modified') <= 0) {
               return '';
            }
            return LangTime($this->Get('Modified'), 0, true);
        break;

        case "topic_admin_modified":
            if($this->Get("Modified")<=0)
				return "-";
			return LangDate($this->Get("Modified"))."<br>".LangTime($this->Get("Modified"));
        break;
        case "topic_created":
            if ($this->Get('CreatedOn') <= 0) {
            	return '';
            }
            return LangDate($this->Get('CreatedOn'), 0, true);
        	break;
        	
        case "topic_created_time":
            if ($this->Get('CreatedOn') <= 0) {
                return '';
            }
            return LangTime($this->Get('CreatedOn'), 0, true);
        break;

		case "topic_text":
			return inp_unescape($this->Get("TopicText"));
			break;
		case "topic_delete":
			if($this->CheckPermission("DELETE"))
			{
				$bb_var_list_update["top"] = $this->Get("TopicId");
				return "<A CLASS=\"topic_delete\" HREF=\"".HREF_Wrapper('', Array('Action' => 'bb_topic_delete') ) ."\">".language("delete")."</A>";
			}
			else
				return "";
			break;
		case "topic_name":
			return inp_unescape($this->Get("TopicText"));
			break;
		case "topic_views":
			return $this->Get("Views");
			break;
		case "topic_posts":
			return $this->GetPosts();
			break;
		case "topic_replies":
			return $this->GetPosts() - 1;
			break;
        case "topic_priority":
            if($this->Get("Priority")>0)
            {
                return (int)$this->Get("Priority");
            }
            else
                return "";
            break;
		case "topic_pick":
			if ($this->Is("EditorsPick"))
				return "pick";
			break;
		case "topic_new":
			if ($this->IsNewItem())
				return "new";
			break;
		case "topic_pop":
			if ($this->IsPopItem())
				return "pop";
			break;
        case "topic_hot":
            if ($this->IsHotItem())
                return "hot";
            break;
        case "topic_poster":
            return $this->Get("PostedBy");
            break;
		case "topic_category":
			return $this->Get("CategoryId");
			break;
		case "topic_last_post":
			return LangDate($this->Get("Modified"));
			break;
		case "topic_link":
			$var_list_update["t"] = "inbulletin/bb_post_list";
			$bb_var_list_update["top"] = $this->Get("TopicId");
			$bb_var_list_update["cat"] = $this->Get("CategoryId");
            $bb_var_list_update["pp"]=1;
			$ret = HREF_Wrapper();
			unset($var_list_update["t"], $bb_var_list_update["top"]);

			return $ret;
			break;
        case "topic_review_link":
            $var_list_update["t"] = "inbulletin/bb_reviews";
            $bb_var_list_update["top"] = $this->Get("TopicId");
            $bb_var_list_update["cat"] = $this->Get("CategoryId");
            $bb_var_list_update["pp"]=1;
            $ret = HREF_Wrapper();
            unset($var_list_update["t"], $bb_var_list_update["top"]);

            return $ret;
            break;

        case "topic_rate_link":
            $var_list_update["t"] = "inbulletin/bb_rate";
            $bb_var_list_update["top"] = $this->Get("TopicId");
            $bb_var_list_update["cat"] = $this->Get("CategoryId");
            $bb_var_list_update["pp"]=1;
            $ret = HREF_Wrapper();
            unset($var_list_update["t"], $bb_var_list_update["top"]);

            return $ret;
            break;
        case "topic_num_reviews":
            $ret = $this->ReviewCount();
            return $ret;
            break;
        case "topic_votes":
            return $this->Get("CachedVotesQty");
            break;
        case "topic_rating":
            return round($this->Get("CachedRating"),1);
            break;
		case "topic_rating_txt":
			return RatingText($this->Get("CachedRating"));
			break;
		case "topic_type_img":
			$last_login = $objSession->GetPersistantVariable("LastLogin");

			if ($objSession->Get("PortalUserId") == -2)
			{
				$n = $this->GetPosts();
				if ($n > 25)
					return "inbulletin/images/hot_folder.gif";
				else
					return "inbulletin/images/folder.gif";

			}

			$n = $this->GetPostsSince($last_login);
			if ($n > 25)
				return "inbulletin/images/hot_red_folder.gif";
			elseif ($n > 0)
				return "inbulletin/images/red_folder.gif";
			else
			{
			$n2 = $this->GetPosts();
			if ($n2 > 25)
				return "inbulletin/images/hot_folder.gif";
			else
				return "inbulletin/images/folder.gif";
			}
			break;

        case "topic_admin_cell_back":
           return int_table_color_ret();
		default:
            return "Undefined:$tagname";
			break;
      }
    }

   function UpdateCategoryPostCount($CatId=NULL)
   {
   	 global $objCatList,$objCountCache;

   	 if(!is_numeric($CatId))
   	   $CatId = $objCatList->CurrentCategoryID();

   	 $PostCount = 0;
   	 $sql = "SELECT SUM(Posts) as PostCount,count(TopicId) as TopicCount FROM ".$this->tablename." INNER JOIN ".GetTablePrefix()."CategoryItems ON ";
   	 $sql .= "(".$this->tablename.".ResourceId=".GetTablePrefix()."CategoryItems.ItemResourceId) WHERE CategoryId=$CatId AND Status=1";
   	 $rs = $this->adodbConnection->Execute($sql);
   	 if($rs && !$rs->EOF)
   	   $PostCount = $rs->fields["PostCount"];

   	 if($PostCount>0)
   	   $PostCount = $PostCount - (int)$rs->fields["TopicCount"];
   	 $sql = "UPDATE ".$objCountCache->SourceTable." SET Value=".(int)$PostCount.",LastUpdate=".adodb_date("U")." WHERE ItemType=30 AND ListType=30 AND ExtraId=$CatId";
   	 $this->adodbConnection->Execute($sql);
   }

   function &AddPost($PosterAlias,$Pending, $PostingText, $Subject="")
   {
      global $objUsers,$objSession, $objCatList;

      $u =& $objSession->CurrentUser;

      if (is_object($u)) {
      	$posts = (int)$u->GetPersistantVariable("bb_posts");
      	$posts++;
      	$u->SetPersistantVariable("bb_posts",$posts);
      }

      $p = New clsPosting(NULL);
	  $p->Set(array("PosterAlias", "Pending", "PostingText", "TopicId"),
              array($PosterAlias, $Pending, str_replace("env=".$objSession->GetSessionKey(), "env=",$PostingText), $this->Get("TopicId")));
      $p->Set("IPAddress",$_SERVER["REMOTE_ADDR"]);
      $p->Set("CreatedOn",adodb_date("U"));
      if (is_object($u)) {
      	$p->Set("CreatedById",$u->Get("PortalUserId"));
      }
      if(strlen($Subject))
      {
          $p->Set("Subject",$Subject);
      }
      $p->Create();


      $this->Increment("Posts");
      $this->Set(array("Modified", "ModifiedById"), array(adodb_mktime(), $objSession->Get("PortalUserId")));
      $this->Set("LastPostId",$p->Get("PostingId"));
      $this->Set("LastPostDate",$p->Get("CreatedOn"));
      $this->Update();

      $this->UpdateCategoryPostCount();
      if($this->Get("NotifyOwnerOnChanges"))
      {
          $this->SendUserEventMail("POST.ADD",$this->Get("OwnerId"));
      }

      if (is_object($u)) {
	      $this->SendUserEventMail("POST.ADD",$u->Get("PortalUserId"));
      }
      $this->SendAdminEventMail("POST.ADD");

      $CategoryId = $this->Get("CategoryId");
      if(!is_numeric($CategoryId))
         $CategoryId = $objCatList->CurrentCategoryID();

      return $p;
   }

   function GetLastPostId()
   {

       $sql = "SELECT PostingId FROM ".GetTablePrefix()."Posting WHERE TopicId=".$this->Get("TopicId");
       $sql .= " ORDER BY CreatedOn DESC LIMIT 1";
       $rs = $this->adodbConnection->Execute($sql);
       if($rs && !$rs->EOF)
       {
           $ret = $rs->fields["PostingId"];
       }
       else
           $ret = 0;
       return $ret;
   }

   function CopyToNewResource($TargetCat = NULL,$NameField="")
   {
     $OldTopicId = $this->Get("TopicId");

     parent::CopyToNewResource($TargetCat,$NameField);
     $p = new clsPostingList();
     $p->TopicID = $OldTopicId;
     $sql = "SELECT * FROM ".$p->SourceTable." WHERE TopicId=$OldTopicId ";
     $p->Query_Item($sql,-1,-1);
     if($p->NumItems()>0)
     {
       foreach($p->Items as $post)
       {
          $post->Set("TopicId",$this->Get("TopicId"));
          $post->UnsetIdField();
	 	  $post->Create();
       }
       $this->Set("Posts",$p->NumItems());
     }
   }

   function SetTodayPosts($IncrementBy)
   {
		$DateNow = adodb_date('Y-m-d', adodb_mktime() );
		$LastTodayDate = $this->Get('TodayDate');
		$TodayPosts = ($DateNow == $LastTodayDate) ? $this->Get('TodayPosts') : 0;
		$TodayPosts += $IncrementBy;
		$this->Set('TodayDate', $DateNow);
		$this->Set('TodayPosts', $TodayPosts);
		$this->Update();
   }

}

class _clsTopicList extends clsCatItemList {
   //var $Page;
   var $CategoryID;
   var $Permissions;
  // var $PerPageVar;

	function _clsTopicList($CatID=NULL)
	{
      	  global $objSession,$bb_var_list;

          $this->clsCatItemList();
          
          $this->Prefix = 'bb';
          $this->classname="clsTopic";
          $this->SourceTable = GetTablePrefix()."Topic";
          $this->Page = $bb_var_list["tp"];
          $this->BasePermission="TOPIC";
          $this->PerPageVar = "Perpage_Topics";
          $this->PageEnvar="bb_var_list_update";
          $this->PageEnvarIndex = "tp";

	  	  $this->PerPageVarLong = "Perpage_Topics";
      	  $this->PerPageShortVar = "Perpage_Topics_Short";

      	  $this->AddSortField('Topic_SortField','Topic_SortOrder');
      	  $this->AddSortField('Topic_SortField2','Topic_SortOrder2');

      	  $this->ItemType = TYPE_TOPIC;

          if( isset($CatID) ) $this->CategoryID = $CatID;
          $this->AdminSearchFields = array('TopicText','PostedBy');
	}

	function SaveNewPage()
	{
		global $bb_var_list;
		$bb_var_list["tp"] = $this->Page;
	}

	function GetHotValue()
	{
		global $objConfig;

		$ado = &GetADODBConnection();
		$sql = "SELECT Views FROM ".GetTablePrefix()."Topic ORDER BY Views DESC LIMIT 0,".$objConfig->Get("Topic_MaxHotNumber");
		$rs = $ado->Execute($sql);

		$hot_val = 0;
		while ($rs && !$rs->EOF) {
			if ($rs->fields['Views'] > 0) {
				$hot_val = $rs->fields['Views'];
			}
			$rs->MoveNext();
		}

		return $hot_val;
	}

	function GetPopValue()
	{
    	global $PopValues,$objConfig, $objSystemCache;

    	if( isset($PopValues['topic']) && is_numeric($PopValues['topic']) )
    	{
        	return $PopValues['topic'];
    	}
    	else
    	{
        	$PopValues['topic'] = $objConfig->Get('Topic_MinPopRating');
    		/*$CachedValue = $objSystemCache->GetValue("TopicPopValue","inbulletin","");
        	if(strlen($CachedValue))
        	{
            	$PopValues["topic"] = $CachedValue;
            	return $CachedValue;
        	}
        	$ado = &GetADODBConnection();
          	$sql = "SELECT CachedRating FROM ".GetTablePrefix()."Topic  WHERE CachedVotesQty > ".(int)$objConfig->Get("Topic_MinPopVotes")." ORDER BY CachedRating DESC,CachedVotesQty DESC LIMIT 0,".(int)$objConfig->Get("Topic_MinPopRating");

        	$rs = $ado->Execute($sql);
        	$PopValues["topic"] = 0;
        	while($rs && !$rs->EOF)
        	{
            	$PopValues["topic"] = $rs->fields["Views"];
            	$rs->MoveNext();
        	}*/
        	$objSystemCache->EditCacheItem('TopicPopValue',$PopValues['topic'],'inbulletin',adodb_mktime()+3600,'');
        	return $PopValues['topic'];
    	}
	}


    function HasPermission($PermissionName)
    {
        global $objSession,$objCatList;

        if($this->CategoryID==0)
        {
            $this->CategoryID=$objCatList->CurrentCategoryID();
        }
        $cat =& $objCatList->GetCategory($this->CategoryID);
        if(is_object($cat))
        {
          return ($cat->HasPermission($PermissionName,$objSession->Get("GroupId")));
        }
        else
            return FALSE;
    }

    function &Add_Topic($TopicText, $CategoryId, $Status, $Pick, $OwnerNotify,$CreatedOn, $UserID = null, $add_fields = null, $auto_filename = 1, $filename = '')
    {
    	// $add_fields - additional fields
        global $objSession,$objUsers;

        $t = new clsTopic(NULL);
//        $filename = $t->StripDisallowed($filename);

        $t->tablename = $this->SourceTable;
        $u = $objUsers->GetItem( isset($UserID) ? $UserID : $objSession->Get("PortalUserId") );
	    $t->Set(array("TopicText", "OwnerId", "TopicType","Status","PostedBy","EditorsPick",
                      "NotifyOwnerOnChanges","CreatedOn", 'AutomaticFilename'),
                array(str_replace("env=".$objSession->GetSessionKey(), "env=",$TopicText), $u->Get("PortalUserId"), 1,$Status,$u->Get("Login"),$Pick,
                      $OwnerNotify, $CreatedOn, $auto_filename));

        if( isset($add_fields) )
        	foreach($add_fields	as $field => $value)
        		$t->Set($field, $value);

  	    $t->Create();
        $t->AddToCategory($CategoryId);
        $t->SendUserEventMail("TOPIC.ADD",$u->Get("PortalUserId"));
        $t->SendAdminEventMail("TOPIC.ADD");
        return $t;
    }

    function LockTopic($TopicId)
    {
    	$p = $this->GetItem($TopicId);
    	$p->Set("TopicType", 0);
    	$p->Update();

    	return $p;
    }

    function &Edit_Topic($TopicId,$TopicSubject,$User,$Status,$Pick, $New,$Hot,$Pop,
                        $OwnerNotify,$CreatedOn,$ModifiedOn, $Rating, $Votes, $Views, $Priority=0,$PostedBy="",
                        $IsLocked = 0, $auto_filename = 1, $filename = '')
    {
    	global $objUsers, $objSession;
        $p = $this->GetItem($TopicId);
//        $filename = $p->StripDisallowed($filename);

        if(!strlen($PostedBy))
        {
        	$PostedByUser = $objUsers->GetUser($User);
        	if(is_object($PostedByUser))
        	{
        		$PostedBy = $PostedByUser->Get("Login");
        	}
        	else
        	{
        		if($User==-1)
        		{
        			$PostedBy="Admin";
        		}
        		else
        		  $PostedBy="";
        	}
        }
        if ($IsLocked == 1) {
        	$TopicType = 0;
        }
        else {
        	$TopicType = 1;
        }

        $p->Set(array("TopicText","ModifiedById","Status", "EditorsPick","NewItem","HotItem","PopItem",
                      "NotifyOwnerOnChanges","CreatedOn","Modified", "CachedRating","CachedVotesQty",
                      "Views","Priority","PostedBy", "TopicType", 'AutomaticFilename'),
                array(str_replace("env=".$objSession->GetSessionKey(), "env=", $TopicSubject),$User,$Status,$Pick,$New,$Hot,$Pop,
                      $OwnerNotify,$CreatedOn,$ModifiedOn,$Rating,$Votes,$Views, $Priority,$PostedBy, $TopicType, $auto_filename));
        $p->Update();
        if($p->Get("NotifyOwnerOnChanges"))
        {
            $p->SendUserEventMail("TOPIC.MODIFY",$p->Get("OwnerId"));
        }
        $p->SendAdminEventMail("TOPIC.MODIFY");
        return $p;
    }


    function PasteFromClipboard($TargetCat)
    {
      global $objSession,$objCatList, $objPostingList;

      $clip = $objSession->GetVariable("ClipBoard");
      if(strlen($clip))
      {
          $ClipBoard = ParseClipboard($clip);
          $IsCopy = (substr($ClipBoard["command"],0,4)=="COPY") || ($ClipBoard["source"] == $TargetCat);

          $item_ids = explode(",",$ClipBoard["ids"]);
          for($i=0;$i<count($item_ids);$i++)
          {
              $item = $this->GetItem($item_ids[$i]);
              if(!$IsCopy)
              {
                  $item->MoveToCategory($ClipBoard["source"],$TargetCat);
                  $clip = str_replace("CUT","COPY",$clip);
                  $objSession->SetVariable("ClipBoard",$clip);
              }
              else
              {
                if($ClipBoard["source"]==$TargetCat)
                {
                    $item->CopyToNewResource($TargetCat,"TopicText");
                    $item->AddToCategory($TargetCat);

                }
                else
                {
                  $CatCount = $item->CategoryMemberCount();
                  if($CatCount==0)
                  {
                    $item->AddToCategory($TargetCat);
                  }
                  else
                  {
                    $item->CopyToNewResource($TargetCat,"TopicText");
                    $item->AddToCategory($TargetCat);
                  }
                }
              }
          }
      }
    }

    function CountPending()
    {
        return TableCount($this->SourceTable,"Status=".STATUS_PENDING,0);
    }

    function LoadTopics($where="",$orderBy = "", $JoinCats=TRUE,$SkipClear=FALSE,$fix_method = 'set_first')
    {
        global $objConfig;

        if(!$SkipClear)
            $this->Clear();

        $limit = $this->GetPageLimitSQL();

		$this->QueryItemCount=TableCount($this->SourceTable,$where,$JoinCats);

       return $this->Query_Topic($where,$orderBy,$limit, $JoinCats, $fix_method);
    }

    function Query_Topic($whereClause,$orderByClause=NULL,$limit=NULL, $JoinCats=TRUE, $fix_method = 'set_first')
    {
	  global $objSession, $Errors;

      if($JoinCats)
      {
        $sql = "SELECT * FROM ".$this->SourceTable." INNER JOIN ".GetTablePrefix()."CategoryItems ON ".GetTablePrefix()."CategoryItems.ItemResourceId=".
               $this->SourceTable.".ResourceId";
      }
      else
      {
          $sql = "SELECT * FROM ".$this->SourceTable;
      }

      if(isset($whereClause))
          $sql = sprintf('%s WHERE %s',$sql,$whereClause);
      if(isset($orderByClause) && strlen(trim($orderByClause))>0)
      {
      	$sql .= " ".$orderByClause;
      }

      if($objSession->HasSystemPermission("DEBUG.LIST"))
          echo htmlentities($sql,ENT_NOQUOTES)."<br>\n";

      return $this->Query_Item($sql,null, $fix_method);
    }

    function &GetCurrentTopic()
    {
        global $bb_var_list;

        $t =& $this->GetItem($bb_var_list["top"]);
        return $t;
    }

    function CurrentTopicID()
    {
        global $bb_var_list;

        return $bb_var_list["top"];
    }

    function LoadTopicsCategory($attribs)
    {
    	global $objCatList, $objSession, $objConfig, $objPermissions;

    	$OrderBy ='';
    	$CatId = $attribs['_catid'];
    	if(!is_numeric($CatId))
    	$CatId = $objCatList->CurrentCategoryID();

    	if(!$CatId && (int)$attribs['_useroot'])
    	$CatId = (int)$objConfig->Get('Topic_Root');

    	$this->CategoryID=$CatId;
    	$this->Clear();

    	$limit = $this->GetPageLimitSQL();

    	if($objSession->HasCatPermission('TOPIC.VIEW',$CatId))
    	{
    		$sort_field = trim( $objSession->GetPersistantVariable('Topic_SortField') );
    		if( !strlen($sort_field) ) $sort_field = trim($objConfig->Get('Topic_SortField'));

    		if($sort_field)
    		{
    			$OrderBy = 'Priority DESC, '.$sort_field.' '.
    			$objSession->GetPersistantVariable('Topic_SortOrder');
    		}
    		else
    		$OrderBy = 'Priority DESC';

    		$pre = GetTablePrefix();
    		$s = $this->SourceTable;
    		$sql = 'SELECT '.$s.'.*,lp.PosterAlias as LastPoster,lp.CreatedOn as PLastPostDate FROM '.$s.' INNER JOIN '.$pre.'CategoryItems ON ('.$pre.'CategoryItems.ItemResourceId='.$s.'.ResourceId) ';
    		$sql .= ' LEFT JOIN '.$pre.'Posting as lp ON (lp.PostingId='.$s.'.LastPostId) WHERE ';

    		$where = 'CategoryId = '.$CatId.' AND '.$s.'.Status = 1 ';

    		$sql .= $where;
    		$this->QueryItemCount=QueryCount($sql);

    		if (($sort_field != 'LastPoster') &&  ($sort_field != 'LastPostDate')) {
    			$use_table = TRUE;
    		}
    		else {
    			$use_table = FALSE;
    		}
    		//echo "$sort_field: $use_table<br>";
    		$OrderBy = $this->QueryOrderByClause(TRUE, TRUE, $use_table);
    		$sql .= " ".$OrderBy;
    		//echo '<b>TopicList SQL</b>: '.$sql.'<br>';

    		return $this->Query_Item($sql);
    	}
    }

    function CategoryCount($attribs=array())
    {
    	global $objItemTypes;

    	if(is_numeric($attribs["_itemtype"]))
    	{
    		$item = $objItemTypes->GetItem($attribs["_itemtype"]);
    	}
    	else
    		$item = $objItemTypes->GetTypeByName($attribs["_itemtype"]);

    	if($item->Get("ItemType") != 30)
    	{
    		return parent::CategoryCount($attribs);
    	}
    	else
    	{
    		global $objPostingList;

    		return $objPostingList->CategoryCount($attribs);
    	}
    }

    function SqlGlobalCount($attribs=array())
    {
  	   	global $objSession, $objItemTypes,$objPermissions, $objCatList;

  	   	//$old_cat=$objCatList->CurrentCategoryID()

    	if(is_numeric($attribs['_itemtype']))
    	{
    		$item = $objItemTypes->GetItem($attribs['_itemtype']);
    	}
    	else
    	{
    		$item = $objItemTypes->GetTypeByName($attribs['_itemtype']);
    	}

    	$t = $this->SourceTable;
    	$acl = $objSession->GetACLClause();
    	$cattable = GetTablePrefix().'CategoryItems';
    	$CategoryTable = GetTablePrefix().'Category';
    	$ptable = GetTablePrefix().'PermCache';
    	$VIEW = $objPermissions->GetPermId('TOPIC.VIEW');

    	$where = '';
    	$today = adodb_mktime(0,0,0,adodb_date('m'),adodb_date('d'),adodb_date('Y'));

    	if($item->Get('ItemType') == $this->ItemType)
    	{
 			// count topics in current category & it's subcategories

 			if($attribs['_today'])
 			{
 				$where = 'AND ('.$t.'.CreatedOn >= '.$today.')';
 			}
 			$sql = "SELECT count(*) as CacheVal FROM $t
    				INNER JOIN $cattable ON ($cattable.ItemResourceId=$t.ResourceId)
    				INNER JOIN $CategoryTable ON ($CategoryTable.CategoryId=$cattable.CategoryId)
    				INNER JOIN $ptable ON ($cattable.CategoryId=$ptable.CategoryId)
    				WHERE	($acl AND PermId=$VIEW AND $cattable.PrimaryCat=1 AND $CategoryTable.Status=1) AND
    						FIND_IN_SET(".$objCatList->CurrentCategoryID().", REPlACE(ParentPath,'|',',')) $where";
    		return $sql;

    	}
    	elseif($item->Get('ItemType') == 30)
    	{
    		// counting post here
  			if (getArrayValue($attribs, '_today'))
 			{
 				$where = 'AND ('.$t.'. TodayDate = \''.adodb_date('Y-m-d', $today).'\')';
 				$CountField = 'TodayPosts';
 			}
 			else
 			{
 				$CountField = 'Posts';
 			}

    		$sql = "SELECT SUM($CountField) as CachedVal FROM $t ";
  			$sql .="INNER JOIN $cattable ON ($cattable.ItemResourceId=$t.ResourceId) ";
    		$sql .="INNER JOIN $CategoryTable ON ($CategoryTable.CategoryId=$cattable.CategoryId) ";
    		$sql .="INNER JOIN $ptable ON ($cattable.CategoryId=$ptable.CategoryId) ";
    		$sql .="WHERE ($acl AND PermId=$VIEW AND $cattable.PrimaryCat=1 AND $CategoryTable.Status=1) ";
    		$sql .=" AND ($t.Status=1) AND FIND_IN_SET(".$objCatList->CurrentCategoryID().", REPlACE(ParentPath,'|',',')) $where";
    		//echo "Posts count sql: $sql<br>";
    		return $sql;
    	}
    }

    function DoGlobalCount($attribs)
    {
    	global $objItemTypes;

    	if(is_numeric($attribs["_itemtype"]))
    	{
    		$item = $objItemTypes->GetItem($attribs["_itemtype"]);
    	}
    	else
    		$item = $objItemTypes->GetTypeByName($attribs["_itemtype"]);

    	// ItemType: 30 - Posts, 3 - Topics

    	if($item->Get("ItemType") != 30)
    	{
    		return parent::DoGlobalCount($attribs);
    	}
    	else
    	{
    		global $objPostingList;
    		//echo "PostsCount: ".$objPostingList->DoGlobalCount($attribs)."<br>";
    		return $objPostingList->DoGlobalCount($attribs);
    	}
    }

    function CacheListExtraId($ListType)
    {
    	if( !strlen($ListType) ) $ListType = '_';
    	switch($ListType)
    	{
    		case '_':
    			global $objCatList;
    			return $objCatList->CurrentCategoryID();
    			break;

    		default:
    			return parent::CacheListExtraId($ListType);
    			break;
    	}
    	return $ExtraId;
    }

    function SqlMyItems($attribs=array())
    {
        global $objSession;

        if(getArrayValue($attribs,'_shortlist'))
        {
            $this->PerPageVar = $this->PerPageShortVar;
        }
        else
          $this->PerPageVar = $this->PerPageVarLong;

		$TableName = $this->SourceTable;
 		$where =  " ".$TableName.".Status>0 AND ".$TableName.".OwnerId=".$objSession->Get("PortalUserId");
        if(getArrayValue($attribs,'_today'))
        {
   	  		$today = adodb_mktime(0,0,0,adodb_date("m"),adodb_date("d"),adodb_date("Y"));
   	  		$where .= " AND ($TableName.CreatedOn>=$today)";
        }
 		$CategoryTable = GetTablePrefix()."Category";
 		$sql = "SELECT $TableName.*,$CategoryTable.CategoryId,$CategoryTable.CachedNavBar FROM $TableName ";
 	    $p = $this->BasePermission.".VIEW";
 	    $sql .= $this->GetJoinedSQL($p,null,$where); // maybe null will be CategoryId someday

 	    $OrderBy = $this->QueryOrderByClause(TRUE,TRUE,TRUE);
        $sql .= " ".$OrderBy;

        return $sql;
    }

    function ResetCache($CategoryId)
    {
    	global $objCountCache;
    	$db =& GetADODBConnection();
    	$sql = 'SELECT ParentPath FROM '.GetTablePrefix().'Category WHERE CategoryId = '.$CategoryId;
    	$parents = $db->GetOne($sql);
    	$parents = substr($parents,1,strlen($parents)-2);
    	$parents = explode('|',$parents);
    	foreach($parents as $ParentCategoryId)
    	{
    		$objCountCache->DeleteValue('_', TYPE_TOPIC, $ParentCategoryId, 0);	// total topic count
    		$objCountCache->DeleteValue('_', TYPE_TOPIC, $ParentCategoryId, 1);	// total
    	}
    }

} /*clsTopicList*/


?>