Comment.php #1

  • //
  • guest/
  • perforce_software/
  • chronicle/
  • main/
  • sites/
  • all/
  • modules/
  • comment/
  • models/
  • Comment.php
  • View
  • Commits
  • Open Download .zip Download (8 KB)
<?php
/**
 * Modelling and storage of comment entries.
 *
 * Comments are grouped by path. Each comment entry id should (typically)
 * be stored in a sub-folder under comments (e.g. comments/content/123)
 * where '123' is the id of the content entry the comment is associated with.
 *
 * We permit numeric ids when adding because we want to include numeric content
 * (or other) record ids as path components of the comment id.
 *
 * @copyright   2011 Perforce Software. All rights reserved.
 * @license     Please see LICENSE.txt in top-level folder of this distribution.
 * @version     <release>/<patch>
 */
class Comment_Model_Comment extends P4Cms_Record
{
    const               STATUS_APPROVED     = 'approved';
    const               STATUS_PENDING      = 'pending';
    const               STATUS_REJECTED     = 'rejected';

    protected static    $_storageSubPath    = 'comments';
    protected static    $_idField           = 'id';
    protected static    $_fields            = array(
        'id',
        'user',
        'name',
        'comment',
        'postTime'  => array(
            'accessor'  => 'getPostTime',
            'mutator'   => 'setPostTime'
        ),
        'votes'     => array(
            'accessor'  => 'getVotes',
            'mutator'   => 'setVotes'
        ),
        'status'    => array(
            'mutator'   => 'setStatus'
        )
    );

    /**
     * Extend parent to join against users and expand user name
     * into full name and email where appropriate.
     *
     * @param   P4Cms_Record_Query|array|null   $query      optional - query options to augment result.
     * @param   P4Cms_Record_Adapter            $adapter    optional - storage adapter to use.
     * @return  P4Cms_Model_Iterator            all records of this type.
     */
    public static function fetchAll($query = null, P4Cms_Record_Adapter $adapter = null)
    {
        // if no adapter given, use default.
        $adapter  = $adapter ?: static::getDefaultAdapter();

        // let parent do initial fetch.
        $comments = parent::fetchAll($query, $adapter);

        // fill in full-name and email of users if we have any comments.
        // we do this because comments from authenticated users are
        // stored without the full-name/email, just the username.
        if (count($comments)) {
            $p4     = $adapter->getConnection();
            $result = $p4->run('users', $comments->invoke('getValue', array('user')));
            $lookup = array();
            foreach ($result->getData() as $user) {
                $lookup[$user['User']] = array(
                    'name'  => $user['FullName'],
                    'email' => $user['Email']
                );
            }
            foreach ($comments as $comment) {
                if (isset($comment->user) && isset($lookup[$comment->user])) {
                    $comment->setValues($lookup[$comment->user]);
                }
            }
        }

        return $comments;
    }

    /**
     * Get the recorded time this comment was posted.
     *
     * @return  int     the time this comment was allegedly posted.
     */
    public function getPostTime()
    {
        return intval($this->_getValue('postTime'));
    }

    /**
     * Explicitly set the time that this comment was posted.
     *
     * @param   int     $time           the time this comment was posted
     * @return  Comment_Model_Comment   provides fluent interface.
     */
    public function setPostTime($time)
    {
        return $this->_setValue('postTime', $time);
    }

    /**
     * Get the votes counted for this comment.
     *
     * @return  int     the number of votes for this comment.
     */
    public function getVotes()
    {
        return intval($this->_getValue('votes'));
    }

    /**
     * Explicitly set the number of votes for this comment
     *
     * @param   int     $votes          the number of votes this comment should have.
     * @return  Comment_Model_Comment   provides fluent interface.
     */
    public function setVotes($votes)
    {
        return $this->_setValue('votes', $votes);
    }

    /**
     * Adjust the number of votes on this comment up by one.
     *
     * @return  Comment_Model_Comment   provides fluent interface.
     */
    public function voteUp()
    {
        return $this->setVotes($this->getVotes() + 1);
    }

    /**
     * Adjust the number of votes on this comment down by one.
     *
     * @return  Comment_Model_Comment   provides fluent interface.
     */
    public function voteDown()
    {
        return $this->setVotes($this->getVotes() - 1);
    }

    /**
     * Set the status of this comment
     *
     * @param   string  $status             the state to set this comment to.
     * @return  Comment_Model_Comment       provides fluent interface.
     * @throws  InvalidArgumentException    if given status is not a valid state.
     */
    public function setStatus($status)
    {
        $states = array(
            static::STATUS_APPROVED,
            static::STATUS_PENDING,
            static::STATUS_REJECTED
        );

        if (!in_array($status, $states, true)) {
            throw new InvalidArgumentException(
                "Cannot set status of comment. Given status is not a valid state."
            );
        }

        return $this->_setValue('status', $status);
    }

    /**
     * Get all comments voted on by the given user under the given path.
     *
     * Any change that contains the word 'vote' in the description is
     * considered to be a vote. This is a rather fragile linkage. If the
     * change description for comment votes is altered, this will stop
     * working.
     *
     * Optimized to only lookup the comment ids. If you wish to read
     * other fields, you will incur a populate per comment.
     *
     * @param   string                  $user       the id of the user to fetch voted comments for.
     * @param   string                  $path       the path under which to fetch comments.
     * @param   P4Cms_Record_Adapter    $adapter    optional - storage adapter to use.
     * @return  P4Cms_Model_Iterator    all comments voted on by the given user under the given path.
     *
     */
    public static function fetchVotedComments($user, $path, P4Cms_Record_Adapter $adapter = null)
    {
        // if no adapter given, use default.
        $adapter = $adapter ?: static::getDefaultAdapter();

        // ensure path has no trailing slash.
        $path = rtrim($path, '/');

        // fetch all changes made by the given user against this path.
        $changes = P4_Change::fetchAll(
            array(
                P4_Change::FETCH_BY_USER     => $user,
                P4_Change::FETCH_BY_FILESPEC => static::getStoragePath() . '/' . $path . '/...'
            ),
            $adapter->getConnection()
        );

        // further limit changes to those with the word 'vote' in the description.
        $changes->filter(
            'Description',
            'Vote',
            array(
                P4_Model_Iterator::FILTER_NO_CASE,
                P4_Model_Iterator::FILTER_CONTAINS
            )
        );

        // if no changes, nothing more to query.
        if (!$changes->count()) {
            return new P4Cms_Model_Iterator;
        }

        // fetch comments affected by these changes.
        $ids      = array_map('strval', $changes->invoke('getId'));
        $filter   = new P4Cms_Record_Filter;
        $filter->addFstat('headChange', $ids);
        $comments = Comment_Model_Comment::fetchAll(
            array(
                'filter'      => $filter,
                'paths'       => array($path . '/...'),
                'limitFields' => 'depotFile'
            ),
            $adapter
        );

        return $comments;
    }
}
# Change User Description Committed
#1 16170 perforce_software Move Chronicle files to follow new path scheme for branching.
//guest/perforce_software/chronicle/sites/all/modules/comment/models/Comment.php
#1 8972 Matt Attaway Initial add of the Chronicle source code