Version 4.5.0
This commit is contained in:
1 parent
1a0c7fd3c2
commit
f79dcf067a
3791 files changed
+248032
-76372
No files matched your search
+201
-211
@@ -11,7 +11,7 @@
|
||||
namespace IPS\Content;
|
||||
|
||||
/* 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;
|
||||
@@ -41,7 +41,12 @@ abstract class _Comment extends \IPS\Content
|
||||
* @brief [Content\Item] Sharelink HTML
|
||||
*/
|
||||
protected $sharelinks = array();
|
||||
|
||||
|
||||
/**
|
||||
* @brief [Content\Comment] EditLine Template
|
||||
*/
|
||||
public static $editLineTemplate = array( array( 'global', 'core', 'front' ), 'commentEditLine' );
|
||||
|
||||
/**
|
||||
* Create comment
|
||||
*
|
||||
@@ -108,7 +113,12 @@ abstract class _Comment extends \IPS\Content
|
||||
}
|
||||
elseif ( $hiddenStatus === NULL )
|
||||
{
|
||||
if ( in_array( 'IPS\Content\Review', class_parents( get_called_class() ) ) )
|
||||
$permissionCheckFunction = \in_array( 'IPS\Content\Review', class_parents( \get_called_class() ) ) ? 'canReview' : 'canComment';
|
||||
if ( !$member->member_id and !$item->$permissionCheckFunction( $member, FALSE ) )
|
||||
{
|
||||
$val = -3;
|
||||
}
|
||||
elseif ( \in_array( 'IPS\Content\Review', class_parents( \get_called_class() ) ) )
|
||||
{
|
||||
$val = $item->moderateNewReviews( $member ) ? 0 : 1;
|
||||
}
|
||||
@@ -145,7 +155,12 @@ abstract class _Comment extends \IPS\Content
|
||||
}
|
||||
elseif ( $hiddenStatus === NULL )
|
||||
{
|
||||
if ( in_array( 'IPS\Content\Review', class_parents( get_called_class() ) ) )
|
||||
$permissionCheckFunction = \in_array( 'IPS\Content\Review', class_parents( \get_called_class() ) ) ? 'canReview' : 'canComment';
|
||||
if ( !$member->member_id and !$item->$permissionCheckFunction( $member, FALSE ) )
|
||||
{
|
||||
$val = -3;
|
||||
}
|
||||
elseif ( \in_array( 'IPS\Content\Review', class_parents( \get_called_class() ) ) )
|
||||
{
|
||||
$val = $item->moderateNewReviews( $member ) ? 1 : 0;
|
||||
}
|
||||
@@ -161,7 +176,7 @@ abstract class _Comment extends \IPS\Content
|
||||
break;
|
||||
}
|
||||
|
||||
foreach ( is_array( static::$databaseColumnMap[ $k ] ) ? static::$databaseColumnMap[ $k ] : array( static::$databaseColumnMap[ $k ] ) as $column )
|
||||
foreach ( \is_array( static::$databaseColumnMap[ $k ] ) ? static::$databaseColumnMap[ $k ] : array( static::$databaseColumnMap[ $k ] ) as $column )
|
||||
{
|
||||
$obj->$column = $val;
|
||||
}
|
||||
@@ -186,7 +201,7 @@ abstract class _Comment extends \IPS\Content
|
||||
|
||||
|
||||
/* Update member's last post and daily post limits */
|
||||
if( $obj->author()->member_id )
|
||||
if( $obj->author()->member_id AND $obj::incrementPostCount() )
|
||||
{
|
||||
$obj->author()->member_last_post = time();
|
||||
|
||||
@@ -208,7 +223,7 @@ abstract class _Comment extends \IPS\Content
|
||||
}
|
||||
|
||||
/* Send notifications */
|
||||
if ( !in_array( 'IPS\Content\Review', class_parents( get_called_class() ) ) )
|
||||
if ( !\in_array( 'IPS\Content\Review', class_parents( \get_called_class() ) ) )
|
||||
{
|
||||
if ( !$obj->hidden() and ( !$first or !$item::$firstCommentRequired ) )
|
||||
{
|
||||
@@ -220,6 +235,12 @@ abstract class _Comment extends \IPS\Content
|
||||
}
|
||||
}
|
||||
|
||||
/* Send webhook */
|
||||
if ( \in_array( $obj->hidden(), array( -1, 0, 1 ) ) ) // i.e. not post before register or pending deletion
|
||||
{
|
||||
\IPS\Api\Webhook::fire( str_replace( '\\', '', \substr( \get_called_class(), 3 ) ) . '_create', $obj, $obj->webhookFilters() );
|
||||
}
|
||||
|
||||
/* Update item */
|
||||
$obj->postCreate();
|
||||
|
||||
@@ -232,105 +253,6 @@ abstract class _Comment extends \IPS\Content
|
||||
/* Return */
|
||||
return $obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check comment against profanity filters
|
||||
*
|
||||
* @note We do not save here, as saving is done in user-land code after
|
||||
* @param bool $first Is this the first comment?
|
||||
* @param bool $edit Are we editing or merging (true) or is this a new comment (false)?
|
||||
* @param string|NULL $content The content to check - useful for if the content needs to be checked first, before it gets saved to the database.
|
||||
* @return bool Whether to send unapproved notifications
|
||||
*/
|
||||
public function checkProfanityFilters( $first=FALSE, $edit=TRUE, $content=NULL )
|
||||
{
|
||||
/* Set our content */
|
||||
$content = $content ?: $this->content();
|
||||
|
||||
/* We need our item */
|
||||
$item = $this->item();
|
||||
|
||||
/* And the author */
|
||||
$member = $this->author();
|
||||
|
||||
/* Pass this through our profanity filters to see if it needs to be mod queued */
|
||||
$sendNotifications = FALSE;
|
||||
|
||||
/* Do we need to recount item comments and container comments? */
|
||||
$recount = FALSE;
|
||||
|
||||
try
|
||||
{
|
||||
$hiddenByFilter = FALSE;
|
||||
if ( !$this->hidden() AND ( ! $item::$firstCommentRequired or ( $item::$firstCommentRequired and !$first ) ) AND !$member->group['g_bypass_badwords'] )
|
||||
{
|
||||
$hiddenByFilter = \IPS\core\Profanity::hiddenByFilters( $content );
|
||||
}
|
||||
/* If the comment is hidden (probably requires moderator approval) and this is the first post in the item that requires a comment (i.e. a post in a topic), then we need to set the item as requiring approval instead. */
|
||||
elseif ( $item instanceof \IPS\Content\Hideable AND !$member->group['g_bypass_badwords'] AND ( $item::$firstCommentRequired and $first ) )
|
||||
{
|
||||
$itemHiddenByFilter = \IPS\core\Profanity::hiddenByFilters( $content );
|
||||
|
||||
if ( isset( $item::$databaseColumnMap['approved'] ) and $itemHiddenByFilter )
|
||||
{
|
||||
/* 'approved' is easy, clear and concise */
|
||||
$column = $item::$databaseColumnMap['approved'];
|
||||
$item->$column = 0;
|
||||
$item->save();
|
||||
$recount = TRUE;
|
||||
}
|
||||
elseif ( isset( $item::$databaseColumnMap['hidden'] ) and $itemHiddenByFilter )
|
||||
{
|
||||
/* 'hidden' is backwards */
|
||||
$column = $item::$databaseColumnMap['hidden'];
|
||||
$item->$column = 1;
|
||||
$item->save();
|
||||
$recount = TRUE;
|
||||
}
|
||||
|
||||
if( $edit === TRUE )
|
||||
{
|
||||
$sendNotifications = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( \BadMethodCallException $e ) { }
|
||||
|
||||
if ( $hiddenByFilter === TRUE )
|
||||
{
|
||||
$recount = TRUE;
|
||||
if ( isset( static::$databaseColumnMap['approved'] ) )
|
||||
{
|
||||
/* 'approved' is easy, clear and concise */
|
||||
$column = static::$databaseColumnMap['approved'];
|
||||
$this->$column = 0;
|
||||
}
|
||||
else if ( isset( static::$databaseColumnMap['hidden'] ) )
|
||||
{
|
||||
/* 'hidden' is backwards */
|
||||
$column = static::$databaseColumnMap['hidden'];
|
||||
$this->$column = 1;
|
||||
}
|
||||
|
||||
$sendNotifications = TRUE;
|
||||
}
|
||||
|
||||
if ( $recount === TRUE )
|
||||
{
|
||||
$item->resyncCommentCounts();
|
||||
$item->resyncLastComment();
|
||||
$item->save();
|
||||
|
||||
if ( $container = $item->containerWrapper() )
|
||||
{
|
||||
$container->resetCommentCounts();
|
||||
$container->save();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $sendNotifications;
|
||||
}
|
||||
|
||||
/**
|
||||
* Join profile fields when loading comments?
|
||||
@@ -381,7 +303,7 @@ abstract class _Comment extends \IPS\Content
|
||||
|
||||
if( isset( static::$databaseColumnMap['date'] ) )
|
||||
{
|
||||
if( is_array( static::$databaseColumnMap['date'] ) )
|
||||
if( \is_array( static::$databaseColumnMap['date'] ) )
|
||||
{
|
||||
$postDateColumn = static::$databaseColumnMap['date'][0];
|
||||
}
|
||||
@@ -396,7 +318,7 @@ abstract class _Comment extends \IPS\Content
|
||||
if ( isset( $item::$databaseColumnMap['last_comment'] ) )
|
||||
{
|
||||
$lastCommentField = $item::$databaseColumnMap['last_comment'];
|
||||
if ( is_array( $lastCommentField ) )
|
||||
if ( \is_array( $lastCommentField ) )
|
||||
{
|
||||
foreach ( $lastCommentField as $column )
|
||||
{
|
||||
@@ -441,8 +363,18 @@ abstract class _Comment extends \IPS\Content
|
||||
|
||||
/* Are we tracking keywords? */
|
||||
$this->checkKeywords( $this->content() );
|
||||
|
||||
if ( \IPS\IPS::classUsesTrait( $item, 'IPS\Content\Statistics' ) )
|
||||
{
|
||||
$item->clearCachedStatistics();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Value to set for the 'tab' parameter when redirecting to the comment (via _find())
|
||||
*/
|
||||
public static $tabParameter = array( 'tab' => 'comments' );
|
||||
|
||||
/**
|
||||
* Get URL
|
||||
*
|
||||
@@ -545,7 +477,7 @@ abstract class _Comment extends \IPS\Content
|
||||
}
|
||||
|
||||
/* Can the member edit their own content? */
|
||||
if ( $member->member_id == $this->author()->member_id and ( $member->group['g_edit_posts'] == '1' or in_array( get_class( $item ), explode( ',', $member->group['g_edit_posts'] ) ) ) and ( !( $item instanceof \IPS\Content\Lockable ) or !$item->locked() ) )
|
||||
if ( $member->member_id == $this->author()->member_id and ( $member->group['g_edit_posts'] == '1' or \in_array( \get_class( $item ), explode( ',', $member->group['g_edit_posts'] ) ) ) and ( !( $item instanceof \IPS\Content\Lockable ) or !$item->locked() ) )
|
||||
{
|
||||
if ( !$member->group['g_edit_cutoff'] )
|
||||
{
|
||||
@@ -574,7 +506,7 @@ abstract class _Comment extends \IPS\Content
|
||||
{
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
|
||||
return ( !$this->isFirst() and ( static::modPermission( 'hide', $member, $this->item()->containerWrapper() ) or ( $member->member_id and $member->member_id == $this->author()->member_id and ( $member->group['g_hide_own_posts'] == '1' or in_array( get_class( $this->item() ), explode( ',', $member->group['g_hide_own_posts'] ) ) ) ) ) );
|
||||
return ( !$this->isFirst() and ( static::modPermission( 'hide', $member, $this->item()->containerWrapper() ) or ( $member->member_id and $member->member_id == $this->author()->member_id and ( $member->group['g_hide_own_posts'] == '1' or \in_array( \get_class( $this->item() ), explode( ',', $member->group['g_hide_own_posts'] ) ) ) ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -607,7 +539,7 @@ abstract class _Comment extends \IPS\Content
|
||||
{
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
|
||||
return ( !$this->isFirst() and ( static::modPermission( 'delete', $member, $this->item()->containerWrapper() ) or ( $member->member_id and $member->member_id == $this->author()->member_id and ( $member->group['g_delete_own_posts'] == '1' or in_array( get_class( $this->item() ), explode( ',', $member->group['g_delete_own_posts'] ) ) ) ) ) );
|
||||
return ( !$this->isFirst() and ( static::modPermission( 'delete', $member, $this->item()->containerWrapper() ) or ( $member->member_id and $member->member_id == $this->author()->member_id and ( $member->group['g_delete_own_posts'] == '1' or \in_array( \get_class( $this->item() ), explode( ',', $member->group['g_delete_own_posts'] ) ) ) ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -716,44 +648,18 @@ abstract class _Comment extends \IPS\Content
|
||||
}
|
||||
|
||||
/* Send notifications */
|
||||
if ( $sendNotifications AND !in_array( 'IPS\Content\Review', class_parents( get_called_class() ) ) )
|
||||
if ( $sendNotifications AND !\in_array( 'IPS\Content\Review', class_parents( \get_called_class() ) ) )
|
||||
{
|
||||
if( $this->hidden() === 1 )
|
||||
{
|
||||
$this->sendUnapprovedNotification();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get edit line
|
||||
*
|
||||
* @return string|NULL
|
||||
*/
|
||||
public function editLine()
|
||||
{
|
||||
if ( $this instanceof \IPS\Content\EditHistory and $this->mapped('edit_time') and ( $this->mapped('edit_show') or \IPS\Member::loggedIn()->modPermission('can_view_editlog') ) and \IPS\Settings::i()->edit_log )
|
||||
|
||||
if ( \IPS\IPS::classUsesTrait( $this->item(), 'IPS\Content\Statistics' ) )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'core' )->commentEditLine( $this, ( isset( static::$databaseColumnMap['edit_reason'] ) and $this->mapped('edit_reason') ) );
|
||||
$this->item()->clearCachedStatistics();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get edit history
|
||||
*
|
||||
* @param bool $staff Set true for moderators who have permission to view the full log which will show edits not made by the author and private edits
|
||||
* @return \IPS\Db\Select
|
||||
*/
|
||||
public function editHistory( $staff=FALSE )
|
||||
{
|
||||
$idColumn = static::$databaseColumnId;
|
||||
$where = array( array( 'class=? AND comment_id=?', get_called_class(), $this->$idColumn ) );
|
||||
if ( !$staff )
|
||||
{
|
||||
$where[] = array( 'member=? AND public=1', $this->author()->member_id );
|
||||
}
|
||||
return \IPS\Db::i()->select( '*', 'core_edit_history', $where, 'time DESC' );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -764,7 +670,8 @@ abstract class _Comment extends \IPS\Content
|
||||
public function html()
|
||||
{
|
||||
$template = static::$commentTemplate[1];
|
||||
return call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), static::$commentTemplate[0] )->$template( $this->item(), $this );
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( static::$commentTemplate[0][0], static::$commentTemplate[0][1], ( isset( static::$commentTemplate[0][2] ) ) ? static::$commentTemplate[0][2] : NULL )->$template( $this->item(), $this );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -777,41 +684,30 @@ abstract class _Comment extends \IPS\Content
|
||||
*/
|
||||
public function notificationRecipients( $limit=array( 0, 25 ), $extra=NULL, $countOnly=FALSE )
|
||||
{
|
||||
$memberFollowers = $this->author()->followers( 3, array( 'immediate' ), $this->mapped('date'), NULL, NULL, NULL );
|
||||
/* Do we only want the count? */
|
||||
if( $countOnly )
|
||||
{
|
||||
$count = 0;
|
||||
$count += $this->author()->followersCount( 3, array( 'immediate' ), $this->mapped('date') );
|
||||
$count += $this->item()->followersCount( 3, array( 'immediate' ), $this->mapped('date') );
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
$memberFollowers = $this->author()->followers( 3, array( 'immediate' ), $this->mapped('date'), NULL );
|
||||
|
||||
if( count( $memberFollowers ) )
|
||||
if( $memberFollowers !== NULL )
|
||||
{
|
||||
$unions = array(
|
||||
$this->item()->followers( static::FOLLOW_PUBLIC + static::FOLLOW_ANONYMOUS, array( 'immediate' ), $this->mapped('date'), NULL, NULL, 0 ),
|
||||
$this->item()->followers( 3, array( 'immediate' ), $this->mapped('date'), NULL ),
|
||||
$memberFollowers
|
||||
);
|
||||
|
||||
if ( $countOnly )
|
||||
{
|
||||
$return = 0;
|
||||
foreach ( $unions as $query )
|
||||
{
|
||||
$return += $query->count();
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
else
|
||||
{
|
||||
return \IPS\Db::i()->union( $unions, 'follow_added', $limit, NULL, FALSE, \IPS\Db::SELECT_SQL_CALC_FOUND_ROWS );
|
||||
}
|
||||
|
||||
return \IPS\Db::i()->union( $unions, 'follow_added', $limit );
|
||||
}
|
||||
else
|
||||
{
|
||||
$query = $this->item()->followers( static::FOLLOW_PUBLIC + static::FOLLOW_ANONYMOUS, array( 'immediate' ), $this->mapped('date'), $limit, 'follow_added', \IPS\Db::SELECT_SQL_CALC_FOUND_ROWS );
|
||||
|
||||
if ( $countOnly )
|
||||
{
|
||||
return $query->count();
|
||||
}
|
||||
else
|
||||
{
|
||||
return $query;
|
||||
}
|
||||
return $this->item()->followers( static::FOLLOW_PUBLIC + static::FOLLOW_ANONYMOUS, array( 'immediate' ), $this->mapped('date'), $limit, 'follow_added' );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -838,7 +734,7 @@ abstract class _Comment extends \IPS\Content
|
||||
|
||||
/* Remove any notifications */
|
||||
$idColumn = static::$databaseColumnId;
|
||||
\IPS\Db::i()->delete( 'core_notifications', array( 'item_sub_class=? AND item_sub_id=?', (string) get_called_class(), (int) $this->$idColumn ) );
|
||||
\IPS\Db::i()->delete( 'core_notifications', array( 'item_sub_class=? AND item_sub_id=?', (string) \get_called_class(), (int) $this->$idColumn ) );
|
||||
|
||||
$item->resyncCommentCounts();
|
||||
$item->resyncLastComment();
|
||||
@@ -854,6 +750,11 @@ abstract class _Comment extends \IPS\Content
|
||||
$item->container()->save();
|
||||
}
|
||||
} catch ( \BadMethodCallException $e ) {}
|
||||
|
||||
if ( \IPS\IPS::classUsesTrait( $item, 'IPS\Content\Statistics' ) )
|
||||
{
|
||||
$item->clearCachedStatistics();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -899,6 +800,11 @@ abstract class _Comment extends \IPS\Content
|
||||
$item->container()->save();
|
||||
}
|
||||
} catch ( \BadMethodCallException $e ) {}
|
||||
|
||||
if ( \IPS\IPS::classUsesTrait( $item, 'IPS\Content\Statistics' ) )
|
||||
{
|
||||
$item->clearCachedStatistics();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -922,24 +828,35 @@ abstract class _Comment extends \IPS\Content
|
||||
\IPS\Db::i()->update( 'core_attachments_map', array( 'id1' => $item->$idColumn ), array( "location_key=? AND id1=? AND id2=?", $oldItem::$application . '_' . mb_ucfirst( $oldItem::$module ), $oldItem->$idColumn, $this->$commentIdColumn ) );
|
||||
|
||||
/* Update notifications */
|
||||
\IPS\Db::i()->update( 'core_notifications', array( 'item_id' => $item->$idColumn ), array( 'item_class=? and item_id=? and item_sub_class=? and item_sub_id=?', (string) get_class( $item ), $oldItem->$idColumn, (string) get_called_class(), $this->$commentIdColumn ) );
|
||||
\IPS\Db::i()->update( 'core_notifications', array( 'item_id' => $item->$idColumn ), array( 'item_class=? and item_id=? and item_sub_class=? and item_sub_id=?', (string) \get_class( $item ), $oldItem->$idColumn, (string) \get_called_class(), $this->$commentIdColumn ) );
|
||||
|
||||
/* Update reputation */
|
||||
if ( \IPS\IPS::classUsesTrait( $this, 'IPS\Content\Reactable' ) )
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_reputation_index', array( 'item_id' => $item->$idColumn ), array( 'class_type_id_hash=?', md5( get_class( $this ) . ':' . $oldItem->$idColumn ) ) );
|
||||
\IPS\Db::i()->update( 'core_reputation_index', array( 'item_id' => $item->$idColumn ), array( 'class_type_id_hash=?', md5( \get_class( $this ) . ':' . $oldItem->$idColumn ) ) );
|
||||
}
|
||||
|
||||
/* Update solved */
|
||||
if ( \IPS\IPS::classUsesTrait( $this, 'IPS\Content\Solvable' ) )
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_solved_index', array( 'item_id' => $item->$idColumn ), array( 'comment_class=? and comment_id=?', \get_class( $this ), $oldItem->$idColumn ) );
|
||||
}
|
||||
|
||||
if( $skip === FALSE )
|
||||
{
|
||||
$oldItem->rebuildFirstAndLastCommentData();
|
||||
$item->rebuildFirstAndLastCommentData();
|
||||
}
|
||||
|
||||
/* Add to search index */
|
||||
if ( $this instanceof \IPS\Content\Searchable )
|
||||
{
|
||||
\IPS\Content\Search\Index::i()->index( $this );
|
||||
/* Add to search index */
|
||||
if ( $this instanceof \IPS\Content\Searchable )
|
||||
{
|
||||
\IPS\Content\Search\Index::i()->index( $this );
|
||||
}
|
||||
|
||||
if ( \IPS\IPS::classUsesTrait( $item, 'IPS\Content\Statistics' ) )
|
||||
{
|
||||
$item->clearCachedStatistics();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1005,10 +922,10 @@ abstract class _Comment extends \IPS\Content
|
||||
|
||||
/* Reduce the number of comment/reviews count on the item but only if the item is unapproved or visible
|
||||
* - hidden as opposed to unapproved items do not get included in either of the unapproved_comments/num_comments columns */
|
||||
if( $this->hidden() !== -1 AND $this->hidden() !== -2 )
|
||||
if( $this->hidden() !== -1 AND $this->hidden() !== -2 AND $this->hidden() !== -3 )
|
||||
{
|
||||
$columnName = ( $this->hidden() === 1 ) ? 'unapproved_comments' : 'num_comments';
|
||||
if ( in_array( 'IPS\Content\Review', class_parents( get_called_class() ) ) )
|
||||
if ( \in_array( 'IPS\Content\Review', class_parents( \get_called_class() ) ) )
|
||||
{
|
||||
$columnName = ( $this->hidden() === 1 ) ? 'unapproved_reviews' : 'num_reviews';
|
||||
}
|
||||
@@ -1023,9 +940,9 @@ abstract class _Comment extends \IPS\Content
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
else if ( $this->hidden() === -1 )
|
||||
{
|
||||
if ( in_array( 'IPS\Content\Review', class_parents( get_called_class() ) ) )
|
||||
if ( \in_array( 'IPS\Content\Review', class_parents( \get_called_class() ) ) )
|
||||
{
|
||||
if( isset( $itemClass::$databaseColumnMap['hidden_reviews'] ) AND $item !== NULL )
|
||||
{
|
||||
@@ -1052,16 +969,32 @@ abstract class _Comment extends \IPS\Content
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ( \IPS\IPS::classUsesTrait( $this->item(), 'IPS\Content\Solvable' ) and isset( $itemClass::$databaseColumnMap['solved_comment_id'] ) )
|
||||
{
|
||||
/* Reset item */
|
||||
if ( $item->mapped('solved_comment_id') and $item->mapped('solved_comment_id') == $this->$idColumn )
|
||||
{
|
||||
\IPS\Db::i()->update( $itemClass::$databaseTable, array( $itemClass::$databaseColumnMap['solved_comment_id'] => 0 ), array( $itemIdColumn . '=?', $itemId ) );
|
||||
|
||||
\IPS\Db::i()->delete( 'core_solved_index', array( 'app=? and comment_class=? and item_id=? and comment_id=?', static::$application, \get_called_class(), $itemId, $this->$idColumn ) );
|
||||
}
|
||||
}
|
||||
|
||||
if ( \IPS\IPS::classUsesTrait( $this->item(), 'IPS\Content\Statistics' ) )
|
||||
{
|
||||
$item->clearCachedStatistics();
|
||||
}
|
||||
|
||||
/* Delete any notifications telling people about this */
|
||||
$memberIds = array();
|
||||
|
||||
foreach( \IPS\Db::i()->select( 'member', 'core_notifications', array( 'item_sub_class=? AND item_sub_id=?', (string) get_called_class(), (int) $this->$idColumn ) ) as $member )
|
||||
foreach( \IPS\Db::i()->select( '`member`', 'core_notifications', array( 'item_sub_class=? AND item_sub_id=?', (string) \get_called_class(), (int) $this->$idColumn ) ) as $member )
|
||||
{
|
||||
$memberIds[ $member ] = $member;
|
||||
}
|
||||
|
||||
\IPS\Db::i()->delete( 'core_notifications', array( 'item_sub_class=? AND item_sub_id=?', (string) get_called_class(), (int) $this->$idColumn ) );
|
||||
\IPS\Db::i()->delete( 'core_notifications', array( 'item_sub_class=? AND item_sub_id=?', (string) \get_called_class(), (int) $this->$idColumn ) );
|
||||
|
||||
foreach( $memberIds as $member )
|
||||
{
|
||||
@@ -1074,7 +1007,7 @@ abstract class _Comment extends \IPS\Content
|
||||
/* Update last comment/review data for container and item */
|
||||
try
|
||||
{
|
||||
if ( $item !== NULL AND in_array( 'IPS\Content\Review', class_parents( get_called_class() ) ) )
|
||||
if ( $item !== NULL AND \in_array( 'IPS\Content\Review', class_parents( \get_called_class() ) ) )
|
||||
{
|
||||
if ( $item->container()->_reviews !== NULL )
|
||||
{
|
||||
@@ -1116,9 +1049,10 @@ abstract class _Comment extends \IPS\Content
|
||||
* Change Author
|
||||
*
|
||||
* @param \IPS\Member $newAuthor The new author
|
||||
* @param bool $log If TRUE, action will be logged to moderator log
|
||||
* @return void
|
||||
*/
|
||||
public function changeAuthor( \IPS\Member $newAuthor )
|
||||
public function changeAuthor( \IPS\Member $newAuthor, $log=TRUE )
|
||||
{
|
||||
$oldAuthor = $this->author();
|
||||
|
||||
@@ -1130,10 +1064,10 @@ abstract class _Comment extends \IPS\Content
|
||||
}
|
||||
|
||||
/* Update the row */
|
||||
parent::changeAuthor( $newAuthor );
|
||||
parent::changeAuthor( $newAuthor, $log );
|
||||
|
||||
/* Adjust post counts */
|
||||
if ( static::incrementPostCount( $this->item()->containerWrapper() ) )
|
||||
if ( static::incrementPostCount( $this->item()->containerWrapper() ) AND ( $oldAuthor->member_id OR ( $this->hidden() === 0 AND $this->item()->hidden === 0 ) ) )
|
||||
{
|
||||
if( $oldAuthor->member_id )
|
||||
{
|
||||
@@ -1217,7 +1151,7 @@ abstract class _Comment extends \IPS\Content
|
||||
$containerWhere = array();
|
||||
|
||||
/* Queries are always more efficient when the WHERE clause is added to the ON */
|
||||
if ( is_array( $where ) )
|
||||
if ( \is_array( $where ) )
|
||||
{
|
||||
foreach( $where as $key => $value )
|
||||
{
|
||||
@@ -1252,7 +1186,7 @@ abstract class _Comment extends \IPS\Content
|
||||
}
|
||||
}
|
||||
|
||||
if ( in_array( 'IPS\Content\Hideable', class_implements( get_called_class() ) ) and $includeHiddenComments === \IPS\Content\Hideable::FILTER_ONLY_HIDDEN )
|
||||
if ( \in_array( 'IPS\Content\Hideable', class_implements( \get_called_class() ) ) and $includeHiddenComments === \IPS\Content\Hideable::FILTER_ONLY_HIDDEN )
|
||||
{
|
||||
/* If we can't view hidden stuff, just return an empty array now */
|
||||
if( !static::modPermission( 'view_hidden', $member ) )
|
||||
@@ -1269,7 +1203,7 @@ abstract class _Comment extends \IPS\Content
|
||||
$where[] = array( static::$databasePrefix . static::$databaseColumnMap['hidden'] . '=?', 1 );
|
||||
}
|
||||
}
|
||||
elseif ( in_array( 'IPS\Content\Hideable', class_implements( get_called_class() ) ) and ( $includeHiddenComments === \IPS\Content\Hideable::FILTER_OWN_HIDDEN OR $includeHiddenComments === \IPS\Content\Hideable::FILTER_PUBLIC_ONLY ) )
|
||||
elseif ( \in_array( 'IPS\Content\Hideable', class_implements( \get_called_class() ) ) and ( $includeHiddenComments === \IPS\Content\Hideable::FILTER_OWN_HIDDEN OR $includeHiddenComments === \IPS\Content\Hideable::FILTER_PUBLIC_ONLY ) )
|
||||
{
|
||||
if ( isset( static::$databaseColumnMap['approved'] ) )
|
||||
{
|
||||
@@ -1282,7 +1216,7 @@ abstract class _Comment extends \IPS\Content
|
||||
}
|
||||
|
||||
/* Exclude hidden items. We don't check FILTER_ONLY_HIDDEN because we should return hidden comments in both approved and unapproved topics. */
|
||||
if ( in_array( 'IPS\Content\Hideable', class_implements( $itemClass ) ) and ( $includeHiddenComments === \IPS\Content\Hideable::FILTER_OWN_HIDDEN OR $includeHiddenComments === \IPS\Content\Hideable::FILTER_PUBLIC_ONLY ) )
|
||||
if ( \in_array( 'IPS\Content\Hideable', class_implements( $itemClass ) ) and ( $includeHiddenComments === \IPS\Content\Hideable::FILTER_OWN_HIDDEN OR $includeHiddenComments === \IPS\Content\Hideable::FILTER_PUBLIC_ONLY ) )
|
||||
{
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
$authorCol = $itemClass::$databaseTable . '.' . $itemClass::$databasePrefix . $itemClass::$databaseColumnMap['author'];
|
||||
@@ -1331,18 +1265,34 @@ abstract class _Comment extends \IPS\Content
|
||||
}
|
||||
}
|
||||
|
||||
/* No matter if we can or cannot view hidden items, we do not want these to show as they are queued for deletion */
|
||||
/* No matter if we can or cannot view hidden items, we do not want these to show: -2 is queued for deletion and -3 is posted before register */
|
||||
if ( isset( static::$databaseColumnMap['hidden'] ) )
|
||||
{
|
||||
$col = static::$databaseTable . '.' . static::$databasePrefix . static::$databaseColumnMap['hidden'];
|
||||
$where[] = array( "{$col}!=-2" );
|
||||
$where[] = array( "{$col}!=-2 AND {$col} !=-3" );
|
||||
}
|
||||
else if ( isset( static::$databaseColumnMap['approved'] ) )
|
||||
{
|
||||
$col = static::$databaseTable . '.' . static::$databasePrefix . static::$databaseColumnMap['approved'];
|
||||
$where[] = array( "{$col}!=-2" );
|
||||
$where[] = array( "{$col}!=-2 AND {$col} !=-3" );
|
||||
}
|
||||
|
||||
|
||||
/* We also need to check the item for soft delete and post before register */
|
||||
if( \in_array( 'IPS\Content\Hideable', class_implements( $itemClass ) ) )
|
||||
{
|
||||
/* No matter if we can or cannot view hidden items, we do not want these to show: -2 is queued for deletion and -3 is posted before register */
|
||||
if ( isset( $itemClass::$databaseColumnMap['hidden'] ) )
|
||||
{
|
||||
$col = $itemClass::$databaseTable . '.' . $itemClass::$databasePrefix . $itemClass::$databaseColumnMap['hidden'];
|
||||
$itemWhere[] = array( "{$col}!=-2 AND {$col} !=-3" );
|
||||
}
|
||||
else if ( isset( $itemClass::$databaseColumnMap['approved'] ) )
|
||||
{
|
||||
$col = $itemClass::$databaseTable . '.' . $itemClass::$databasePrefix . $itemClass::$databaseColumnMap['approved'];
|
||||
$itemWhere[] = array( "{$col}!=-2 AND {$col} !=-3" );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $joinContainer AND isset( $itemClass::$containerNodeClass ) )
|
||||
{
|
||||
$containerClass = $itemClass::$containerNodeClass;
|
||||
@@ -1367,7 +1317,7 @@ abstract class _Comment extends \IPS\Content
|
||||
/* Build the select clause */
|
||||
if( $countOnly )
|
||||
{
|
||||
if ( in_array( 'IPS\Content\Permissions', class_implements( $itemClass ) ) AND $permissionKey !== NULL )
|
||||
if ( \in_array( 'IPS\Content\Permissions', class_implements( $itemClass ) ) AND $permissionKey !== NULL )
|
||||
{
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
|
||||
@@ -1383,7 +1333,7 @@ abstract class _Comment extends \IPS\Content
|
||||
->join( $itemClass::$databaseTable, array_merge( array( array( static::$databaseTable . "." . static::$databasePrefix . static::$databaseColumnMap['item'] . "=" . $itemClass::$databaseTable . "." . $itemClass::$databasePrefix . $itemClass::$databaseColumnId ) ), $itemWhere ), 'STRAIGHT_JOIN' );
|
||||
}
|
||||
|
||||
if ( $joins !== NULL AND count( $joins ) )
|
||||
if ( $joins !== NULL AND \count( $joins ) )
|
||||
{
|
||||
foreach( $joins as $join )
|
||||
{
|
||||
@@ -1394,7 +1344,7 @@ abstract class _Comment extends \IPS\Content
|
||||
}
|
||||
|
||||
$selectClause = static::$databaseTable . '.*';
|
||||
if ( $joins !== NULL AND count( $joins ) )
|
||||
if ( $joins !== NULL AND \count( $joins ) )
|
||||
{
|
||||
foreach( $joins as $join )
|
||||
{
|
||||
@@ -1405,7 +1355,7 @@ abstract class _Comment extends \IPS\Content
|
||||
}
|
||||
}
|
||||
|
||||
if ( in_array( 'IPS\Content\Permissions', class_implements( $itemClass ) ) AND $permissionKey !== NULL )
|
||||
if ( \in_array( 'IPS\Content\Permissions', class_implements( $itemClass ) ) AND $permissionKey !== NULL )
|
||||
{
|
||||
$containerClass = $itemClass::$containerNodeClass;
|
||||
|
||||
@@ -1418,7 +1368,7 @@ abstract class _Comment extends \IPS\Content
|
||||
static::$permissionSelect[ $lookupKey ] = array();
|
||||
$permQuery = \IPS\Db::i()->select( 'perm_type_id', 'core_permission_index', array( "core_permission_index.app='" . $containerClass::$permApp . "' AND core_permission_index.perm_type='" . $containerClass::$permType . "' AND (" . \IPS\Db::i()->findInSet( 'perm_' . $containerClass::$permissionMap[ $permissionKey ], $member->permissionArray() ) . ' OR ' . 'perm_' . $containerClass::$permissionMap[ $permissionKey ] . "='*' )" ) );
|
||||
|
||||
if ( count( $containerWhere ) )
|
||||
if ( \count( $containerWhere ) )
|
||||
{
|
||||
$permQuery->join( $containerClass::$databaseTable, array_merge( $containerWhere, array( 'core_permission_index.perm_type_id=' . $containerClass::$databaseTable . '.' . $containerClass::$databasePrefix . $containerClass::$databaseColumnId ) ), 'STRAIGHT_JOIN' );
|
||||
}
|
||||
@@ -1431,7 +1381,7 @@ abstract class _Comment extends \IPS\Content
|
||||
|
||||
$categories = static::$permissionSelect[ $lookupKey ];
|
||||
|
||||
if( count( $categories ) )
|
||||
if( \count( $categories ) )
|
||||
{
|
||||
$where[] = array( $itemClass::$databaseTable . "." . $itemClass::$databasePrefix . $itemClass::$databaseColumnMap['container'] . ' IN(' . implode( ',', $categories ) . ')' );
|
||||
}
|
||||
@@ -1451,7 +1401,7 @@ abstract class _Comment extends \IPS\Content
|
||||
->join( $itemClass::$databaseTable, array_merge( array( array( static::$databaseTable . "." . static::$databasePrefix . static::$databaseColumnMap['item'] . "=" . $itemClass::$databaseTable . "." . $itemClass::$databasePrefix . $itemClass::$databaseColumnId ) ), $itemWhere ), 'STRAIGHT_JOIN' );
|
||||
}
|
||||
|
||||
if ( $joins !== NULL AND count( $joins ) )
|
||||
if ( $joins !== NULL AND \count( $joins ) )
|
||||
{
|
||||
foreach( $joins as $join )
|
||||
{
|
||||
@@ -1460,7 +1410,7 @@ abstract class _Comment extends \IPS\Content
|
||||
}
|
||||
|
||||
/* Return */
|
||||
return new \IPS\Patterns\ActiveRecordIterator( $select, get_called_class() );
|
||||
return new \IPS\Patterns\ActiveRecordIterator( $select, \get_called_class(), $itemClass );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1497,12 +1447,12 @@ abstract class _Comment extends \IPS\Content
|
||||
/**
|
||||
* Returns the content images
|
||||
*
|
||||
* @param int|null $limit Number of attachments to fetch, or NULL for all
|
||||
*
|
||||
* @param int|null $limit Number of attachments to fetch, or NULL for all
|
||||
* @param bool $ignorePermissions If set to TRUE, permission to view the images will not be checked
|
||||
* @return array|NULL
|
||||
* @throws \BadMethodCallException
|
||||
*/
|
||||
public function contentImages( $limit = NULL )
|
||||
public function contentImages( $limit = NULL, $ignorePermissions = FALSE )
|
||||
{
|
||||
$idColumn = static::$databaseColumnId;
|
||||
$item = $this->item();
|
||||
@@ -1514,8 +1464,14 @@ abstract class _Comment extends \IPS\Content
|
||||
{
|
||||
$attachments[] = array( 'core_Attachment' => $row['attach_location'] );
|
||||
}
|
||||
|
||||
/* IS there a club with a cover photo? */
|
||||
if ( \IPS\IPS::classUsesTrait( $item->container(), 'IPS\Content\ClubContainer' ) and $club = $item->container()->club() )
|
||||
{
|
||||
$attachments[] = array( 'core_Clubs' => $club->cover_photo );
|
||||
}
|
||||
|
||||
return count( $attachments ) ? $attachments : NULL;
|
||||
return \count( $attachments ) ? $attachments : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1530,7 +1486,7 @@ abstract class _Comment extends \IPS\Content
|
||||
*/
|
||||
public function canShare()
|
||||
{
|
||||
return ( $this->canView( \IPS\Member::load( 0 ) ) and in_array( 'IPS\Content\Shareable', class_implements( get_called_class() ) ) );
|
||||
return ( $this->canView( \IPS\Member::load( 0 ) ) and \in_array( 'IPS\Content\Shareable', class_implements( \get_called_class() ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1540,7 +1496,7 @@ abstract class _Comment extends \IPS\Content
|
||||
*/
|
||||
public function sharelinks()
|
||||
{
|
||||
if( !count( $this->sharelinks ) )
|
||||
if( !\count( $this->sharelinks ) )
|
||||
{
|
||||
if ( $this instanceof Shareable and $this->canShare() )
|
||||
{
|
||||
@@ -1575,6 +1531,8 @@ abstract class _Comment extends \IPS\Content
|
||||
return \IPS\Application::load('core')->extensions( 'core', 'MetaData' )['FeaturedComments']->isFeatured( $this );
|
||||
}
|
||||
|
||||
/* !API */
|
||||
|
||||
/**
|
||||
* Get output for API
|
||||
*
|
||||
@@ -1597,12 +1555,44 @@ abstract class _Comment extends \IPS\Content
|
||||
'item_id' => $this->$itemColumn,
|
||||
'author' => $this->author()->apiOutput( $authorizedMember ),
|
||||
'date' => \IPS\DateTime::ts( $this->mapped('date') )->rfc3339(),
|
||||
'content' => $this->content(),
|
||||
'content' => \IPS\Text\Parser::removeLazyLoad( $this->content() ),
|
||||
'hidden' => (bool) $this->hidden(),
|
||||
'url' => (string) $this->url()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Webhook filters
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function webhookFilters()
|
||||
{
|
||||
$filters = parent::webhookFilters();
|
||||
$item = $this->item();
|
||||
|
||||
$filters['hidden'] = ( ( (bool) $this->hidden() ) or ( (bool) $item->hidden() ) );
|
||||
|
||||
if ( \in_array( 'IPS\Content\Lockable', class_implements( $item ) ) )
|
||||
{
|
||||
$filters['locked'] = $item->locked();
|
||||
}
|
||||
if ( \in_array( 'IPS\Content\Pinnable', class_implements( $item ) ) )
|
||||
{
|
||||
$filters['pinned'] = (bool) $item->mapped('pinned');
|
||||
}
|
||||
if ( \in_array( 'IPS\Content\Featurable', class_implements( $item ) ) )
|
||||
{
|
||||
$filters['featured'] = (bool) $item->mapped('featured');
|
||||
}
|
||||
if ( \in_array( 'IPS\Content\Polls', class_implements( $item ) ) )
|
||||
{
|
||||
$filters['hasPoll'] = (bool) $item->mapped('poll');
|
||||
}
|
||||
|
||||
return $filters;
|
||||
}
|
||||
|
||||
/* !Embeddable */
|
||||
|
||||
/**
|
||||
|
||||
Reference in new issue
Block a user