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

+299 -175
View File
@@ -2,9 +2,9 @@
/**
* @brief Content Comment Model
* @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 8 Jul 2013
* @version SVN_VERSION_NUMBER
*/
@@ -53,9 +53,11 @@ abstract class _Comment extends \IPS\Content
* @param bool|NULL $incrementPostCount Increment post count? If NULL, will use static::incrementPostCount()
* @param \IPS\Member|NULL $member The author of this comment. If NULL, uses currently logged in member.
* @param \IPS\DateTime|NULL $time The time
* @param string|NULL $ipAddress The IP address or NULL to detect automatically
* @param int|NULL $hiddenStatus NULL to set automatically or override: 0 = unhidden; 1 = hidden, pending moderator approval; -1 = hidden (as if hidden by a moderator)
* @return static
*/
public static function create( $item, $comment, $first=FALSE, $guestName=NULL, $incrementPostCount=NULL, $member=NULL, \IPS\DateTime $time=NULL )
public static function create( $item, $comment, $first=FALSE, $guestName=NULL, $incrementPostCount=NULL, $member=NULL, \IPS\DateTime $time=NULL, $ipAddress=NULL, $hiddenStatus=NULL )
{
if ( $member === NULL )
{
@@ -93,7 +95,7 @@ abstract class _Comment extends \IPS\Content
break;
case 'ip_address':
$val = \IPS\Request::i()->ipAddress();
$val = $ipAddress ?: \IPS\Request::i()->ipAddress();
break;
case 'first':
@@ -101,43 +103,62 @@ abstract class _Comment extends \IPS\Content
break;
case 'approved':
if ( in_array( 'IPS\Content\Review', class_parents( get_called_class() ) ) )
if ( $first ) // If this is the first post within an item, don't mark it hidden, otherwise the count of unapproved comments/items will include both the comment and the item when really only the item is hidden
{
$val = $item->moderateNewReviews( $member ) ? 0 : 1;
$val = TRUE;
}
elseif ( $hiddenStatus === NULL )
{
if ( in_array( 'IPS\Content\Review', class_parents( get_called_class() ) ) )
{
$val = $item->moderateNewReviews( $member ) ? 0 : 1;
}
else
{
$val = $item->moderateNewComments( $member ) ? 0 : 1;
}
}
else
{
$val = $item->moderateNewComments( $member ) ? 0 : 1;
}
/* If this is the first post within an item, don't mark it hidden, otherwise the count of unapproved comments/items will include both the comment and the item when really only the item is hidden */
if ( $first )
{
$val = TRUE;
switch ( $hiddenStatus )
{
case 0:
$val = 1;
break;
case 1:
$val = 0;
break;
case -1:
$val = -1;
break;
}
}
break;
case 'hidden':
if ( in_array( 'IPS\Content\Review', class_parents( get_called_class() ) ) )
{
$val = $item->moderateNewReviews( $member ) ? 1 : 0;
}
else
{
$val = $item->moderateNewComments( $member ) ? 1 : 0;
}
/* If this is the first post within an item, don't mark it hidden, otherwise the count of unapproved comments/items will include both the comment and the item when really only the item is hidden */
if ( $first )
{
$val = FALSE;
$val = FALSE; // If this is the first post within an item, don't mark it hidden, otherwise the count of unapproved comments/items will include both the comment and the item when really only the item is hidden
}
if ( ! $first and $item->approvedButHidden() )
elseif ( $item->approvedButHidden() )
{
$val = 2;
}
elseif ( $hiddenStatus === NULL )
{
if ( in_array( 'IPS\Content\Review', class_parents( get_called_class() ) ) )
{
$val = $item->moderateNewReviews( $member ) ? 1 : 0;
}
else
{
$val = $item->moderateNewComments( $member ) ? 1 : 0;
}
}
else
{
$val = $hiddenStatus;
}
break;
}
@@ -149,6 +170,35 @@ abstract class _Comment extends \IPS\Content
}
$obj->save();
/* Pass this through our profanity filters to see if it needs to be mod queued */
try
{
$hiddenByFilter = FALSE;
if ( !$obj->hidden() AND ( ! $item::$firstCommentRequired or ( $item::$firstCommentRequired and !$obj->isFirst() ) ) AND !$member->group['g_bypass_badwords'] )
{
$hiddenByFilter = \IPS\core\Profanity::hiddenByFilters( $comment );
}
}
catch( \BadMethodCallException $e ) { }
if ( $hiddenByFilter === TRUE )
{
if ( isset( static::$databaseColumnMap['approved'] ) )
{
/* 'approved' is easy, clear and concise */
$column = static::$databaseColumnMap['approved'];
$obj->$column = 0;
}
else if ( isset( static::$databaseColumnMap['hidden'] ) )
{
/* 'hidden' is backwards */
$column = static::$databaseColumnMap['hidden'];
$obj->$column = 1;
}
$obj->save();
}
/* Increment post count */
try
{
@@ -197,13 +247,16 @@ abstract class _Comment extends \IPS\Content
}
/* Send notifications */
if ( !$obj->hidden() and ( !$first or !$item::$firstCommentRequired ) )
if ( !in_array( 'IPS\Content\Review', class_parents( get_called_class() ) ) )
{
$obj->sendNotifications();
}
else if( $obj->hidden() === 1 )
{
$obj->sendUnapprovedNotification();
if ( !$obj->hidden() and ( !$first or !$item::$firstCommentRequired ) )
{
$obj->sendNotifications();
}
else if( $obj->hidden() === 1 )
{
$obj->sendUnapprovedNotification();
}
}
/* Update item */
@@ -327,66 +380,20 @@ abstract class _Comment extends \IPS\Content
}
}
/**
* @brief Cached URLs
*/
protected $_url = array();
/**
* Get URL
*
* @param string|NULL $action Action
* @return \IPS\Http\Url
*/
public function url( $action=NULL )
public function url( $action='find' )
{
$_key = md5( $action );
if( !isset( $this->_url[ $_key ] ) )
{
$itemClass = static::$itemClass;
$itemField = static::$databaseColumnMap['item'];
$idColumn = static::$databaseColumnId;
$this->_url[ $_key ] = $this->item()->url();
if( $action )
{
$this->_url[ $_key ] = $this->_url[ $_key ]->setQueryString( array( 'do' => $action . 'Comment', 'comment' => $this->$idColumn ) );
}
else
{
$where = array( array( static::$databasePrefix . static::$databaseColumnMap['item'] . '=? AND ' . static::$databasePrefix . static::$databaseColumnId . '<=?', $this->$itemField, $this->$idColumn ) );
if ( static::commentWhere() !== NULL )
{
$where[] = static::commentWhere();
}
if ( static::modPermission( 'view_hidden' ) === FALSE )
{
if ( isset( static::$databaseColumnMap['approved'] ) )
{
$where[] = array( static::$databasePrefix . static::$databaseColumnMap['approved'] . '=?', 1 );
}
elseif( isset( static::$databaseColumnMap['hidden'] ) )
{
$where[] = array( static::$databasePrefix . static::$databaseColumnMap['hidden'] . '=?', 0 );
}
}
$commentPosition = \IPS\Db::i()->select( 'COUNT(*) AS position', static::$databaseTable, $where, static::$databasePrefix . static::$databaseColumnMap['date'] . ' asc' )->first();
$page = ceil( $commentPosition / $itemClass::getCommentsPerPage() );
if ( $page != 1 )
{
$this->_url[ $_key ] = $this->_url[ $_key ]->setQueryString( 'page', $page );
}
$this->_url[ $_key ] = $this->_url[ $_key ]->setFragment( 'comment-' . $this->$idColumn );
}
}
return $this->_url[ $_key ];
$idColumn = static::$databaseColumnId;
return $this->item()->url()->setQueryString( array(
'do' => $action . 'Comment',
'comment' => $this->$idColumn
) );
}
/**
@@ -703,13 +710,14 @@ abstract class _Comment extends \IPS\Content
}
/**
* Users to receieve immediate notifications
* Users to receive immediate notifications
*
* @param int|array $limit LIMIT clause
* @param string|NULL $extra Additional data
* @param int|array $limit LIMIT clause
* @param string|NULL $extra Additional data
* @param boolean $countOnly Just return the count
* @return \IPS\Db\Select
*/
public function notificationRecipients( $limit=array( 0, 25 ), $extra=NULL )
public function notificationRecipients( $limit=array( 0, 25 ), $extra=NULL, $countOnly=FALSE )
{
$memberFollowers = $this->author()->followers( 3, array( 'immediate' ), $this->mapped('date'), NULL, NULL, NULL );
@@ -720,11 +728,32 @@ abstract class _Comment extends \IPS\Content
$memberFollowers
);
return \IPS\Db::i()->union( $unions, 'follow_added', $limit, 'follow_member_id, follow_id, follow_app, follow_area, follow_rel_id, follow_added, follow_is_anon, follow_notify_do, follow_notify_meta, follow_notify_freq, follow_notify_sent, follow_visible', FALSE, \IPS\Db::SELECT_SQL_CALC_FOUND_ROWS );
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 );
}
}
else
{
return $this->item()->followers( static::FOLLOW_PUBLIC + static::FOLLOW_ANONYMOUS, array( 'immediate' ), $this->mapped('date'), $limit, 'follow_added', \IPS\Db::SELECT_SQL_CALC_FOUND_ROWS );
$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;
}
}
}
@@ -742,9 +771,10 @@ abstract class _Comment extends \IPS\Content
/**
* Syncing to run when hiding
*
* @param \IPS\Member|NULL|FALSE $member The member doing the action (NULL for currently logged in member, FALSE for no member)
* @return void
*/
public function onHide()
public function onHide( $member )
{
$item = $this->item();
@@ -761,8 +791,8 @@ abstract class _Comment extends \IPS\Content
{
if ( $item->container()->_comments !== NULL )
{
$item->container()->_comments = $item->container()->_comments - 1;
$item->container()->setLastComment();
$item->container()->resetCommentCounts();
$item->container()->save();
}
} catch ( \BadMethodCallException $e ) {}
@@ -771,36 +801,29 @@ abstract class _Comment extends \IPS\Content
/**
* Syncing to run when unhiding
*
* @param bool $approving If true, is being approved for the first time
* @param bool $approving If true, is being approved for the first time
* @param \IPS\Member|NULL|FALSE $member The member doing the action (NULL for currently logged in member, FALSE for no member)
* @return void
*/
public function onUnhide( $approving )
public function onUnhide( $approving, $member )
{
$item = $this->item();
if ( $approving )
{
try
/* We should only do this if it is an actual account, and not a guest. */
if ( $this->author()->member_id )
{
if ( $item->container()->_unapprovedComments !== NULL )
try
{
if ( $item->container()->_unapprovedComments > 0 )
if ( static::incrementPostCount( $item->container() ) )
{
$item->container()->_unapprovedComments = $item->container()->_unapprovedComments - 1;
$item->container()->save();
$this->author()->member_posts++;
$this->author()->save();
}
}
} catch ( \BadMethodCallException $e ) {}
try
{
if ( static::incrementPostCount( $item->container() ) )
{
$this->author()->member_posts++;
$this->author()->save();
}
catch( \BadMethodCallException $e ) { }
}
catch( \BadMethodCallException $e ) { }
}
@@ -813,8 +836,8 @@ abstract class _Comment extends \IPS\Content
{
if ( $item->container()->_comments !== NULL )
{
$item->container()->_comments = $item->container()->_comments + 1;
$item->container()->setLastComment();
$item->container()->resetCommentCounts();
$item->container()->save();
}
} catch ( \BadMethodCallException $e ) {}
@@ -832,9 +855,22 @@ abstract class _Comment extends \IPS\Content
$idColumn = $item::$databaseColumnId;
$itemColumn = static::$databaseColumnMap['item'];
$commentIdColumn = static::$databaseColumnId;
$this->$itemColumn = $item->$idColumn;
$this->save();
/* The new item needs to re-claim any attachments associated with this comment */
\IPS\Db::i()->update( 'core_attachments_map', array( 'id1' => $item->$idColumn ), array( "location_key=? AND id1=? AND id2=?", $oldItem::$application . '_' . 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 ) );
/* Update reputation */
if ( $this instanceof \IPS\Content\Reputation )
{
\IPS\Db::i()->update( 'core_reputation_index', array( 'item_id' => $item->$idColumn ), array( 'class_type_id_hash=?', md5( get_class( $this ) . ':' . $oldItem->$idColumn ) ) );
}
$oldItem->rebuildFirstAndLastCommentData();
$item->rebuildFirstAndLastCommentData();
@@ -873,13 +909,31 @@ abstract class _Comment extends \IPS\Content
*/
public function delete()
{
/* Remove from search index first */
if ( $this instanceof \IPS\Content\Searchable )
{
\IPS\Content\Search\Index::i()->removeFromSearchIndex( $this );
}
/* Init */
$idColumn = static::$databaseColumnId;
$itemClass = static::$itemClass;
$itemIdColumn = $itemClass::$databaseColumnId;
/* It is possible to delete a comment that is orphaned, so let's try to protect against that */
try
{
$item = $this->item();
$itemId = $this->item()->$itemIdColumn;
}
catch( \OutOfRangeException $e )
{
$item = NULL;
$itemId = $this->mapped('item');
}
/* Unclaim attachments */
\IPS\File::unclaimAttachments( $itemClass::$application . '_' . ucfirst( $itemClass::$module ), $this->item()->$itemIdColumn, $this->$idColumn );
\IPS\File::unclaimAttachments( $itemClass::$application . '_' . ucfirst( $itemClass::$module ), $itemId, $this->$idColumn );
/* 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 */
@@ -890,14 +944,14 @@ abstract class _Comment extends \IPS\Content
{
$columnName = ( $this->hidden() === 1 ) ? 'unapproved_reviews' : 'num_reviews';
}
if ( isset( $itemClass::$databaseColumnMap[$columnName] ) )
if ( isset( $itemClass::$databaseColumnMap[$columnName] ) AND $item !== NULL )
{
$column = $itemClass::$databaseColumnMap[$columnName];
if ( $this->item()->$column > 0 )
if ( $item->$column > 0 )
{
$this->item()->$column--;
$this->item()->save();
$item->$column--;
$item->save();
}
}
}
@@ -905,27 +959,27 @@ abstract class _Comment extends \IPS\Content
{
if ( in_array( 'IPS\Content\Review', class_parents( get_called_class() ) ) )
{
if( isset( $itemClass::$databaseColumnMap['hidden_reviews'] ) )
if( isset( $itemClass::$databaseColumnMap['hidden_reviews'] ) AND $item !== NULL )
{
$column = $itemClass::$databaseColumnMap['hidden_reviews'];
if ( $this->item()->$column > 0 )
if ( $item->$column > 0 )
{
$this->item()->$column--;
$this->item()->save();
$item->$column--;
$item->save();
}
}
}
else
{
if( isset( $itemClass::$databaseColumnMap['hidden_comments'] ) )
if( isset( $itemClass::$databaseColumnMap['hidden_comments'] ) AND $item !== NULL )
{
$column = $itemClass::$databaseColumnMap['hidden_comments'];
if ( $this->item()->$column > 0 )
if ( $item->$column > 0 )
{
$this->item()->$column--;
$this->item()->save();
$item->$column--;
$item->save();
}
}
}
@@ -934,7 +988,7 @@ abstract class _Comment extends \IPS\Content
/* 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;
}
@@ -949,48 +1003,42 @@ abstract class _Comment extends \IPS\Content
/* Actually delete */
parent::delete();
/* Remove from search index */
if ( $this instanceof \IPS\Content\Searchable )
{
\IPS\Content\Search\Index::i()->removeFromSearchIndex( $this );
}
/* Update last comment/review data for container and item */
try
{
if ( 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 ( $this->item()->container()->_reviews !== NULL )
if ( $item->container()->_reviews !== NULL )
{
$this->item()->container()->_reviews = ( $this->item()->container()->_reviews - 1 );
$this->item()->resyncLastReview();
$this->item()->save();
$this->item()->container()->setLastReview();
$item->container()->_reviews = ( $item->container()->_reviews - 1 );
$item->resyncLastReview();
$item->save();
$item->container()->setLastReview();
}
if ( $this->item()->container()->_unapprovedReviews !== NULL )
if ( $item->container()->_unapprovedReviews !== NULL )
{
$this->item()->container()->_unapprovedReviews = ( $this->item()->container()->_unapprovedReviews > 0 ) ? ( $this->item()->container()->_unapprovedReviews - 1 ) : 0;
$item->container()->_unapprovedReviews = ( $item->container()->_unapprovedReviews > 0 ) ? ( $item->container()->_unapprovedReviews - 1 ) : 0;
}
$this->item()->container()->save();
$item->container()->save();
}
else if ( $this->item()->container() !== NULL )
else if ( $item !== NULL AND $item->container() !== NULL )
{
if ( $this->item()->container()->_comments !== NULL )
if ( $item->container()->_comments !== NULL )
{
if ( !$this->hidden() )
{
$this->item()->container()->_comments = ( $this->item()->container()->_comments > 0 ) ? ( $this->item()->container()->_comments - 1 ) : 0;
$item->container()->_comments = ( $item->container()->_comments > 0 ) ? ( $item->container()->_comments - 1 ) : 0;
}
$this->item()->resyncLastComment();
$this->item()->save();
$this->item()->container()->setLastComment();
$item->resyncLastComment();
$item->save();
$item->container()->setLastComment();
}
if ( $this->item()->container()->_unapprovedComments !== NULL and $this->hidden() === 1 )
if ( $item->container()->_unapprovedComments !== NULL and $this->hidden() === 1 )
{
$this->item()->container()->_unapprovedComments = ( $this->item()->container()->_unapprovedComments > 0 ) ? ( $this->item()->container()->_unapprovedComments - 1 ) : 0;
$item->container()->_unapprovedComments = ( $item->container()->_unapprovedComments > 0 ) ? ( $item->container()->_unapprovedComments - 1 ) : 0;
}
$this->item()->container()->save();
$item->container()->save();
}
}
catch ( \BadMethodCallException $e ) {}
@@ -1035,6 +1083,12 @@ abstract class _Comment extends \IPS\Content
$container->setLastReview();
$container->save();
}
/* Update search index */
if ( $this instanceof \IPS\Content\Searchable )
{
\IPS\Content\Search\Index::i()->index( $this );
}
}
/**
@@ -1064,17 +1118,17 @@ abstract class _Comment extends \IPS\Content
* @param string $order MySQL ORDER BY clause (NULL to order by date)
* @param int|array $limit Limit clause
* @param string|NULL $permissionKey A key which has a value in the permission map (either of the container or of this class) matching a column ID in core_permission_index, or NULL to ignore permissions
* @param bool|NULL $includeHiddenComments Include hidden comments? Boolean or NULL to detect if currently logged member has permission
* @param int $queryFlags Select bitwise flags
* @param \IPS\Member $member The member (NULL to use currently logged in member)
* @param bool $joinContainer If true, will join container data (set to TRUE if your $where clause depends on this data)
* @param bool $joinComments If true, will join comment data (set to TRUE if your $where clause depends on this data)
* @param bool $joinReviews If true, will join review data (set to TRUE if your $where clause depends on this data)
* @param bool $countOnly If true will return the count
* @param array|null $joins Additional arbitrary joins for the query
* @return array|NULL|\IPS\Content\Comment If $limit is 1, will return \IPS\Content\Comment or NULL for no results. For any other number, will return an array.
* @param mixed $includeHiddenComments Include hidden comments? NULL to detect if currently logged in member has permission, -1 to return public content only, TRUE to return unapproved content and FALSE to only return unapproved content the viewing member submitted
* @param int $queryFlags Select bitwise flags
* @param \IPS\Member $member The member (NULL to use currently logged in member)
* @param bool $joinContainer If true, will join container data (set to TRUE if your $where clause depends on this data)
* @param bool $joinComments If true, will join comment data (set to TRUE if your $where clause depends on this data)
* @param bool $joinReviews If true, will join review data (set to TRUE if your $where clause depends on this data)
* @param bool $countOnly If true will return the count
* @param array|null $joins Additional arbitrary joins for the query
* @return array|NULL|\IPS\Content\Comment If $limit is 1, will return \IPS\Content\Comment or NULL for no results. For any other number, will return an array.
*/
public static function getItemsWithPermission( $where=array(), $order=NULL, $limit=10, $permissionKey='read', $includeHiddenComments=NULL, $queryFlags=0, \IPS\Member $member=NULL, $joinContainer=FALSE, $joinComments=FALSE, $joinReviews=FALSE, $countOnly=FALSE, $joins=NULL )
public static function getItemsWithPermission( $where=array(), $order=NULL, $limit=10, $permissionKey='read', $includeHiddenComments=\IPS\Content\Hideable::FILTER_AUTOMATIC, $queryFlags=0, \IPS\Member $member=NULL, $joinContainer=FALSE, $joinComments=FALSE, $joinReviews=FALSE, $countOnly=FALSE, $joins=NULL )
{
/* Get the item class - we need it later */
$itemClass = static::$itemClass;
@@ -1106,9 +1160,36 @@ abstract class _Comment extends \IPS\Content
$order = $order ?: ( static::$databasePrefix . static::$databaseColumnMap['date'] . ' DESC' );
/* Exclude hidden comments */
$includeHiddenComments = ( $includeHiddenComments === NULL ) ? static::modPermission( 'view_hidden' ) : $includeHiddenComments;
if( $includeHiddenComments === \IPS\Content\Hideable::FILTER_AUTOMATIC )
{
if( static::modPermission( 'view_hidden', $member ) )
{
$includeHiddenComments = \IPS\Content\Hideable::FILTER_SHOW_HIDDEN;
}
else
{
$includeHiddenComments = \IPS\Content\Hideable::FILTER_OWN_HIDDEN;
}
}
if ( in_array( 'IPS\Content\Hideable', class_implements( get_called_class() ) ) and !$includeHiddenComments )
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 ) )
{
return array();
}
if ( isset( static::$databaseColumnMap['approved'] ) )
{
$where[] = array( static::$databasePrefix . static::$databaseColumnMap['approved'] . '=?', 0 );
}
elseif ( isset( static::$databaseColumnMap['hidden'] ) )
{
$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 ) )
{
if ( isset( static::$databaseColumnMap['approved'] ) )
{
@@ -1120,16 +1201,17 @@ abstract class _Comment extends \IPS\Content
}
}
/* Exclude hidden items */
if ( in_array( 'IPS\Content\Hideable', class_implements( $itemClass ) ) and !$includeHiddenComments )
/* 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 ) )
{
$member = $member ?: \IPS\Member::loggedIn();
$authorCol = $itemClass::$databaseTable . '.' . $itemClass::$databasePrefix . $itemClass::$databaseColumnMap['author'];
if ( isset( $itemClass::$databaseColumnMap['approved'] ) )
{
$col = $itemClass::$databaseTable . '.' . $itemClass::$databasePrefix . $itemClass::$databaseColumnMap['approved'];
if ( \IPS\Member::loggedIn()->member_id )
if ( $member->member_id AND $includeHiddenComments !== \IPS\Content\Hideable::FILTER_PUBLIC_ONLY )
{
$itemWhere[] = array( "( {$col}=1 OR ( {$col}=0 AND {$authorCol}=" . \IPS\Member::loggedIn()->member_id . " ) )" );
$itemWhere[] = array( "( {$col}=1 OR ( {$col}=0 AND {$authorCol}=" . $member->member_id . " ) )" );
}
else
{
@@ -1139,9 +1221,9 @@ abstract class _Comment extends \IPS\Content
elseif ( isset( $itemClass::$databaseColumnMap['hidden'] ) )
{
$col = $itemClass::$databaseTable . '.' . $itemClass::$databasePrefix . $itemClass::$databaseColumnMap['hidden'];
if ( \IPS\Member::loggedIn()->member_id )
if ( $member->member_id AND $includeHiddenComments !== \IPS\Content\Hideable::FILTER_PUBLIC_ONLY )
{
$itemWhere[] = array( "( {$col}=0 OR ( {$col}=1 AND {$authorCol}=" . \IPS\Member::loggedIn()->member_id . " ) )" );
$itemWhere[] = array( "( {$col}=0 OR ( {$col}=1 AND {$authorCol}=" . $member->member_id . " ) )" );
}
else
{
@@ -1169,7 +1251,7 @@ abstract class _Comment extends \IPS\Content
}
}
if ( $joinContainer )
if ( $joinContainer AND isset( $itemClass::$containerNodeClass ) )
{
$containerClass = $itemClass::$containerNodeClass;
$joins[] = array(
@@ -1181,14 +1263,27 @@ abstract class _Comment extends \IPS\Content
/* Build the select clause */
if( $countOnly )
{
$select = \IPS\Db::i()->select( 'COUNT(*) as cnt', static::$databaseTable, $where, NULL, NULL, NULL, NULL, $queryFlags )
->join( $itemClass::$databaseTable, array_merge( array( array( static::$databaseTable . "." . static::$databasePrefix . static::$databaseColumnMap['item'] . "=" . $itemClass::$databaseTable . "." . $itemClass::$databasePrefix . $itemClass::$databaseColumnId ) ), $itemWhere ), 'STRAIGHT_JOIN' );
if ( in_array( 'IPS\Content\Permissions', class_implements( $itemClass ) ) AND $permissionKey !== NULL )
{
$member = $member ?: \IPS\Member::loggedIn();
$containerClass = $itemClass::$containerNodeClass;
$select = \IPS\Db::i()->select( 'COUNT(*) as cnt', static::$databaseTable, $where, NULL, NULL, NULL, NULL, $queryFlags )
->join( $itemClass::$databaseTable, array_merge( array( array( static::$databaseTable . "." . static::$databasePrefix . static::$databaseColumnMap['item'] . "=" . $itemClass::$databaseTable . "." . $itemClass::$databasePrefix . $itemClass::$databaseColumnId ) ), $itemWhere ), 'STRAIGHT_JOIN' )
->join( 'core_permission_index', array( "core_permission_index.app=? AND core_permission_index.perm_type=? AND core_permission_index.perm_type_id=" . $itemClass::$databaseTable . "." . $itemClass::$databasePrefix . $itemClass::$databaseColumnMap['container'] . ' AND (' . \IPS\Db::i()->findInSet( 'perm_' . $containerClass::$permissionMap[ $permissionKey ], $member->groups ) . ' OR ' . 'perm_' . $containerClass::$permissionMap[ $permissionKey ] . '=? )', $containerClass::$permApp, $containerClass::$permType, '*' ), 'STRAIGHT_JOIN' );
}
else
{
$select = \IPS\Db::i()->select( 'COUNT(*) as cnt', static::$databaseTable, $where, NULL, NULL, NULL, NULL, $queryFlags )
->join( $itemClass::$databaseTable, array_merge( array( array( static::$databaseTable . "." . static::$databasePrefix . static::$databaseColumnMap['item'] . "=" . $itemClass::$databaseTable . "." . $itemClass::$databasePrefix . $itemClass::$databaseColumnId ) ), $itemWhere ), 'STRAIGHT_JOIN' );
}
if ( count( $joins ) )
{
foreach( $joins as $join )
{
$select->join( $join['from'], ( isset( $join['where'] ) ? $join['where'] : null ), 'LEFT' );
$select->join( $join['from'], ( isset( $join['where'] ) ? $join['where'] : null ), ( isset( $join['type'] ) ) ? $join['type'] : 'LEFT' );
}
}
return $select->first();
@@ -1208,13 +1303,15 @@ abstract class _Comment extends \IPS\Content
if ( in_array( 'IPS\Content\Permissions', class_implements( $itemClass ) ) AND $permissionKey !== NULL )
{
$member = $member ?: \IPS\Member::loggedIn();
$containerClass = $itemClass::$containerNodeClass;
$selectClause .= ', ' . $itemClass::$databaseTable . '.*';
$select = \IPS\Db::i()->select( $selectClause, static::$databaseTable, $where, $order, $limit, NULL, NULL, $queryFlags )
->join( $itemClass::$databaseTable, array_merge( array( array( static::$databaseTable . "." . static::$databasePrefix . static::$databaseColumnMap['item'] . "=" . $itemClass::$databaseTable . "." . $itemClass::$databasePrefix . $itemClass::$databaseColumnId ) ), $itemWhere ), 'STRAIGHT_JOIN' )
->join( 'core_permission_index', array( "core_permission_index.app=? AND core_permission_index.perm_type=? AND core_permission_index.perm_type_id=" . $itemClass::$databaseTable . "." . $itemClass::$databasePrefix . $itemClass::$databaseColumnMap['container'] . ' AND (' . \IPS\Db::i()->findInSet( 'perm_' . $containerClass::$permissionMap[ $permissionKey ], \IPS\Member::loggedIn()->groups ) . ' OR ' . 'perm_' . $containerClass::$permissionMap[ $permissionKey ] . '=? )', $containerClass::$permApp, $containerClass::$permType, '*' ), 'STRAIGHT_JOIN' );
->join( 'core_permission_index', array( "core_permission_index.app=? AND core_permission_index.perm_type=? AND core_permission_index.perm_type_id=" . $itemClass::$databaseTable . "." . $itemClass::$databasePrefix . $itemClass::$databaseColumnMap['container'] . ' AND (' . \IPS\Db::i()->findInSet( 'perm_' . $containerClass::$permissionMap[ $permissionKey ], $member->groups ) . ' OR ' . 'perm_' . $containerClass::$permissionMap[ $permissionKey ] . '=? )', $containerClass::$permApp, $containerClass::$permType, '*' ), 'STRAIGHT_JOIN' );
}
else
{
@@ -1226,7 +1323,7 @@ abstract class _Comment extends \IPS\Content
{
foreach( $joins as $join )
{
$select->join( $join['from'], ( isset( $join['where'] ) ? $join['where'] : null ), 'LEFT' );
$select->join( $join['from'], ( isset( $join['where'] ) ? $join['where'] : null ), ( isset( $join['type'] ) ) ? $join['type'] : 'LEFT' );
}
}
@@ -1294,7 +1391,7 @@ abstract class _Comment extends \IPS\Content
$idColumn = static::$databaseColumnId;
$shareUrl = $this->url( 'find' )->setQueryString( 'comment', $this->$idColumn );
$this->sharelinks = \IPS\core\ShareLinks\Service::getAllServices( $shareUrl, $this->item()->mapped('title') );
$this->sharelinks = \IPS\core\ShareLinks\Service::getAllServices( $shareUrl, $this->item()->mapped('title'), NULL, $this->item() );
}
}
@@ -1311,6 +1408,33 @@ abstract class _Comment extends \IPS\Content
return NULL;
}
/**
* Get output for API
*
* @return array
* @apiresponse int id ID number
* @apiresponse int item_id The ID number of the item this belongs to
* @apiresponse \IPS\Member author Author
* @apiresponse datetime date Date
* @apiresponse string content The content
* @apiresponse bool hidden Is hidden?
* @apiresponse string url URL to content
*/
public function apiOutput()
{
$idColumn = static::$databaseColumnId;
$itemColumn = static::$databaseColumnMap['item'];
return array(
'id' => $this->$idColumn,
'item_id' => $this->$itemColumn,
'author' => $this->author()->apiOutput(),
'date' => \IPS\DateTime::ts( $this->mapped('date') )->rfc3339(),
'content' => $this->content(),
'hidden' => (bool) $this->hidden(),
'url' => (string) $this->url()
);
}
/* !Embeddable */
/**