Version 4.1.19

This commit is contained in:
Neo committed 2025-12-19 05:38:56 -08:00
1 parent 28bd025b35
commit 2bd5025018
2674 files changed
+233518 -77766

No files matched your search

+77 -43
View File
@@ -2,9 +2,9 @@
/**
* @brief Notification Class
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @package IPS Community Suite
* @since 23 Apr 2013
* @version SVN_VERSION_NUMBER
*/
@@ -196,7 +196,7 @@ class _Notification
protected $item;
/**
* @brief An SplObjectStorage object which contains \IPS\Member objects and replacements to use for that member in the notification content.
* @brief An \IPS\Notification\Recipients object which contains \IPS\Member objects and replacements to use for that member in the notification content.
* @code
$notification->recipients->attach( $member, array( 'foo' => 'bar' ) );
$notification->recipients->attach( $member2, array( 'foo' => 'baz' ) );
@@ -218,7 +218,12 @@ class _Notification
* @brief Unsubscribe Type
*/
public $unsubscribeType = 'notification';
/**
* @brief Allow merging of notifications
*/
protected $allowMerging = TRUE;
/**
* Constructor
*
@@ -227,67 +232,70 @@ class _Notification
* @param object|NULL $item The thing the notification is about
* @param array $emailParams Data for notification emails
* @param array $inlineExtra Extra data to save with inline notifications. Use sparingly: only in cases where it is not possible to obtain the same data later. Will be merged for duplicate notifications.
* @param bool $allowMerging Allow two identical notification types to be merged
* @return void
*/
public function __construct( \IPS\Application $app, $key, $item=NULL, $emailParams=array(), $inlineExtra=array() )
public function __construct( \IPS\Application $app, $key, $item=NULL, $emailParams=array(), $inlineExtra=array(), $allowMerging=TRUE )
{
$this->app = $app;
$this->key = $key;
$this->item = $item;
$this->recipients = new \SplObjectStorage;
$this->emailParams = $emailParams;
$this->inlineExtra = $inlineExtra;
$this->app = $app;
$this->key = $key;
$this->item = $item;
$this->recipients = new \IPS\Notification\Recipients;
$this->emailParams = $emailParams;
$this->inlineExtra = $inlineExtra;
$this->allowMerging = $allowMerging;
}
/**
* Send Notification
*
* @return array $sentTo Members notified
* @param array $sentTo Members who have already received a notification and how (same format as the return value) to prevent duplicates
* @return array The members that were notified and how they were notified
*/
public function send()
public function send( $sentTo = array() )
{
/* Make a placeholder for emails - we'll need to generate one per language */
$emails = array();
$emailRecipients = array();
$sentTo = array();
$thingsBeingFollowed = array();
/* Send */
/* Loop recipients */
foreach ( $this->recipients as $member )
{
/* let's not send notifications to banned members */
{
/* Let's not send notifications to banned members */
if ( $member->isBanned() )
{
$this->recipients->detach( $member );
continue;
}
/* If there's an item, check the user has permission to view it and is not ignoring */
if ( $this->item )
{
/* Permission check */
$item = $this->item;
if ( $item instanceof \IPS\Content\Item )
{
$application = \IPS\Application::load( $item::$application );
if ( !$application->canAccess( $member ) )
{
$this->recipients->detach( $member );
continue;
}
if ( $member->isIgnoring( $item->author(), 'topics' ) )
/* Skip if member is ignoring the item author but only if this is a new content item.
If a member is following content they should still receive reply notifications regardless of author */
if ( $this->key == "new_content" and $member->isIgnoring( $item->author(), 'topics' ) )
{
$this->recipients->detach( $member );
continue;
}
}
/* Not ignoring the comment this is about */
foreach( $this->emailParams AS $param )
{
if ( $param instanceof \IPS\Content\Comment OR $param instanceof \IPS\Content\Review )
{
if ( $member->isIgnoring( $param->author(), 'topics' ) )
{
$this->recipients->detach( $member );
continue 2;
}
}
@@ -296,16 +304,15 @@ class _Notification
{
if ( $member->isIgnoring( $param, 'topics' ) )
{
$this->recipients->detach( $member );
continue 2;
}
}
}
}
/* Work out how the user wants to receive this notification */
$notificationPreferences = $member->notificationsConfiguration();
$info = $this->recipients->getInfo();
if ( $info['follow_app'] === 'core' and $info['follow_area'] === 'member' )
{
$keyToCheck = 'follower_content';
@@ -322,14 +329,26 @@ class _Notification
$keyToCheck = 'unapproved_content';
}
}
if ( isset( $notificationPreferences[ $keyToCheck ] ) AND in_array( 'email', $notificationPreferences[ $keyToCheck ] ) )
/* They want to receive an email (we don't send until the end once we've collated all the emails to send) */
if ( isset( $notificationPreferences[ $keyToCheck ] ) AND in_array( 'email', $notificationPreferences[ $keyToCheck ] ) and ( !isset( $sentTo[ $member->member_id ] ) or !in_array( 'email', $sentTo[ $member->member_id ] ) ) )
{
$language = $member->language()->id;
if ( !isset( $emails[ $language ] ) )
{
$emails[ $language ] = \IPS\Email::buildFromTemplate( $this->app->directory, 'notification_' . $this->key, $this->emailParams, TRUE );
$email = \IPS\Email::buildFromTemplate( $this->app->directory, 'notification_' . $this->key, $this->emailParams, \IPS\Email::TYPE_LIST );
if ( $info )
{
$email->setUnsubscribe( 'core', 'unsubscribeFollow', array( $this->key ) );
}
else
{
$email->setUnsubscribe( 'core', 'unsubscribeNotification', array( $this->key ) );
}
$emails[ $language ] = $email;
}
$unsubscribeBlurb = NULL;
@@ -375,23 +394,21 @@ class _Notification
if ( $okToEmail )
{
$emails[ $language ]->buildUnsubscribe( $this->unsubscribeType, $this->key );
$emailRecipients[ $language ][ $member->email ] = array(
'recipient_name' => $member->name,
'recipient_photo' => (string) $member->photo,
'member_name' => $member->name,
'unsubscribe_blurb' => $unsubscribeBlurb,
'unfollow_link' => $unfollowLink
);
}
$sentTo[ $member->member_id ] = $member->member_id;
$sentTo[ $member->member_id ][] = 'email';
}
/* Send inline notifications, but only if this is not for report center. Report center is treated special and the 'inline' notification
preference actually instead controls whether the bubble should be shown on the report center icon at the top or not */
if ( $this->key != 'report_center' AND isset( $notificationPreferences[ $keyToCheck ] ) AND in_array( 'inline', $notificationPreferences[ $keyToCheck ] ) )
/* They want to receive an inline notification... (ignore for report center which is treated special and the 'inline' notification
preference actually instead controls whether the bubble should be shown on the report center icon at the top or not) */
if ( $this->key != 'report_center' and isset( $notificationPreferences[ $keyToCheck ] ) and in_array( 'inline', $notificationPreferences[ $keyToCheck ] ) and ( !isset( $sentTo[ $member->member_id ] ) or !in_array( 'inline', $sentTo[ $member->member_id ] ) ) )
{
if ( $this->item )
if ( $this->item AND $this->allowMerging )
{
try
{
@@ -408,7 +425,7 @@ class _Notification
}
catch ( \UnderflowException $e ) { }
}
$notification = new \IPS\Notification\Inline;
$notification->member = $member;
$notification->notification_app = $this->app;
@@ -431,9 +448,24 @@ class _Notification
* If this is a grouped comment or review, set the sent time to the same time as the comment just in case there is a slight delay
* @see <a href='http://community.invisionpower.com/resources/bugs.html/_/4-0-0/reply-notifications-missing-names-r46841'>Bug Report</a>
*/
if ( ( $param instanceof \IPS\Content\Comment OR $param instanceof \IPS\Content\Review ) && in_array( $this->key, array( 'new_comment', 'new_review', 'quote' ) ) )
if ( ( $param instanceof \IPS\Content\Comment OR $param instanceof \IPS\Content\Review ) && in_array( $this->key, array( 'new_comment', 'new_review', 'quote', 'new_likes' ) ) )
{
$notification->sent_time = $param->mapped('date');
if ( $this->key === 'new_likes' and $this->emailParams[1] instanceof \IPS\Member )
{
/* Reset the time to the time of the rep to prevent a slight delay from missing this notification */
try
{
$where = $param->getReputationWhereClause();
$where[] = array( 'member_id = ?', $this->emailParams[1]->member_id );
$notification->sent_time = \IPS\Db::i()->select( 'rep_date', 'core_reputation_index', $where )->first();
}
catch( \Exception $ex ) { }
}
else
{
$notification->sent_time = $param->mapped('date');
}
}
}
}
@@ -442,12 +474,14 @@ class _Notification
$notification->save();
$sentTo[ $member->member_id ] = $member->member_id;
$sentTo[ $member->member_id ][] = 'inline';
}
}
/* Send any emails */
$this->sendEmails( $emails, $emailRecipients );
/* And return */
return $sentTo;
}
@@ -464,7 +498,7 @@ class _Notification
{
if ( !empty( $emailRecipients[ $languageId ] ) )
{
$email->mergeAndSend( $emailRecipients[ $languageId ] );
$email->mergeAndSend( $emailRecipients[ $languageId ], NULL, NULL, array(), \IPS\Lang::load( $languageId ) );
}
}
}