isLiked( $relId ); * $html = $like->render( 'summary', $relId ); * print $html; * * Matt, Joe, Bob and 5 others like this * * * This loads the app specific composite class (which inherits from the abstract class classes_like_composite * The composite class calls upon the registry and cache classes to manage data */ if ( ! defined( 'IN_IPB' ) ) { print "

Incorrect access

You cannot access this file directly. If you have recently upgraded, make sure you upgraded all the relevant files."; exit(); } /** * Quick registry class for common methods * * @author matt */ class classes_like_registry { /** * App key * * @var string */ static private $app = null; /** * Area key * * @var string */ static private $area = null; /** * Total count * * @var string */ static private $count = null; /** * Cached bootstrap loaders * * @var array */ static private $bootstraps = array(); /** * Get app key * * @return string */ static public function getApp() { return self::$app; } /** * Set app key * * @param string * @return void */ static public function setApp( $app ) { self::$app = $app; } /** * Get area key * * @return string */ static public function getArea() { return self::$area; } /** * Set area key * * @param string * @return void */ static public function setArea( $area ) { self::$area = $area; } /** * Get total count (saves on queries) * * @return string */ static public function getTotalCount() { return self::$count; } /** * Set total count (saves on queries) * * @param string * @return void */ static public function setTotalCount( $count ) { self::$count = $count; } /** * Pack key. Either for cache table, or full table * * @param int relationship ID * @param int member ID * @return binary binary key */ static public function getKey( $relId, $memberId=null ) { /* Check */ if ( empty( $relId ) ) { trigger_error( "Relationship ID missing in " . __CLASS__ . '::' . __FUNCTION__, E_USER_WARNING ); } if ( $memberId === null ) { /* For relative item only */ return md5( self::$app . ';' . self::$area . ';' . $relId ); } else if ( ! empty( $memberId ) ) { /* For member speciifc relative item */ return md5( self::$app . ';' . self::$area . ';' . $relId . ';' . $memberId ); } else { trigger_error( "Member ID missing in " . __CLASS__ . '::' . __FUNCTION__, E_USER_WARNING ); } } } /** * Simple static class for fetching meta data * @author matt * */ class classes_like_meta { /** * Retrieve the content title * * @param array Like data * @return string Title of content liked */ static public function getTitleFromId( $like ) { if ( empty( $like['like_app'] ) OR empty( $like['like_area'] ) OR empty( $like['like_rel_id'] ) ) { trigger_error( "You must have like_app, like_rel_id and like_area set", E_USER_WARNING ); } $_bootstrap = classes_like::bootstrap( $like['like_app'], $like['like_area'] ); return $_bootstrap->getTitleFromId( $like['like_rel_id'] ); } /** * Retrieve the content URL * * @param array Like data * @return string URL of content liked */ static public function getUrlFromId( $like ) { if ( empty( $like['like_app'] ) OR empty( $like['like_area'] ) OR empty( $like['like_rel_id'] ) ) { trigger_error( "You must have like_app, like_rel_id and like_area set", E_USER_WARNING ); } $_bootstrap = classes_like::bootstrap( $like['like_app'], $like['like_area'] ); return $_bootstrap->getUrlFromId( $like['like_rel_id'] ); } /** * Fetch all meta data from various like rows * @param array $likes * @return array */ static public function get( array $likes ) { $apps = array(); $process = array(); $lookUp = array(); foreach( $likes as $id => $like ) { if ( empty( $like['like_app'] ) OR empty( $like['like_area'] ) OR empty( $like['like_rel_id'] ) ) { continue; } $apps[ $like['like_app'] . '-' . $like['like_area'] ][ $id ] = $like; $lookUp[ $like['like_app'] . '-' . $like['like_area'] . '-' . $like['like_rel_id'] ] = $like['like_id']; } /* Process based on apps */ foreach( $apps as $app => $data ) { list( $_app, $_area ) = explode( '-', $app ); $_bootstrap = classes_like::bootstrap( $_app, $_area ); $relIds = array(); foreach( $data as $_k => $_v ) { $relIds[] = $_v['like_rel_id']; } /* Bulk fetch */ $process[ $app ] = $_bootstrap->getMeta( $relIds ); } /* Fold up array */ foreach( $process as $app => $data ) { list( $_app, $_area ) = explode( '-', $app ); foreach( $data as $relId => $_like ) { if ( $relId ) { $like_id = $lookUp[ $_app . '-' . $_area . '-' . $relId ]; if ( $like_id AND is_array( $_like ) AND is_array( $likes[ $like_id ] ) ) { $likes[ $like_id ] = array_merge( $likes[ $like_id ], $_like ); } } } } return $likes; } } /** * Factory class, loads composite and child class * * @author matt */ class classes_like { /** * App object * * @var array */ static private $apps; /** * Construct * * @param string Application * @param string Area * @return string */ static public function bootstrap( $app=null, $area=null ) { if ( $app === null OR $area === null ) { trigger_error( "App or area missing from classes_like", E_USER_WARNING ); } /* Pointless comment! */ $_file = IPSLib::getAppDir( $app ) . '/extensions/like/' . $area . '.php'; $_class = 'like_' . $app . '_' . $area . '_composite'; $_key = md5( $app . $area ); /* Get from cache if already cached */ if( isset( self::$apps[ $_key ] ) ) { return self::$apps[ $_key ]; } /* Otherwise create object and cache */ if ( file_exists( $_file ) ) { require_once( $_file ); if ( class_exists( $_class ) ) { classes_like_registry::setApp( $app ); classes_like_registry::setArea( $area ); self::$apps[ $_key ] = new $_class(); self::$apps[ $_key ]->init(); } else { throw new Exception( "No like class available for $app - $area" ); } } else { throw new Exception( "No like class available for $app - $area" ); } return self::$apps[ $_key ]; } } /** * Composite class. Holds main functionality. * * @author matt */ abstract class classes_like_composite { /**#@+ * Registry Object Shortcuts * * @var object */ protected $registry; protected $DB; protected $settings; protected $request; protected $lang; protected $member; protected $memberData; protected $cache; protected $caches; /**#@-*/ /** * Cache object * * @var object */ protected $likeCache = null; /** * App key * * @var object */ protected $_app; /** * App key * * @var object */ protected $_area; /** * Local settings object * * @var array */ protected $_settings; /** * Init. Yes, it is. * * @return void */ public function init() { $this->_app = classes_like_registry::getApp(); $this->_area = classes_like_registry::getArea(); if ( empty( $this->_app ) OR empty( $this->_area ) ) { trigger_error( "Missing area or app variable in " . __CLASS__ . '::' . __FUNCTION__, E_USER_WARNING ); } /* Fetch cache class */ $this->likeCache = classes_like_cache::getInstance(); /* Set a default cache expiration of an hour */ $this->likeCache->setExpiration( 3600 ); } /** * Add a like * * @param int Relationship ID * @param int Member ID of user being added * @param array Notification options * @param int Anon flag * @return boolean */ public function add( $relId, $memberId, array $notifyOpts, $isAnon=false ) { if ( empty( $relId ) OR empty( $memberId ) ) { trigger_error( "Data missing in " . __CLASS__ . '::' . __FUNCTION__, E_USER_WARNING ); } /* first check to ensure we've not already like'd this item */ if ( $this->isLiked($relId, $memberId) ) { /* if any one cares to check, then we're all good */ return false; } $notifyOpts = $this->_cleanNotifyOptions($notifyOpts); /* Save to deebee */ $this->DB->insert( 'core_like', array( 'like_id' => classes_like_registry::getKey( $relId, $memberId ), 'like_lookup_id' => classes_like_registry::getKey( $relId ), 'like_app' => $this->_app, 'like_area' => $this->_area, 'like_rel_id' => $relId, 'like_member_id' => $memberId, 'like_added' => time(), 'like_is_anon' => $isAnon, 'like_notify_do' => $notifyOpts['like_notify_do'], 'like_notify_meta' => $notifyOpts['like_notify_meta'], 'like_notify_freq' => ( $notifyOpts['like_notify_do'] ) ? $notifyOpts['like_notify_freq'] : '', 'like_notify_sent' => 0 ) ); /* Flag cache as stale */ $this->likeCache->isNowStale( $relId ); return true; } /** * Send notifications to anyone subscribed to item * * @param int Relationship ID * @param array Types of notifications to send (Possible: immediate, offline, daily, weekly) * @param array Notification options (Keys: notification_key, notification_url, email_template, email_subject, build_message_array, from (optional)) * @return boolean * @see allowedFrequencies() */ public function sendNotifications( $relId, $type, $notificationOpts=array() ) { if ( empty( $relId ) ) { trigger_error( "Data missing in " . __CLASS__ . '::' . __FUNCTION__, E_USER_WARNING ); } $type = is_array($type) ? $type : array( $type ); //----------------------------------------- // Get users who have liked this item //----------------------------------------- $data = $this->getDataByRelationshipId( $relId ); //----------------------------------------- // If no users, just return //----------------------------------------- if ( is_null($data) ) { return false; } $classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . '/sources/classes/member/notifications.php', 'notifications' ); $notifyLibrary = new $classToLoad( $this->registry ); //----------------------------------------- // Loop over members and send notifications //----------------------------------------- foreach( $data as $row ) { //----------------------------------------- // Make sure this user is subscribed with this type //----------------------------------------- if( !$row['like_notify_freq'] OR !in_array( $row['like_notify_freq'], $type ) ) { continue; } //----------------------------------------- // If "offline" type, make sure user is offline //----------------------------------------- if( $row['like_notify_freq'] == 'offline' AND $row['last_activity'] > ( time() - $this->settings['session_expiration'] ) ) { continue; } //----------------------------------------- // Start building notification //----------------------------------------- IPSText::getTextClass('email')->getTemplate( $notificationOpts['email_template'], $row['language'] ); //----------------------------------------- // Dynamically replace per-user data in message array //----------------------------------------- $buildMessage = array(); if ( is_array( $notificationOpts['build_message_array'] ) and count( $notificationOpts['build_message_array'] ) ) { foreach( $notificationOpts['build_message_array'] as $k => $v ) { if ( preg_match( '/\-member:(.+?)\-/', $v, $_matches ) ) { $v = str_replace( $_matches[0], $row[$_matches[1]], $v ); } $buildMessage[$k] = $v; } } IPSText::getTextClass('email')->buildMessage( $buildMessage ); $notifyLibrary->setMember( $row ); $notifyLibrary->setFrom( $notificationOpts['from'] ? $notificationOpts['from'] : $this->memberData ); $notifyLibrary->setNotificationKey( $notificationOpts['notification_key'] ); $notifyLibrary->setNotificationUrl( $notificationOpts['notification_url'] ); $notifyLibrary->setNotificationText( IPSText::getTextClass('email')->message ); $notifyLibrary->setNotificationTitle( $notificationOpts['email_subject'] ); try { $notifyLibrary->sendNotification(); } catch( Exception $e ){} //----------------------------------------- // Update sent timestamp //----------------------------------------- $this->DB->update( 'core_like', array( 'like_notify_sent' => time() ), 'like_id=\'' . classes_like_registry::getKey( $row['like_rel_id'], $row['like_member_id'] ) . '\'' ); } return true; } /** * Removes a like * * @param int Relationship ID * @param int Optional - If supplied, it'll remove that member rel. or it will remove all * @param array Notification options * @param int Anon flag * @return boolean */ public function remove( $relId, $memberId=null ) { if ( empty( $relId ) ) { trigger_error( "Data missing in " . __CLASS__ . '::' . __FUNCTION__, E_USER_WARNING ); } if ( $memberId === null ) { /* Save to deebee */ $this->DB->delete( 'core_like', 'like_lookup_id=\'' . classes_like_registry::getKey( $relId ) . '\'' ); } else { /* Not liked? Save us the bother, then */ if ( ! $this->isLiked($relId, $memberId) ) { /* if any one cares to check, then we're all good */ return false; } /* Save to deebee */ $this->DB->delete( 'core_like', 'like_id=\'' . classes_like_registry::getKey( $relId, $memberId ) . '\'' ); } /* Flag cache as stale */ $this->likeCache->isNowStale( $relId ); return true; } /** * Render a view * * @param string $view * @param int $relId * @param array Options * @param int $memberId * @return string */ public function render( $view, $relId, $opts=array(), $memberId = null ) { /* In the future we could abstract this out to its own class * At this time we only have a few views so it would be overkill */ if ( $view == 'summary' ) { $data = array( 'names' => array(), 'count' => 0, 'formatted' => '', 'iFave' => false ); $cache = $this->likeCache->get( $relId ); /* We had the total count set from cache.get */ if ( classes_like_registry::getTotalCount() ) { /* fetch data */ if ( $this->memberData['member_id'] AND $this->isLiked($relId, $this->memberData['member_id'] ) ) { /* Now mix up the data */ $data['names'][] = array( 'name' => $this->lang->words['fave_moi'], 'seo' => $this->memberData['members_seo_name'], 'id' => $this->memberData['member_id'] ); /* Flag as me */ $data['iFave'] = true; } if ( is_array( $cache['members'] ) ) { $i = 1; $max = 3; foreach( $cache['members'] as $mid => $mdata ) { $_last = ( $i == $cache['count'] || $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'] = $cache['count']; $data['othersCount'] = ( $cache['count'] > $max ) ? $cache['count'] - $max : 0; $data['app'] = $this->_app; $data['area'] = $this->_area; $data['formatted'] = $this->_formatNameString( $data ); if ( IPS_IS_AJAX ) { return $this->registry->output->getTemplate( $this->skin() )->likeSummaryContents( $data, $relId, $opts ); } else { return $this->registry->output->getTemplate( $this->skin() )->likeSummary( $data, $relId, $opts ); } } else if ( $view == 'more' ) { /* Fetch members who have wanted to favorite this item */ $data = $this->getDataByRelationshipId( $relId ); return $this->registry->output->getTemplate( $this->skin() )->likeMoreDialogue( $data, $relId ); } } /** * Fetch form data for set dialogue * * @param int relationship id * @return array */ public function getDataForSetDialogue( $relid ) { $return = array( 'frequencies' => $this->allowedFrequencies(), 'notifyType' => $this->getNotifyType() ); return $return; } /** * Has this user made this item a fave already dudes? * * @param int Relationship ID * @param int Member ID * @return boolean */ public function isLiked( $relId, $memberId ) { /* Grab the data */ return ( $this->getDataByMemberIdAndRelationshipId( $relId, $memberId ) === null ) ? false : true; } /** * Get data based on a relationship ID and a member ID * * @param mixed int $relId or array $relId (many) * @param int $memberId * @return array Favorite data OR null */ public function getDataByMemberIdAndRelationshipId( $relId, $memberId ) { $where = ''; if ( is_numeric( $relId ) ) { $where = 'like_id=\'' . classes_like_registry::getKey( $relId, $memberId ) . '\''; } else if ( is_array( $relId ) ) { $relId = IPSLib::cleanIntArray( $relId ); $keys = array(); foreach( $relId as $id ) { $keys[] = "'" . classes_like_registry::getKey( $id, $memberId ) . "'"; } if ( ! count( $keys ) ) { return null; } $where = 'like_id IN (' . implode( ',', $keys ) . ')'; } $this->DB->build( array( 'select' => '*', 'from' => 'core_like', 'where' => $where ) ); $o = $this->DB->execute(); while( $row = $this->DB->fetch( $o ) ) { $data[ $row['like_rel_id'] ] = $row; } /* Just the one? */ if ( is_numeric( $relId ) and count( $data ) ) { $data = array_shift( $data ); } return ( is_array( $data ) ) ? $data : null; } /** * Get data based on a relationship ID * * @param int $relId * @return mixed Array of like data OR null */ public function getDataByRelationshipId( $relId ) { /* Init */ $mids = array(); $members = array(); $rows = array(); /* Fetch data */ $this->DB->build( array( 'select' => '*', 'from' => 'core_like', 'where' => 'like_lookup_id=\'' . classes_like_registry::getKey( $relId ) . '\' AND like_is_anon=0', 'order' => 'like_added DESC', 'limit' => array( 0, 250 ) ) ); $o = $this->DB->execute(); while( $row = $this->DB->fetch( $o ) ) { $data[ $row['like_member_id'] ] = $row; $mids[ $row['like_member_id'] ] = intval( $row['like_member_id'] ); } /* Just the one? */ if ( count( $mids ) ) { $members = IPSMember::load( $mids, 'all' ); foreach( $members as $i => $d ) { $_m = IPSMember::buildProfilePhoto( $d ); $data[ $i ] = array_merge( (array) $_m, (array) $data[ $i ] ); } } return ( is_array( $data ) ) ? $data : null; } /** * Clean the notification options to make sure they're all nice and fluffy * * @param array $notifyOpts * @return array */ private function _cleanNotifyOptions( array $notifyOpts ) { if ( isset( $notifyOpts['like_notify_do'] ) ) { $notifyOpts['like_notify_do'] = intval( $notifyOpts['like_notify_do'] ); } else { $notifyOpts['like_notify_do'] = 0; } if ( ! isset( $notifyOpts['like_notify_meta'] ) ) { $notifyOpts['like_notify_meta'] = ''; } if ( isset( $notifyOpts['like_notify_freq'] ) ) { $notifyOpts['like_notify_freq'] = ( in_array( $notifyOpts['like_notify_freq'], $this->allowedFrequencies() ) ) ? $notifyOpts['like_notify_freq'] : ''; } else { $notifyOpts['like_notify_freq'] = 0; } return $notifyOpts; } /** * Return an array of acceptable frequencies * Possible: immediate, offline, daily, weekly * * @return array */ public function allowedFrequencies() { return array( 'immediate', 'offline', 'daily', 'weekly' ); } /** * return type of notification available for this item * * @return array key, human readable */ public function getNotifyType() { return array( 'comments', 'comments' ); } /** * Fetch the template group * * @return string */ public function skin() { return 'global_other'; } /** * Return the title based on the passed id * * @param int Relationship ID * @return string Title */ public function getTitleFromId( $relId ) { $meta = $this->getMeta( $relId, array( 'title' ) ); if ( is_numeric( $relId ) ) { return $meta[ $relId ]['like.title']; } else { $return = array(); foreach( $meta as $id => $data ) { $return[ $id ] = $data['like.title']; } return $return; } } /** * Return the URL based on the passed id * * @param int Relationship ID * @return string URL */ public function getUrlFromId( $relId ) { $meta = $this->getMeta( $relId, array( 'url' ) ); if ( is_numeric( $relId ) ) { return $meta[ $relId ]['like.url']; } else { $return = array(); foreach( $meta as $id => $data ) { $return[ $id ] = $data['like.url']; } return $return; } } /** * Formats the Bob, Bill, Joe and 2038 Others Hate You * * @param array $data * @return string */ private function _formatNameString( array $data ) { $langString = ''; $seeMoreLink = 'app=core&module=global&section=like&do=more'; 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] = IPSLib::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['fave_and'] . ' ' . $_names[1]; $langString = sprintf( $this->lang->words['fave_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['fave_formatted_many'], $_n ); } /* Joe, Matt, Mike and 1 more love you */ else if ( $data['totalCount'] == 4 ) { $_n = $_names[0] . ', ' . $_names[1] . ' ' . $this->lang->words['fave_and'] . ' ' . $_names[2]; $langString = sprintf( $this->lang->words['fave_formatted_one_more'], $_n, $seeMoreLink ); } /* 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['fave_formatted_more'], $_n, $seeMoreLink, $data['othersCount'] ); } } else { /* Just the one and it might be you! */ if ( $data['names'][0]['id'] == $this->memberData['member_id'] ) { $langString = $this->lang->words['fave_formatted_me']; } else { $langString = sprintf( $this->lang->words['fave_formatted_one'], $_names[0] ); } } return $langString; } } /** * Favorites cache class * * @author matt */ class classes_like_cache { /**#@+ * Registry Object Shortcuts * * @var object */ protected $registry; protected $DB; protected $settings; protected $request; protected $lang; protected $member; protected $cache; /**#@-*/ /** * Cache expiration * * @var int */ protected $_expire = 0; /** * App key * * @var object */ protected $_app; /** * App key * * @var object */ protected $_area; /** * Instance of an object * * @var object */ private static $instance = null; /** * Singleton * * @return object */ public static function getInstance() { if ( self::$instance === null ) { self::$instance = new self(); } return self::$instance; } /** * Our desctructor. Just kidding. * * @return void */ public function __construct() { /* Fetch registry like a good boy */ $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->_app = classes_like_registry::getApp(); $this->_area = classes_like_registry::getArea(); if ( empty( $this->_app ) OR empty( $this->_area ) ) { trigger_error( "Missing area or app variable in " . __CLASS__ . '::' . __FUNCTION__, E_USER_WARNING ); } } /** * Set the cache expiration * * @param int $seconds * @return void */ public function setExpiration( $seconds ) { $this->_expire = intval( $seconds ); } /** * Fetch an item from the cache * * @param int $relId * @param int $memberId * @return array */ public function get( $relId, $memberId = null ) { /* Possible future expansion */ if ( $memberId === null ) { $cache = $this->DB->buildAndFetch( array( 'select' => '*', 'from' => 'core_like_cache', 'where' => 'like_cache_id=\'' . classes_like_registry::getKey( $relId ) . '\'' ) ); if ( ! is_array( $cache ) OR ( $cache['like_cache_expire'] <= time() ) ) { /* We don't have a valid cache, so create one and return the data */ $cache = $this->create( $relId, $memberId ); } $tmp = unserialize( $cache['like_cache_data'] ); $cache['members'] = $tmp['members']; $cache['count'] = intval( $tmp['count'] ); /* Set total count for use elsewhere */ classes_like_registry::setTotalCount( $cache['count'] ); return $cache; } } /** * Creates/updates the relationship ID's cache. * * @param int $relId * @param int $memberId * @return array Array of data stored */ public function create( $relId, $memberId = null ) { $items = array(); $members = array(); $mids = array(); $data = array( 'members' => null, 'count' => 0 ); /* Possible future expansion */ if ( $memberId === null ) { /* Count all first */ $cou = $this->DB->buildAndFetch( array( 'select' => 'COUNT(*) as nt', 'from' => 'core_like', 'where' => 'like_lookup_id=\'' . classes_like_registry::getKey( $relId ) . '\' AND like_is_anon=0' ) ); $data['count'] = intval( $cou['nt'] ); /* Fetch all items for this app:key:$relId */ $this->DB->build( array( 'select' => '*', 'from' => 'core_like', 'where' => 'like_lookup_id=\'' . classes_like_registry::getKey( $relId ) . '\' AND like_is_anon=0', 'order' => 'like_added DESC', 'limit' => array( 0, 5 ) ) ); $o = $this->DB->execute(); while( $row = $this->DB->fetch($o) ) { $items[ $row['like_rel_id'] ] = $row; $mids[ $row['like_member_id'] ] = $row['like_member_id']; } /* Load members */ $members = IPSMember::load( $mids, 'core' ); /* We don't need all the member's infos */ foreach( $members as $mid => $mdata ) { $data['members'][ $mid ] = array( 'n' => $mdata['members_display_name'], 's' => $mdata['members_seo_name'] ); } /* Build save array */ $store = array( 'like_cache_id' => classes_like_registry::getKey( $relId ), 'like_cache_app' => $this->_app, 'like_cache_area' => $this->_area, 'like_cache_rel_id' => $relId, 'like_cache_data' => serialize( $data ), 'like_cache_expire' => time() + $this->_expire ); /* Update the cache */ $this->DB->replace( 'core_like_cache', $store, array( 'like_cache_id' ) ); return $store; } /* We know there's a previous cache row, so delete it */ $this->DB->delete( 'core_like_cache', 'like_cache_id=\'' . classes_like_registry::getKey( $relId ) . '\'' ); } /** * Deletes a cache. * * @param int $relId * @param int $memberId * @return void */ public function delete( $relId, $memberId = null ) { /* Possible future expansion */ if ( $memberId === null ) { $this->DB->delete( 'core_like_cache', 'like_cache_id=\'' . classes_like_registry::getKey( $relId ) . '\'' ); } } /** * Flags a cache as stale. We choose to delete, but the cache class should make the call * not the application * * @param int $relId * @param int $memberId * @return void */ public function isNowStale( $relId, $memberId = null ) { return $this->delete( $relId, $memberId ); } }