Version 4.7.23
This commit is contained in:
1 parent
7124a02564
commit
25ddeb65d6
1791 files changed
+76990
-44452
No files matched your search
+106
-25
@@ -13,6 +13,8 @@ namespace IPS\Content;
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
|
||||
use http\Exception\BadMethodCallException;
|
||||
use function array_merge;
|
||||
use function implode;
|
||||
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
@@ -50,7 +52,7 @@ trait Statistics
|
||||
*/
|
||||
public function imageAttachments( $count = 10 ): array
|
||||
{
|
||||
$attachments = $this->_getAllAttachments( array( 'attach_is_image=1' ), $count, 'attach_date DESC' );
|
||||
$attachments = $this->_getAllAttachments( array( 'attach_is_image=1' ), $count, 'attachment_id DESC' );
|
||||
$attachments = \array_slice( $attachments, 0, $count );
|
||||
|
||||
return $attachments;
|
||||
@@ -120,11 +122,12 @@ trait Statistics
|
||||
/**
|
||||
* Most Recent Participans
|
||||
*
|
||||
* @param string|NULL $name If we are looking for a specific user.
|
||||
* @param int $limit The amount of results to return.
|
||||
* @param string|NULL $name If we are looking for a specific user.
|
||||
* @param int $limit The amount of results to return.
|
||||
* @param bool $incBanned Include banned members? (Used to exclude from recent mentions)
|
||||
* @return \IPS\Patterns\ActiveRecordIterator
|
||||
*/
|
||||
public function mostRecent( ?string $name = NULL, int $limit = 10 )
|
||||
public function mostRecent( ?string $name = NULL, int $limit = 10, bool $incBanned = TRUE )
|
||||
{
|
||||
$commentClass = static::$commentClass;
|
||||
|
||||
@@ -135,11 +138,11 @@ trait Statistics
|
||||
|
||||
if ( $name )
|
||||
{
|
||||
$cacheKey = 'mostRecent_' . $limit . '_' . $name;
|
||||
$cacheKey = 'mostRecent_' . $limit . '_' . $name . '_' . (int) $incBanned;
|
||||
}
|
||||
else
|
||||
{
|
||||
$cacheKey = 'mostRecent_' . $limit;
|
||||
$cacheKey = 'mostRecent_' . $limit . '_' . (int) $incBanned;
|
||||
}
|
||||
|
||||
try
|
||||
@@ -152,7 +155,13 @@ trait Statistics
|
||||
$where = $this->_getVisibleWhere();
|
||||
if ( $name )
|
||||
{
|
||||
$subQuery = \IPS\Db::i()->select( 'core_members.member_id', 'core_members', \IPS\Db::i()->like( 'core_members.name', $name ) );
|
||||
$subWhere = array();
|
||||
$subWhere[] = \IPS\Db::i()->like( 'core_members.name', $name );
|
||||
if ( !$incBanned )
|
||||
{
|
||||
$subWhere[] = array( "core_members.temp_ban=?", 0 );
|
||||
}
|
||||
$subQuery = \IPS\Db::i()->select( 'core_members.member_id', 'core_members', $subWhere );
|
||||
$where[] = [ $commentClass::$databaseTable . '.' . $commentClass::$databasePrefix . $commentClass::$databaseColumnMap['author'] . ' IN(?)', $subQuery ];
|
||||
}
|
||||
|
||||
@@ -299,13 +308,22 @@ trait Statistics
|
||||
/**
|
||||
* Clear any cached stats
|
||||
*
|
||||
* @param bool $force Force immediate cache delete
|
||||
* @return void
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function clearCachedStatistics()
|
||||
public function clearCachedStatistics( bool $force=FALSE )
|
||||
{
|
||||
$idField = static::$databaseColumnId;
|
||||
\IPS\Db::i()->delete( 'core_item_statistics_cache', array( 'cache_class=? and cache_item_id=?', \get_class( $this ), $this->$idField ) );
|
||||
if( $force )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_item_statistics_cache', [ 'cache_class=? and cache_item_id=?', \get_class( $this ), $this->$idField ] );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set cache to time out in 10 minutes. */
|
||||
\IPS\Db::i()->update( 'core_item_statistics_cache', [ 'cache_added' => ( time() - 172200 ) ], [ 'cache_class=? and cache_item_id=?', \get_class( $this ), $this->$idField ] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -334,7 +352,13 @@ trait Statistics
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
{
|
||||
$where = array( array( 'location_key=? and id1=? and id2 IN(?)', static::$application . '_' . mb_ucfirst( static::$module ), $this->$idField, $this->_subQueryVisibleComments( $this->$idField ) ) );
|
||||
/* This is more efficient and avoids a very slow table join */
|
||||
if ( \stristr( $orderBy, 'attach_date' ) )
|
||||
{
|
||||
$orderBy = str_replace( 'attach_date', 'attachment_id', $orderBy );
|
||||
}
|
||||
|
||||
$where = array( array( 'location_key=? and id1=?', static::$application . '_' . mb_ucfirst( static::$module ), $this->$idField ) );
|
||||
|
||||
if ( $extraWhere !== NULL )
|
||||
{
|
||||
@@ -342,7 +366,24 @@ trait Statistics
|
||||
}
|
||||
|
||||
/* Get attachments from all comments */
|
||||
$return = iterator_to_array( \IPS\Db::i()->select( '*', 'core_attachments_map', $where, $orderBy, $limit )->join( 'core_attachments', array( 'attach_id=attachment_id' ) ) );
|
||||
$commentClass = static::$commentClass;
|
||||
$commentTableJoin = [ 'id2=' . $commentClass::$databasePrefix . $commentClass::$databaseColumnId ];
|
||||
if ( isset( $commentClass::$databaseColumnMap['approved'] ) )
|
||||
{
|
||||
$approvedColumn = $commentClass::$databasePrefix . $commentClass::$databaseColumnMap['approved'];
|
||||
$commentTableJoin[] = "{$approvedColumn} = 1";
|
||||
}
|
||||
if ( isset( $commentClass::$databaseColumnMap['hidden'] ) )
|
||||
{
|
||||
$hiddenColumn = $commentClass::$databasePrefix . $commentClass::$databaseColumnMap['hidden'];
|
||||
$commentTableJoin[] = "{$hiddenColumn} = 0";
|
||||
}
|
||||
|
||||
$return = iterator_to_array(
|
||||
\IPS\Db::i()->select( '*', 'core_attachments_map', $where, $orderBy, $limit )
|
||||
->join( 'core_attachments', array( 'attach_id=attachment_id' ) )
|
||||
->join( $commentClass::$databaseTable, array( implode( ' AND ', $commentTableJoin ) ), 'INNER' )
|
||||
);
|
||||
|
||||
/* Get link to comments */
|
||||
foreach( $return as $k => $map )
|
||||
@@ -443,6 +484,11 @@ trait Statistics
|
||||
*/
|
||||
static $cachedActivity = NULL;
|
||||
|
||||
/**
|
||||
* @var bool|null Process has rebuild lock
|
||||
*/
|
||||
protected ?bool $hasRebuildLock = NULL;
|
||||
|
||||
/**
|
||||
* Get the cached data
|
||||
*
|
||||
@@ -453,28 +499,57 @@ trait Statistics
|
||||
protected function _getCached( $key )
|
||||
{
|
||||
$idField = static::$databaseColumnId;
|
||||
if( $this->hasRebuildLock === FALSE )
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
$class = \get_class( $this );
|
||||
$arrayKey = $class.'.'.$this->$idField;
|
||||
if ( !isset( static::$cachedActivity[$arrayKey] ) )
|
||||
$arrayKey = $class . '.' . $this->$idField;
|
||||
if ( !isset( static::$cachedActivity[ $arrayKey ] ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$cache = \IPS\Db::i()->select( '*', 'core_item_statistics_cache', array( 'cache_class=? and cache_item_id=?', $class, $this->$idField ) )->first();
|
||||
|
||||
if ( $cache['cache_added'] > time() - 86400 )
|
||||
$cache = \IPS\Db::i()->select( '*', 'core_item_statistics_cache', [ 'cache_class=? and cache_item_id=?', $class, $this->$idField ] )->first();
|
||||
if ( $cache['cache_added'] > ( time() - 172800 ) )
|
||||
{
|
||||
static::$cachedActivity[ $arrayKey ] = json_decode( $cache['cache_contents'], TRUE );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_item_statistics_cache', array( 'cache_class=? and cache_item_id=?', \get_class( $this ), $this->$idField ) );
|
||||
$this->hasRebuildLock = TRUE;
|
||||
$affectedRows = \IPS\Db::i()->delete( 'core_item_statistics_cache', [ 'cache_class=? and cache_item_id=?', \get_class( $this ), $this->$idField ] );
|
||||
if( $affectedRows == 0 )
|
||||
{
|
||||
/* We did not delete the row, allow another process to rebuild the cache */
|
||||
$this->hasRebuildLock = FALSE;
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( \UnderflowException $e )
|
||||
{
|
||||
/* Try to get the lock for new cache generation */
|
||||
try
|
||||
{
|
||||
\IPS\Db::i()->insert( 'core_item_statistics_cache', [
|
||||
'cache_class' => \get_class( $this ),
|
||||
'cache_item_id' => $this->$idField,
|
||||
'cache_contents' => '[]',
|
||||
'cache_added' => time()
|
||||
] );
|
||||
$this->hasRebuildLock = TRUE;
|
||||
}
|
||||
/* We didn't get the lock, return empty array and allow other process to build cache */
|
||||
catch( \IPS\Db\Exception $e )
|
||||
{
|
||||
$this->hasRebuildLock = FALSE;
|
||||
return [];
|
||||
}
|
||||
}
|
||||
catch( \UnderflowException $e ) { }
|
||||
}
|
||||
|
||||
if ( isset(static::$cachedActivity[ $arrayKey ] ) and isset( static::$cachedActivity[ $arrayKey ][ $key ] ) )
|
||||
if ( isset( static::$cachedActivity[ $arrayKey ] ) and isset( static::$cachedActivity[ $arrayKey ][ $key ] ) )
|
||||
{
|
||||
return static::$cachedActivity[ $arrayKey ][ $key ];
|
||||
}
|
||||
@@ -482,10 +557,10 @@ trait Statistics
|
||||
{
|
||||
if( !isset( static::$cachedActivity[ $arrayKey ] ) )
|
||||
{
|
||||
static::$cachedActivity[ $arrayKey ] = array();
|
||||
static::$cachedActivity[ $arrayKey ] = [];
|
||||
}
|
||||
|
||||
static::$cachedActivity[ $arrayKey ][ $key ] = array();
|
||||
static::$cachedActivity[ $arrayKey ][ $key ] = [];
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
}
|
||||
@@ -528,14 +603,20 @@ trait Statistics
|
||||
{
|
||||
if( $this->storeCache )
|
||||
{
|
||||
$insert = [];
|
||||
foreach( $this->storeCache as $key => $data )
|
||||
{
|
||||
\IPS\Db::i()->insert( 'core_item_statistics_cache', array(
|
||||
$insert[] = array(
|
||||
'cache_class' => \get_class( $this ),
|
||||
'cache_item_id' => str_replace( \get_class($this) . '.', '', $key),
|
||||
'cache_contents' => json_encode( static::$cachedActivity[$key] ),
|
||||
'cache_item_id' => str_replace( \get_class( $this ) . '.', '', $key ),
|
||||
'cache_contents' => json_encode( static::$cachedActivity[ $key ] ) ?? '[]',
|
||||
'cache_added' => time()
|
||||
), TRUE );
|
||||
);
|
||||
}
|
||||
|
||||
if( \count( $insert ) )
|
||||
{
|
||||
\IPS\Db::i()->insert( 'core_item_statistics_cache', $insert, TRUE );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user