Location: PHPKode > projects > QuickTicket > quickticket/bin/qti_class_sec.php
<?php

// QuickTicket 2.5 build:20101222

class cSection extends aQTcontainer implements IOptions,IStats
{

// aQTcontainer's extra properties
public $domname;     // Domain name
public $name;        // Section name (translation of the title)
public $notify;      // Notify: 0=disable, 1=enabled
public $modid;       // Moderator id
public $modname;     // Moderaotr name
public $numfield;    // Format of the ref number: 'N' means no ref number
public $titlefield;  // Topic title: 0=None, 1=Optional, 2=Mandatory
public $wisheddate=0;// Topic wisheddate: 0=None, 1=Optional, 2=Mandatory
public $wisheddflt=0;// Topic wisheddate [2] default: 0=None, 1=Today, 2=Day+1, 3=Day+2
public $notifycc;    // Topic alternate notify: 0=None, 1=Optional, 2=Mandatory
public $prefix;      // Prefix icon from the serie 'a'
public $options='';  // Several stats (no used)
public $stats='';    // Several stats (no used)

// stats
// public $items=0;  // Total topics (including news) //already defined in aQTcontainer
public $itemsZ=0;    // Total topics closed (including news)
public $replies=0;   // Total replies (type R and F), not D
public $repliesZ=0;  // Total replies in topics closed (type R,F or  D)
public $tags=0;      // >0 means tags exists (may be several time the same!)

// options
public $d_order='';  // Teams member default sort order (not used)
public $d_last='none'; // Last column in the topic list: 'none' means no last column
public $d_logo='';   // Section picture named s_x.gif/.jpeg/.jpg/.png (where x is the section id)

// computed values
public $lastpostid;
public $lastposttopic;
public $lastpostdate;
public $lastpostuser;
public $lastpostname;

// --------

function __construct($aSection=null,$bLast=false)
{
  // Constructor accepts an id or an array as parameter

  if ( isset($aSection) )
  {
    if ( is_int($aSection) )
    {
      if ( $aSection<0 ) die('No section '.$aSection);
      global $oDB;
      $oDB->Query('SELECT * FROM '.TABSECTION.' WHERE id='.$aSection);
      $row = $oDB->Getrow();
      if ( $row===False ) die('No section '.$aSection);      
      $this->MakeFromArray($row);
    }
    elseif ( is_array($aSection) )
    {
      $this->MakeFromArray($aSection);
    }
    else
    {
      die('Invalid constructor parameter #1 for the class cSection');
    }
  }

  // Read options/stats

  $this->ReadOptions(); // initialise options properties
  $this->ReadStats();   // initialise stats properties

  // Find last post. NOTE $bLast can be an id (int) to bypass the search step and get directly the lastpost info
  
  if ( $bLast ) $this->GetSectionLastPost($bLast); 
  
  // Default sort order and last column
  
  if ( empty($this->d_order) ) $this->d_order='lastpostdate';
  if ( $this->d_last=='wisheddate' && $this->wisheddate==0 ) $this->d_last='none';
  if ( $this->d_last=='notifiedname' && $this->notifycc==0 ) $this->d_last='none';
  if ( $this->d_last=='no' || empty($this->d_last) ) $this->d_last='none';

}

// --------

private function MakeFromArray($aSection)
{
  foreach($aSection as $strKey=>$oValue) {
  switch ($strKey) {
    case 'domainid':     $this->parentid  = intval($oValue); break;
    case 'id':           $this->id        = intval($oValue); break;
    case 'title':        $this->title     = $oValue; break;
    case 'type':         $this->type      = intval($oValue); break;
    case 'status':       $this->status    = intval($oValue); break;
    case 'notify':       $this->notify    = intval($oValue); break;
    case 'moderator':    $this->modid     = intval($oValue); break;
    case 'moderatorname':$this->modname   = $oValue; break;
    case 'stats':        $this->stats     = $oValue; break;
    case 'options':      $this->options   = $oValue; break;
    case 'numfield':     $this->numfield  = $oValue; break;
    case 'titlefield':   $this->titlefield= intval($oValue); break;
    case 'wisheddate':
      $this->wisheddate = intval($oValue);
      if ( $this->wisheddate>2 ) { $this->wisheddflt=$this->wisheddate-2; $this->wisheddate=2;  }
      break;
    case 'alternate':    $this->notifycc  = intval($oValue); break;
    case 'prefix':       $this->prefix    = $oValue; break;
  }}
  $this->name = ObjTrans('sec','s'.$this->id,$this->title);
  $this->descr = ObjTrans('secdesc','s'.$this->id,false);
  $this->domname= ObjTrans('domain','d'.$this->parentid,'(domain '.$this->parentid.')');
}

// --------

public function GetSectionLastPost($intLast)
{  
  // Initialize
  
  $this->lastpostid = null;
  $this->lastposttopic = null;
  $this->lastpostdate = null;
  $this->lastpostuser = null;
  $this->lastpostname = null;
  
  // Check
  
  if ( $this->id<0 ) return null;
  if ( $this->items==0 ) return null;

  // Query - attention: Subqueries requires mysql 4.1. We use two queries
  // Search query can be bypassed by providing a $intLast
  
  global $oDB;
  
  // Search (maxid)
  
  if ( is_integer($intLast) )
  {
    $intId = $intLast;
  }
  else
  {
    $oDB->Query( 'SELECT MAX(id) as maxid FROM '.TABPOST.' WHERE forum='.$this->id );
    $row = $oDB->Getrow();
    $intId = intval($row['maxid']);
  }
  
  // Get lastpost informations

  if ( $intId>0 ) 
  {
    $oDB->Query( 'SELECT id,topic,issuedate,userid,username FROM '.TABPOST.' WHERE id='.$intId );
    if ( $row=$oDB->Getrow() )
    {
    $this->lastpostid = intval($row['id']);
    $this->lastposttopic = intval($row['topic']);
    $this->lastpostdate = $row['issuedate'];
    $this->lastpostuser = intval($row['userid']);
    $this->lastpostname = $row['username'];
    }
  }
}

// --------

public function GetLogo()
{
  if ( !empty($this->d_logo) )
  {
  if ( file_exists('upload/section/'.$this->d_logo) ) return 'upload/section/'.$this->d_logo;
  }
  return $_SESSION[QT]['skin_dir'].'/ico_section_'.$this->type.'_'.$this->status.'.gif';
}

// --------

public static function GetTagsUsed($id=-1,$intMax=50)
{
  // -1 to compute on all sections // maximum returned is $intMax distinct tags
  
  // Check

  if ( !is_int($id) ) die('cSection->GetTagsUsed: Argument #1 must be integer');

  // Process

  $arrTags = array();  
  global $oDB;
  $oDB->Query( 'SELECT DISTINCT tags FROM '.TABTOPIC.($id==-1 ? '' : ' WHERE forum='.$id) );
  $i=0;
  while($row=$oDB->Getrow()) {
  if ( !empty($row['tags']) ) {
    $arr = explode(';',$row['tags']);
    foreach($arr as $str)
    {
      if ( !empty($str) ) {
      if ( !in_array($str,$arrTags) ) {
        $arrTags[$str] = $str;
        $i++;
        if ( $i>$intMax ) break;      
      }}
    }    
    if ( $i>$intMax ) break;
  }}
  if ( count($arrTags)>2 ) asort($arrTags);
  return $arrTags;
}

// --------

public function MoveTopics($intD=0,$intRenum=1,$intTopic=-1,$bClosedOnly=false,$strYear='')
{
  if ( !is_int($intD) ) die('cSection->MoveTopics: Argument #2 must be integer');
  if ( $this->id<0 ) die('cSection->MoveTopics: Wrong argument #1 (id<0)');
  if ( $intD<0 ) die('cSection->MoveTopics: Wrong argument #2 (d<1)');
  if ( $this->id==$intD ) die('cSection->MoveTopics: Wrong argument, source=destination');
  if ( !is_string($strYear) ) $strYear = intval($strYear); // $strYear can be a integer or "old"
  if ( strlen($strYear)>4 ) die('cSection->MoveTopics: Argument #2 must be a string');

  global $oDB;

  $strWhere = (empty($strYear) ? '' : ' AND '.SqlDateCondition($strYear));
  $strTopic = '';
  $strPost = '';
  $strField = ''; if ( $intRenum==0 ) $strField = ', numid = 0';

  // Move only one topic

  if ( $intTopic>=0 )
  {
    $strTopic=" AND id=$intTopic";
    $strPost=" AND topic=$intTopic";
    if ( $intRenum==2 )
    {
    $nextnumid = $oDB->Nextid(TABTOPIC,'numid','WHERE forum='.$intD);
    $strField = ', numid='.intval($nextnumid);
    }
    $bClosedOnly=false;
  }
  else
  {
    if ( $intRenum==2 )
    {
    $nextnumid = $oDB->Nextid(TABTOPIC,'numid','WHERE forum='.$intD);
    $oDB->Query('SELECT MIN(numid) as minnumid FROM '.TABTOPIC.' WHERE forum='.$this->id);
    $row = $oDB->Getrow();
    $minnumid = $row['minnumid'];
    $strField = ", numid = $nextnumid + (numid - $minnumid)";
    }
  }

  // Check if prefix system are the same. If not, remove the prefix.

  $strSetPrefix = '';
  if ( !empty($this->prefix) )
  {
    $oDB->Query('SELECT prefix FROM '.TABSECTION.' WHERE id='.$intD);
    $row = $oDB->Getrow();
    if ( $row['prefix']!=$this->prefix ) $strSetPrefix = ',icon="00"';
  }

  // Update topics and posts

  if ( $bClosedOnly )
  {
    $arr = array();
    $oDB->Query('SELECT id FROM '.TABTOPIC.' WHERE forum='.$this->id.' AND status="Z" AND type="T"'.$strWhere);
    while($row=$oDB->Getrow()) $arr[] = intval($row['id']);
    foreach($arr as $intVal)
    {
    $oDB->Query( 'UPDATE '.TABTOPIC.' SET forum='.$intD.$strField.',modifdate="'.date('Ymd His').'" WHERE id='.$intVal );
    $oDB->Query( 'UPDATE '.TABPOST.' SET forum='.$intD.$strSetPrefix.' WHERE topic='.$intVal );
    }
  }
  else
  {
    $oDB->Query( 'UPDATE '.TABTOPIC.' SET forum='.$intD.$strField.',modifdate="'.date('Ymd His').'" WHERE forum='.$this->id.$strTopic.$strWhere );
    $oDB->Query( 'UPDATE '.TABPOST.' SET forum='.$intD.$strSetPrefix.' WHERE forum='.$this->id.$strPost.str_replace('firstpostdate','issuedate',$strWhere) );
  }

  // Update stats of this section and stats of destination section
  
  $this->UpdateStats(array('tags'=>$this->tags),true,true);
  $voidSEC = new cSection(); $voidSEC->id=$intD; $voidSEC->UpdateStats(array(),true,true);
}

// --------

public function DeleteTopics($bClosedOnly=false,$strYear='',$bUpdateStats=true)
{
  if ( $this->id<0 ) die('cSection->DeleteTopics: Wrong argument #1 (id<0)');
  if ( !is_string($strYear) ) $strYear = intval($strYear); // $strYear can be a integer or the string 'old'
  if ( strlen($strYear)>4 ) die('cSection->DeleteTopics: Argument #2 must be a string');

  // Process - delete topics and posts
  
  global $oDB;

  $strWhere = (empty($strYear) ? '' : ' AND '.SqlDateCondition($strYear));

  if ( $bClosedOnly )
  {
    $arr = array();
    $oDB->Query( 'SELECT id FROM '.TABTOPIC.' WHERE forum='.$this->id.' AND status="Z" AND type="T"'.$strWhere );
    while($row=$oDB->Getrow())
    {
      $arr[] = $row['id'];
    }
    foreach($arr as $intKey=>$id)
    {
      $oDB->Query( 'DELETE FROM '.TABPOST.' WHERE topic='.$id );
      $oDB->Query( 'DELETE FROM '.TABTOPIC.' WHERE id='.$id );
    }
  }
  else
  {
    $oDB->Query( 'DELETE FROM '.TABPOST.' WHERE forum='.$this->id.str_replace('firstpostdate','issuedate',$strWhere) );
    $oDB->Query( 'DELETE FROM '.TABTOPIC.' WHERE forum='.$this->id.$strWhere );
  }

  if ( $bUpdateStats ) $this->UpdateStats(array('tags'=>$this->tags));

}

// --------

public function UpdateLastPostDate()
{
  global $oDB;
  if ( in_array($oDB->type,array('sqlite','mssql','pg','access','db2')) )
  {
  $oDB->Query( 'UPDATE '.TABTOPIC.' SET lastpostdate=(SELECT MAX(issuedate) FROM '.TABPOST.' p, '.TABTOPIC.' t WHERE t.id=p.topic) WHERE forum='.$this->id );
  }
  else
  {
  $oDB->Query( 'UPDATE '.TABTOPIC.' t SET t.lastpostdate=(SELECT MAX(p.issuedate) FROM '.TABPOST.' p WHERE t.id=p.topic) WHERE t.forum='.$this->id );
  }
}
public function UpdateReplies()
{
  global $oDB;
  if ( in_array($oDB->type,array('sqlite','mssql','pg','access','db2')) )
  {
  $oDB->Query( 'UPDATE '.TABTOPIC.' SET replies=(SELECT COUNT(*) FROM '.TABPOST.' p, '.TABTOPIC.' t WHERE t.id=p.topic) WHERE forum='.$this->id );
  }
  else
  {
  $oDB->Query( 'UPDATE '.TABTOPIC.' t SET t.replies=(SELECT COUNT(p.id) FROM '.TABPOST.' p WHERE t.id=p.topic AND p.type<>"P") WHERE t.forum='.$this->id );
  }
}

// --------

public function UpdateStats($arrValues=array(),$bLastPostDate=false,$bReplies=false)
{
  if ( $this->id<0 ) die('UpdateSectionStats: Wrong id');

  // Process (provided values are not recomputed)
  
  if ( !isset($arrValues['topics']) )   $arrValues['topics']  = cSection::CountItems($this->id,'topics');
  if ( !isset($arrValues['replies']) )  $arrValues['replies'] = cSection::CountItems($this->id,'replies');
  if ( !isset($arrValues['tags']) )     $arrValues['tags']    = cSection::CountItems($this->id,'tags');
  if ( !isset($arrValues['topicsZ']) )  $arrValues['topicsZ'] = cSection::CountItems($this->id,'topicsZ');
  if ( !isset($arrValues['repliesZ']) ) $arrValues['repliesZ']= cSection::CountItems($this->id,'repliesZ');
  
  $this->stats = QTimplode($arrValues);
  $this->WriteStats();
  if ( $bLastPostDate ) $this->UpdateLastPostDate(); // used after import
  if ( $bReplies ) $this->UpdateReplies();  // used after import
}

// --------
// aQTcontainer implementations
// --------

public static function Create($title,$parentid)
{
  QTargs( 'cSection->Create',array($title,$parentid),array('str','int') );
  if ( empty($title) ) die('cSection->Create: Argument #1 must be a string');
  global $oDB;
  $id = $oDB->Nextid(TABSECTION);
  $oDB->Query( 'INSERT INTO '.TABSECTION.' (domainid,id,titleorder,moderator,type,status,notify,titlefield,wisheddate,alternate,title,stats,options,moderatorname,numfield,prefix) VALUES ('.$parentid.','.$id.',0,1,"0","0","0","0","0","0","'.addslashes($title).'","","coord=0;order=0;last=0;logo=0","Admin","%03s","a")' );
  // Impact on globals
  if ( isset($_SESSION[QT]['sys_sections']) ) Unset($_SESSION[QT]['sys_sections']);
  return $id;
}

public static function Drop($id)
{
  if ( $id<1 ) die('cSection->Drop: Cannot delete section 0');
  global $oDB;
  $oDB->Query('DELETE FROM '.TABSECTION.' WHERE id='.$id);
  cVIP::LangDel(array('sec','secdesc'),'s'.$id);
  // Impact on globals
  if ( isset($_SESSION[QT]['sys_sections']) ) Unset($_SESSION[QT]['sys_sections']);
}

public static function MoveItems($id,$destination)
{
  // See MoveTopics
}

public static function CountItems($id,$status,$intD=10,$strYear='')
{
  if ( !is_int($intD) ) die('cSection->Count: Argument #2 must be an int');
  if ( $id<0 ) die('cSection->Count: Wrong argument (id<0)');
  if ( $intD<1 ) die('cSection->Count: Wrong argument #2 (d<1)');
  if ( !is_string($strYear) ) $strYear = intval($strYear); // $strYear can be a integer or "old"
  if ( strlen($strYear)>4 ) die('cSection->Count: Argument #3 must be a string');

  global $oDB;
  
  $strWhere = (empty($strYear) ? '' : ' AND '.SqlDateCondition($strYear));
  
  // Process

  switch($status)
  {
  case 'topics': $oDB->Query( 'SELECT count(*) as countid FROM '.TABTOPIC.' WHERE forum='.$id.$strWhere ); break;
  case 'topicsZ': $oDB->Query( 'SELECT count(*) as countid FROM '.TABTOPIC.' WHERE status="Z" AND forum='.$id.$strWhere ); break;
  case 'news': $oDB->Query( 'SELECT count(*) as countid FROM '.TABTOPIC.' WHERE forum='.$id.' AND type="A"'.$strWhere ); break;
  case 'inspections': $oDB->Query( 'SELECT count(*) as countid FROM '.TABTOPIC.' WHERE forum='.$id.' AND type="I"'.$strWhere ); break;
  case 'replies': $oDB->Query( 'SELECT count(*) as countid FROM '.TABPOST.' WHERE forum='.$id.' AND (type="R" OR type="F")'.str_replace('firstpostdate','issuedate',$strWhere) ); break;
  case 'repliesZ': $oDB->Query( 'SELECT count(*) as countid FROM '.TABPOST.' p INNER JOIN '.TABTOPIC.' t ON p.topic=t.id WHERE p.forum='.$id.' AND p.type<>"P" AND t.status="Z"'.$strWhere ); break;
  case 'unreplied': $oDB->Query( 'SELECT count(*) as countid FROM '.TABTOPIC.' WHERE forum='.$id.' AND replies=0 AND firstpostdate<"'.DateAdd(date('Ymd His'),-$intD,'day').'"'.$strWhere ); break;
  case 'unrepliedT': $oDB->Query( 'SELECT count(id) as countid FROM '.TABTOPIC.' WHERE forum='.$id.' AND type="T" AND replies=0 AND firstpostdate<"'.DateAdd(date('Ymd His'),-$intD,'day').'"'.$strWhere ); break;
  case 'unrepliedA': $oDB->Query( 'SELECT count(id) as countid FROM '.TABTOPIC.' WHERE forum='.$id.' AND type="A" AND replies=0 AND firstpostdate<"'.DateAdd(date('Ymd His'),-$intD,'day').'"'.$strWhere ); break;
  case 'unrepliedI': $oDB->Query( 'SELECT count(id) as countid FROM '.TABTOPIC.' WHERE forum='.$id.' AND type="I" AND replies=0 AND firstpostdate<"'.DateAdd(date('Ymd His'),-$intD,'day').'"'.$strWhere ); break;
  case 'tags': $oDB->Query( 'SELECT count(*) as countid FROM '.TABTOPIC.' WHERE tags<>"" AND forum='.$id.$strWhere ); break;
  case 'messages': $oDB->Query( 'SELECT count(*) as countid FROM '.TABPOST.' WHERE forum='.$id.$strWhere ); break;
  case 'unrepliednews': $oDB->Query( 'SELECT count(id) as countid FROM '.TABTOPIC.' WHERE forum='.$id.' AND type="A" AND replies=0 AND firstpostdate<"'.DateAdd(date('Ymd His'),-$intD,'day').'"'.$strWhere ); break; // (unrepliedA) stays for backbward compatibility
  default: die('cSection->Count: Wrong argument #1 '.$strObject);
  }
  $row = $oDB->Getrow();
  return intval($row['countid']);
}

// --------
// IOptions, IStats implementations
// --------

public function ChangeOption($strKey,$strValue)
{
  QTargs('cSection->ChangeOption',array($strKey,$strValue));
  if ( $strKey==='' ) die ('cSection->ChangeOption: Missing key'); // $strKey can be ''

  $arr = QTarradd(QTexplode($this->options),$strKey,$strValue);
  $this->options = QTimplode($arr);
  $this->WriteOptions();
  return $arr;
}

public function ReadOptions()
{
  $arr = QTexplode($this->options);
  if ( isset($arr['order']) ) $this->d_order = $arr['order'];
  if ( isset($arr['last']) ) $this->d_last = $arr['last'];
  if ( isset($arr['logo']) ) $this->d_logo = $arr['logo']; 
  return $arr;
}

public function WriteOptions()
{
  global $oDB;
  $oDB->Query('UPDATE '.TABSECTION.' SET options="'.$this->options.'" WHERE id='.$this->id);
}

public function ChangeStat($strKey,$strValue)
{
  QTargs('cSection->ChangeStat',array($strKey,$strValue));
  if ( $strKey==='' ) die ('cSection->ChangeStat: Missing key'); // $strKey can be ''

  $arr = QTarradd(QTexplode($this->stats),$strKey,$strValue);
  $this->stats = QTimplode($arr);
  $this->WriteOptions();
  return $arr;
}

public function ReadStats()
{
  $arr = QTexplode($this->stats);
  if ( isset($arr['topics']) ) $this->items = intval($arr['topics']);
  if ( isset($arr['replies']) ) $this->replies = intval($arr['replies']);
  if ( isset($arr['tags']) ) $this->tags = intval($arr['tags']);
  if ( isset($arr['topicsZ']) ) $this->itemsZ = intval($arr['topicsZ']);
  if ( isset($arr['repliesZ']) ) $this->repliesZ = intval($arr['repliesZ']);
  return $arr;
}

public function WriteStats()
{
  global $oDB;
  $oDB->Query('UPDATE '.TABSECTION.' SET stats="'.$this->stats.'" WHERE id='.$this->id);
}

// --------

}
Return current item: QuickTicket