'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; } }