Version 4.5.0

This commit is contained in:
Neo committed 2025-12-19 05:51:58 -08:00
1 parent 1a0c7fd3c2
commit f79dcf067a
3791 files changed
+248032 -76372

No files matched your search

+87 -9
View File
@@ -11,7 +11,7 @@
namespace IPS\core\Digest;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -61,6 +61,12 @@ class _Digest
return;
}
/* Don't try on rows where the member may have been removed */
if ( !$this->member->member_id )
{
return;
}
/* We just do it this way because for backwards-compatibility, template parsing expects an \IPS\Email object with a $language property
This email is never actually sent and a new one is generated in send() */
$this->mail = \IPS\Email::buildFromTemplate( 'core', 'digest', array( $this->member, $this->frequency ), \IPS\Email::TYPE_LIST );
@@ -71,7 +77,7 @@ class _Digest
{
foreach ( $area as $items )
{
$numberOfItems += count( $items );
$numberOfItems += \count( $items );
}
}
$max = ceil( 80 / $numberOfItems );
@@ -93,7 +99,7 @@ class _Digest
{
$parents = class_parents( $class );
if ( in_array( 'IPS\Node\Model', $parents ) )
if ( \in_array( 'IPS\Node\Model', $parents ) )
{
foreach ( $follows as $follow )
{
@@ -109,8 +115,15 @@ class _Digest
$commentClass::$joinProfileFields = FALSE;
}
foreach ( $itemClass::getItemsWithPermission( array(
array( $itemClass::$databaseTable . '.' . $itemClass::$databasePrefix . $itemClass::$databaseColumnMap['container'] . '=? AND ' . $itemClass::$databaseTable . '.' . $itemClass::$databasePrefix . $itemClass::$databaseColumnMap['date'] . ' > ? AND ' . $itemClass::$databaseTable . '.' .$itemClass::$databasePrefix . $itemClass::$databaseColumnMap['author'] . '!=?', $follow['follow_rel_id'], $follow['follow_notify_sent'] ?: $follow['follow_added'], $follow['follow_member_id'] ) ),
$where = array(
array( $itemClass::$databaseTable . '.' . $itemClass::$databasePrefix . $itemClass::$databaseColumnMap['container'] . '=? AND ' . $itemClass::$databaseTable . '.' . $itemClass::$databasePrefix . $itemClass::$databaseColumnMap['date'] . ' > ? AND ' . $itemClass::$databaseTable . '.' .$itemClass::$databasePrefix . $itemClass::$databaseColumnMap['author'] . '!=?',
$follow['follow_rel_id'],
$follow['follow_notify_sent'] ?: $follow['follow_added'],
$follow['follow_member_id']
)
);
foreach ( $itemClass::getItemsWithPermission( array_merge( $itemClass::digestWhere(), $where ),
$itemClass::$databaseTable . '.' . $itemClass::$databasePrefix . $itemClass::$databaseColumnMap['date'] . ' ASC',
$max,
'read',
@@ -134,7 +147,7 @@ class _Digest
}
}
}
else if ( in_array( 'IPS\Content\Item', $parents ) )
else if ( \in_array( 'IPS\Content\Item', $parents ) )
{
foreach ( $follows as $follow )
{
@@ -148,6 +161,15 @@ class _Digest
continue;
}
/* Make sure the item is not archived */
if ( isset( $item::$archiveClass ) and method_exists( $item, 'isArchived' ) )
{
if ( $item->isArchived() )
{
continue;
}
}
/* Force custom profile fields not to be returned, as they can reference templates */
if( isset( $item::$commentClass ) )
{
@@ -205,13 +227,69 @@ class _Digest
{
$this->mail->setUnsubscribe( 'core', 'unsubscribeDigest' );
$subject = $this->mail->compileSubject( $this->member );
$htmlContent = str_replace( "<%digest%>", $this->output['html'], $this->mail->compileContent( 'html', $this->member ) );
$plaintextContent = str_replace( "<%digest%>", $this->output['plain'], $this->mail->compileContent( 'plaintext', $this->member ) );
$htmlContent = str_replace( "___digest___", $this->output['html'], $this->mail->compileContent( 'html', $this->member ) );
$plaintextContent = str_replace( "___digest___", $this->output['plain'], $this->mail->compileContent( 'plaintext', $this->member ) );
\IPS\Email::buildFromContent( $subject, $htmlContent, $plaintextContent, \IPS\Email::TYPE_LIST, FALSE )->send( $this->member );
\IPS\Email::buildFromContent( $subject, $htmlContent, $plaintextContent, \IPS\Email::TYPE_LIST, FALSE, $this->frequency . '_digest' )->send( $this->member );
}
/* After sending digest update core_follows to set notify_sent (don't forget where clause for frequency) */
\IPS\Db::i()->update( 'core_follow', array( 'follow_notify_sent' => time() ), array( 'follow_member_id=? AND follow_notify_freq=?', $this->member->member_id, $this->frequency ) );
}
/**
* Process a batch of digests
*
* @param string $frequency One of either "daily" or "weekly" to denote the kind of digest to send
* @param int $numberToSend The number of digests to send for this batch
* @return bool
*/
public static function sendDigestBatch( $frequency='daily', $numberToSend=50 )
{
/* Grab some members to send digests to. */
$members = iterator_to_array( \IPS\Db::i()->select( 'follow_member_id, follow_notify_sent', 'core_follow', array( 'follow_notify_do=1 AND follow_notify_freq = ? AND follow_notify_sent < ?', $frequency, ( $frequency == 'daily' ) ? time() - 86400 : time() - 604800 ), 'follow_notify_sent ASC', array( 0, $numberToSend ), NULL, NULL, \IPS\Db::SELECT_DISTINCT ) );
if( !\count( $members ) )
{
/* Nothing to send */
return FALSE;
}
$memberIDs = array();
foreach( $members as $member )
{
$memberIDs[] = $member['follow_member_id'];
}
/* Fetch the member's follows so we can build their digest */
$follows = \IPS\Db::i()->select( '*', 'core_follow', array( 'follow_notify_do=1 AND follow_notify_freq=? AND follow_notify_sent < ? AND ' . \IPS\Db::i()->in( 'follow_member_id', $memberIDs ), $frequency, ( $frequency == 'daily' ) ? time() - 86400 : time() - 604800 ) );
$groupedFollows = array();
foreach( $follows as $follow )
{
$groupedFollows[ $follow['follow_member_id'] ][ $follow['follow_app'] ][ $follow['follow_area'] ][] = $follow;
}
foreach( $groupedFollows as $id => $data )
{
$member = \IPS\Member::load( $id );
if( !$member->email )
{
/* Update notification sent time, so the batch doesn't get stuck in a loop */
\IPS\Db::i()->update( 'core_follow', array( 'follow_notify_sent' => time() ), array( 'follow_member_id=? AND follow_notify_freq=?', $id, $frequency ) );
continue;
}
/* Build it */
$digest = new static;
$digest->member = $member;
$digest->frequency = $frequency;
$digest->build( $data );
/* Send it */
$digest->send();
}
return TRUE;
}
}