Version 4.7.6
This commit is contained in:
1 parent
8ba7d43898
commit
7b7404e741
1085 files changed
+30590
-7837
No files matched your search
@@ -343,11 +343,14 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
{
|
||||
/*
|
||||
* We prefer fetching post, joining topic, etc. but that is not efficient and causes a temp table and filesort against posts table so we'll lean on the cached last_post value for the topic
|
||||
* We also need to fetch from the write server in the event that something has just been deleted and the comment hasn't been passed
|
||||
* We also need to fetch from the write server in the event that something has just been deleted and the comment hasn't been passed.
|
||||
* We also cannot look for future entries since this code is used in older upgrades, but we can look for the date instead.
|
||||
*/
|
||||
$select = \IPS\Db::i()->select( '*', 'forums_topics', array( "forums_topics.forum_id=? AND forums_topics.approved=1 AND forums_topics.state != ?", $this->id, 'link' ), 'forums_topics.last_post DESC', 1, NULL, NULL, \IPS\Db::SELECT_FROM_WRITE_SERVER )->first();
|
||||
|
||||
$select = \IPS\Db::i()->select( '*', 'forums_topics', array( "forums_topics.forum_id=? AND forums_topics.approved=1 AND forums_topics.state != ? AND forums_topics.last_post<=?", $this->id, 'link', time() ), 'forums_topics.last_post DESC', 1, NULL, NULL, \IPS\Db::SELECT_FROM_WRITE_SERVER )->first();
|
||||
|
||||
$topic = \IPS\forums\Topic::constructFromData( $select );
|
||||
|
||||
|
||||
if ( $topic->last_poster_id and ! $topic->last_poster_name )
|
||||
{
|
||||
$member = \IPS\Member::load( $topic->last_poster_id );
|
||||
@@ -436,7 +439,7 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
{
|
||||
try
|
||||
{
|
||||
$lastPost = \IPS\forums\Topic\Post::constructFromData( \IPS\Db::i()->select( '*', 'forums_posts', array( 'topic_id=? AND queued=0', \IPS\Db::i()->select( 'tid', 'forums_topics', array( 'forum_id=? AND approved=1 AND starter_id=?', $this->_id, \IPS\Member::loggedIn()->member_id ), 'last_post DESC', 1 )->first() ), 'post_date DESC', 1 )->first() );
|
||||
$lastPost = \IPS\forums\Topic\Post::constructFromData( \IPS\Db::i()->select( '*', 'forums_posts', array( 'topic_id=? AND queued=0', \IPS\Db::i()->select( 'tid', 'forums_topics', array( 'forum_id=? AND approved=1 AND starter_id=? AND is_future_entry=0', $this->_id, \IPS\Member::loggedIn()->member_id ), 'last_post DESC', 1 )->first() ), 'post_date DESC', 1 )->first() );
|
||||
$result = array(
|
||||
'author' => $lastPost->author(),
|
||||
'topic_url' => $lastPost->item()->url(),
|
||||
@@ -663,11 +666,6 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
}
|
||||
|
||||
if ( !$this->viglink )
|
||||
{
|
||||
\IPS\Settings::i()->viglink_enabled = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -883,7 +881,6 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
'normal' => array( // make sure when adding here that you also add to qa below
|
||||
'forum_password_on',
|
||||
'forum_ipseo_priority',
|
||||
'forum_viglink',
|
||||
'forum_min_posts_view',
|
||||
'forum_can_view_others',
|
||||
'forum_permission_showtopic',
|
||||
@@ -903,7 +900,6 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
'qa' => array(
|
||||
'forum_password_on',
|
||||
'forum_ipseo_priority',
|
||||
'forum_viglink',
|
||||
'forum_min_posts_view',
|
||||
'forum_can_view_others_qa',
|
||||
'forum_permission_showtopic_qa',
|
||||
@@ -1010,11 +1006,6 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
)
|
||||
), NULL, NULL, NULL, 'forum_ipseo_priority' ) );
|
||||
|
||||
if ( \IPS\Settings::i()->viglink_enabled )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'forum_viglink', $this->id ? $this->viglink : TRUE, FALSE, array(), NULL, NULL, NULL, 'forum_viglink' ) );
|
||||
}
|
||||
|
||||
$form->addHeader( 'permissions' );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'forum_min_posts_view', $this->id ? $this->min_posts_view : 0, FALSE, array( 'unlimited' => 0, 'unlimitedLang' => 'no_restriction' ), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack('approved_posts_comments'), 'forum_min_posts_view' ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'forum_can_view_others', $this->id ? $this->can_view_others : TRUE, FALSE, array(), NULL, NULL, NULL, 'forum_can_view_others' ) );
|
||||
@@ -1074,7 +1065,7 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'forum_disable_sharelinks', $this->id ? !$this->disable_sharelinks : TRUE, FALSE, array(), NULL, NULL, NULL, 'forum_disable_sharelinks' ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'bw_enable_answers_moderator', $this->id ? $this->forums_bitoptions['bw_enable_answers_moderator'] : FALSE, FALSE, array( 'togglesOn' => array( 'bw_enable_answers__member' ) ), NULL, NULL, NULL, 'forum_best_answer' ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'bw_enable_answers__member', $this->id ? $this->forums_bitoptions['bw_enable_answers_member'] : FALSE, FALSE, array(), NULL, NULL, NULL, 'bw_enable_answers__member' ) );
|
||||
|
||||
|
||||
$form->addTab( 'posting_settings' );
|
||||
$form->addHeader('posts');
|
||||
|
||||
@@ -1213,8 +1204,18 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
{
|
||||
if( isset( $values[ $k ] ) )
|
||||
{
|
||||
$values['forums_bitoptions'][ $k ] = ( $k == 'bw_enable_answers_member' or $k == 'bw_enable_answers_moderator' or $k == 'bw_fluid_view' ) ? $values[ $k ] : !$values[ $k ];
|
||||
unset( $values[ $k ] );
|
||||
/* If were disabling bw_enable_answers_moderator for discussion forums, we need to make sure bw_enable_answers_member is also disabled */
|
||||
if ( $k == 'bw_enable_answers_moderator' AND !$values[ $k ] )
|
||||
{
|
||||
$values['forums_bitoptions']['bw_enable_answers_moderator'] = FALSE;
|
||||
$values['forums_bitoptions']['bw_enable_answers_member'] = FALSE;
|
||||
unset( $values['bw_enable_answers_moderator'], $values['bw_enable_answers_member'] );
|
||||
}
|
||||
else
|
||||
{
|
||||
$values['forums_bitoptions'][ $k ] = ( $k == 'bw_enable_answers_member' or $k == 'bw_enable_answers_moderator' or $k == 'bw_fluid_view' ) ? $values[ $k ] : !$values[ $k ];
|
||||
unset( $values[ $k ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1281,6 +1282,8 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
$values['preview_posts'] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
$values['min_posts_post'] = (int) $values['min_posts_post'];
|
||||
|
||||
/* Feature color */
|
||||
if ( isset( $values['use_feature_color'] ) )
|
||||
@@ -1889,6 +1892,43 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the time the first topic was marked as solved in this forum
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getFirstSolvedTime(): int
|
||||
{
|
||||
if ( ! $this->solved_stats_from )
|
||||
{
|
||||
try
|
||||
{
|
||||
$post = \IPS\Db::i()->select( '*', 'forums_posts', [
|
||||
'pid IN (?)', \IPS\Db::i()->select( 'topic_answered_pid', 'forums_topics', ['forum_id=?', $this->_id] )
|
||||
], 'post_date ASC', 1 )->first();
|
||||
|
||||
try
|
||||
{
|
||||
$this->solved_stats_from = \IPS\Db::i()->select( 'solved_date', 'core_solved_index', [ 'app=? and comment_id=?', 'forums', $post['pid'] ] )->first();
|
||||
}
|
||||
catch( \Exception $e )
|
||||
{
|
||||
/* If that goes wrong... */
|
||||
$this->solved_stats_from = $post['post_date'];
|
||||
}
|
||||
}
|
||||
catch( \UnderflowException $e )
|
||||
{
|
||||
/* If all that goes wrong, we have nothing marked so just store now to prevent it rebuilding over and over */
|
||||
$this->solved_stats_from = time();
|
||||
}
|
||||
|
||||
$this->save();
|
||||
}
|
||||
|
||||
return $this->solved_stats_from;
|
||||
}
|
||||
|
||||
/* !Clubs */
|
||||
|
||||
@@ -2016,7 +2056,7 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
$method = ( isset( \IPS\Request::i()->cookie['forum_list_view'] ) ) ? \IPS\Request::i()->cookie['forum_list_view'] : NULL;
|
||||
$chooseable = \IPS\Settings::i()->forums_view_list_choose;
|
||||
|
||||
if ( ! $chooseable )
|
||||
if ( ! $chooseable or !\IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
return \IPS\Settings::i()->forums_view_list_method;
|
||||
}
|
||||
@@ -2049,7 +2089,7 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
$method = ( isset( \IPS\Request::i()->cookie['forum_view'] ) ) ? \IPS\Request::i()->cookie['forum_view'] : NULL;
|
||||
$chooseable = \IPS\Settings::i()->forums_default_view_choose ? json_decode( \IPS\Settings::i()->forums_default_view_choose , TRUE ) : FALSE;
|
||||
|
||||
if ( ! $chooseable )
|
||||
if ( ! $chooseable or !\IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
return \IPS\Settings::i()->forums_default_view;
|
||||
}
|
||||
@@ -2172,4 +2212,33 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
|
||||
return $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Content was held for approval by container
|
||||
* Allow node classes that can determine if content should be held for approval in individual nodes
|
||||
*
|
||||
* @param string $content The type of content we are checking (item, comment, review).
|
||||
* @param \IPS\Member|NULL $member Member to check or NULL for currently logged in member.
|
||||
* @return bool
|
||||
*/
|
||||
public function contentHeldForApprovalByNode( string $content, ?\IPS\Member $member = NULL ): bool
|
||||
{
|
||||
/* If members group bypasses, then no. */
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
if ( $member->group['g_avoid_q'] )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
switch( $content )
|
||||
{
|
||||
case 'item':
|
||||
return (bool) ( \in_array( $this->preview_posts, array( 1, 2 ) ) );
|
||||
break;
|
||||
|
||||
case 'comment':
|
||||
return (bool) ( \In_array( $this->preview_posts, array( 1, 3 ) ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -560,8 +560,23 @@ class _Post extends \IPS\Content\Comment implements \IPS\Content\EditHistory, \I
|
||||
public function webhookFilters()
|
||||
{
|
||||
$return = parent::webhookFilters();
|
||||
$return['forums'] = $this->item()->container()->_id;
|
||||
$return['hasBestAnswer'] = (bool) $this->item()->topic_answered_pid;
|
||||
try
|
||||
{
|
||||
$return['forums'] = $this->item()->container()->_id;
|
||||
$return['hasBestAnswer'] = (bool) $this->item()->topic_answered_pid;
|
||||
}
|
||||
catch( \OutOfRangeException $e ) {}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this a future entry?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isFutureDate()
|
||||
{
|
||||
return $this->item()->isFutureDate();
|
||||
}
|
||||
}
|
||||
@@ -34,7 +34,8 @@ class _Topic extends \IPS\Content\Item implements
|
||||
\IPS\Content\Searchable,
|
||||
\IPS\Content\Embeddable,
|
||||
\IPS\Content\MetaData,
|
||||
\IPS\Content\Anonymous
|
||||
\IPS\Content\Anonymous,
|
||||
\IPS\Content\FuturePublishing
|
||||
{
|
||||
use \IPS\Content\Reactable, \IPS\Content\Reportable, \IPS\Content\Statistics, \IPS\Content\Solvable { toggleSolveComment as protected _toggleSolveComment; }
|
||||
|
||||
@@ -123,6 +124,8 @@ class _Topic extends \IPS\Content\Item implements
|
||||
'solved_comment_id' => 'topic_answered_pid',
|
||||
'is_anon' => 'is_anon',
|
||||
'last_comment_anon' => 'last_poster_anon',
|
||||
'is_future_entry' => 'is_future_entry',
|
||||
'future_date' => 'publish_date',
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -302,9 +305,10 @@ class _Topic extends \IPS\Content\Item implements
|
||||
* @param bool $joinAuthor If true, will join the members table for the author
|
||||
* @param bool $joinLastCommenter If true, will join the members table for the last commenter
|
||||
* @param bool $showMovedLinks If true, moved item links are included in the results
|
||||
* @param array|null $location Array of item lat and long
|
||||
* @return \IPS\Patterns\ActiveRecordIterator|int
|
||||
*/
|
||||
public static function getItemsWithPermission( $where=array(), $order=NULL, $limit=10, $permissionKey='read', $includeHiddenItems=\IPS\Content\Hideable::FILTER_AUTOMATIC, $queryFlags=0, \IPS\Member $member=NULL, $joinContainer=FALSE, $joinComments=FALSE, $joinReviews=FALSE, $countOnly=FALSE, $joins=NULL, $skipPermission=FALSE, $joinTags=TRUE, $joinAuthor=TRUE, $joinLastCommenter=TRUE, $showMovedLinks=FALSE )
|
||||
public static function getItemsWithPermission( $where=array(), $order=NULL, $limit=10, $permissionKey='read', $includeHiddenItems=\IPS\Content\Hideable::FILTER_AUTOMATIC, $queryFlags=0, \IPS\Member $member=NULL, $joinContainer=FALSE, $joinComments=FALSE, $joinReviews=FALSE, $countOnly=FALSE, $joins=NULL, $skipPermission=FALSE, $joinTags=TRUE, $joinAuthor=TRUE, $joinLastCommenter=TRUE, $showMovedLinks=FALSE, $location=NULL )
|
||||
{
|
||||
$where = static::getItemsWithPermissionWhere( $where, $permissionKey, $member, $joinContainer, $skipPermission );
|
||||
return parent::getItemsWithPermission( $where, $order, $limit, $permissionKey, $includeHiddenItems, $queryFlags, $member, $joinContainer, $joinComments, $joinReviews, $countOnly, $joins, $skipPermission, $joinTags, $joinAuthor, $joinLastCommenter, $showMovedLinks );
|
||||
@@ -2176,6 +2180,8 @@ class _Topic extends \IPS\Content\Item implements
|
||||
'poll' => $this->poll_state ? \IPS\Poll::load( $this->poll_state )->apiOutput( $authorizedMember ) : null,
|
||||
'url' => (string) $this->url(),
|
||||
'rating' => $this->averageRating(),
|
||||
'is_future_entry' => $this->is_future_entry,
|
||||
'publish_date' => $this->publish_date ? \IPS\DateTime::ts( $this->publish_date )->rfc3339() : NULL
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user