<?PHP
#
#   FILE:  Topic.php
#
#   FUNCTIONS PROVIDED:
#       Topic->Topic($TopicId)
#           - constructor
#       Topic->TopicId()
#       Topic->ForumId()
#       Topic->CreatorId()
#       Topic->DateCreated()
#       Topic->TopicName()
#       Topic->ViewCount()
#       Topic->MessageCount()
#       Topic->Delete()
#           - methods to retrieve resource attributes
#
#   Copyright 2011 Internet Scout Project
#   http://scout.wisc.edu/
#

/**
 * Abstraction for topics within a Forum
 * \nosubgrouping
 */

class Topic {

    # ---- PUBLIC INTERFACE --------------------------------------------------


    # Error codes for the TOPIC
    const OK = 0;
    const NONEXISTENT = 1;

    /** @name Setup/Initialization/Destruction */
    /*@{*/

    /**
     * Object Constructor.
     * After constructing the object, be sure to call GetErrorStatus()
     * and verify that it returns Topic::OK
     * @param TopicId The Id desired from the database, or -1 to genreate
     *    a new topic
     */
    function Topic($TopicId = NULL )
    {
        $this->ErrorStatus = Topic::OK;
        # locate class in database
        $this->DB = new Database();
        $DB = $this->DB;
        # if ID supplied
        if ($TopicId !== NULL)
        {
            $this->TopicId = intval($TopicId);
            $DB->Query("SELECT * FROM Topics WHERE TopicId = ".$this->TopicId);

            # if row was loaded
            if ($DB->NumRowsSelected() > 0)
            {
                # set attributes to values returned by database
                $this->DBFields = $DB->FetchRow();
            }
            else
            {
                $this->ErrorStatus = Topic::NONEXISTENT;
            }
        }
        elseif (func_num_args()==0)
        {
            # add record to database with that ID
            $DB->Query("INSERT INTO Topics (TopicId) VALUES (NULL)");
            $this->TopicId = $DB->Query("SELECT LAST_INSERT_ID()"
                    ." AS TopicId FROM Topics", "TopicId");
        }
        else
        {
            $this->ErrorStatus = Topic::NONEXISTENT;
        }
    }

    /**
     * Remove this topic from the database, deleting the underlying messages
     */
    function Delete()
    {
        if ($this->ErrorStatus == Topic::OK)
        {
            # decrement the topic count for the parent forum
            $Forum = new Forum($this->ForumId());
            $Forum->TopicCount($Forum->TopicCount() - 1);

            $this->DB->Query("Select * from Messages where ParentId = ".
                             $this->TopicId." AND ParentType = 1");

            # delete messages associated with this topic
            while ($Entry = $this->DB->FetchRow())
            {
                $Message = new Message($Entry["MessageId"]);
                $Message->Delete();
            }
            $this->DB->Query("DELETE FROM Topics WHERE TopicId=".$this->TopicId);
        }
    }

    /*@}*/

    /** @name Accessors */
    /*@{*/

    /**
     * Get a list of messages in this topic
     * @return An array of Message objects, indexed by message Id
     */
    function GetMessageList()
    {
        $Messages = array();

        # query for messages associated with this topic
        $this->DB->Query("
            SELECT * FROM Messages
            WHERE ParentId = '".addslashes($this->TopicId)."'
            AND ParentType = '1'
            ORDER BY DatePosted ASC");

        # create Message objects from the results
        while (FALSE !== ($Row = $this->DB->FetchRow()))
        {
            $Messages[$Row["MessageId"]] = new Message($Row["MessageId"]);
        }

        return $Messages;
    }

    /**
     * Get the Id of this topic
     * @return Id of this topic
     */
    function TopicId()        {  return $this->TopicId;  }

    /**
     * Get the CWIS name of the user who created this topic
     * @return CWIS name of the user who created this topic
     */
    function CreatorName()
    {
        $CreatorName = new User($this->DB, (int)$this->CreatorId());
        return $CreatorName->Get("UserName");
    }

    /**
     * Get the email address of the user who created this topic
     * @return Email address of the user who created this topic
     */
    function CreatorEmail()
    {
        $CreatorName = new User($this->DB, (int)$this->CreatorId());
        return $CreatorName->Get("EMail");
    }

    /**
     * Set or modify the forum with which this topic is associated
     * @param NewValue (OPTIONAL)
     * @return The current ForumId
     */
    function ForumId($NewValue = DB_NOVALUE) {  return $this->UpdateValue("ForumId", $NewValue);  }

    /**
     * Get or Set the creator of this topic
     * @param NewValue (OPTIONAL)
     * @return The current CreatorId
     */
    function CreatorId($NewValue = DB_NOVALUE) {  return $this->UpdateValue("CreatorId", $NewValue);  }

    /**
     * Get or set set the creation date of this topic
     * @param NewValue (OPTIONAL)
     * @return The current creation date
     */
    function DateCreated($NewValue = DB_NOVALUE) {  return $this->UpdateValue("DateCreated", $NewValue);  }

    /**
     * Get or modify the name of this topic
     * @param NewValue (OPTIONAL)
     * @return The current name of this topic
     */
    function TopicName($NewValue = DB_NOVALUE) {  return $this->UpdateValue("TopicName", $NewValue);  }

    /**
     * Get or set the viewcount for this topic
     * @param NewValue (OPTIONAL)
     * @return The current viewcount
     */
    function ViewCount($NewValue = DB_NOVALUE) {  return $this->UpdateValue("ViewCount", $NewValue);  }

    /**
     * Get or set the messagecount for this topic
     * @param NewValue (OPTIONAL)
     * @return The current message count
     */
    function MessageCount($NewValue = DB_NOVALUE) {  return $this->UpdateValue("MessageCount", $NewValue);  }

    /**
     * Retrieve the error status
     * @return Topic::OK if everything worked, something else otherwise
     */
    function GetErrorStatus() { return $this->ErrorStatus; }

    /*@}*/

    # ---- PRIVATE INTERFACE -------------------------------------------------

    private $TopicId;
    private $DB;
    private $DBFields;
    private $ErrorStatus;

    # convenience function to supply parameters to Database->UpdateValue()
    private function UpdateValue($FieldName, $NewValue)
    {
        if ($this->ErrorStatus == Topic::OK)
        {
            return $this->DB->UpdateValue("Topics", $FieldName, $NewValue,
                                          "TopicId = '".$this->TopicId."'", $this->DBFields, TRUE);
        }
        else
        {
            return NULL;
        }
    }
}

?>
