Version 4.1.19
This commit is contained in:
1 parent
28bd025b35
commit
2bd5025018
2674 files changed
+233518
-77766
No files matched your search
+299
-175
@@ -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 */
|
||||
|
||||
/**
|
||||
|
||||
Reference in new issue
Block a user