| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316 | <?php/** * * PHP Pro Bid $Id$ /hUzA/d/lsDObXj/yDUpPZrTott3xGoV8tph/Uvm1Wo= * * @link        http://www.phpprobid.com * @copyright   Copyright (c) 2015 Online Ventures Software & CodeCube SRL * @license     http://www.phpprobid.com/license Commercial License * * @version     7.5 *//** * reputation (feedback) table service class */namespace Ppb\Service;use Ppb\Db\Table\Reputation as ReputationTable,    Cube\Db\Expr;class Reputation extends AbstractService{    const SALE = 'sale';    const PURCHASE = 'purchase';    /**     * positive rating threshold     * any rating that is above this value will be considered positive     */    const POSITIVE_THRESHOLD = 3;    /**     * reputation intervals     */    const INTERVAL_ONE_MONTH = 'INTERVAL 1 MONTH';    const INTERVAL_SIX_MONTHS = 'INTERVAL 6 MONTH';    const INTERVAL_TWELVE_MONTHS = 'INTERVAL 1 YEAR';    /**     *     * allowed reputation scores     *     * @var array     */    public static $scores = array(        5 => '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   => '<i class="fa fa-star-o fa-lg star-yellow"></i>',        10  => '<i class="fa fa-star-o fa-lg star-green"></i>',        50  => '<i class="fa fa-star-o fa-lg star-blue"></i>',        100 => '<i class="fa fa-star-o fa-lg star-red"></i>',        200 => '<i class="fa fa-star-o fa-lg star-gold"></i>',    );    /**     *     * 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;    }}
 |