<?/*
Copyright (C) 2003 Media Net Link, Inc. Danville, CA 94526 USA

This file is part of AthenaRMS.

AthenaRMS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

AthenaRMS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/?>
<?php
require_once 'base_object.php';
require_once 'blob.php';

function shrink_url ($matches) {
  $url = $matches[1];
  $rest = $matches[2];

  if (preg_match('/(\.|,)$/',$url,$ends)) {
    $url = substr($url,0,-1);
    $rest = $ends[1].$rest;
  }

  $length = strlen( $url ); 
          
  if ($length > 54) {
    $pretty_url = substr($url,0,25).'...'.substr($url,($length-25));
  } else {
    $pretty_url = $url;
  }

  return "<a href=\"$url\" target=\"_blank\">$pretty_url</a>$rest";
}

class Comment extends Base_Object {

  function Comment () {
    global $dbi;
    global $adodb;
    $this->db = &$dbi;
    $this->adodb = &$adodb;

    $this->error = "";
  }

  function Count_by_Ticket_ID ($tid) {
    $h = $this->db->prepare('
      select count(*)
        from comments
       where ticket_id = ?
    ');
    $res = $this->db->execute($h, array($tid));

    if (DB::isError($res)) {
      $this->error = $res->getMessage();
      return;
    }

    $r = $res->fetchRow();
    return $r[0];
  }

  function Delete ($cid) {
    $h = $this->db->prepare('
      delete from comments
            where comment_id = ?
    ');
    $res = $this->db->execute($h, array($cid));

    if (DB::isError($res)) {
      $this->error = $res->getMessage();
      return 0;
    }

    return 1;
  }

  ## NOTUSED
  function Delete_by_Ticket_ID ($tid, $crm_id='') {
    return 0;
  }

  function Add ($in_ary) {
    $save = array();
    foreach ($in_ary as $k => $v) {
      $save[strtoupper($k)] = $v;
    }

    if (!array_key_exists('COMMENT_ID', $save))
      $save['COMMENT_ID'] = $this->db->nextId('comments_comment_id');

    $save['INTERNAL'] = array_key_exists('INTERNAL', $save)
		      ? (string) $save['INTERNAL']
		      : '';

    if ($save['INTERNAL'] != 'Y') $save['INTERNAL'] = 'N';

    $this->Set_Audit_Info ($save);

    $to_date = to_date();
    $sql = "
      insert into comments (
        comment_id,
        ticket_id,
        person_id,
        comments,
        updated_by,
        updated_date,
        created_by,
        created_date,
        internal
      ) values (
        ?, ?, ?, ?, ?,
        $to_date,
	?,
        $to_date,
        ?
      )
    ";

    $h = $this->db->prepare($sql);

    $args = array(
	$save['COMMENT_ID'],
	$save['TICKET_ID'],
	$save['PERSON_ID'],
	$save['COMMENTS'],
	$save['UPDATED_BY'],
	$save['UPDATED_DATE'],
	$save['CREATED_BY'],
	$save['CREATED_DATE'],
	$save['INTERNAL']
    );

    $res = $this->db->execute ($h, $args);

    if (DB::isError($res)) {
      $this->error = $res->getMessage();
      return 0;
    }

    return $save['COMMENT_ID'];
  }

  function Info_by_Comment_ID ($cid) {
    $record = new Comment_Record ();

    $record->Select_by_Comment_ID ($cid);

    return $record;
  }

  function Update () {
    $this->Set_Audit_Info ($this);

    $to_date = to_date();
    $h = $this->db->prepare("
      update comments
         set comments = ?,
             person_id = ?,
             updated_by = ?,
             updated_date = $to_date,
             ticket_id = ?,
             internal = ?
       where comment_id = ?
    ");
    $res = $this->db->execute ($h,
      array(
	$this->comments,
	$this->person_id,
	$this->updated_by,
	$this->updated_date,
	$this->ticket_id,
	$this->internal,
	$this->comment_id
      )
    );

    if (DB::isError($res)) {
      $this->error = $res->getMessage();
      return 0;
    }
    return 1;
  }

  ##
  ## Saves object state in case we need to rollback an update.
  ##
  function SaveState() {
    $this->state = array(
	'comments' => $this->comments,
	'person_id' => $this->person_id,
	'updated_by' => $this->updated_by,
	'ticket_id' => $this->ticket_id,
	'internal' => $this->internal,
	'comment_id' => $this->comment_id
    );
  }

  ##
  ## Restores object state when we want to rollback an update.
  ##
  function RestoreState() {
    foreach ($this->state as $k => $v){ 
      $this->$k = $v;
    }
  }

  function Valid_Attachment_for_Ticket ($attach_id, $ticket_id) {
    $h = $this->db->prepare("
      select count(*)
        from comment_attachments ca,
             comments c,
             ticket t
       where ca.attachment_id = ?
	 and ca.active = 'Y'
         and t.ticket_id = ?
         and ca.comment_id = c.comment_id
         and c.ticket_id = t.ticket_id
    ");

    $res = $this->db->execute($h, array($attach_id, $ticket_id));

    if (DB::isError($res)) {
      $this->error = $res->getMessage();
      return 0;
    }

    $r = $res->fetchRow();
    return $r[0];
  }

  function Delete_Attachment ($attach_id) {
    $a = $this->Get_Attachment_Info ($attach_id);

    ##
    ## Let's not delete LOBs just yet.  Deleting an attachment no longer
    ## involves removing the row from the table -- we just instead set
    ## its status to inactive.  Later on a script can go through and
    ## purge the inactive records as needed.
    ##
    ## This was done to solve the "how do we roll back multiple deletes
    ## when we don't have transactions" problem.
    ##
/*
    if (!$this->Delete_LOB ($a[attachment_oid])) {
	$this->error = "Comment::Delete_Attachment(): Could not delete LOB (OID=".$a[attachment_oid].")";
	return 0;
    }
*/

    return $this->Delete_Attachment_Record ($attach_id);
  }

  function Delete_Attachment_Record ($attach_id) {
    $h = $this->db->prepare("
      update comment_attachments
      set    active = 'N'
      where attachment_id = ?
    ");
    $res = $this->db->execute($h, array($attach_id));

    if (DB::isError($res)) {
      $this->error = "Comment::Delete_Attachment_Record(): ".$res->getMessage();
      return 0;
    }
    return 1;
  }

  function Undelete_Attachment_Record($attach_id) {
    $sql = "
      update comment_attachments
      set    active = 'Y'
      where  attachment_id = ?
    ";
    $res = $this->db->execute($h, array($attach_id));

    if (DB::isError($res)) {
      $this->error = "Comment::Undelete_Attachment_Record(): ".$res->getMessage();
      return 0;
    }
    return 1;
  }

  function Attachments ($cid) {
    $dfud = date_format('updated_date');
    $dfcd = date_format('created_date');
    $sql = "
      select attachment_name,
             attachment_type,
             attachment_oid,
             attachment_id,
             comment_id,
             $dfud as updated_date,
             updated_by,
             $dfcd as created_date,
             created_by
        from comment_attachments
       where comment_id = ?
       and   active = 'Y'
    order by upper(attachment_name)
    ";

    $res = $this->db->getAll($sql,array($cid),DB_FETCHMODE_ASSOC);

    if (DB::isError($res)) {
      $this->error = "Attachments: ".$res->getMessage();
      return array();
    }

    return $res;
  }


  function Get_Attachment_Info ($id) {
    $h = $this->db->prepare("
      select attachment_name,
             attachment_type,
             attachment_oid,
             comment_id,
             updated_by
        from comment_attachments
       where attachment_id = ?
       and   active = 'Y'
    ");
    $res = $this->db->execute($h,array($id));

    return $res->fetchRow(DB_FETCHMODE_ASSOC);
  }

  function Save_Attachment ($cid, $name, $type, $upd_by, &$object) {
    if (!$cid or !$name or !$type or !$object) return;

    $blob = new Blob();

    if (!($oid = $blob->save($object))) {
      $this->error = 'Comment::Save_Attachment(): ' . $blob->error;
      return;
    }

    $attach_id = $this->db->nextId('attachment_id');
    $this->last_saved_attachment_id = $attach_id;

    $add = array();
    $this->Set_Audit_Info( $add );

    $to_date = to_date();
    $h = $this->db->prepare("
      insert into comment_attachments (
	attachment_id,
	comment_id,
	attachment_name,
	attachment_type,
	attachment_oid,
	updated_by,
	active,
	created_by,
	created_date,
	updated_date
      ) values (
	?, ?, ?, ?, ?, ?, ?, ?,
	$to_date,
	$to_date
      )
    ");
    $res = $this->db->execute($h, array($attach_id, $cid, $name, $type, 
      $oid, $add['UPDATED_BY'], 'Y', $add['CREATED_BY'], $add['CREATED_DATE'], 
      $add['UPDATED_DATE']));

    if (DB::isError($res)) {
      $this->error = "Comment::Save_Attachment(): ".$res->getMessage()
	. "\n" . $res->getUserInfo();
      return;
    }

    return $attach_id;
  }

  function DeleteAllAttachments($comment_id) {
    $a = $this->Attachments($comment_id);
    foreach ($a as $attachment) {
      if (!$this->Delete_Attachment($attachment['attachment_id'])) {
	return 0;
      }
    }
    return 1;
  }

  function DeleteLastSavedAttachment() {
    if (!strlen($this->last_saved_attachment_id)) {
      $this->error = "Comment::DeleteLastSavedAttachment(): No previously saved attachment for this object.";
      return 0;
    }
    return $this->Delete_Attachment($this->last_saved_attachment_id);
  }
  
  function Get_LOB ($oid) {
    $blob = new Blob();
    return $blob->get($oid);
  }

  function Delete_LOB ($oid) {
    $blob = new Blob();
    return $blob->delete($oid);
  }

  function List_By_Ticket_CRM ($tid, $crm_id='', $datefmt='') {
    if (!$crm_id) $crm_id = $this->Current_CRM ();

    $dfcd = date_format('c.created_date', $datefmt);
    $dfud = date_format('c.updated_date', $datefmt);

    $sql = "
       select c.comment_id,
              c.person_id,
              c.ticket_id,
              c.comments,
              c.internal,
              $dfcd as created_date,
              c.created_by,
              $dfud as updated_date,
              c.updated_by,
              p.last_name,
              p.first_name,
              p.middle_initial,
              p.email,
              pcm.person_id as is_in_crm,
              t.user_person_id,
              t.crm_id
         from comments c
                inner join person p
                  on (c.person_id = p.person_id)
                left outer join person_crm_map pcm
		  on (c.person_id = pcm.person_id and
		      pcm.crm_id = ?)
                inner join ticket t
                  on c.ticket_id = t.ticket_id
        where c.ticket_id = ?
     order by c.created_date
    ";

    $res =  $this->db->getAll($sql, array($crm_id, $tid), DB_FETCHMODE_ASSOC);
    if (DB::isError($res)) {
	$this->error = "Comment::List_By_Ticket_CRM(): " . $res->getMessage()
	  . "\n" . $res->getUserInfo();
	return;
    }

    ## We need to fake the coalesce(pcm.person_id, 0)
    foreach ($res as $i => $r) {
	if (!strlen($res[$i]['is_in_crm'])) $res[$i]['is_in_crm'] = 0;
    }

    return $res;
  }

  function First_User_Comments ($tid,$pid) {
    $sql = "
      select comments
        from comments
       where ticket_id = ?
         and person_id = ?
    order by created_date
    ";

    $ret = $this->db->getAll($sql, array($tid,$pid));

    if (DB::isError($ret)) {
      $this->error = 'Comment::First_User_Comments';
      return;
    }

    return $ret[0][0];
  }

  ## ret_all_fields is:
  ##   0 (just ticket_id)
  ##   1 (person & comment info)
  ##   2 (person, ticket, comment info)
  function &List_By_Ticket ($tid, $hide_internal=0, $datefmt='') {

    $binds = array ($tid);

    if ($hide_internal) {
      $internal = 'and not (c.internal = ?)';
      $binds[] = 'Y';
    }

    $dfcd = date_format('c.created_date', $datefmt);
    $dfud = date_format('c.updated_date', $datefmt);

    $sql = "
       select c.comment_id,
              c.person_id,
              c.ticket_id,
              c.comments,
              c.internal,
              $dfcd as created_date,
              c.created_by,
              $dfud as updated_date,
              c.created_date as order_create,
              c.updated_date as order_update,
              c.updated_by,
              p.last_name,
              p.first_name,
              p.middle_initial,
              p.email,
              t.user_person_id,
              t.crm_id
         from comments c
                inner join person p
                  on (c.person_id = p.person_id)
                inner join ticket t
                  on t.ticket_id = c.ticket_id
        where c.ticket_id = ?
              $internal
     order by order_create
    ";

    if (DB::isError($ret=$this->db->getAll($sql, $binds, DB_FETCHMODE_ASSOC))) {
      $this->error = 'Comment::List_By_Ticket(): ' . $ret->getMessage()
	. "\n" . $ret->getUserInfo();
      return;
    }

    return $ret;
  }

  function to_HTML ( $text ) {
    $text = htmlspecialchars ($text);

    foreach (array ("\r\n", "\n\r", "\n", "\r",) as $sub) {
      $text = str_replace ($sub, "<br />", $text);
    }

    return preg_replace_callback(
             '/(https?:\/\/\S+?)(\s|<|&gt|&lt|$)/is',
             'shrink_url',
             $text
           );  
  }
}

class Comment_Record extends Comment {
  function Comment_Record () {
    global $dbi;
    $this->db = &$dbi;

    $this->error = "";
  }

  function Select_by_Comment_ID ($cid) {
    $dfud = date_format('updated_date');
    $dfcd = date_format('created_date');

    $h = $this->db->prepare ("
      select ticket_id,
             person_id,
             comments,
             $dfud as updated_date,
             updated_by,
             $dfcd as created_date,
             created_by,
	     comment_id,
             internal
        from comments
       where comment_id = ?
    ");
    $res = $this->db->execute($h,array($cid));

    if (DB::isError($res)) {
      $this->error = $res->getMessage();
      return 0;
    }

    $r = $res->fetchRow(DB_FETCHMODE_ASSOC);

    foreach ($r as $k => $v) {
      $k = strtolower ($k);
      $this->$k = $v;
    }
  }
}
?>
