* Invision Power Services * IP.Board v3.4.6 * Facilitates reputation plugins * Last Updated: $Date: 2013-03-05 09:42:55 -0500 (Tue, 05 Mar 2013) $ * * * @author Joshua Williams * @package IP.Board * @copyright (c) 2001 - 2009 Invision Power Services, Inc. * @license http://www.invisionpower.com/company/standards.php#license * @link http://www.invisionpower.com * @since Wednesday 14th May 2008 14:00 */ class classReputationCache { /** * Variable that determines if the reputation system is activated * * @access public * @var boolean */ public $rep_system_on; /** * Error string * * @access public * @var string */ public $error_message; /** * CONSTRUCTOR * * @access public * @return @e void */ public function __construct() { /* Make object */ $this->registry = ipsRegistry::instance(); $this->DB = $this->registry->DB(); $this->settings =& $this->registry->fetchSettings(); $this->request =& $this->registry->fetchRequest(); $this->lang = $this->registry->getClass('class_localization'); $this->member = $this->registry->member(); $this->memberData =& $this->registry->member()->fetchMemberData(); $this->cache = $this->registry->cache(); $this->caches =& $this->registry->cache()->fetchCaches(); $this->rep_system_on = ipsRegistry::$settings['reputation_enabled']; /* re-assign some language strings */ if ( $this->settings['reputation_point_types'] == 'like' ) { foreach( array( 'rep_description', 'member_has_x_rep' ) as $lang ) { if ( ! empty( $this->lang->words[ $lang ] ) && ! empty( $this->lang->words[ $lang . '_like' ] ) ) { $this->lang->words[ $lang ] = $this->lang->words[ $lang . '_like' ]; } } } } /** * Retuns an array for use in a join statement * * @access public * @param string $type Type of content, ex; Post * @param integer $type_id ID of the type, ex: pid * @param string [$app] App for this content, by default the current application * @return array */ public function getTotalRatingJoin( $type, $type_id, $app='' ) { /* Online? */ if( ! $this->rep_system_on ) { return array(); } /* INIT */ $app = ( $app ) ? $app : ipsRegistry::$current_application; /* Return the join array */ return array( 'select' => 'rep_cache.rep_points, rep_cache.rep_like_cache', 'from' => array( 'reputation_cache' => 'rep_cache' ), 'where' => "rep_cache.app='{$app}' AND rep_cache.type='{$type}' AND rep_cache.type_id={$type_id}", 'type' => 'left' ); } /** * Has this member rated this item? * @param array $data (app, id, type, memberId ) * @return boolean */ public function getCurrentMemberRating( $data ) { return $this->DB->buildAndFetch( array( 'select' => '*, rep_rating as has_given_rep', 'from' => 'reputation_index', 'where' => "app='" . $data['app'] . "' AND type='" . $data['type'] . "' AND type_id=" . intval( $data['id'] ) . " AND member_id=" . intval( $data['memberId'] ) ) ); } /** * Has this member rated this item? * @param array $data (app, id, type, memberId ) * @return int */ public function getCurrentRating( $data ) { $rating = $this->DB->buildAndFetch( array( 'select' => 'rep_points', 'from' => 'reputation_cache', 'where' => "app='" . $data['app'] . "' AND type='" . $data['type'] . "' AND type_id=" . intval( $data['id'] ) ) ); return intval( $rating['rep_points'] ); } /** * Retuns an array for use in a join statement * * @access public * @param string $type Type of content, ex; Post * @param integer $type_id ID of the type, ex: pid * @param string [$app] App for this content, by default the current application * @return array */ public function getUserHasRatedJoin( $type, $type_id, $app='' ) { /* Online? */ if( ! $this->rep_system_on ) { return array(); } /* INIT */ $app = ( $app ) ? $app : ipsRegistry::$current_application; /* Return the join array */ return array( 'select' => 'rep_index.rep_rating as has_given_rep', 'from' => array( 'reputation_index' => 'rep_index' ), 'where' => "rep_index.app='{$app}' AND rep_index.type='{$type}' AND rep_index.type_id={$type_id} AND rep_index.member_id=" . $this->memberData['member_id'], 'type' => 'left', ); } /** * Adds a rating to the index and updates caches * * @access public * @param string $type Type of content, ex; Post * @param integer $type_id ID of the type, ex: pid * @param integer $rating Either 1 or -1 * @param string $message Message associated with this rating * @param integer $member_id Id of the owner of the content being rated * @param string [$app] App for this content, by default the current application * @todo [Future] Move forum notifications to an onRep memberSync callback * @return bool */ public function addRate( $type, $type_id, $rating, $message='', $member_id=0, $app='' ) { $this->registry->getClass('class_localization')->loadLanguageFile( array( 'public_global' ), 'core' ); /* Online? */ if ( ! $this->rep_system_on ) { $this->error_message = $this->lang->words['reputation_offline']; return false; } /* INIT */ $app = ( $app ) ? $app : ipsRegistry::$current_application; $rating = intval( $rating ); if ( ! $this->memberData['member_id'] ) { $this->error_message = $this->lang->words['reputation_guest']; return false; } if ( $rating != -1 && $rating != 1 ) { $this->error_message = $this->lang->words['reputation_invalid']; return false; } /* Does the rep item exist? */ if( ! $this->likeItemExists( $app, $type, $type_id ) ) { /* See ticket #845557 - item may not exist when not in LIKE mode. Need to add functionalty so each app can return boolean if item exists in native tables */ //$this->error_message = $this->lang->words['reputation_invalid']; //return false; } /* Check for existing rating */ $currentRating = $this->getCurrentMemberRating( array( 'app' => $app, 'type' => $type, 'id' => $type_id, 'memberId' => $this->memberData['member_id'] ) ); /* Check the point types */ if ( $rating == -1 && IPSMember::canRepDown( $currentRating, $this->memberData ) === false ) { $this->error_message = $this->lang->words['reputation_invalid']; return false; } if ( $rating == 1 && IPSMember::canRepUp( $currentRating, $this->memberData ) === false ) { $this->error_message = $this->lang->words['reputation_invalid']; return false; } /* Day Cutoff */ $day_cutoff = time() - 86400; /* Check Max Positive Votes */ if( $rating == 1 ) { if ( intval( $this->memberData['g_rep_max_positive'] ) === 0 ) { $this->error_message = $this->lang->words['reputation_quota_pos']; return false; } $total = $this->DB->buildAndFetch( array( 'select' => 'count(*) as votes', 'from' => 'reputation_index', 'where' => 'member_id=' . $this->memberData['member_id'] . ' AND rep_rating=1 AND rep_date > ' . $day_cutoff ) ); if ( $total['votes'] >= $this->memberData['g_rep_max_positive'] ) { $this->error_message = $this->lang->words['reputation_quota_pos']; return false; } } /* Check Max Negative Votes if not like mode */ if ( $rating == -1 AND ! $this->isLikeMode() ) { if ( intval( $this->memberData['g_rep_max_negative'] ) === 0 ) { $this->error_message = $this->lang->words['reputation_quota_neg']; return false; } $total = $this->DB->buildAndFetch( array( 'select' => 'count(*) as votes', 'from' => 'reputation_index', 'where' => 'member_id=' . $this->memberData['member_id'] . ' AND rep_rating=-1 AND rep_date > ' . $day_cutoff ) ); if( $total['votes'] >= $this->memberData['g_rep_max_negative'] ) { $this->error_message = $this->lang->words['reputation_quota_neg']; return false; } } /* If no member id was passed in, we have to query it using the config file */ if( ! $member_id ) { /* Reputation Config */ if( is_file( IPSLib::getAppDir( $app ) . '/extensions/reputation.php' ) ) { $rep_author_config = array(); require( IPSLib::getAppDir( $app ) . '/extensions/reputation.php' );/*maybeLibHook*/ } else { $this->error_message = $this->lang->words['reputation_config']; return false; } if( ! $rep_author_config[$type]['column'] || ! $rep_author_config[$type]['table'] ) { $this->error_message = $this->lang->words['reputation_config']; return false; } $_col = $rep_author_config[$type]['id_field'] ? $rep_author_config[$type]['id_field'] : $type; /* Query the content author */ $content_author = $this->DB->buildAndFetch( array( 'select' => "{$rep_author_config[$type]['column']} as id", 'from' => $rep_author_config[$type]['table'], 'where' => "{$_col}={$type_id}" ) ); $member_id = $content_author['id']; } if( ! ipsRegistry::$settings['reputation_can_self_vote'] && $member_id == $this->memberData['member_id'] ) { $this->error_message = $this->lang->words['reputation_yourown']; return false; } /* Query the member group */ if( ipsRegistry::$settings['reputation_protected_groups'] ) { $member_group = $this->DB->buildAndFetch( array( 'select' => 'member_group_id', 'from' => 'members', 'where' => "member_id={$member_id}" ) ); if( in_array( $member_group['member_group_id'], explode( ',', ipsRegistry::$settings['reputation_protected_groups'] ) ) ) { $this->error_message = $this->lang->words['reputation_protected']; return false; } } /* Build the insert array */ $db_insert = array( 'member_id' => $this->memberData['member_id'], 'app' => $app, 'type' => $type, 'type_id' => $type_id, 'rep_date' => time(), 'rep_msg' => $message, 'rep_rating' => $rating ); /* Insert */ if ( $currentRating ) { if ( $rating == -1 && $this->isLikeMode() ) { $this->DB->delete( 'reputation_index', "app='{$app}' AND type='{$type}' AND type_id={$type_id} AND member_id=".$this->memberData['member_id'] ); } } else { $this->DB->replace( 'reputation_index', $db_insert, array( 'app', 'type', 'type_id', 'member_id' ) ); } /* Update cache */ $this->updateCache( $app, $type, $type_id ); /* Get authors current rep */ $author_points = $this->DB->buildAndFetch( array( 'select' => 'pp_reputation_points', 'from' => 'profile_portal', 'where' => "pp_member_id=" . intval($member_id) ) ); /* Figure out new rep */ if( $currentRating['rep_rating'] == -1 ) { $author_points['pp_reputation_points'] += 1; } else if ( $currentRating['rep_rating'] == 1 ) { $author_points['pp_reputation_points'] -= 1; } /* now add on new rating if we're not like mode-ing */ if ( ( ! $this->isLikeMode() ) || ( empty( $currentRating['rep_rating'] ) && $this->isLikeMode() ) ) { $author_points['pp_reputation_points'] += $rating; } $this->DB->update( 'profile_portal', array( 'pp_reputation_points' => $author_points['pp_reputation_points'] ), "pp_member_id={$member_id}" ); /* Notification */ if ( $rating == 1 && $this->isLikeMode() && $app == 'forums' && $type == 'pid' ) { /* Check for class_forums */ if ( ! $this->registry->isClassLoaded( 'class_forums' ) ) { $classToLoad = IPSLib::loadLibrary( IPSLib::getAppDir( 'forums' ) . "/sources/classes/forums/class_forums.php", 'class_forums', 'forums' ); $this->registry->setClass( 'class_forums', new $classToLoad( $this->registry ) ); $this->registry->strip_invisible = 0; $this->registry->class_forums->forumsInit(); } $classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . '/sources/classes/member/notifications.php', 'notifications' ); $notifyLibrary = new $classToLoad( $this->registry ); if ( ! $this->registry->isClassLoaded('topics') ) { $classToLoad = IPSLib::loadLibrary( IPSLib::getAppDir( 'forums' ) . "/sources/classes/topics.php", 'app_forums_classes_topics', 'forums' ); $this->registry->setClass( 'topics', new $classToLoad( $this->registry ) ); } $post = $this->registry->getClass('topics')->getPostById( $type_id ); /* Set topic data */ $this->registry->getClass('topics')->setTopicData( $post ); /* Quick check */ if ( ! $post['author_id'] OR $post['author_id'] == $this->memberData['member_id'] ) { return true; } $_toMember = IPSMember::load( $post['author_id'] ); /* Set language */ $_toMember['language'] = $_toMember['language'] == "" ? IPSLib::getDefaultLanguage() : $_toMember['language']; /* Quick permission check */ if ( $this->registry->getClass('topics')->canView() !== true ) { return true; } $url = $this->registry->output->buildSEOUrl( "showtopic={$post['topic_id']}&view=findpost&p={$post['pid']}", "publicNoSession", $post['title_seo'], 'showtopic' ); IPSText::getTextClass('email')->getTemplate( "new_likes", $_toMember['language'] ); IPSText::getTextClass('email')->buildMessage( array('MEMBER_NAME' => $this->memberData['members_display_name'], 'SHORT_POST' => IPSText::truncate( IPSText::getTextClass( 'bbcode' )->stripAllTags( $post['post'] ), 300 ), 'URL' => $url ) ); IPSText::getTextClass('email')->subject = sprintf( IPSText::getTextClass('email')->subject, $this->registry->output->buildSEOUrl( 'showuser=' . $this->memberData['member_id'], 'publicNoSession', $this->memberData['members_seo_name'], 'showuser' ), $this->memberData['members_display_name'], $url, $this->registry->output->buildSEOUrl( "showtopic={$post['topic_id']}", "publicNoSession", $post['title_seo'], 'showtopic' ), IPSText::truncate( $post['topic_title'], 30 ) ); $notifyLibrary->setMember( $_toMember ); $notifyLibrary->setFrom( $this->memberData ); $notifyLibrary->setNotificationKey( 'new_likes' ); $notifyLibrary->setNotificationUrl( $url ); $notifyLibrary->setNotificationText( IPSText::getTextClass('email')->message ); $notifyLibrary->setNotificationTitle( IPSText::getTextClass('email')->subject ); try { $notifyLibrary->sendNotification(); } catch( Exception $e ){} } return true; } /** * Returns an array of reputation information based on the points passed in * * @access public * @param integer $points Number of points to base the repuation information on * @return array 'text' and 'image' */ public function getReputation( $points ) { /* INIT */ $cache = ipsRegistry::cache()->getCache( 'reputation_levels' ); $cache = is_array( $cache ) && count( $cache ) ? $cache : array(); $points = intval( $points ); if( count($cache) AND is_array($cache) ) { foreach( $cache as $k => $r ) { if( $r['level_points'] == 0 ) { if( $points >= 0 && $points < intval( $cache[ $k -1 ]['level_points'] ) ) { return array( 'text' => $r['level_title'], 'image' => $r['level_image'] ? ipsRegistry::$settings['public_dir'] . 'style_extra/reputation_icons/' . $r['level_image'] : '' ); } else if( $points <= 0 && $points > intval( $cache[ $k + 1 ]['level_points'] ) ) { return array( 'text' => $r['level_title'], 'image' => $r['level_image'] ? ipsRegistry::$settings['public_dir'] . 'style_extra/reputation_icons/' . $r['level_image'] : '' ); } else if( $points == 0 ) { return array( 'text' => $r['level_title'], 'image' => $r['level_image'] ? ipsRegistry::$settings['public_dir'] . 'style_extra/reputation_icons/' . $r['level_image'] : '' ); } } else if( $r['level_points'] > 0 ) { if( $points >= intval( $r['level_points'] ) ) { return array( 'text' => $r['level_title'], 'image' => $r['level_image'] ? ipsRegistry::$settings['public_dir'] . 'style_extra/reputation_icons/' . $r['level_image'] : '' ); } } else { if( $points <= intval( $r['level_points'] ) && $points > intval( $cache[ $k + 1 ]['level_points'] ) ) { return array( 'text' => $r['level_title'], 'image' => $r['level_image'] ? ipsRegistry::$settings['public_dir'] . 'style_extra/reputation_icons/' . $r['level_image'] : '' ); } } } } /* Return the lowest rep, if we're still here */ $r = array_pop( $cache ); return array( 'text' => $r['level_title'], 'image' => $r['level_image'] ? ipsRegistry::$settings['public_dir'] . 'style_extra/reputation_icons/' . $r['level_image'] : '' ); } /** * Get 'like' formatted for this item * * @param array Data array ( id, type, app ) */ public function getLikeFormatted( $item ) { $data = array( 'names' => array(), 'count' => 0, 'formatted' => '', 'iLike' => false ); $max = 0; /* Like system enabled? */ if ( $this->settings['reputation_point_types'] != 'like' ) { return $data; } $cache = $this->getLikeData( $item ); /* We had the total count set from cache.get */ if ( isset($cache['count']) AND $cache['count'] ) { /* fetch data */ if ( $this->memberData['member_id'] AND in_array( $this->memberData['member_id'], $cache['memberIds'] ) ) { /* Now mix up the data */ $data['names'][] = array( 'name' => $this->lang->words['post_like_moi'], 'seo' => $this->memberData['members_seo_name'], 'id' => $this->memberData['member_id'] ); /* Flag as me */ $data['iLike'] = true; } if ( is_array( $cache['memberNames'] ) ) { $i = 1; $max = 3; foreach( $cache['memberNames'] as $mid => $mdata ) { $_last = ( $i == count( $cache['memberNames'] ) || $i == $max ) ? 1 : 0; /* Is this you? */ if ( $mid == $this->memberData['member_id'] ) { continue; } /* Push it on */ $data['names'][] = array( 'name' => $mdata['n'], 'seo' => $mdata['s'], 'id' => $mid, 'last' => $_last ); $i++; if ( $i > $max ) { /* Done thanks */ break; } } } } /* Finish off */ $data['totalCount'] = isset($cache['count']) ? $cache['count'] : 0; $data['othersCount'] = isset($cache['count']) ? ( ( $cache['count'] > $max ) ? $cache['count'] - $max : 0 ) : 0; $data['formatted'] = $this->formatLikeNameString( $data, $item ); return $data; } /** * Gets 'like' data for this item * * @param array ( id, type, app ) * @return array * */ public function getRepPoints( $data ) { if ( ! isset( $data['rep_points'] ) || $data['rep_points'] == '' ) { $data['rep_points'] = $this->updateCache( $data['app'], $data['type'], $data['type_id'] ); } return intval( $data['rep_points'] ); } /** * Gets 'like' data for this item * * @param array ( id, type, app ) * @return array * */ public function getLikeData( $data ) { $store = array( 'cache_data' => array() ); $expired = false; if ( IPSLib::isSerialized( $data['rep_like_cache'] ) ) { $store = unserialize( $data['rep_like_cache'] ); if ( empty( $store['cache_expire'] ) OR time() >= $store['cache_expire'] ) { $expired = true; $store = array(); } } if ( ! isset( $data['rep_like_cache'] ) OR $expired === true ) { unset( $data['rep_like_cache'] ); $store = $this->getLikeRawData( $data ); $this->DB->replace( 'reputation_cache', array( 'app' => $data['app'], 'type' => $data['type'], 'type_id' => $data['id'], 'rep_points' => intval( $store['cache_data']['count'] ), 'cache_date' => time(), 'rep_like_cache' => serialize( $store ) ), array( 'app', 'type', 'type_id' ) ); } return $store['cache_data']; } /** * Get the like data from the DB (no cache) * * @param array $data Like data ( id, type, app ) * @return @e array Cache data */ public function getLikeRawData( $data ) { /* Get data */ $store = array( 'cache_data' => array(), 'cache_expire' => time() + 86400 ); $this->DB->build( array( 'select' => 'r.member_id, r.rep_rating', 'from' => array( 'reputation_index' => 'r' ), 'where' => "r.app='" . $data['app'] . "' AND r.type='" . $data['type'] . "' AND r.type_id='" . $data['id'] . "'", //'order' => 'r.rep_date', 'add_join' => array( array( 'select' => 'm.members_display_name, m.members_seo_name', 'from' => array( 'members' => 'm' ), 'where' => 'm.member_id=r.member_id', 'type' => 'left' ) ) ) ); $q = $this->DB->execute(); while ( $row = $this->DB->fetch( $q ) ) { if ( $row['rep_rating'] == 1 ) { $data['count']++; if ( $data['count'] <= 5 ) { $data['memberNames'][ $row['member_id'] ] = array( 'n' => $row['members_display_name'], 's' => $row['members_seo_name'] ); } if ( $data['count'] <= 500 ) { $data['memberIds'][] = $row['member_id']; } } } /* Fetch and store */ if ( $data['count'] > 0 ) { $store = array( 'cache_data' => $data, 'cache_expire' => time() + 86400 ); } return $store; } /** * Formats the Bob, Bill, Joe and 2038 Others Hate You * * @param array $data * @param array $item Data (id, type, app) * @return string */ public function formatLikeNameString( array $data, array $item ) { $langString = ''; $seeMoreLink = '#'; if ( ! is_array( $data['names'] ) OR ! count( $data['names'] ) ) { return false; } /* Format up the names */ $i = 0; $_names = array(); foreach( $data['names'] as $name ) { if ( $this->memberData['member_id'] AND ( $this->memberData['member_id'] == $name['id'] ) ) { $_names[$i] = $name['name']; } else { $_names[$i] = IPSMember::makeProfileLink($name['name'], $name['id'], $name['seo'] ); } $i++; } /* More than one? */ if ( $data['totalCount'] > 1 ) { /* Joe and Matt love you */ if ( $data['totalCount'] == 2 ) { $_n = $_names[0] . ' ' . $this->lang->words['post_like_and'] . ' ' . $_names[1]; $langString = sprintf( $this->lang->words['post_like_formatted_many'], $_n ); } /* Joe, Matt and Mike love you more */ else if ( $data['totalCount'] == 3 ) { $_n = $_names[0] . ', ' . $_names[1] . ' ' . $this->lang->words['fave_and'] . ' ' . $_names[2]; $langString = sprintf( $this->lang->words['post_like_formatted_many'], $_n ); } /* Joe, Matt, Mike and 1 more love you */ else if ( $data['totalCount'] == 4 ) { $_n = $_names[0] . ', ' . $_names[1] . ', ' . $_names[2]; $langString = sprintf( $this->lang->words['post_like_formatted_one_more'], $_n, $seeMoreLink, $item['id'], $item['type'], $item['app'] ); } /* Joe, Matt, Mike and 5 more are indifferent to your redonkulous comments */ else { $_n = $_names[0] . ', ' . $_names[1] . ', ' . $_names[2]; $langString = sprintf( $this->lang->words['post_like_formatted_more'], $_n, $seeMoreLink, $item['id'], $item['type'], $item['app'], $data['othersCount'] ); } } else { /* Just the one and it might be you! */ if ( $data['names'][0]['id'] == $this->memberData['member_id'] ) { $langString = $this->lang->words['post_like_formatted_me']; } else { $langString = sprintf( $this->lang->words['post_like_formatted_one'], $_names[0] ); } } return $langString; } /** * Get data based on a relationship ID * * @param array $data (id, type, app) * @return mixed Array of like data OR null */ public function getDataByRelationshipId( $data ) { /* Init */ $mids = array(); $members = array(); $rows = array(); $where = ( ! empty( $data['rating'] ) ) ? " AND rep_rating=" . $data['rating'] : ''; /* Fetch data */ $this->DB->build( array( 'select' => '*', 'from' => 'reputation_index', 'where' => 'app=\'' . $data['app'] . "' AND type='" . $data['type'] . "' AND type_id=" . intval( $data['id'] ) . $where, 'order' => 'rep_date DESC', 'limit' => array( 0, 250 ) ) ); $o = $this->DB->execute(); while( $row = $this->DB->fetch( $o ) ) { $return[ $row['member_id'] ] = $row; $mids[ $row['member_id'] ] = intval( $row['member_id'] ); } /* Just the one? */ if ( count( $mids ) ) { $members = IPSMember::load( $mids, 'all' ); foreach( $members as $i => $d ) { $_m = IPSMember::buildProfilePhoto( $d ); $return[ $i ] = array_merge( (array) $_m, (array) $return[ $i ] ); } } return ( is_array( $return ) ) ? $return : null; } /** * Handles updating and creating new caches * * @access private * @param string $app App for this content * @param string $type Type of content, ex; Post * @param integer $type_id ID of the type, ex: pid * @return @e void */ public function updateCache( $app, $type, $type_id ) { /* Update type cache */ $data = $this->DB->buildAndFetch( array( 'select' => 'SUM(rep_rating) as sum, COUNT(*) as count', 'from' => 'reputation_index', 'where' => "app='{$app}' AND type='$type' AND type_id='$type_id'" ) ); /* Fetch LIKE data */ $store = $this->getLikeRawData( array( 'id' => $type_id, 'type' => $type, 'app' => $app ) ); /* Update cache */ $this->DB->replace( 'reputation_cache', array( 'app' => $app, 'type' => $type, 'type_id' => $type_id, 'rep_points' => intval($data['sum']), 'cache_date' => time(), 'rep_like_cache' => serialize( $store ) ), array( 'app', 'type', 'type_id' ) ); /* Update totals */ $idKey = md5( $app . ';' . $type . ';' . $type_id ); $typeKey = md5( $app . ';' . $type ); $this->DB->replace( 'reputation_totals', array( 'rt_key' => $idKey, 'rt_app_type' => $typeKey, 'rt_type_id' => $type_id, 'rt_total' => intval( $data['sum'] ) ), array( 'rt_key' ) ); return $data['sum']; } /** * Is this in like mode? */ public function isLikeMode() { return ( $this->settings['reputation_point_types'] == 'like' ) ? true : false; } public function likeItemExists( $app, $type, $type_id ) { $data = $this->DB->buildAndFetch( array( 'select' => 'id', 'from' => 'reputation_cache', 'where' => "app='{$app}' AND type='$type' AND type_id='$type_id'" ) ); return ( count( $data ) ) ? TRUE : FALSE; } }