'Positive',
3 => 'Neutral',
1 => 'Negative',
);
/**
*
* reputation intervals (used by the reputation details page)
*
* @var array
*/
public static $intervals = array(
self::INTERVAL_ONE_MONTH => 'Last Month',
self::INTERVAL_SIX_MONTHS => 'Last 6 Months',
self::INTERVAL_TWELVE_MONTHS => 'Last 12 Months',
);
/**
*
* reputation icons
*
* @var array
*/
public static $icons = array(
1 => '',
10 => '',
50 => '',
100 => '',
200 => '',
);
/**
*
* users table service
*
* @var \Ppb\Service\Users
*/
protected $_users;
/**
*
* class constructor
*/
public function __construct()
{
parent::__construct();
$this->setTable(
new ReputationTable());
}
/**
*
* get users table service
*
* @return \Ppb\Service\Users
*/
public function getUsers()
{
if (!$this->_users instanceof Users) {
$this->setUsers(
new Users());
}
return $this->_users;
}
/**
*
* set users table service
*
* @param \Ppb\Service\Users $users
*
* @return \Ppb\Service\Reputation
*/
public function setUsers(Users $users)
{
$this->_users = $users;
return $this;
}
/**
*
* create or update an row in the reputation table
*
* @param array $data
* @param int $posterId force poster id in case the reputation is updated from the members module
* only the admin can update any reputation row
*
* @return \Ppb\Service\Reputation
*/
public function save($data, $posterId = null)
{
$row = null;
$data = $this->_prepareSaveData($data);
if (array_key_exists('id', $data)) {
$select = $this->_table->select()
->where("id = ?", $data['id']);
unset($data['id']);
$row = $this->_table->fetchRow($select);
}
if (count($row) > 0) {
$data['updated_at'] = new Expr('now()');
$where = "id='{$row['id']}'";
if ($posterId !== null) {
$where .= " AND poster_id = '" . intval($posterId) . "'";
}
$this->_table->update($data, $where);
}
else {
$data['created_at'] = new Expr('now()');
$this->_table->insert($data);
}
return $this;
}
/**
*
* save the data from a reputation form post
* this method will also update the reputation_data column in the users table
*
* @param array $ids
* @param float $score
* @param string $comments
* @param int $posterId
*
* @return \Ppb\Service\Reputation
*/
public function postReputation(array $ids, $score, $comments, $posterId = null)
{
foreach ($ids as $id) {
$this->save(array(
'id' => $id,
'score' => $score,
'comments' => $comments,
'posted' => 1
), $posterId);
$user = $this->findBy('id', $id)->findParentRow('\Ppb\Db\Table\Users', 'User');
$reputationData = serialize(array(
'score' => $this->getScore($user->getData('id')),
'percentage' => $this->getPercentage($user->getData('id')),
));
$user->save(array(
'reputation_data' => $reputationData,
));
}
return $this;
}
/**
*
* calculate the reputation score of a user based on different input variables
*
* @param int $userId the id of the user
* @param float $score score threshold
* @param string $operand calculation operand
* @param string $reputationType reputation type to be calculated (sale, purchase)
* @param string $interval calculation interval
*
* @return int resulted score
*/
public function calculateScore($userId, $score = null, $operand = '=', $reputationType = null, $interval = null)
{
$select = $this->_table->select(array('total' => new Expr('count(*)')))
->where('user_id = ?', $userId)
->where('posted = ?', 1);
if ($score !== null) {
$select->where("score {$operand} ?", $score);
}
if (in_array($reputationType, array(self::SALE, self::PURCHASE))) {
$select->where('reputation_type = ?', $reputationType);
}
if (in_array($interval, array_keys(self::$intervals))) {
$select->where('updated_at >= date_sub(now(), ?)', new Expr($interval));
}
return $this->_table->fetchRow($select)->getData('total');
}
/**
*
* get the reputation score of a certain user
* the method will always get live values from the reputation table
*
* @param int $userId
*
* @return int
*/
public function getScore($userId)
{
$positive = $this->calculateScore($userId, self::POSITIVE_THRESHOLD, '>');
$negative = $this->calculateScore($userId, self::POSITIVE_THRESHOLD, '<');
return $positive - $negative;
}
/**
*
* get the positive reputation percentage of a certain user
* the method will always get live values from the reputation table
*
* @param int $userId
*
* @return string
*/
public function getPercentage($userId)
{
$all = $this->calculateScore($userId);
if (!$all) {
return 'n/a';
}
$positive = $this->calculateScore($userId, self::POSITIVE_THRESHOLD, '>');
$percentage = round($positive * 100 / $all);
return $percentage . '%';
}
/**
*
* reputation can only be deleted by the administrator, and only from the admin area
*
* @param array $ids reputation ids
*
* @return int the number of affected rows
*/
public function delete(array $ids)
{
$result = 0;
foreach ($ids as $id) {
$user = $this->findBy('id', $id)->findParentRow('\Ppb\Db\Table\Users', 'User');
$result += $this->_table->delete(
$this->_table->getAdapter()->quoteInto('id = ?', $id));
$reputationData = serialize(array(
'score' => $this->getScore($user->getData('id')),
'percentage' => $this->getPercentage($user->getData('id')),
));
$user->save(array(
'reputation_data' => $reputationData,
));
}
return $result;
}
}