Version 4.6.0
This commit is contained in:
1 parent
f79dcf067a
commit
517a5e1f70
2036 files changed
+110041
-26162
No files matched your search
+360
-115
@@ -346,13 +346,13 @@ abstract class _Item extends \IPS\Content
|
||||
}
|
||||
|
||||
/* Increment post count */
|
||||
if ( !$obj->hidden() and static::incrementPostCount( $container ) )
|
||||
if ( !$obj->hidden() and static::incrementPostCount( $container ) and ! $obj->isAnonymous() )
|
||||
{
|
||||
$obj->author()->member_posts++;
|
||||
}
|
||||
|
||||
/* Update member's last post */
|
||||
if( $obj->author()->member_id AND $obj::incrementPostCount() )
|
||||
if( $obj->author()->member_id AND $obj::incrementPostCount() AND ! $obj->isAnonymous() )
|
||||
{
|
||||
$obj->author()->member_last_post = time();
|
||||
$obj->author()->save();
|
||||
@@ -434,9 +434,16 @@ abstract class _Item extends \IPS\Content
|
||||
$member->save();
|
||||
}
|
||||
|
||||
|
||||
/* Post anonymously */
|
||||
if( isset( $values[ 'post_anonymously' ] ) )
|
||||
{
|
||||
$obj->setAnonymous( $values[ 'post_anonymously' ] );
|
||||
}
|
||||
|
||||
/* Do any processing */
|
||||
$obj->processAfterCreate( $comment, $values );
|
||||
|
||||
|
||||
/* Auto-follow */
|
||||
if( isset( $values[ static::$formLangPrefix . 'auto_follow'] ) AND $values[ static::$formLangPrefix . 'auto_follow'] )
|
||||
{
|
||||
@@ -494,6 +501,12 @@ abstract class _Item extends \IPS\Content
|
||||
$obj->sendUnapprovedNotification();
|
||||
}
|
||||
}
|
||||
|
||||
/* Dish out points */
|
||||
if ( !$obj->isFutureDate() and !$obj->hidden() )
|
||||
{
|
||||
$member->achievementAction( 'core', 'NewContentItem', $obj );
|
||||
}
|
||||
|
||||
/* Return */
|
||||
return $obj;
|
||||
@@ -756,6 +769,12 @@ abstract class _Item extends \IPS\Content
|
||||
$return['auto_follow'] = new \IPS\Helpers\Form\YesNo( static::$formLangPrefix . 'auto_follow', (bool) \IPS\Member::loggedIn()->auto_follow['content'], FALSE, array( 'label' => \IPS\Member::loggedIn()->language()->addToStack( static::$formLangPrefix . 'auto_follow_suffix' ) ), NULL, NULL, NULL, static::$formLangPrefix . 'auto_follow' );
|
||||
}
|
||||
|
||||
/* Post Anonymously */
|
||||
if ( $container and $container->canPostAnonymously( $container::ANON_ITEMS ) )
|
||||
{
|
||||
$return['post_anonymously'] = new \IPS\Helpers\Form\YesNo( 'post_anonymously', ( $item ) ? $item->isAnonymous() : FALSE , FALSE, array( 'label' => \IPS\Member::loggedIn()->language()->addToStack( 'post_anonymously_suffix' ) ), NULL, NULL, NULL, 'post_anonymously' );
|
||||
}
|
||||
|
||||
/* Share Links */
|
||||
if ( $item === NULL and \in_array( 'IPS\Content\Shareable', class_implements( \get_called_class() ) ) )
|
||||
{
|
||||
@@ -1080,7 +1099,7 @@ abstract class _Item extends \IPS\Content
|
||||
}
|
||||
|
||||
/* Check if profanity filters should mod-queue this comment */
|
||||
$sendNotifications = $commentObj->checkProfanityFilters( TRUE, TRUE );
|
||||
$sendNotifications = $commentObj->checkProfanityFilters( TRUE, TRUE, $values[ static::$formLangPrefix . 'content'] );
|
||||
|
||||
/* Send notifications */
|
||||
if ( $sendNotifications AND !\in_array( 'IPS\Content\Review', class_parents( \get_called_class() ) ) )
|
||||
@@ -1093,7 +1112,7 @@ abstract class _Item extends \IPS\Content
|
||||
}
|
||||
|
||||
$oldValue = $commentObj->$column;
|
||||
$commentObj->$column = $values[static::$formLangPrefix . 'content'];
|
||||
$commentObj->$column = $values[ static::$formLangPrefix . 'content'];
|
||||
$commentObj->save();
|
||||
$commentObj->sendAfterEditNotifications( $oldValue );
|
||||
|
||||
@@ -1129,6 +1148,12 @@ abstract class _Item extends \IPS\Content
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Post anonymously */
|
||||
if( isset( $values[ 'post_anonymously' ] ) and ( isset( $container ) and $container->canPostAnonymously( $container::ANON_ITEMS ) ) )
|
||||
{
|
||||
$this->setAnonymous( $values[ 'post_anonymously' ] );
|
||||
}
|
||||
}
|
||||
|
||||
/* Holds the old content for edit logging */
|
||||
@@ -1336,7 +1361,7 @@ abstract class _Item extends \IPS\Content
|
||||
switch( $pref )
|
||||
{
|
||||
case 'unread':
|
||||
$action = 'getNewComment';
|
||||
$action = \IPS\Member::loggedIn()->member_id ? 'getNewComment' : NULL;
|
||||
break;
|
||||
|
||||
case 'last':
|
||||
@@ -1348,6 +1373,10 @@ abstract class _Item extends \IPS\Content
|
||||
break;
|
||||
}
|
||||
}
|
||||
elseif( !\IPS\Member::loggedIn()->member_id AND $action == 'getNewComment' )
|
||||
{
|
||||
$action = NULL;
|
||||
}
|
||||
|
||||
if ( isset( static::$urlBase ) and isset( static::$urlTemplate ) and isset( static::$seoTitleColumn ) )
|
||||
{
|
||||
@@ -1407,7 +1436,7 @@ abstract class _Item extends \IPS\Content
|
||||
switch( $pref )
|
||||
{
|
||||
case 'unread':
|
||||
$action = 'getNewComment';
|
||||
$action = \IPS\Member::loggedIn()->member_id ? 'getNewComment' : NULL;
|
||||
break;
|
||||
|
||||
case 'last':
|
||||
@@ -1419,6 +1448,10 @@ abstract class _Item extends \IPS\Content
|
||||
break;
|
||||
}
|
||||
}
|
||||
elseif( !\IPS\Member::loggedIn()->member_id AND $action == 'getNewComment' )
|
||||
{
|
||||
$action = NULL;
|
||||
}
|
||||
|
||||
$url = \IPS\Http\Url::internal( static::$urlBase . $indexData['index_item_id'], 'front', static::$urlTemplate, \IPS\Http\Url\Friendly::seoTitle( $indexData['index_title'] ?: $itemData[ static::$databasePrefix . static::$databaseColumnMap['title'] ] ) );
|
||||
|
||||
@@ -1641,7 +1674,7 @@ abstract class _Item extends \IPS\Content
|
||||
|
||||
if ( $return )
|
||||
{
|
||||
$return = trim( str_replace( array( '"', "'", '>', '<' ), '', preg_replace( "/\s+/um", " ", str_replace( ' ', ' ', strip_tags( preg_replace('#(<(script|style)\b[^>]*>).*?(</\2>)#is', "$1$3", $return ) ) ) ) ) );
|
||||
$return = trim( preg_replace( "/\s+/um", " ", str_replace( ' ', ' ', strip_tags( preg_replace('#(<(script|style)\b[^>]*>).*?(</\2>)#is', "$1$3", $return ) ) ) ) );
|
||||
if ( mb_strlen( $return ) > 300 )
|
||||
{
|
||||
$return = mb_substr( $return, 0, 297 ) . '...';
|
||||
@@ -1864,12 +1897,15 @@ abstract class _Item extends \IPS\Content
|
||||
}
|
||||
|
||||
/* Rebuild node data */
|
||||
$oldContainer->setLastComment();
|
||||
$oldContainer->setLastReview();
|
||||
$oldContainer->save();
|
||||
$container->setLastComment();
|
||||
$container->setLastReview();
|
||||
$container->save();
|
||||
if( !$this->skipContainerRebuild )
|
||||
{
|
||||
$oldContainer->setLastComment();
|
||||
$oldContainer->setLastReview();
|
||||
$oldContainer->save();
|
||||
$container->setLastComment();
|
||||
$container->setLastReview();
|
||||
$container->save();
|
||||
}
|
||||
|
||||
/* Add to search index */
|
||||
if ( $this instanceof \IPS\Content\Searchable )
|
||||
@@ -2063,6 +2099,9 @@ abstract class _Item extends \IPS\Content
|
||||
\IPS\Db::i()->update( 'core_moderator_logs', array( 'item_id' => $this->$idColumn ), array( 'item_id=? AND class=?', $item->$idColumn, (string) \get_class( $this ) ) );
|
||||
\IPS\Session::i()->modLog( 'modlog__action_merge', array( $item->mapped('title') => FALSE, $this->url()->__toString() => FALSE, $this->mapped('title') => FALSE ), $this );
|
||||
|
||||
/* Add to the redirect table */
|
||||
$item->setRedirectTo( $this );
|
||||
|
||||
/* If we are adding redirects to the merged items, then we need to change these to link items. */
|
||||
if ( $keepLinks AND isset( $item::$databaseColumnMap['moved_to'] ) )
|
||||
{
|
||||
@@ -2264,6 +2303,12 @@ abstract class _Item extends \IPS\Content
|
||||
$this->hide( NULL );
|
||||
}
|
||||
}
|
||||
|
||||
/* Update mappings */
|
||||
if ( isset( static::$databaseColumnMap['container'] ) and \IPS\IPS::classUsesTrait( $this->container(), 'IPS\Node\Statistics' ) )
|
||||
{
|
||||
$this->container()->rebuildPostedIn( array( $this->$idColumn ) );
|
||||
}
|
||||
}
|
||||
|
||||
/* Update last comment stuff */
|
||||
@@ -2290,6 +2335,12 @@ abstract class _Item extends \IPS\Content
|
||||
$this->container()->setLastReview();
|
||||
$this->container()->save();
|
||||
}
|
||||
|
||||
/* Clear cached statistics */
|
||||
if ( \IPS\IPS::classUsesTrait( $this, 'IPS\Content\Statistics' ) )
|
||||
{
|
||||
$this->clearCachedStatistics();
|
||||
}
|
||||
|
||||
/* Add to search index */
|
||||
if ( $this instanceof \IPS\Content\Searchable )
|
||||
@@ -2487,6 +2538,8 @@ abstract class _Item extends \IPS\Content
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Db::i()->delete( 'core_item_member_map', array( 'map_class=? and map_item_id=?', (string) \get_class( $this ), (int) $this->$idColumn ) );
|
||||
|
||||
/* Remove any meta data */
|
||||
if ( ( $this instanceof \IPS\Content\MetaData ) AND isset( static::$databaseColumnMap['meta_data'] ) )
|
||||
@@ -2539,34 +2592,34 @@ abstract class _Item extends \IPS\Content
|
||||
$commentIds[] = $commentId;
|
||||
}
|
||||
|
||||
\IPS\Db::i()->delete( 'core_deletion_log', array( "dellog_content_class=? AND " . \IPS\Db::i()->in( 'dellog_content_id', $commentIds ), $commentClass ) );
|
||||
\IPS\Db::i()->delete( 'core_social_promote', array( "promote_class=? AND " . \IPS\Db::i()->in( 'promote_class_id', $commentIds ), $commentClass ) );
|
||||
\IPS\Db::i()->delete( 'core_reputation_index', array( "rep_class=? AND " . \IPS\Db::i()->in( 'type_id', $commentIds ), $commentClass ) );
|
||||
\IPS\Db::i()->delete( 'core_solved_index', array( "comment_class=? AND " . \IPS\Db::i()->in( 'comment_id', $commentIds ), $commentClass ) );
|
||||
$this->deleteCommentOrReviewData( $commentIds, $commentClass );
|
||||
|
||||
if ( \is_array( $where ) and \count( $where ) )
|
||||
{
|
||||
\IPS\Db::i()->delete( $commentClass::$databaseTable, $where );
|
||||
}
|
||||
|
||||
try
|
||||
if( !$this->skipContainerRebuild )
|
||||
{
|
||||
if ( $this->container()->_comments !== NULL )
|
||||
try
|
||||
{
|
||||
/* We decrement the comment count onHide() */
|
||||
if ( ! $this->hidden() )
|
||||
if ( $this->container()->_comments !== NULL )
|
||||
{
|
||||
$this->container()->_comments = ( $this->container()->_comments - $this->mapped('num_comments') );
|
||||
/* We decrement the comment count onHide() */
|
||||
if ( ! $this->hidden() )
|
||||
{
|
||||
$this->container()->_comments = ( $this->container()->_comments - $this->mapped('num_comments') );
|
||||
}
|
||||
|
||||
$this->container()->setLastComment();
|
||||
}
|
||||
|
||||
$this->container()->setLastComment();
|
||||
}
|
||||
if ( $this->container()->_unapprovedComments !== NULL )
|
||||
{
|
||||
$this->container()->_unapprovedComments = ( $this->container()->_unapprovedComments - $this->mapped('unapproved_comments') );
|
||||
}
|
||||
$this->container()->save();
|
||||
} catch ( \BadMethodCallException $e ) {}
|
||||
if ( $this->container()->_unapprovedComments !== NULL )
|
||||
{
|
||||
$this->container()->_unapprovedComments = ( $this->container()->_unapprovedComments - $this->mapped('unapproved_comments') );
|
||||
}
|
||||
$this->container()->save();
|
||||
} catch ( \BadMethodCallException $e ) {}
|
||||
}
|
||||
}
|
||||
|
||||
/* Delete reviews */
|
||||
@@ -2587,32 +2640,32 @@ abstract class _Item extends \IPS\Content
|
||||
{
|
||||
$reviewIds[] = $reviewId;
|
||||
}
|
||||
|
||||
\IPS\Db::i()->delete( 'core_deletion_log', array( "dellog_content_class=? AND " . \IPS\Db::i()->in( 'dellog_content_id', $reviewIds ), $reviewClass ) );
|
||||
\IPS\Db::i()->delete( 'core_social_promote', array( "promote_class=? AND " . \IPS\Db::i()->in( 'promote_class_id', $reviewIds ), $reviewClass ) );
|
||||
\IPS\Db::i()->delete( 'core_reputation_index', array( "rep_class=? AND " . \IPS\Db::i()->in( 'type_id', $reviewIds ), $reviewClass ) );
|
||||
\IPS\Db::i()->delete( 'core_solved_index', array( "comment_class=? AND " . \IPS\Db::i()->in( 'comment_id', $reviewIds ), $reviewClass ) );
|
||||
|
||||
$this->deleteCommentOrReviewData( $reviewIds, $reviewClass );
|
||||
|
||||
\IPS\Db::i()->delete( $reviewClass::$databaseTable, $where );
|
||||
|
||||
try
|
||||
if( !$this->skipContainerRebuild )
|
||||
{
|
||||
if ( $this->container()->_reviews !== NULL )
|
||||
try
|
||||
{
|
||||
/* We decrement the review count onHide() */
|
||||
if ( ! $this->hidden() )
|
||||
if ( $this->container()->_reviews !== NULL )
|
||||
{
|
||||
$this->container()->_reviews = ( $this->container()->_reviews - $this->mapped('num_reviews') );
|
||||
/* We decrement the review count onHide() */
|
||||
if ( ! $this->hidden() )
|
||||
{
|
||||
$this->container()->_reviews = ( $this->container()->_reviews - $this->mapped('num_reviews') );
|
||||
}
|
||||
|
||||
$this->container()->setLastReview();
|
||||
}
|
||||
|
||||
$this->container()->setLastReview();
|
||||
}
|
||||
if ( $this->container()->_unapprovedReviews !== NULL )
|
||||
{
|
||||
$this->container()->_unapprovedReviews = ( $this->container()->_unapprovedReviews - $this->mapped('unapproved_reviews') );
|
||||
}
|
||||
$this->container()->save();
|
||||
} catch ( \BadMethodCallException $e ) {}
|
||||
if ( $this->container()->_unapprovedReviews !== NULL )
|
||||
{
|
||||
$this->container()->_unapprovedReviews = ( $this->container()->_unapprovedReviews - $this->mapped('unapproved_reviews') );
|
||||
}
|
||||
$this->container()->save();
|
||||
} catch ( \BadMethodCallException $e ) {}
|
||||
}
|
||||
}
|
||||
|
||||
/* Delete tags */
|
||||
@@ -2645,6 +2698,9 @@ abstract class _Item extends \IPS\Content
|
||||
/* Delete from Our Picks */
|
||||
\IPS\Db::i()->delete( 'core_social_promote', array( 'promote_class=? AND promote_class_id=?', (string) \get_class( $this ), (int) $this->$idColumn ) );
|
||||
|
||||
/* Delete from redirect links */
|
||||
\IPS\Db::i()->delete( 'core_item_redirect', array( 'redirect_class=? AND redirect_new_item_id=?', (string) \get_class( $this ), (int) $this->$idColumn ) );
|
||||
|
||||
/* Delete Polls */
|
||||
if ( $this instanceof \IPS\Content\Polls and $this->getPoll() )
|
||||
{
|
||||
@@ -2662,6 +2718,20 @@ abstract class _Item extends \IPS\Content
|
||||
\IPS\Member::load( $member )->recountNotifications();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes any additional comment Related data
|
||||
*
|
||||
* @param array $ids comment or review ids which are going to be deleted
|
||||
* @param string $class comment or review class name
|
||||
*/
|
||||
protected function deleteCommentOrReviewData( array $ids, string $class )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_deletion_log', array('dellog_content_class=? AND ' . \IPS\Db::i()->in( 'dellog_content_id', $ids ), $class) );
|
||||
\IPS\Db::i()->delete( 'core_social_promote', array('promote_class=? AND ' . \IPS\Db::i()->in( 'promote_class_id', $ids ), $class) );
|
||||
\IPS\Db::i()->delete( 'core_reputation_index', array('rep_class=? AND ' . \IPS\Db::i()->in( 'type_id', $ids ), $class) );
|
||||
\IPS\Db::i()->delete( 'core_solved_index', array('comment_class=? AND ' . \IPS\Db::i()->in( 'comment_id', $ids ), $class) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Change IP Address
|
||||
@@ -2707,7 +2777,7 @@ abstract class _Item extends \IPS\Content
|
||||
parent::changeAuthor( $newAuthor, $log );
|
||||
|
||||
/* Adjust post counts, but only if this is a visible post or the previous user was not a guest */
|
||||
if ( static::incrementPostCount( $this->containerWrapper() ) AND ( $oldAuthor->member_id OR $this->hidden() === 0 ) )
|
||||
if ( static::incrementPostCount( $this->containerWrapper() ) AND ( $oldAuthor->member_id OR $this->hidden() === 0 ) and ! $this->isAnonymous() )
|
||||
{
|
||||
if( $oldAuthor->member_id )
|
||||
{
|
||||
@@ -2885,8 +2955,8 @@ abstract class _Item extends \IPS\Content
|
||||
$col = static::$databaseTable . '.' . static::$databasePrefix . static::$databaseColumnMap['approved'];
|
||||
if ( $member->member_id and $includeHiddenItems !== \IPS\Content\Hideable::FILTER_PUBLIC_ONLY )
|
||||
{
|
||||
/* Only fetching a count, for a single container, no future publishing, and there is only one where clause (the container limitation) */
|
||||
if( $countOnly === TRUE AND $skipPermission instanceof \IPS\Node\Model AND !\in_array( 'IPS\Content\FuturePublishing', class_implements( \get_called_class() ) ) AND \count( $where ) === 1 )
|
||||
/* Only fetching a count, for a single container with a item cache count, no future publishing, and there is only one where clause (the container limitation) */
|
||||
if( $countOnly === TRUE AND $skipPermission instanceof \IPS\Node\Model AND $skipPermission->_items !== NULL AND !\in_array( 'IPS\Content\FuturePublishing', class_implements( \get_called_class() ) ) AND \count( $where ) === 1 )
|
||||
{
|
||||
$countShortcut = TRUE;
|
||||
$where[] = array( "({$col}=0 AND ( {$authorCol}={$member->member_id}{$extra} ) )" );
|
||||
@@ -2906,8 +2976,8 @@ abstract class _Item extends \IPS\Content
|
||||
$col = static::$databaseTable . '.' . static::$databasePrefix . static::$databaseColumnMap['hidden'];
|
||||
if ( $member->member_id and $includeHiddenItems !== \IPS\Content\Hideable::FILTER_PUBLIC_ONLY )
|
||||
{
|
||||
/* Only fetching a count, for a single container, no future publishing, and there is only one where clause (the container limitation) */
|
||||
if( $countOnly === TRUE AND $skipPermission instanceof \IPS\Node\Model AND !\in_array( 'IPS\Content\FuturePublishing', class_implements( \get_called_class() ) ) AND \count( $where ) === 1 )
|
||||
/* Only fetching a count, for a single container with a item cache count, no future publishing, and there is only one where clause (the container limitation) */
|
||||
if( $countOnly === TRUE AND $skipPermission instanceof \IPS\Node\Model AND $skipPermission->_items !== NULL AND !\in_array( 'IPS\Content\FuturePublishing', class_implements( \get_called_class() ) ) AND \count( $where ) === 1 )
|
||||
{
|
||||
$countShortcut = TRUE;
|
||||
$where[] = array( "({$col}=1 AND ( {$authorCol}={$member->member_id}{$extra} ) )" );
|
||||
@@ -3086,7 +3156,7 @@ abstract class _Item extends \IPS\Content
|
||||
/* Are we doing a pseudo-rand ordering? */
|
||||
if( $order == '_rand' )
|
||||
{
|
||||
$subSelectClause .= static::_getRandomizationSql( static::$databaseTable . '.' . static::$databasePrefix . static::$databaseColumnMap['date'] );
|
||||
$subSelectClause .= static::_getRandomizationSql( static::$databaseTable . '.' . static::$databasePrefix . static::$databaseColumnId, static::$databaseTable . '.' . static::$databasePrefix . static::$databaseColumnMap['title'] );
|
||||
}
|
||||
|
||||
$select = \IPS\Db::i()->select( $subSelectClause, static::$databaseTable, array_merge( $where, $containerWhere ), $order, $limit, ( $joinComments ? static::$databasePrefix . static::$databaseColumnId : NULL ), NULL, $queryFlags );
|
||||
@@ -3163,7 +3233,7 @@ abstract class _Item extends \IPS\Content
|
||||
/* Are we doing a pseudo-rand ordering? */
|
||||
if( $order == '_rand' )
|
||||
{
|
||||
$selectClause .= static::_getRandomizationSql( static::$databaseTable . '.' . static::$databasePrefix . static::$databaseColumnMap['date'] );
|
||||
$selectClause .= static::_getRandomizationSql( static::$databaseTable . '.' . static::$databasePrefix . static::$databaseColumnId, static::$databaseTable . '.' . static::$databasePrefix . static::$databaseColumnMap['title'] );
|
||||
}
|
||||
|
||||
if ( $joins !== NULL AND \count( $joins ) )
|
||||
@@ -3237,12 +3307,13 @@ abstract class _Item extends \IPS\Content
|
||||
/**
|
||||
* Get randomization SQL query clause
|
||||
*
|
||||
* @param string $column Column to use for randomization
|
||||
* @param string $id ID column to use
|
||||
* @param string $title Text column to use
|
||||
* @return string
|
||||
*/
|
||||
protected static function _getRandomizationSql( $column )
|
||||
protected static function _getRandomizationSql( $id, $title )
|
||||
{
|
||||
return ', CONCAT( SUBSTR(' . $column . ', ' . '10, 10 ), SUBSTR(' . $column . ', ' . '9, 10 ), SUBSTR( ' . $column . ', ' . rand( 1, 9 ) . ', 10 ), SUBSTR( ' . $column . ', ' . rand( 4, 7 ) . ', 9 ) ) as _rand';
|
||||
return ", SUBSTR( MD5( CONCAT( {$id}, {$title} ) ), " . rand( 2, 25 ) . " ) as _rand";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3979,7 +4050,15 @@ abstract class _Item extends \IPS\Content
|
||||
elseif ( $this->mapped('num_comments') >= 500 )
|
||||
{
|
||||
/* Its more efficient to just get the primary ids first without joins and then we can fetch all the data on the second query once the offset gets larger */
|
||||
$ids = iterator_to_array( $class::db()->select( $class::$databasePrefix . $class::$databaseColumnId, $class::$databaseTable, $where, $order, array( $offset, $limit ) )->setKeyField( $class::$databasePrefix . $class::$databaseColumnId ) );
|
||||
if( method_exists( $this, 'forceIndexForPaginatedIds' ) and $this->forceIndexForPaginatedIds() and $offset < 20000 )
|
||||
{
|
||||
/* Only use the index if we're not at a massive offset */
|
||||
$ids = iterator_to_array( $class::db()->select( $class::$databasePrefix . $class::$databaseColumnId, $class::$databaseTable, $where, $order, array($offset, $limit) )->forceIndex( $this->forceIndexForPaginatedIds() )->setKeyField( $class::$databasePrefix . $class::$databaseColumnId ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$ids = iterator_to_array( $class::db()->select( $class::$databasePrefix . $class::$databaseColumnId, $class::$databaseTable, $where, $order, array($offset, $limit) )->setKeyField( $class::$databasePrefix . $class::$databaseColumnId ) );
|
||||
}
|
||||
|
||||
$where = array( array( $class::db()->in( $class::$databaseTable . '.' . $class::$databasePrefix . $class::$databaseColumnId, array_keys( $ids ) ) ) );
|
||||
$offset = 0;
|
||||
@@ -4263,13 +4342,13 @@ abstract class _Item extends \IPS\Content
|
||||
}
|
||||
|
||||
/* Solved count */
|
||||
$commentClass = static::$commentClass;
|
||||
if ( \IPS\IPS::classUsesTrait( $this, 'IPS\Content\Solvable' ) )
|
||||
{
|
||||
if ( $this->containerAllowsMemberSolvable() OR $this->containerAllowsSolvable() )
|
||||
{
|
||||
$memberIds = array();
|
||||
$solvedCounts = array();
|
||||
$commentClass = static::$commentClass;
|
||||
$authorField = $commentClass::$databaseColumnMap['author'];
|
||||
|
||||
foreach( $results as $id => $data )
|
||||
@@ -4295,6 +4374,18 @@ abstract class _Item extends \IPS\Content
|
||||
}
|
||||
}
|
||||
|
||||
/* Recognized content */
|
||||
if ( \IPS\IPS::classUsesTrait( $commentClass, 'IPS\Content\Recognizable' ) )
|
||||
{
|
||||
foreach( \IPS\Db::i()->select( '*', 'core_member_recognize', [ [ 'r_content_class=?', $commentClass ], [ \IPS\Db::i()->in('r_content_id', array_keys( $results ) ) ] ] ) as $row )
|
||||
{
|
||||
if ( isset( $results[ $row['r_content_id'] ] ) )
|
||||
{
|
||||
$results[ $row['r_content_id'] ]->recognized = \IPS\core\Achievements\Recognize::constructFromData( $row );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Return */
|
||||
return ( $limit === 1 ) ? NULL : $results;
|
||||
}
|
||||
@@ -4357,6 +4448,21 @@ abstract class _Item extends \IPS\Content
|
||||
*/
|
||||
public static $checkPostsPerDay = TRUE;
|
||||
|
||||
/**
|
||||
* Return the comment form object
|
||||
*
|
||||
* @return \IPS\Helpers\Form
|
||||
*/
|
||||
protected function _commentForm()
|
||||
{
|
||||
$idColumn = static::$databaseColumnId;
|
||||
$form = new \IPS\Helpers\Form( 'commentform' . '_' . $this->$idColumn, static::$formLangPrefix . 'submit_comment' );
|
||||
$form->class = 'ipsForm_vertical';
|
||||
$form->hiddenValues['_contentReply'] = TRUE;
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build comment form
|
||||
*
|
||||
@@ -4379,9 +4485,7 @@ abstract class _Item extends \IPS\Content
|
||||
$commentIdColumn = $commentClass::$databaseColumnId;
|
||||
$commentDateColumn = $commentClass::$databaseColumnMap['date'];
|
||||
|
||||
$form = new \IPS\Helpers\Form( 'commentform' . '_' . $this->$idColumn, static::$formLangPrefix . 'submit_comment' );
|
||||
$form->class = 'ipsForm_vertical';
|
||||
$form->hiddenValues['_contentReply'] = TRUE;
|
||||
$form = $this->_commentForm();
|
||||
|
||||
$elements = $this->commentFormElements();
|
||||
|
||||
@@ -4457,15 +4561,21 @@ abstract class _Item extends \IPS\Content
|
||||
/* Or post? */
|
||||
$comment = $this->processCommentForm( $values );
|
||||
unset( $this->commentPageCount );
|
||||
|
||||
$newPageCount = $this->commentPageCount();
|
||||
|
||||
if ( $comment->hidden() === -3 )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=register', 'front', 'register' ) );
|
||||
}
|
||||
elseif( $comment->hidden() AND !\IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
\IPS\Output::i()->json( array( 'type' => 'add', 'id' => $comment->$commentIdColumn, 'page' => $newPageCount, 'total' => $this->mapped('num_comments'), 'content' => '', 'message' => \IPS\Member::loggedIn()->language()->addToStack( 'mod_queue_message' ) ) );
|
||||
}
|
||||
elseif ( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
$this->markRead( NULL, NULL, NULL, TRUE );
|
||||
|
||||
$newPageCount = $this->commentPageCount();
|
||||
if ( $currentPageCount != $newPageCount )
|
||||
{
|
||||
\IPS\Output::i()->json( array( 'type' => 'redirect', 'page' => $newPageCount, 'total' => $this->mapped('num_comments'), 'content' => \IPS\Output::i()->replaceEmojiWithImages( $comment->html() ), 'url' => (string) $comment->url('find') ) );
|
||||
@@ -4618,6 +4728,12 @@ abstract class _Item extends \IPS\Content
|
||||
$return['hide'] = new \IPS\Helpers\Form\YesNo( 'hide', FALSE , FALSE, array( 'label' => 'hide' ) );
|
||||
}
|
||||
|
||||
/* Post Anonymously */
|
||||
if ( $container and $container->canPostAnonymously( $container::ANON_COMMENTS ) )
|
||||
{
|
||||
$return['post_anonymously'] = new \IPS\Helpers\Form\YesNo( 'post_anonymously', FALSE, FALSE, array( 'label' => \IPS\Member::loggedIn()->language()->addToStack( 'post_anonymously_suffix' ) ), NULL, NULL, NULL, 'post_anonymously' );
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
@@ -4649,7 +4765,13 @@ abstract class _Item extends \IPS\Content
|
||||
$parameters = array_merge( array( 'reply-' . static::$application . '/' . static::$module . '-' . $this->$idColumn ), $comment->attachmentIds() );
|
||||
\IPS\File::claimAttachments( ...$parameters );
|
||||
|
||||
/* Auto-follow */
|
||||
/* Post anonymously */
|
||||
if( isset( $values[ 'post_anonymously' ] ) )
|
||||
{
|
||||
$comment->setAnonymous( $values[ 'post_anonymously' ] );
|
||||
}
|
||||
|
||||
/* Auto-follow - If posted anonymously we should set follow to anonymous as well */
|
||||
if( isset( $values[ static::$formLangPrefix . 'auto_follow' ] ) )
|
||||
{
|
||||
if ( $values[ static::$formLangPrefix . 'auto_follow' ] and !\IPS\Member::loggedIn()->following( static::$application, $followArea, $this->$idColumn ) )
|
||||
@@ -5133,12 +5255,6 @@ abstract class _Item extends \IPS\Content
|
||||
*/
|
||||
protected $_averageReviewRating = NULL;
|
||||
|
||||
/**
|
||||
* @brief Have we output the average review rating?
|
||||
* @note Structured data only allows this to be output once, so we need to track if we've output it
|
||||
*/
|
||||
public $printedAverageReviewRating = FALSE;
|
||||
|
||||
/**
|
||||
* Get average review rating
|
||||
*
|
||||
@@ -5199,7 +5315,15 @@ abstract class _Item extends \IPS\Content
|
||||
{
|
||||
$this->_lastCommenter = \IPS\Member::load( $this->mapped('last_comment_by') );
|
||||
|
||||
if ( ! $this->_lastCommenter->member_id and isset( static::$databaseColumnMap['last_comment_name'] ) )
|
||||
if ( ! $this->_lastCommenter->member_id and isset( static::$databaseColumnMap['is_anon'] ) )
|
||||
{
|
||||
$_lastComment = $this->comments( 1, 0, 'date', 'desc' );
|
||||
if ( $_lastComment !== NULL AND $_lastComment->isAnonymous() )
|
||||
{
|
||||
$this->_lastCommenter->name = \IPS\Member::loggedIn()->language()->addToStack( "post_anonymously_placename" );
|
||||
}
|
||||
}
|
||||
else if ( ! $this->_lastCommenter->member_id and isset( static::$databaseColumnMap['last_comment_name'] ) )
|
||||
{
|
||||
if ( $this->mapped('last_comment_name') )
|
||||
{
|
||||
@@ -5217,7 +5341,15 @@ abstract class _Item extends \IPS\Content
|
||||
|
||||
if( $_lastComment !== NULL )
|
||||
{
|
||||
$this->_lastCommenter = $this->comments( 1, 0, 'date', 'desc' )->author();
|
||||
if ( $_lastComment->isAnonymous() )
|
||||
{
|
||||
$this->_lastCommenter = new \IPS\Member;
|
||||
$this->_lastCommenter->name = \IPS\Member::loggedIn()->language()->addToStack( "post_anonymously_placename" );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->_lastCommenter = $this->comments( 1, 0, 'date', 'desc' )->author();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -5416,7 +5548,7 @@ abstract class _Item extends \IPS\Content
|
||||
return;
|
||||
}
|
||||
|
||||
$columns = array( 'last_comment', 'last_comment_by', 'last_comment_name' );
|
||||
$columns = array( 'last_comment', 'last_comment_by', 'last_comment_name', 'last_comment_anon' );
|
||||
$resync = FALSE;
|
||||
foreach ( $columns as $k )
|
||||
{
|
||||
@@ -5471,6 +5603,11 @@ abstract class _Item extends \IPS\Content
|
||||
$lastCommentNameField = static::$databaseColumnMap['last_comment_name'];
|
||||
$this->$lastCommentNameField = ( !$comment->author()->member_id and isset( $comment::$databaseColumnMap['author_name'] ) ) ? $comment->mapped('author_name') : $comment->author()->name;
|
||||
}
|
||||
if ( isset( static::$databaseColumnMap['last_comment_anon'] ) )
|
||||
{
|
||||
$lastCommentAnonField = static::$databaseColumnMap['last_comment_anon'];
|
||||
$this->$lastCommentAnonField = $comment->isAnonymous();
|
||||
}
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
{
|
||||
@@ -5846,15 +5983,45 @@ abstract class _Item extends \IPS\Content
|
||||
/**
|
||||
* Generate meta data between comments. It is assumed they all belong to the same topic
|
||||
*
|
||||
* @param array $comments Array of $comment objects
|
||||
* @param array $comments Array of $comment objects
|
||||
* @param bool $anonymous Anonymize the moderator actions
|
||||
* @return array
|
||||
*/
|
||||
public function generateCommentMetaData( array $comments ) : array
|
||||
public function generateCommentMetaData( array $comments, $anonymous = FALSE ) : array
|
||||
{
|
||||
if ( ! $this->showCommentMeta('time') and ! $this->showCommentMeta('moderation') )
|
||||
{
|
||||
return $comments;
|
||||
}
|
||||
|
||||
$showAnonymous = FALSE;
|
||||
|
||||
if( $anonymous )
|
||||
{
|
||||
$containerClass = static::$containerNodeClass;
|
||||
|
||||
if( isset( $containerClass::$modPerm ) AND $containerClass::$modPerm )
|
||||
{
|
||||
$showAnonymous = !(
|
||||
\IPS\Member::loggedIn()->modPermission( $containerClass::$modPerm ) === TRUE
|
||||
or
|
||||
\IPS\Member::loggedIn()->modPermission( $containerClass::$modPerm ) === -1
|
||||
or
|
||||
(
|
||||
\is_array( \IPS\Member::loggedIn()->modPermission( $containerClass::$modPerm ) )
|
||||
and
|
||||
\in_array( $this->container()->_id, \IPS\Member::loggedIn()->modPermission( $containerClass::$modPerm ) )
|
||||
)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$showAnonymous = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$anonymous ? (bool) \IPS\Member::loggedIn()->modPermissions() : FALSE;
|
||||
|
||||
$lastDate = NULL;
|
||||
|
||||
@@ -5892,9 +6059,9 @@ abstract class _Item extends \IPS\Content
|
||||
|
||||
if ( ( $modActionDate > $commentDate and $modActionDate < $nextCommentDate ) or ( $modActionDate > $commentDate and !$next ) )
|
||||
{
|
||||
|
||||
$commentDate = $modActionDate;
|
||||
$blurb = NULL;
|
||||
$langKey = 'comment_meta_moderation_' . $data['lang_key'];
|
||||
$langKey = 'comment_meta_moderation_' . ( $showAnonymous ? 'anon_' : '' ) . $data['lang_key'];
|
||||
|
||||
/* Edits always get their own meta action bubble, so handle those individually */
|
||||
if ( \in_array( $data['lang_key'], array( 'modlog__item_edit', 'modlog__comment_edit_title' ) ) )
|
||||
@@ -5964,7 +6131,7 @@ abstract class _Item extends \IPS\Content
|
||||
/* If this is just one action, generate a full bubble */
|
||||
$comment->_data['metaData']['comment']['moderation'][$actions[0]['action']] = array(
|
||||
'row' => $actions[0]['row'],
|
||||
'blurb' => \IPS\Member::loggedIn()->language()->addToStack( $actions[0]['lang_key'], FALSE, array('htmlsprintf' => array($this->definiteArticle(), \IPS\Member::load( $data['member_id'] )->link())) ),
|
||||
'blurb' => \IPS\Member::loggedIn()->language()->addToStack( $actions[0]['lang_key'], FALSE, array('htmlsprintf' => array($this->definiteArticle(), \IPS\Member::load( $actions[0]['row']['member_id'] )->link())) ),
|
||||
'action' => $actions[0]['lang_key']
|
||||
);
|
||||
}
|
||||
@@ -5979,7 +6146,7 @@ abstract class _Item extends \IPS\Content
|
||||
|
||||
$comment->_data['metaData']['comment']['moderation'][$groupIdx] = array(
|
||||
'row' => $actions[0]['row'], // Use the first action in this group as the 'row', to provide the time etc. for all items in this bubble
|
||||
'blurb' => \IPS\Member::loggedIn()->language()->addToStack( 'comment_meta_moderation_modlog__action_group', FALSE, array('htmlsprintf' => array($this->definiteArticle(), \IPS\Member::load( $data['member_id'] )->link(), \IPS\Member::loggedIn()->language()->formatList( $actionPhrases ) ) ) ),
|
||||
'blurb' => \IPS\Member::loggedIn()->language()->addToStack( 'comment_meta_moderation_' . ( $showAnonymous ? 'anon_' : '' ) . 'modlog__action_group', FALSE, array('htmlsprintf' => array($this->definiteArticle(), \IPS\Member::load( $lastActionMember )->link(), \IPS\Member::loggedIn()->language()->formatList( $actionPhrases ) ) ) ),
|
||||
'action' => $actions[0]['lang_key']
|
||||
);
|
||||
}
|
||||
@@ -6034,6 +6201,11 @@ abstract class _Item extends \IPS\Content
|
||||
*/
|
||||
public function showCommentMeta( $key )
|
||||
{
|
||||
if( $key == 'moderation' AND \IPS\Member::loggedIn()->group['gbw_hide_inline_modevents'] )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$metaKey = static::$showMetaSettingKey;
|
||||
|
||||
if ( isset( \IPS\Settings::i()->$metaKey ) and \IPS\Settings::i()->$metaKey )
|
||||
@@ -6200,7 +6372,7 @@ abstract class _Item extends \IPS\Content
|
||||
// OK
|
||||
}
|
||||
/* If it's pending approval, and we're the author it's fine */
|
||||
elseif ( $this->hidden() === 1 and $this->author()->member_id == $member->member_id )
|
||||
elseif ( $this->hidden() === 1 and $this->author()->member_id and $this->author()->member_id == $member->member_id )
|
||||
{
|
||||
// OK
|
||||
}
|
||||
@@ -6722,8 +6894,7 @@ abstract class _Item extends \IPS\Content
|
||||
*/
|
||||
public function onHide( $member )
|
||||
{
|
||||
$container = NULL;
|
||||
if ( method_exists( $this, 'container' ) )
|
||||
if ( method_exists( $this, 'container' ) AND !$this->skipContainerRebuild )
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -6759,13 +6930,11 @@ abstract class _Item extends \IPS\Content
|
||||
*/
|
||||
public function onUnhide( $approving, $member )
|
||||
{
|
||||
$container = NULL;
|
||||
|
||||
/* If approving, we may need to increase the post count */
|
||||
if ( $approving AND isset( static::$commentClass ) )
|
||||
{
|
||||
$commentClass = static::$commentClass;
|
||||
if ( ( static::$firstCommentRequired and $commentClass::incrementPostCount( $this->containerWrapper() ) ) or static::incrementPostCount( $this->containerWrapper() ) )
|
||||
if ( !$this->isAnonymous() and ( static::$firstCommentRequired and $commentClass::incrementPostCount( $this->containerWrapper() ) ) or static::incrementPostCount( $this->containerWrapper() ) )
|
||||
{
|
||||
$this->author()->member_posts++;
|
||||
$this->author()->save();
|
||||
@@ -6773,7 +6942,7 @@ abstract class _Item extends \IPS\Content
|
||||
}
|
||||
|
||||
/* Update container */
|
||||
if ( method_exists( $this, 'container' ) )
|
||||
if ( method_exists( $this, 'container' ) AND !$this->skipContainerRebuild )
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -6800,7 +6969,6 @@ abstract class _Item extends \IPS\Content
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Warning Reference Key
|
||||
*
|
||||
@@ -6865,6 +7033,20 @@ abstract class _Item extends \IPS\Content
|
||||
return $this->sharelinks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Web Share Data
|
||||
*
|
||||
* @return array|NULL
|
||||
*/
|
||||
public function webShareData(): ?array
|
||||
{
|
||||
return array(
|
||||
'title' => \IPS\Text\Parser::truncate( $this->mapped('title'), TRUE ),
|
||||
'text' => \IPS\Text\Parser::truncate( $this->mapped('title'), TRUE ),
|
||||
'url' => (string) $this->url()
|
||||
);
|
||||
}
|
||||
|
||||
/* !ReadMarkers */
|
||||
|
||||
/**
|
||||
@@ -6974,7 +7156,7 @@ abstract class _Item extends \IPS\Content
|
||||
$latestThing = 0;
|
||||
foreach ( array( 'updated', 'last_comment', 'last_review' ) as $k )
|
||||
{
|
||||
if ( isset( static::$databaseColumnMap[ $k ] ) and ( $this->mapped( $k ) < time() AND $this->mapped( $k ) > $latestThing ) )
|
||||
if ( isset( static::$databaseColumnMap[ $k ] ) and ( $this->mapped( $k ) <= time() AND $this->mapped( $k ) > $latestThing ) )
|
||||
{
|
||||
$latestThing = $this->mapped( $k );
|
||||
}
|
||||
@@ -7001,7 +7183,7 @@ abstract class _Item extends \IPS\Content
|
||||
* @return int|NULL 0 = read. -1 = never read. 1 = updated since last read. NULL = unsupported
|
||||
* @note When a node is marked read, we stop noting which individual content items have been read. Therefore, -1 vs 1 is not always accurate but rather goes on if the item was created
|
||||
*/
|
||||
public static function unreadFromData( \IPS\Member $member = NULL, $updateDate, $createDate, $itemId, $containerId, $limitToApp = TRUE )
|
||||
public static function unreadFromData( ?\IPS\Member $member, $updateDate, $createDate, $itemId, $containerId, $limitToApp = TRUE )
|
||||
{
|
||||
/* Get the member */
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
@@ -7034,7 +7216,7 @@ abstract class _Item extends \IPS\Content
|
||||
}
|
||||
else
|
||||
{
|
||||
$resetTime = ( $resetTimes > $member->marked_site_read ) ? $resetTimes : $member->marked_site_read;
|
||||
$resetTime = ( !\is_array( $resetTimes ) AND $resetTimes > $member->marked_site_read ) ? $resetTimes : $member->marked_site_read;
|
||||
}
|
||||
|
||||
/* If the reset time is after when this item was updated, it's read */
|
||||
@@ -7251,8 +7433,14 @@ abstract class _Item extends \IPS\Content
|
||||
{
|
||||
$subWhere = array();
|
||||
$checked = array();
|
||||
foreach ( array( 'updated', 'last_comment', 'last_review' ) as $k )
|
||||
foreach ( array( 'last_comment', 'last_review', 'updated' ) as $k )
|
||||
{
|
||||
/* If we already hit last_comment and/or last_review, skip updated since we don't mark as unread when stuff is updated */
|
||||
if( \count( $checked ) AND $k == 'updated' )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if ( isset( static::$databaseColumnMap[ $k ] ) )
|
||||
{
|
||||
if ( \is_array( static::$databaseColumnMap[ $k ] ) )
|
||||
@@ -8091,6 +8279,9 @@ abstract class _Item extends \IPS\Content
|
||||
|
||||
/* Send notifications if necessary */
|
||||
$this->sendNotifications();
|
||||
|
||||
/* Give out points */
|
||||
$this->author()->achievementAction( 'core', 'NewContentItem', $this );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -8101,7 +8292,6 @@ abstract class _Item extends \IPS\Content
|
||||
*/
|
||||
public function onPublish( $member )
|
||||
{
|
||||
$container = NULL;
|
||||
if ( method_exists( $this, 'container' ) )
|
||||
{
|
||||
try
|
||||
@@ -8113,20 +8303,23 @@ abstract class _Item extends \IPS\Content
|
||||
$container->_futureItems = ( $container->_futureItems > 0 ) ? $container->_futureItems - 1 : 0;
|
||||
}
|
||||
|
||||
$container->_items = $container->_items + 1;
|
||||
|
||||
if ( isset( static::$commentClass ) )
|
||||
if( !$this->skipContainerRebuild )
|
||||
{
|
||||
$container->_comments = $container->_comments + $this->mapped('num_comments');
|
||||
$container->setLastComment();
|
||||
}
|
||||
if ( isset( static::$reviewClass ) )
|
||||
{
|
||||
$container->_reviews = $container->_reviews + $this->mapped('num_reviews');
|
||||
$container->setLastReview();
|
||||
}
|
||||
$container->_items = $container->_items + 1;
|
||||
|
||||
$container->save();
|
||||
if ( isset( static::$commentClass ) )
|
||||
{
|
||||
$container->_comments = $container->_comments + $this->mapped('num_comments');
|
||||
$container->setLastComment();
|
||||
}
|
||||
if ( isset( static::$reviewClass ) )
|
||||
{
|
||||
$container->_reviews = $container->_reviews + $this->mapped('num_reviews');
|
||||
$container->setLastReview();
|
||||
}
|
||||
|
||||
$container->save();
|
||||
}
|
||||
}
|
||||
catch ( \BadMethodCallException $e ) { }
|
||||
}
|
||||
@@ -8318,11 +8511,12 @@ abstract class _Item extends \IPS\Content
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
\IPS\Db::i()->insert( 'core_ratings', array(
|
||||
'class' => \get_called_class(),
|
||||
'item_id' => $this->$idColumn,
|
||||
'member' => (int) \IPS\Member::loggedIn()->member_id,
|
||||
'rating' => $values['rating'],
|
||||
'ip' => \IPS\Request::i()->ipAddress()
|
||||
'class' => \get_called_class(),
|
||||
'item_id' => $this->$idColumn,
|
||||
'member' => (int) \IPS\Member::loggedIn()->member_id,
|
||||
'rating' => $values['rating'],
|
||||
'ip' => \IPS\Request::i()->ipAddress(),
|
||||
'rating_date' => time()
|
||||
), TRUE );
|
||||
|
||||
if ( isset( static::$databaseColumnMap['rating_average'] ) )
|
||||
@@ -8560,7 +8754,9 @@ abstract class _Item extends \IPS\Content
|
||||
'meta_class' => \get_class( $this ),
|
||||
'meta_item_id' => $this->$idColumn,
|
||||
'meta_type' => $type,
|
||||
'meta_data' => $data
|
||||
'meta_data' => $data,
|
||||
'meta_item_author' => $this->author()->member_id,
|
||||
'meta_added' => time()
|
||||
) );
|
||||
|
||||
$column = static::$databaseColumnMap['meta_data'];
|
||||
@@ -8644,6 +8840,49 @@ abstract class _Item extends \IPS\Content
|
||||
\IPS\Db::i()->delete( 'core_content_meta', array( "meta_class=? AND meta_item_id=?", \get_class( $this ), $this->$idColumn ) );
|
||||
}
|
||||
|
||||
/* ! Redirect links */
|
||||
|
||||
/**
|
||||
* Store a redirect
|
||||
*
|
||||
* Saves a redirect so when this class:item_id is attempted to be loaded in the future, it 301 redirects to the new item
|
||||
*
|
||||
* @param \IPS\Content\Item $item The item to redirect to
|
||||
*/
|
||||
public function setRedirectTo( \IPS\Content\Item $item )
|
||||
{
|
||||
$idColumn = static::$databaseColumnId;
|
||||
\IPS\Db::i()->insert( 'core_item_redirect', array(
|
||||
'redirect_class' => \get_class( $item ),
|
||||
'redirect_item_id' => $this->$idColumn,
|
||||
'redirect_new_item_id' => $item->$idColumn
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the redirect to data
|
||||
*
|
||||
* Fetches the \IPS\Content\Item we want to redirect to
|
||||
*
|
||||
* @param object $class Class to look up
|
||||
* @param int $id The ID to look up
|
||||
* @param bool $checkPerms Check permissions when loading
|
||||
* @throws \OutOfRangeException
|
||||
*/
|
||||
public static function getRedirectFrom( $id, $checkPerms=TRUE )
|
||||
{
|
||||
$idColumn = static::$databaseColumnId;
|
||||
try
|
||||
{
|
||||
$method = ( $checkPerms ) ? 'loadAndCheckPerms' : 'load';
|
||||
return static::$method( \IPS\Db::i()->select( 'redirect_new_item_id', 'core_item_redirect', array( 'redirect_class=? and redirect_item_id=?', \get_called_class(), $id ) )->first() );
|
||||
}
|
||||
catch( \UnderflowException $e )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Can perform an action on a message
|
||||
*
|
||||
@@ -8747,6 +8986,12 @@ abstract class _Item extends \IPS\Content
|
||||
public function featureComment( \IPS\Content\Comment $comment, $note = NULL, \IPS\Member $member = NULL )
|
||||
{
|
||||
\IPS\Application::load('core')->extensions( 'core', 'MetaData' )['FeaturedComments']->featureComment( $this, $comment, $note, $member );
|
||||
|
||||
/* Give points */
|
||||
$comment->author()->achievementAction( 'core', 'ContentPromotion', [
|
||||
'content' => $comment,
|
||||
'promotype' => 'recommend' //Yeah it says feature, but it's really recommend
|
||||
] );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -8815,7 +9060,7 @@ abstract class _Item extends \IPS\Content
|
||||
* @param \IPS\Member|NULL $member
|
||||
* @return void
|
||||
*/
|
||||
public function toggleItemModeration( $action, ?\IPS\Member $member = NULL ): void
|
||||
public function toggleItemModeration( $action, ?\IPS\Member $member = NULL )
|
||||
{
|
||||
if ( !\in_array( $action, array( 'enable', 'disable' ) ) )
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user