1. matteosister
  2. sfPropelORMRatableBehaviorPlugin

Source

sfPropelORMRatableBehaviorPlugin / lib / behavior / RatableBehavior.php

<?php

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

class RatableBehavior extends Behavior
{
    protected $parameters = array(
        'average_column'  => 'ratable_average',
        'average_column_phpname' => 'Average',
        'nb_votes_column' => 'ratable_nb_votes',
        'nb_votes_column_phpname' => 'NbVotes',
        'precision'       => 1,
        'max_vote'        => 5
    );

    /**
    * Add the two column to the table
    */
	public function modifyTable()
	{
		if(!$this->getTable()->containsColumn($this->getParameter('average_column'))) {
			$this->getTable()->addColumn(array(
				'name' => $this->getParameter('average_column'),
                'phpName' => $this->getParameter('average_column_phpname'),
				'type' => PropelTypes::FLOAT
			));
		}

        if(!$this->getTable()->containsColumn($this->getParameter('nb_votes_column'))) {
			$this->getTable()->addColumn(array(
				'name' => $this->getParameter('nb_votes_column'),
                'phpName' => $this->getParameter('nb_votes_column_phpname'),
				'type' => PropelTypes::INTEGER
			));
		}
	}

    /**
	 * 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('nb_votes_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('nb_votes_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()
    {
        $precision = $this->parameters['precision'];
        return "
/**
* Rate a propel object with ratable behavior
*/
public function setRating(\$rating) {
    if (!is_int(\$rating)) {
        throw new InvalidArgumentException('You must provide an integer to rate an object');
    }
    if (!in_array(\$rating, array(1, 2, 3, 4, 5))) {
        throw new InvalidArgumentException('You must provide a vote from 1 to 5, 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()}(round(\$newSum / \$this->{$this->getNbVotesColumnGetter()}(), {$precision}));
}
";
    }

    protected function generateGetRatingMethod()
    {
        $precision = $this->parameters['precision'];
        $maxVote = $this->parameters['max_vote'];
        return "
/**
 * Get the average rate for a Propel object with ratable behavior
 * @int \$max          The maximum vote
 * @bool \$precision   Precision value for the 'round' php function
 *
 * @return \$vote or null
 */
public function getRating(\$max = {$maxVote}, \$precision = {$precision}) {
    return null === \$this->{$this->getAverageColumnGetter()}() ? null : round((\$this->{$this->getAverageColumnGetter()}() * \$max) / 5, \$precision);
}
";
    }
}