Source

sfPropelORMRatableBehaviorPlugin / lib / behavior / RatableBehavior.php

Full commit
<?php

/*
 *  matteosister <matteog@gmail.com>
 *  Just for fun...
 */

class RatableBehavior extends Behavior
{
    protected $parameters = array(
        'average_column'  => 'ratable_average',
        'vote_number_column' => 'ratable_nb_votes',
        'max_vote'        => 10
    );

    /**
    * Add the two column to the table
    */
	public function modifyTable()
	{
        // add the average column
		if(!$this->getTable()->hasColumn($this->getParameter('average_column'))) {
			$this->getTable()->addColumn(array(
				'name'         => $this->getParameter('average_column'),
				'type'         => 'FLOAT',
                'defaultValue' => NULL
			));
		}

        // add the vote number column
        if(!$this->getTable()->hasColumn($this->getParameter('vote_number_column'))) {
			$this->getTable()->addColumn(array(
				'name'         => $this->getParameter('vote_number_column'),
				'type'         => 'INTEGER',
                'defaultValue' => 0
			));
		}
	}

    /**
	 * Get the getter of the average column of the behavior
	 *
	 * @return string The related getter, e.g. 'getAverage'
	 */
	protected function getAverageColumnGetter()
	{
		return 'get' . $this->getColumnForParameter('average_column')->getPhpName();
	}

	/**
	 * Get the setter of the average column of the behavior
	 *
	 * @return string The related setter, e.g. 'setAverage'
	 */
	protected function getAverageColumnSetter()
	{
		return 'set' . $this->getColumnForParameter('average_column')->getPhpName();
	}

    /**
	 * Get the getter of the average column of the behavior
	 *
	 * @return string The related getter, e.g. 'getAverage'
	 */
	protected function getNbVotesColumnGetter()
	{
		return 'get' . $this->getColumnForParameter('vote_number_column')->getPhpName();
	}

	/**
	 * Get the setter of the average column of the behavior
	 *
	 * @return string The related setter, e.g. 'setAverage'
	 */
	protected function getNbVotesColumnSetter()
	{
		return 'set' . $this->getColumnForParameter('vote_number_column')->getPhpName();
	}

	/**
	 * Add code in ObjectBuilder::preSave
	 *
	 * @return string The code to put at the hook
	 */
	public function preInsert($builder)
	{
        $script = "
\$this->{$this->getNbVotesColumnSetter()}(0);
";

		return $script;
	}

    public function objectMethods()
    {
        $script = '';
        $script .= $this->generateSetRatingMethod();
        $script .= $this->generateGetRatingMethod();
        return $script;
    }



    protected function generateSetRatingMethod()
    {
        return "
/**
* Rate the {$this->getTable()->getName()}
*
* @param \$rating the vote from 1 to 10
* @return float the new rating
*/
public function setRating(\$rating) {
    if (!is_int(\$rating)) {
        throw new InvalidArgumentException('You must provide an integer to rate an object');
    }
    if (!in_array(\$rating, range(1, 10, 1))) {
        throw new InvalidArgumentException('You must provide a vote from 1 to 10, no float number allowed');
    }

    if (null === \$this->{$this->getAverageColumnGetter()}()) {
        \$newSum = \$rating;
    } else {
        \$newSum = (\$this->{$this->getAverageColumnGetter()}() * \$this->{$this->getNbVotesColumnGetter()}()) + \$rating;
    }
    \$this->{$this->getNbVotesColumnSetter()}(\$this->{$this->getNbVotesColumnGetter()}() + 1);
    \$this->{$this->getAverageColumnSetter()}(\$newSum / \$this->{$this->getNbVotesColumnGetter()}());
}
";
    }

    protected function generateGetRatingMethod()
    {
        $maxVote = $this->parameters['max_vote'];
        return "
/**
 * Get the average rate for this {$this->getTable()->getName()}
 *
 * @int \$max          The maximum vote
 * @return float|null the rating or null if the object has never been rated
 */
public function getRating(\$max = {$maxVote}) {
    return null === \$this->{$this->getAverageColumnGetter()}() ? null : (\$this->{$this->getAverageColumnGetter()}() / 10) * \$max;
}
";
    }
}