Version 3.1.4

This commit is contained in:
Neo committed 2025-12-19 00:32:22 -08:00
1 parent 1d4720f3e2
commit ae5c01cc78
2563 files changed
+283048 -240689

No files matched your search

@@ -1,19 +1,21 @@
<?php
/**
* <pre>
* Invision Power Services
* IP.Board v3.0.5
* IP.Board v3.1.4
* Item Marking
* Owner: Matt "Oh Lord, why did I get assigned this?" Mecham
* Last Updated: $Date: 2009-12-07 08:17:42 -0500 (Mon, 07 Dec 2009) $
* Last Updated: $Date: 2010-10-06 06:09:32 -0400 (Wed, 06 Oct 2010) $
* </pre>
*
* @author $Author: matt $
* @author $Author: mmecham $
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
* @license http://www.iinvisionpower.com/community/board/license.html
* @package Invision Power Board
* @link http://www.iinvisionpower.com
* @license http://www.invisionpower.com/community/board/license.html
* @package IP.Board
* @link http://www.invisionpower.com
* @since 9th March 2005 11:03
* @version $Revision: 5523 $
* @version $Revision: 6946 $
*
* @todo [Future] Perhaps find more ways to reduce the size of items_read
* @todo [Future] Maybe add an IN_DEV tool to warn when markers have been cancelled out / size drastically reduced
@@ -150,6 +152,8 @@ class classItemMarking
*/
private $_noGuestMarking = false;
private $_setSaveCookie = false;
/**
* Method constructor
*
@@ -383,6 +387,35 @@ class classItemMarking
}
}
/**
* Public method to get cookie
*
* @access public
* @param string APP
* @param string Type of key (items, read)
* @return mixed
*/
public function fetchCookieData( $app, $type )
{
if ( $app )
{
$key = ( $type != 'items' ) ? 'itemMarking_' . $app : 'itemMarking_' . $app . '_items';
return $this->_fetchCookieData( $key );
}
}
/**
* Set the flag to save cookies in mydestruct
*
* @access protected
* @return void
*/
protected function _setSaveCookie()
{
$this->_setSaveCookie = true;
}
/**
* Save cookie
*
@@ -396,7 +429,7 @@ class classItemMarking
{
return;
}
if ( $key AND is_array( $this->_cookie[ $key ] ) )
{
IPSCookie::set( $key, $this->_cookie[ $key ], 1 );
@@ -434,7 +467,7 @@ class classItemMarking
*
* Forum example (forumID is mapped to :item_app_key_1). itemID is the topic ID
*
* @example $read = $itemMarking->isRead( array( 'forumID' => 2, 'itemID' => 99, 'itemLastUpdate' => 1989098989 ) );
* <code>$read = $itemMarking->isRead( array( 'forumID' => 2, 'itemID' => 99, 'itemLastUpdate' => 1989098989 ) );</code>
*
* @access public
* @param array Array of data
@@ -489,8 +522,8 @@ class classItemMarking
*
* Forum example (forumID is mapped to :item_app_key_1). itemID is the topic ID
*
* @example $itemMarking->markAsRead( array( 'forumID' => 34, 'itemID' => 99 ) )
* @example $itemMarking->markAsRead( array( 'forumID' => 34 ) )
* <code>$itemMarking->markAsRead( array( 'forumID' => 34, 'itemID' => 99 ) );</code>
* <code>$itemMarking->markAsRead( array( 'forumID' => 34 ) );</code>
*
* @access public
* @param array
@@ -545,36 +578,45 @@ class classItemMarking
}
/* Overwrite read items */
$_readItems = $this->_itemMarkers[ $app ][ $mainKey ]['item_read_array'];
if ( is_array( $this->_itemMarkers[ $app ][ $mainKey ]['item_read_array'] ) )
{
foreach( $this->_itemMarkers[ $app ][ $mainKey ]['item_read_array'] as $i => $d )
{
$_readItems[ $i ] = $d;
}
}
}
/* Check last reset time */
$_lastReset = IPSLib::fetchHighestNumber( array( $_cookieGreset, isset( $cookie['global']) ? $cookie['global'] : 0, intval( $this->_itemMarkers[ $app ][ $mainKey ]['item_global_reset'] ) ) );
/* Fetch unread items */
$_unreadCount = $this->_fetchModule( $app )->fetchUnreadCount( $origData, $_readItems, $_lastReset );
if ( $_unreadCount['count'] > 0 )
if ( $this->settings['topic_marking_enable'] OR ( ! $this->settings['topic_marking_enable'] AND ! $this->settings['topic_marking_noquery'] ) )
{
if ( $this->settings['topic_marking_enable'] )
$_unreadCount = $this->_fetchModule( $app )->fetchUnreadCount( $origData, $_readItems, $_lastReset );
if ( $_unreadCount['count'] > 0 )
{
$this->_itemMarkers[ $app ][ $mainKey ]['item_unread_count'] = $_unreadCount['count'];
if ( $this->settings['topic_marking_enable'] )
{
$this->_itemMarkers[ $app ][ $mainKey ]['item_unread_count'] = $_unreadCount['count'];
}
}
}
else
{
if ( $this->settings['topic_marking_enable'] )
else
{
/* Update the last global reset time and clear the read array */
$this->_itemMarkers[ $app ][ $mainKey ]['item_read_array'] = array();
$this->_itemMarkers[ $app ][ $mainKey ]['item_global_reset'] = time();
$this->_itemMarkers[ $app ][ $mainKey ]['item_unread_count'] = 0;
if ( $this->settings['topic_marking_enable'] )
{
/* Update the last global reset time and clear the read array */
$this->_itemMarkers[ $app ][ $mainKey ]['item_read_array'] = array();
$this->_itemMarkers[ $app ][ $mainKey ]['item_global_reset'] = time();
$this->_itemMarkers[ $app ][ $mainKey ]['item_unread_count'] = 0;
}
/* Cookie */
$cookie['greset'][ $this->_makeKey( $data, TRUE ) ] = time();
$this->_updateCookieData( 'itemMarking_' . $app, $cookie );
$this->_updateCookieData( 'itemMarking_' . $app . '_items', array() );
}
/* Cookie */
$cookie['greset'][ $this->_makeKey( $data, TRUE ) ] = time();
$this->_updateCookieData( 'itemMarking_' . $app, $cookie );
$this->_updateCookieData( 'itemMarking_' . $app . '_items', array() );
}
}
else
@@ -597,7 +639,7 @@ class classItemMarking
$this->_itemMarkers[ $app ][ $mainKey ]['item_last_update'] = time();
/* Save cookie */
$this->_saveCookie();
$this->_setSaveCookie();
/* Save markers */
if ( $this->fetchInstantSaveStatus() )
@@ -637,8 +679,8 @@ class classItemMarking
/* Reset member cache */
IPSMember::packMemberCache( $this->memberData['member_id'], array('gb_mark__' . $app => time() ) );
/* Delete permanent rows */
$this->DB->delete( 'core_item_markers', "item_app='" . $app . "' AND item_member_id=" . intval( $this->memberData['member_id'] ) );
/* Mark rows for deletion */
$this->DB->update( 'core_item_markers', array( 'item_is_deleted' => 1 ), "item_app='" . $app . "' AND item_member_id=" . intval( $this->memberData['member_id'] ) );
/* Update the last global reset time and clear the read array */
$this->_itemMarkers[ $app ][ $_key ]['item_read_array'] = array();
@@ -661,8 +703,27 @@ class classItemMarking
/* Do 'em all */
$cache = array();
/* Bug #23130 If DB marking is off, _itemMarkers is empty, so we just assume forums */
if ( ! count( $this->_itemMarkers ) )
{
$this->_itemMarkers = array( 'forums' => array() );
}
foreach( $this->_itemMarkers as $app => $data )
{
/* Only process is the app actually does topic marking */
$f = IPSLib::getAppDir( $app ) . '/extensions/coreExtensions.php';
if ( file_exists( $f ) )
{
require_once( $f );
if ( ! @class_exists( 'itemMarking__' . $app ) )
{
continue;
}
}
$cache[ 'gb_mark__' . $app ] = time();
/* Update cookies */
@@ -679,8 +740,8 @@ class classItemMarking
/* Delete temporary storage */
$this->DB->delete( 'core_item_markers_storage', 'item_member_id=' . intval( $this->memberData['member_id'] ) );
/* Delete permanent rows */
$this->DB->delete( 'core_item_markers', "item_member_id=" . intval( $this->memberData['member_id'] ) );
/* Mark rows for deletion */
$this->DB->update( 'core_item_markers', array( 'item_is_deleted' => 1 ), 'item_member_id=' . intval( $this->memberData['member_id'] ) );
/* Reset internal array */
$this->_itemMarkers = array();
@@ -690,7 +751,7 @@ class classItemMarking
}
/* Save cookie */
$this->_saveCookie();
$this->_setSaveCookie();
}
/**
@@ -750,17 +811,62 @@ class classItemMarking
return 0;
}
/**
* Fetches the oldest unread timestamp
*
* In this example we are retrieving the number of unread items for a forum id 2
* $unreadCount = $this->fetchOldestUnreadTimestamp( array( 'forumID' => 2 ) );
*
* @access public
* @param array Data
* @param string App
* @return int Number of unread items left
*/
public function fetchOldestUnreadTimestamp( $data, $app='' )
{
$app = ( $app ) ? $app : IPS_APP_COMPONENT;
$data = $this->_fetchModule( $app )->convertData( $data );
$time = IPS_UNIX_TIME_NOW;
if ( ! isset( $data['item_app_key_1'] ) )
{
if ( is_array( $this->_itemMarkers[ $app ] ) AND count( $this->_itemMarkers[ $app ] ) )
{
foreach( $this->_itemMarkers[ $app ] as $key => $_data )
{
if ( $_data['item_global_reset'] && ( $_data['item_global_reset'] < $time ) )
{
$time = $_data['item_global_reset'];
}
}
}
}
else
{
$mainKey = $this->_findMainRowByKey( $data, $app );
$_data = $this->_itemMarkers[ $app ][ $mainKey ];
if ( $_data['item_global_reset'] && ( $_data['item_global_reset'] < $time ) )
{
$time = $_data['item_global_reset'];
}
}
return $time;
}
/**
* Fetch read IDs since last global reset
* Returns IDs read based on incoming data
*
* @example $readIDs = $itemMarking->fetchReadIds( array( 'forumID' => 2 ) );
* <code>$readIDs = $itemMarking->fetchReadIds( array( 'forumID' => 2 ) );</code>
* @access public
* @param array Array of data
* @param strng [App]
* @return array Array of read item IDs
*/
public function fetchReadIds( $data, $app='' )
public function fetchReadIds( $data, $app='', $keysOnly=true )
{
$app = ( $app ) ? $app : IPS_APP_COMPONENT;
$origData = $data;
@@ -769,7 +875,7 @@ class classItemMarking
if ( isset( $this->_itemMarkers[ $app ][ $mainKey ]['item_read_array'] ) AND is_array($this->_itemMarkers[ $app ][ $mainKey ]['item_read_array']) )
{
return array_keys( $this->_itemMarkers[ $app ][ $mainKey ]['item_read_array'] );
return ( $keysOnly ) ? array_keys( $this->_itemMarkers[ $app ][ $mainKey ]['item_read_array'] ) : $this->_itemMarkers[ $app ][ $mainKey ]['item_read_array'];
}
else
{
@@ -777,6 +883,32 @@ class classItemMarking
}
}
/**
* Fetch read ID
* If forum was cleared, it may not exist as global reset takes precidence.
* <code>$readIDs = $itemMarking->fetchReadId( array( 'forumID' => 2, 'itemId' => 2 ) );</code>
* @access public
* @param array Array of data
* @param strng [App]
* @return int 0 or timestamp
*/
public function fetchItemReadTime( $data, $app='' )
{
$app = ( $app ) ? $app : IPS_APP_COMPONENT;
$origData = $data;
$data = $this->_fetchModule( $app )->convertData( $data );
$mainKey = $this->_findMainRowByKey( $data, $app );
if ( isset( $this->_itemMarkers[ $app ][ $mainKey ]['item_read_array'] ) AND is_array($this->_itemMarkers[ $app ][ $mainKey ]['item_read_array']) )
{
return intval( $this->_itemMarkers[ $app ][ $mainKey ]['item_read_array'][ $data['itemID'] ] );
}
else
{
return 0;
}
}
/**
* Save my markers to DB
*
@@ -784,6 +916,7 @@ class classItemMarking
*
* @access public
* @return int Number of rows saved
* @deprecated 3.1.0
*/
public function writeMyMarkersToDB()
{
@@ -819,7 +952,7 @@ class classItemMarking
}
/**
* Find latest Global reset
* Find latest Item reset
*
* @access protected
* @param array Array of data (DB field names)
@@ -882,7 +1015,7 @@ class classItemMarking
}
$mainKey = $this->_findMainRowByKey( $data, $app );
/* Got all fields? */
if ( isset( $this->_itemMarkers[ $app ][ $mainKey ]['item_global_reset'] ) )
{
@@ -925,7 +1058,7 @@ class classItemMarking
$_key = $this->_makeKey( $data );
if ( ! is_array( $this->_itemMarkers[ $app ] ) )
if ( ! isset( $this->_itemMarkers[ $app ] ) OR ! is_array( $this->_itemMarkers[ $app ] ) )
{
/* Mark markers as having changed */
$this->_changesMade = TRUE;
@@ -943,7 +1076,7 @@ class classItemMarking
return $_key;
}
if ( is_array( $this->_itemMarkers[ $app ][ $_key ] ) )
if ( ! empty( $this->_itemMarkers[ $app ][ $_key ] ) AND is_array( $this->_itemMarkers[ $app ][ $_key ] ) )
{
/* Make sure it contains the app & key */
$this->_itemMarkers[ $app ][ $_key ]['item_app'] = $app;
@@ -1167,7 +1300,8 @@ class classItemMarking
'item_last_saved' => time(),
'item_read_array' => ( is_array( $data['item_read_array'] ) ) ? serialize( $data['item_read_array'] ) : $data['item_read_array'],
'item_global_reset' => intval( $data['item_global_reset'] ),
'item_last_update' => intval( $data['item_last_update'] ) );
'item_last_update' => intval( $data['item_last_update'] ),
'item_is_deleted' => 0 );
/* Overwrite $data with the values in $row */
$new_array = array_merge( $data, $row );
@@ -1181,13 +1315,11 @@ class classItemMarking
/* Weed out useless rows */
if ( ! $new_array['item_global_reset'] AND ! $new_array['item_unread_count'] AND ( ! $new_array['item_read_array'] OR $new_array['item_read_array'] == 'a:0:{}' ) )
{
$this->DB->delete( 'core_item_markers', "item_key='{$key}' AND item_app='{$app}' AND item_member_id=" . $memberID );
$new_array['item_is_deleted'] = 1;
IPSDebug::addLogMessage( "Item Markers NOT saved", 'marker_skipped-' . $memberID, $new_array );
}
else
{
$this->DB->replace( 'core_item_markers', $new_array, array( 'item_key', 'item_app', 'item_member_id' ) );
}
$this->DB->replace( 'core_item_markers', $new_array, array( 'item_key', 'item_app', 'item_member_id' ) );
}
}
}
@@ -1221,6 +1353,12 @@ class classItemMarking
return;
}
/* Save cookies */
if ( $this->_setSaveCookie )
{
$this->_saveCookie();
}
/* Save the storage table if not done so already */
$this->_saveStorage();
@@ -1229,13 +1367,11 @@ class classItemMarking
{
/* Check every 5 mins */
$cache = $this->caches['systemvars'];
$update = 0;
/* Fail safe */
if ( ! $cache['itemMarkerClean'] )
{
$cache['itemMarkerClean'] = 0;
$update = 1;
}
if ( time() - 300 > $cache['itemMarkerClean'] )
@@ -1249,6 +1385,10 @@ class classItemMarking
$_time = 1;
}
/* Save Cache BEFORE running clean up to stop race conditions */
$cache['itemMarkerClean'] = time();
$this->cache->setCache( 'systemvars', $cache, array( 'array' => 1, 'donow' => 1 ) );
/* Clean 'em up */
$_c = $this->manualCleanUp( 50, ++$_time, FALSE );
@@ -1256,16 +1396,6 @@ class classItemMarking
{
IPSDebug::addLogMessage( "Manually cleaned up: " . $_c . ' hit by ID ' . $this->memberData['member_id'], 'markerClean' );
}
$update = 1;
}
/* Update */
if ( $update )
{
/* Save Cache */
$cache['itemMarkerClean'] = time();
$this->cache->setCache( 'systemvars', $cache, array( 'array' => 1, 'donow' => 1 ) );
}
}
}
@@ -1303,46 +1433,6 @@ class classItemMarking
return true;
}
/**
* Check to see if we need to save our markers. Or not.
* And then write them. If we need too. I'm sure you get what
* I mean.
*
* @access protected
* @return boolean If writing was required
*/
protected function _checkThenWriteMarkers()
{
if ( ! $this->settings['topic_marking_enable'] )
{
return FALSE;
}
$_write = FALSE;
if ( $this->settings['topic_marking_save_freq'] == 'page' )
{
$_write = TRUE;
}
else if ( strstr( $this->settings['topic_marking_save_freq'], 'min-' ) )
{
$_min = str_replace( 'min-', '', $this->settings['topic_marking_save_freq'] );
if ( ( time() - $this->_lastSaved ) > ( $_min * 60 ) )
{
$_write = TRUE;
}
}
/* Write, right? */
if ( $_write === TRUE )
{
$this->writeMyMarkersToDB();
}
return $_write;
}
/**
* Build item markers.
* Ok, this function attempts to gather the corret item markers.
@@ -1387,7 +1477,10 @@ class classItemMarking
while( $row = $this->DB->fetch( $itemMarking ) )
{
$items[ $row['item_app'] ][ $row['item_key'] ] = $row;
if ( ! $row['item_is_deleted'] )
{
$items[ $row['item_app'] ][ $row['item_key'] ] = $row;
}
}
}