<?PHP
#
#   FILE:  Message.php
#
#   Part of the Collection Workflow Integration System (CWIS)
#   Copyright 2012-2013 Edward Almasy and Internet Scout Research Group
#   http://scout.wisc.edu/cwis
#

/**
 * Abstraction for forum messages and resource comments
 * \nosubgrouping
 */

class Message {

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

    const OK = 0;
    const NONEXISTENT = 1;

    const PARENTTYPE_TOPIC = 1;
    const PARENTTYPE_RESOURCE = 2;

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

    /**
     * Object constructor.
     * After constructing the object, be sure to call GetErrorStatus() and verify
     * that it returns Message::OK.
     * @param int $MessageId The message Id to retrieve from the database, or
     *   -1 to create a new message
     */
    function Message($MessageId = NULL)
    {
        $this->ErrorStatus = self::NONEXISTENT;
        $this->DB = new Database();

        # no ID supplied
        if (is_null($MessageId))
        {
            # add record to database with that ID
            $this->DB->Query("INSERT INTO Messages (MessageId) VALUES (NULL)");
            $this->DB->Query("SELECT LAST_INSERT_ID() AS Id FROM Messages");

            if ($this->DB->NumRowsSelected())
            {
                $this->MessageId = intval($this->DB->FetchField("Id"));
                $this->ErrorStatus = self::OK;
            }
        }

        # ID supplied
        else
        {
            $this->DB->Query("
                SELECT * FROM Messages
                WHERE MessageId = '".intval($MessageId)."'");

            if ($this->DB->NumRowsSelected())
            {
                # set attributes to values returned by database
                $this->DBFields = $this->DB->FetchRow();
                $this->MessageId = intval($this->DBFields["MessageId"]);
                $this->ErrorStatus = Message::OK;
            }
        }
    }

    /**
     * Delete this message from the underlying database
     */
    function Delete()
    {
        if ($this->ErrorStatus == Message::OK)
        {
            $this->DB->Query("DELETE FROM Messages WHERE MessageId = ".$this->MessageId);
        }
    }

    /*@}*/

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

    /**
     * Get this message's messageId
     * @return MessageId
     */
    function MessageId()    {  return $this->MessageId;  }

    /**
     * Get the CWIS username of the most recent poster
     * @return CWIS username of the most recent poster
     */
    function PosterName()
    {
        $PosterName = new CWUser((int)$this->PosterId());
        return $PosterName->Get("UserName");
    }

    /**
     * Get the email address of the most recent poster
     * @return Email address of the most recent poster
     */
    function PosterEmail()
    {
        $PosterName = new CWUser((int)$this->PosterId());
        return $PosterName->Get("EMail");
    }

    /**
     * Get the CWIS user ID of the most recent editor
     * @return CWIS user ID of the most recent editor
     */
    function EditorId($NewValue = DB_NOVALUE) {  return $this->UpdateValue("EditorId", $NewValue);  }

    /**
     * Get or set the ParentId.
     * For forum posts, the ParentId is a TopicId.
     * For resource comments, the ParentId is the ResourceId.
     * @param int $NewValue New value to set (OPTIONAL)
     * @return The current ParentId
     */
    function ParentId($NewValue = DB_NOVALUE) {  return $this->UpdateValue("ParentId", $NewValue);  }

    /**
     * Get or set the ParentType.
     * Parent Type = 1 for forum posts and
     * Parent Type = 2 for resource comments
     * @param int $NewValue (OPTIONAL)
     * @return The current ParentType
     */
    function ParentType($NewValue = DB_NOVALUE) {  return $this->UpdateValue("ParentType", $NewValue);  }

    /**
     * Get or set the date posted
     * @param string $NewValue (OPTIONAL)
     * @return Posting date
     */
    function DatePosted($NewValue = DB_NOVALUE) {  return $this->UpdateValue("DatePosted", $NewValue);  }

    /**
     * Get or set the date the message was last edited
     * @param string $NewValue (OPTIONAL)
     * @return date the message was last edited
     */
    function DateEdited($NewValue = DB_NOVALUE) {  return $this->UpdateValue("DateEdited", $NewValue);  }

    /**
     * Get or set the poster id (e.g., the author) for this message
     * @param int $NewValue (OPTIONAL)
     * @return CWIS Id number of this message's author
     */
    function PosterId($NewValue = DB_NOVALUE) {  return $this->UpdateValue("PosterId", $NewValue);  }

    /**
     * Get or set the message subject
     * @param string $NewValue (OPTIONAL)
     * @return Message subject
     */
    function Subject($NewValue = DB_NOVALUE) {  return $this->UpdateValue("Subject", $NewValue);  }

    /**
     * Get or set the message body
     * @param string $NewValue (OPTIONAL)
     * @return Message body
     */
    function Body($NewValue = DB_NOVALUE) {  return $this->UpdateValue("Body", $NewValue);  }

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

    /*@}*/

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

    private $MessageId;
    private $DB;
    private $DBFields;
    private $ErrorStatus;

    /**
    * Convenience function to supply parameters to Database->UpdateValue().
    * @param string $FieldName The name of the field to be updated.
    * @param mixed $NewValue The new value of the specified field.
    * @return The updated value if the operation was successful,
    *        otherwise NULL.
    */
    private function UpdateValue($FieldName, $NewValue)
    {
        if ($this->ErrorStatus == Message::OK)
        {
            return $this->DB->UpdateValue("Messages", $FieldName, $NewValue,
                                          "MessageId = '".$this->MessageId."'", $this->DBFields, TRUE);
        }
        else
        {
            return NULL;
        }
    }
}
