Version 4.5.0
This commit is contained in:
1 parent
1a0c7fd3c2
commit
f79dcf067a
3791 files changed
+248032
-76372
No files matched your search
@@ -12,7 +12,7 @@
|
||||
namespace IPS\forums;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
@@ -112,10 +112,11 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
public static $bitOptions = array(
|
||||
'forums_bitoptions' => array(
|
||||
'forums_bitoptions' => array(
|
||||
'bw_disable_tagging' => 1,
|
||||
'bw_disable_prefixes' => 2,
|
||||
'bw_enable_answers' => 4,
|
||||
'bw_enable_answers_member' => 8,
|
||||
'bw_disable_tagging' => 1,
|
||||
'bw_disable_prefixes' => 2,
|
||||
'bw_enable_answers' => 4,
|
||||
'bw_enable_answers_member' => 8,
|
||||
'bw_enable_answers_moderator' => 16
|
||||
)
|
||||
)
|
||||
);
|
||||
@@ -381,7 +382,7 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
*/
|
||||
public function getLastCommentTime()
|
||||
{
|
||||
if( !$this->can_view_others and !\IPS\Member::loggedIn()->modPermission( 'can_read_all_topics' ) )
|
||||
if( !$this->memberCanAccessOthersTopics( \IPS\Member::loggedIn() ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -398,23 +399,6 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
return $this->last_post ? \IPS\DateTime::ts( $this->last_post ) : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the comment/approved/hidden counts
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function resetCommentCounts()
|
||||
{
|
||||
parent::resetCommentCounts();
|
||||
|
||||
/* Archiving? */
|
||||
try
|
||||
{
|
||||
$this->_comments += \IPS\forums\Topic\ArchivedPost::db()->select( 'COUNT(*)', 'forums_archive_posts', array( 'archive_forum_id=?', $this->id ) )->first();
|
||||
}
|
||||
catch( \Exception $e ){}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get last post data
|
||||
*
|
||||
@@ -422,41 +406,11 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
*/
|
||||
public function lastPost()
|
||||
{
|
||||
/* If this is a forum where users cannot see other user's posts, and the user is not a moderator
|
||||
who can override that, we'll show the last post that was created by the user */
|
||||
$fetchLastPostFromUser = FALSE;
|
||||
|
||||
/* This forum does not allow you to see topics from other users... */
|
||||
if( !$this->can_view_others )
|
||||
{
|
||||
/* If we do not have the 'can_read_all_topics' permission, then it doesn't matter what forums we can moderate - we can't see
|
||||
other users posts */
|
||||
if( !\IPS\Member::loggedIn()->modPermission( 'can_read_all_topics' ) )
|
||||
{
|
||||
$fetchLastPostFromUser = TRUE;
|
||||
}
|
||||
/* If we hit the else statement, we do have moderator permissions to read all topics, so now we have to see if we can
|
||||
moderate in this forum */
|
||||
else
|
||||
{
|
||||
/* If we are not a moderator of all forums... */
|
||||
if( \IPS\Member::loggedIn()->modPermission( 'forums' ) !== -1 AND \IPS\Member::loggedIn()->modPermission( 'forums' ) !== TRUE )
|
||||
{
|
||||
/* If we cannot moderate in this forum, we need to fetch our last post */
|
||||
if( !is_array( \IPS\Member::loggedIn()->modPermission( 'forums' ) ) OR
|
||||
!in_array( $this->_id, \IPS\Member::loggedIn()->modPermission( 'forums' ) ) )
|
||||
{
|
||||
$fetchLastPostFromUser = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !$this->loggedInMemberHasPasswordAccess() )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
elseif ( $fetchLastPostFromUser )
|
||||
elseif ( !$this->memberCanAccessOthersTopics( \IPS\Member::loggedIn() ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -541,7 +495,7 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
}
|
||||
}
|
||||
|
||||
if ( $this->sub_can_post and !$this->permission_showtopic and !$this->can('read') AND !is_null( $result ) )
|
||||
if ( $this->sub_can_post and !$this->permission_showtopic and !$this->can('read') AND !\is_null( $result ) )
|
||||
{
|
||||
$result['topic_title'] = NULL;
|
||||
}
|
||||
@@ -689,6 +643,27 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
\IPS\Settings::i()->viglink_enabled = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch All Root Nodes
|
||||
*
|
||||
* @param string|NULL $permissionCheck The permission key to check for or NULl to not check permissions
|
||||
* @param \IPS\Member|NULL $member The member to check permissions for or NULL for the currently logged in member
|
||||
* @param mixed $where Additional WHERE clause
|
||||
* @param array|NULL $limit Limit/offset to use, or NULL for no limit (default)
|
||||
* @return array
|
||||
*/
|
||||
public static function roots( $permissionCheck='view', $member=NULL, $where=array(), $limit=NULL )
|
||||
{
|
||||
/* @todo remove this temp fix */
|
||||
if( !isset( \IPS\Data\Store::i()->_forumsChecked ) OR !\IPS\Data\Store::i()->_forumsChecked )
|
||||
{
|
||||
\IPS\Db::i()->update( 'forums_forums', array( 'parent_id' => '-1' ), array( 'parent_id=?', 0 ) );
|
||||
\IPS\Data\Store::i()->_forumsChecked = 1;
|
||||
}
|
||||
|
||||
return parent::roots( $permissionCheck, $member, $where, $limit );
|
||||
}
|
||||
|
||||
/**
|
||||
* Load into memory (taking permissions into account)
|
||||
@@ -700,9 +675,16 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
*/
|
||||
public static function loadIntoMemory( $permissionCheck='view', $member=NULL, $where = array() )
|
||||
{
|
||||
/* @todo remove this temp fix */
|
||||
if( !isset( \IPS\Data\Store::i()->_forumsChecked ) OR !\IPS\Data\Store::i()->_forumsChecked )
|
||||
{
|
||||
\IPS\Db::i()->update( 'forums_forums', array( 'parent_id' => '-1' ), array( 'parent_id=?', 0 ) );
|
||||
\IPS\Data\Store::i()->_forumsChecked = 1;
|
||||
}
|
||||
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
|
||||
if ( in_array( $permissionCheck, array( 'add', 'reply' ) ) )
|
||||
if ( \in_array( $permissionCheck, array( 'add', 'reply' ) ) )
|
||||
{
|
||||
$where[] = array( 'sub_can_post=1' );
|
||||
$where[] = array( 'min_posts_post<=?', $member->member_posts );
|
||||
@@ -710,18 +692,14 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
|
||||
if ( $permissionCheck == 'view' )
|
||||
{
|
||||
$where[] = array( 'min_posts_view<=?', $member->member_posts );
|
||||
if ( !$member->member_id )
|
||||
{
|
||||
$where[] = array( '(sub_can_post=0 OR can_view_others=1)' );
|
||||
}
|
||||
$where[] = array( '(sub_can_post=0 OR min_posts_view<=?)', $member->member_posts );
|
||||
}
|
||||
|
||||
if ( in_array( $permissionCheck, array( 'read', 'add' ) ) )
|
||||
if ( \in_array( $permissionCheck, array( 'read', 'add' ) ) )
|
||||
{
|
||||
$whereString = 'password=? OR ' . \IPS\Db::i()->findInSet( 'forums_forums.password_override', $member->groups );
|
||||
$whereParams = array( NULL );
|
||||
if ( $member === \IPS\Member::loggedIn() )
|
||||
if ( $member->member_id === \IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
foreach ( \IPS\Request::i()->cookie as $k => $v )
|
||||
{
|
||||
@@ -742,35 +720,32 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
/**
|
||||
* Check permissions
|
||||
*
|
||||
* @param mixed $permission A key which has a value in static::$permissionMap['view'] matching a column ID in core_permission_index
|
||||
* @param \IPS\Member|\IPS\Member\Group|NULL $member The member or group to check (NULL for currently logged in member)
|
||||
* @param mixed $permission A key which has a value in static::$permissionMap['view'] matching a column ID in core_permission_index
|
||||
* @param \IPS\Member|\IPS\Member\Group|NULL $member The member or group to check (NULL for currently logged in member)
|
||||
* @param bool $considerPostBeforeRegistering If TRUE, and $member is a guest, will return TRUE if "Post Before Registering" feature is enabled
|
||||
* @return bool
|
||||
* @throws \OutOfBoundsException If $permission does not exist in static::$permissionMap
|
||||
*/
|
||||
public function can( $permission, $member=NULL )
|
||||
public function can( $permission, $member=NULL, $considerPostBeforeRegistering = TRUE )
|
||||
{
|
||||
if ( !$this->sub_can_post and in_array( $permission, array( 'add', 'reply' ) ) )
|
||||
if ( !$this->sub_can_post and \in_array( $permission, array( 'add', 'reply' ) ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$_member = $member ?: \IPS\Member::loggedIn();
|
||||
if ( $permission == 'view' and $this->min_posts_view and $this->min_posts_view > $_member->member_posts )
|
||||
if ( $permission == 'view' and $this->sub_can_post and $this->min_posts_view and $this->min_posts_view > $_member->member_posts )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if ( !$_member->member_id and $this->sub_can_post and !$this->can_view_others )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if ( in_array( $permission, array( 'add', 'reply' ) ) and $this->min_posts_post and $this->min_posts_post > $_member->member_posts )
|
||||
if ( \in_array( $permission, array( 'add', 'reply' ) ) and $this->min_posts_post and $this->min_posts_post > $_member->member_posts )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$return = parent::can( $permission, $member );
|
||||
$return = parent::can( $permission, $member, $considerPostBeforeRegistering );
|
||||
|
||||
if ( $return === TRUE and $this->password !== NULL and in_array( $permission, array( 'read', 'add' ) ) and ( ( $member !== NULL and $member !== \IPS\Member::loggedIn() ) or !$this->loggedInMemberHasPasswordAccess() ) )
|
||||
if ( $return === TRUE and $this->password !== NULL and \in_array( $permission, array( 'read', 'add' ) ) and ( ( $member !== NULL and $member->member_id !== \IPS\Member::loggedIn()->member_id ) or !$this->loggedInMemberHasPasswordAccess() ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -790,7 +765,7 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
$message = trim( \IPS\Member::loggedIn()->language()->get( "forums_forum_{$this->id}_permerror" ) );
|
||||
if ( $message and $message != '<p></p>' )
|
||||
{
|
||||
return $message;
|
||||
return \IPS\Theme::i()->getTemplate('global', 'core', 'global')->richText( $message, array('ipsType_normal') );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -892,7 +867,9 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
"form_{$id}_header_forum_display_topic",
|
||||
'forum_preview_posts',
|
||||
'forum_icon',
|
||||
'forum_sort_key'
|
||||
'forum_sort_key',
|
||||
'forum_best_answer',
|
||||
'forum_use_feature_color'
|
||||
),
|
||||
'qa' => array(
|
||||
'forum_password_on',
|
||||
@@ -914,7 +891,8 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
'forum_qa_rate_answers',
|
||||
'forum_preview_posts_qa',
|
||||
'forum_icon',
|
||||
'forum_sort_key_qa'
|
||||
'forum_sort_key_qa',
|
||||
'forum_use_feature_color'
|
||||
),
|
||||
'category' => array(
|
||||
"form_{$id}_tab_forum_display",
|
||||
@@ -924,18 +902,20 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
'redirect' => array(
|
||||
'forum_password_on',
|
||||
'forum_redirect_url',
|
||||
'forum_redirect_hits'
|
||||
'forum_redirect_hits',
|
||||
'forum_icon',
|
||||
'forum_use_feature_color'
|
||||
),
|
||||
)
|
||||
) ) );
|
||||
|
||||
$class = get_called_class();
|
||||
$class = \get_called_class();
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'forum_parent_id', ( !$this->id AND $this->parent_id === -1 ) ? NULL : ( $this->parent_id === -1 ? 0 : $this->parent_id ), FALSE, array(
|
||||
'class' => '\IPS\forums\Forum',
|
||||
'disabled' => array(),
|
||||
'zeroVal' => 'node_no_parentf',
|
||||
'zeroValTogglesOff' => array( 'form_new_forum_type', 'forum_icon' ),
|
||||
'zeroValTogglesOff' => array( 'form_new_forum_type', 'forum_icon', 'forum_card_image' ),
|
||||
'permissionCheck' => function( $node ) use ( $class )
|
||||
{
|
||||
if( isset( $class::$subnodeClass ) AND $class::$subnodeClass AND $node instanceof $class::$subnodeClass )
|
||||
@@ -952,15 +932,21 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
throw new \DomainException('forum_parent_id_error');
|
||||
}
|
||||
} ) );
|
||||
|
||||
|
||||
/* Color */
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'forum_use_feature_color', $this->feature_color ? 1 : 0, FALSE, array( 'togglesOn' => array( 'forum_feature_color' ) ), NULL, NULL, NULL, 'forum_use_feature_color' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Color( 'forum_feature_color', $this->feature_color ?: '', FALSE, array(), NULL, NULL, NULL, 'forum_feature_color' ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Upload( 'forum_icon', $this->icon ? \IPS\File::get( 'forums_Icons', $this->icon ) : NULL, FALSE, array( 'image' => TRUE, 'storageExtension' => 'forums_Icons' ), NULL, NULL, NULL, 'forum_icon' ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Upload( 'forum_card_image', $this->card_image ? \IPS\File::get( 'forums_Cards', $this->card_image ) : NULL, FALSE, array( 'image' => TRUE, 'storageExtension' => 'forums_Cards', 'allowStockPhotos' => TRUE ), NULL, NULL, NULL, 'forum_card_image' ) );
|
||||
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Url( 'forum_redirect_url', $this->id ? $this->redirect_url : array(), FALSE, array( 'placeholder' => 'http://www.example.com/' ), NULL, NULL, NULL, 'forum_redirect_url' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'forum_redirect_hits', $this->id ? $this->redirect_hits : 0, FALSE, array(), NULL, NULL, NULL, 'forum_redirect_hits' ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'forum_password_on', $this->id ? ( $this->password !== NULL ) : FALSE, FALSE, array( 'togglesOn' => array( 'forum_password', 'forum_password_override' ) ), NULL, NULL, NULL, 'forum_password_on' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Password( 'forum_password', $this->password, FALSE, array(), NULL, NULL, NULL, 'forum_password' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'forum_password_override', $this->id ? explode( ',', $this->password_override ) : array(), FALSE, array( 'options' => $groups, 'multiple' => TRUE ), NULL, NULL, NULL, 'forum_password_override' ) );
|
||||
if ( count( \IPS\Theme::themes() ) > 1 )
|
||||
if ( \count( \IPS\Theme::themes() ) > 1 )
|
||||
{
|
||||
$themes = array( 0 => 'forum_skin_id_default' );
|
||||
foreach ( \IPS\Theme::themes() as $theme )
|
||||
@@ -1029,10 +1015,6 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
$form->add( new \IPS\Helpers\Form\Translatable( 'forum_rules_title', NULL, FALSE, array( 'app' => 'forums', 'key' => ( $this->id ? "forums_forum_{$this->id}_rulestitle" : NULL ) ), NULL, NULL, NULL, 'forum_rules_title' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Translatable( 'forum_rules_text', NULL, FALSE, array( 'app' => 'forums', 'key' => ( $this->id ? "forums_forum_{$this->id}_rules" : NULL ), 'editor' => array( 'app' => 'forums', 'key' => 'Forums', 'autoSaveKey' => ( $this->id ? "forums-rules-{$this->id}" : "forums-new-rules" ), 'attachIds' => $this->id ? array( $this->id, NULL, 'rules' ) : NULL ) ), NULL, NULL, NULL, 'forum_rules_text' ) );
|
||||
|
||||
/* Color */
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'forum_use_feature_color', $this->feature_color ? 1 : 0, FALSE, array( 'togglesOn' => array( 'forum_feature_color' ) ), NULL, NULL, NULL, 'forum_use_feature_color' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Color( 'forum_feature_color', $this->feature_color ?: '', FALSE, array(), NULL, NULL, NULL, 'forum_feature_color' ) );
|
||||
|
||||
$form->addHeader( 'forum_display_topic' );
|
||||
$form->addHeader( 'forum_display_question' );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'bw_enable_answers_member', $this->id ? $this->forums_bitoptions['bw_enable_answers_member'] : TRUE, FALSE, array(), NULL, NULL, NULL, 'bw_enable_answers_member' ) );
|
||||
@@ -1040,7 +1022,8 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'forum_qa_rate_answers', $this->id ? ( ( $this->qa_rate_answers == '*' or $this->qa_rate_answers === NULL ) ? '*' : explode( ',', $this->qa_rate_answers ) ) : '*', FALSE, array( 'options' => $groupsNoGuests, 'unlimited' => '*', 'multiple' => TRUE ), NULL, NULL, NULL, 'forum_qa_rate_answers' ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'forum_forum_allow_rating', $this->id ? $this->forum_allow_rating : FALSE, FALSE, array(), NULL, NULL, NULL, 'forum_allow_rating' ) );
|
||||
$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');
|
||||
@@ -1075,10 +1058,7 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
$form->addHeader( 'tags' );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'bw_disable_tagging', !$this->forums_bitoptions['bw_disable_tagging'], FALSE, array( 'togglesOn' => array( 'bw_disable_prefixes', 'forum_tag_predefined' ) ), NULL, NULL, NULL, 'bw_disable_tagging' ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'bw_disable_prefixes', !$this->forums_bitoptions['bw_disable_prefixes'], FALSE, array(), NULL, NULL, NULL, 'bw_disable_prefixes' ) );
|
||||
if ( !\IPS\Settings::i()->tags_open_system )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'forum_tag_predefined', $this->tag_predefined ?: NULL, FALSE, array( 'autocomplete' => array( 'unique' => 'true' ), 'nullLang' => 'forum_tag_predefined_unlimited' ), NULL, NULL, NULL, 'forum_tag_predefined' ) );
|
||||
}
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'forum_tag_predefined', $this->tag_predefined ?: NULL, FALSE, array( 'autocomplete' => array( 'unique' => 'true' ), 'nullLang' => 'forum_tag_predefined_unlimited' ), NULL, NULL, NULL, 'forum_tag_predefined' ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1129,6 +1109,11 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
else
|
||||
{
|
||||
$values['forums_bitoptions']['bw_enable_answers'] = FALSE;
|
||||
|
||||
if ( isset( $values['bw_enable_answers__member'] ) )
|
||||
{
|
||||
$values['bw_enable_answers_member'] = $values['bw_enable_answers__member'];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1137,17 +1122,34 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
$values['redirect_on'] = TRUE;
|
||||
}
|
||||
|
||||
if ( isset( $values['bw_enable_answers__member'] ) )
|
||||
{
|
||||
unset( $values['bw_enable_answers__member'] );
|
||||
}
|
||||
|
||||
unset( $values['forum_can_view_others_qa'] );
|
||||
unset( $values['forum_permission_showtopic_qa'] );
|
||||
unset( $values['forum_preview_posts_qa'] );
|
||||
unset( $values['forum_sort_key_qa'] );
|
||||
}
|
||||
|
||||
/* We are copying the "Allow user to mark topic as solved" option */
|
||||
if( !isset( $values['forum_type'] ) AND isset( $values['bw_enable_answers__member'] ) )
|
||||
{
|
||||
/* We don't want to copy this to QA forums */
|
||||
if( $this->forum_type == 'normal' )
|
||||
{
|
||||
$values['bw_enable_answers_member'] = $values['bw_enable_answers__member'];
|
||||
}
|
||||
|
||||
unset( $values['bw_enable_answers__member'] );
|
||||
}
|
||||
|
||||
if ( isset( $values['forum_parent_id'] ) )
|
||||
{
|
||||
if ( $values['forum_parent_id'] )
|
||||
{
|
||||
$values['forum_parent_id'] = is_scalar( $values['forum_parent_id'] ) ? intval( $values['forum_parent_id'] ) : intval( $values['forum_parent_id']->id );
|
||||
$values['forum_parent_id'] = is_scalar( $values['forum_parent_id'] ) ? \intval( $values['forum_parent_id'] ) : \intval( $values['forum_parent_id']->id );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1156,11 +1158,11 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
}
|
||||
|
||||
/* Bitwise */
|
||||
foreach ( array( 'bw_disable_tagging', 'bw_disable_prefixes', 'bw_enable_answers_member' ) as $k )
|
||||
foreach ( array( 'bw_disable_tagging', 'bw_disable_prefixes', 'bw_enable_answers_member', 'bw_enable_answers_moderator' ) as $k )
|
||||
{
|
||||
if( isset( $values[ $k ] ) )
|
||||
{
|
||||
$values['forums_bitoptions'][ $k ] = ( $k == 'bw_enable_answers_member' ) ? $values[ $k ] : !$values[ $k ];
|
||||
$values['forums_bitoptions'][ $k ] = ( $k == 'bw_enable_answers_member' or $k == 'bw_enable_answers_moderator' ) ? $values[ $k ] : !$values[ $k ];
|
||||
unset( $values[ $k ] );
|
||||
}
|
||||
}
|
||||
@@ -1185,7 +1187,7 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
{
|
||||
if ( isset( $values[ $k ] ) )
|
||||
{
|
||||
$values[ $k ] = ( is_array( $values[ $k ] ) ) ? implode( ',', $values[ $k ] ) : $values[ $k ];
|
||||
$values[ $k ] = ( \is_array( $values[ $k ] ) ) ? implode( ',', $values[ $k ] ) : $values[ $k ];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1196,7 +1198,7 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
}
|
||||
|
||||
/* Reset password and can view others if toggling back to a category */
|
||||
if( in_array( $values['type'], array( 'category', 'redirect' ) ) )
|
||||
if( isset( $values['type'] ) AND \in_array( $values['type'], array( 'category', 'redirect' ) ) )
|
||||
{
|
||||
$values['password'] = NULL;
|
||||
$values['can_view_others'] = TRUE;
|
||||
@@ -1211,15 +1213,15 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
/* Moderation */
|
||||
if( isset( $values['preview_posts'] ) )
|
||||
{
|
||||
if ( in_array( 'topics', $values['preview_posts'] ) and in_array( 'posts', $values['preview_posts'] ) )
|
||||
if ( \in_array( 'topics', $values['preview_posts'] ) and \in_array( 'posts', $values['preview_posts'] ) )
|
||||
{
|
||||
$values['preview_posts'] = 1;
|
||||
}
|
||||
elseif ( in_array( 'topics', $values['preview_posts'] ) )
|
||||
elseif ( \in_array( 'topics', $values['preview_posts'] ) )
|
||||
{
|
||||
$values['preview_posts'] = 2;
|
||||
}
|
||||
elseif ( in_array( 'posts', $values['preview_posts'] ) )
|
||||
elseif ( \in_array( 'posts', $values['preview_posts'] ) )
|
||||
{
|
||||
$values['preview_posts'] = 3;
|
||||
}
|
||||
@@ -1271,7 +1273,7 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
}
|
||||
|
||||
/* Update index */
|
||||
if( $this->can_view_others !== NULL and isset( $values['can_view_others'] ) and $values['can_view_others'] != $this->can_view_others )
|
||||
if( $this->can_view_others !== NULL and array_key_exists( 'can_view_others', $values ) and $values['can_view_others'] != $this->can_view_others )
|
||||
{
|
||||
$this->can_view_others = $values['can_view_others'];
|
||||
$this->updateSearchIndexPermissions();
|
||||
@@ -1296,6 +1298,8 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
/**
|
||||
* Can a value be copied to this node?
|
||||
*
|
||||
* @param string $key Setting key
|
||||
* @param mixed $value Setting value
|
||||
* @return bool
|
||||
*/
|
||||
public function canCopyValue( $key, $value )
|
||||
@@ -1334,8 +1338,6 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
\IPS\File::unclaimAttachments( 'forums_Forums', $this->id );
|
||||
|
||||
try
|
||||
{
|
||||
\IPS\File::get( 'forums_Icons', $this->icon )->delete();
|
||||
@@ -1421,6 +1423,51 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
{
|
||||
return static::theOnlyNode( array( 'redirect_url' => FALSE, 'password' => FALSE ), FALSE );
|
||||
}
|
||||
|
||||
/**
|
||||
* Can a given member view topics created by other members in this forum?
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @return bool
|
||||
*/
|
||||
public function memberCanAccessOthersTopics( \IPS\Member $member )
|
||||
{
|
||||
/* If everyone can view topics posted in this forum by others then this whole check is irrelevant */
|
||||
if ( $this->can_view_others )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
/* If this is a club forum, we defer to if the member is a moderator of it (which will include members who have the global "Has leader privileges in all clubs?" permission") */
|
||||
elseif ( $club = $this->club() )
|
||||
{
|
||||
return $club->isModerator( $member );
|
||||
}
|
||||
/* Otherwise, it depends on if this user is a moderator with the "Can view all topics/questions?" permission for THIS forum */
|
||||
else
|
||||
{
|
||||
if ( $member->modPermission('can_read_all_topics') )
|
||||
{
|
||||
$forumsTheMemberIsModeratorOf = $member->modPermission('forums');
|
||||
|
||||
if ( $forumsTheMemberIsModeratorOf === TRUE ) // All forums
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
elseif ( \is_array( $forumsTheMemberIsModeratorOf ) and \in_array( $this->_id, $forumsTheMemberIsModeratorOf ) ) // This forum specifically
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get which permission keys can access all topics in a forum which
|
||||
@@ -1434,28 +1481,36 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
$return = array();
|
||||
$members = array();
|
||||
|
||||
foreach ( \IPS\Db::i()->select( '*', 'core_moderators' ) as $moderator )
|
||||
if ( $club = $this->club() )
|
||||
{
|
||||
if ( $moderator['perms'] === '*' or in_array( 'can_read_all_topics', explode( ',', $moderator['perms'] ) ) )
|
||||
$return[] = 'cm';
|
||||
$members[] = "cm{$club->id}";
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ( \IPS\Db::i()->select( '*', 'core_moderators' ) as $moderator )
|
||||
{
|
||||
if( $moderator['type'] === 'g' )
|
||||
if ( $moderator['perms'] === '*' or \in_array( 'can_read_all_topics', explode( ',', $moderator['perms'] ) ) )
|
||||
{
|
||||
$return[] = $moderator['id'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$members[] = "m{$moderator['id']}";
|
||||
if( $moderator['type'] === 'g' )
|
||||
{
|
||||
$return[] = $moderator['id'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$members[] = "m{$moderator['id']}";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$return = ( $normal == '*' ) ? array_unique( $return ) : array_intersect( explode( ',', $normal ), array_unique( $return ) );
|
||||
|
||||
if( count( $members ) )
|
||||
|
||||
if( \count( $members ) )
|
||||
{
|
||||
$return = array_merge( $return, $members );
|
||||
}
|
||||
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
@@ -1498,7 +1553,7 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
if( isset( $data['additional'] ) AND
|
||||
( isset( $data['additional']['author'] ) OR ( isset( $data['additional']['no_comments'] ) AND $data['additional']['no_comments'] > 0 ) OR
|
||||
( isset( $data['additional']['num_comments'] ) AND $data['additional']['num_comments'] > 0 ) OR isset( $data['additional']['state'] ) OR
|
||||
( isset( $data['additional']['pinned'] ) AND $data['additional']['pinned'] === TRUE ) OR ( isset( $data['additional']['featured'] ) AND $data['additional']['featured'] === TRUE ) )
|
||||
( isset( $data['additional']['pinned'] ) AND $data['additional']['pinned'] === TRUE ) OR ( isset( $data['additional']['featured'] ) AND $data['additional']['featured'] === TRUE ) OR ( isset( $data['additional']['last_post'] ) AND $data['additional']['last_post'] > 0 ) OR ( isset( $data['additional']['date'] ) AND $data['additional']['date'] > 0 ) )
|
||||
)
|
||||
{
|
||||
return parent::massMoveorDelete( $node, $data );
|
||||
@@ -1559,7 +1614,7 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
\IPS\Db::i()->update( 'forums_question_ratings', array( 'forum' => $node->_id ), array( 'forum=?', $this->_id ) );
|
||||
|
||||
/* Rebuild tags */
|
||||
if ( in_array( 'IPS\Content\Tags', class_implements( $contentItemClass ) ) )
|
||||
if ( \in_array( 'IPS\Content\Tags', class_implements( $contentItemClass ) ) )
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_tags', array(
|
||||
'tag_aap_lookup' => md5( static::$permApp . ';' . static::$permType . ';' . $node->_id ),
|
||||
@@ -1584,7 +1639,7 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
$this->save();
|
||||
|
||||
/* Add to search index */
|
||||
if ( in_array( 'IPS\Content\Searchable', class_implements( $contentItemClass ) ) )
|
||||
if ( \in_array( 'IPS\Content\Searchable', class_implements( $contentItemClass ) ) )
|
||||
{
|
||||
/* Grab permissions...we already account for !can_view_others by letting the parent handle this the old fashioned way in that case at the start of the method */
|
||||
$permissions = $node->searchIndexPermissions();
|
||||
@@ -1597,7 +1652,7 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
if ( isset( $contentItemClass::$$class ) )
|
||||
{
|
||||
$className = $contentItemClass::$$class;
|
||||
if ( in_array( 'IPS\Content\Searchable', class_implements( $className ) ) )
|
||||
if ( \in_array( 'IPS\Content\Searchable', class_implements( $className ) ) )
|
||||
{
|
||||
\IPS\Content\Search\Index::i()->massUpdate( $className, $this->_id, NULL, $permissions, NULL, $node->_id );
|
||||
}
|
||||
@@ -1644,23 +1699,12 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
*/
|
||||
public function disabledPermissions()
|
||||
{
|
||||
$disabled = array();
|
||||
|
||||
try
|
||||
{
|
||||
$guestGroup = \IPS\Member\Group::load( \IPS\Settings::i()->guest_group );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
{
|
||||
throw new \UnderflowException( 'invalid_guestgroup_admin', 199 );
|
||||
}
|
||||
|
||||
if( $this->sub_can_post and !$this->can_view_others )
|
||||
{
|
||||
$disabled[ $guestGroup->g_id ][] = 'view';
|
||||
return array( \IPS\Settings::i()->guest_group => array( 2, 3, 4, 5 ) );
|
||||
}
|
||||
|
||||
return $disabled;
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1694,7 +1738,7 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
* This is used for search and the activity stream.
|
||||
* We return a list of IDs and not node objects for memory efficiency.
|
||||
*
|
||||
* return null|array
|
||||
* @return null|array
|
||||
*/
|
||||
public static function unsearchableNodeIds()
|
||||
{
|
||||
@@ -1705,7 +1749,7 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
|
||||
/* For memory efficiency, we query the database directly rather than manage nodes */
|
||||
$forums = iterator_to_array( \IPS\Db::i()->select( 'id', 'forums_forums', array( 'min_posts_view > ?', \IPS\Member::loggedIn()->member_posts ) )->setKeyField('id') );
|
||||
static::$unsearchableNodeIds = count( $forums ) ? $forums : NULL;
|
||||
static::$unsearchableNodeIds = \count( $forums ) ? $forums : NULL;
|
||||
return static::$unsearchableNodeIds;
|
||||
}
|
||||
|
||||
@@ -1714,19 +1758,38 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
*
|
||||
* @param \IPS\Member|NULL $authorizedMember The member making the API request or NULL for API Key / client_credentials
|
||||
* @return array
|
||||
* @apiresponse int id ID number
|
||||
* @apiresponse string name Forum name
|
||||
* @apiresponse int topics Number of topics in forum
|
||||
* @apiresponse string url URL
|
||||
* @apiresponse int id ID number
|
||||
* @apiresponse string name Forum name
|
||||
* @apiresponse string path Forum name including parents (e.g. "Example Category > Example Forum")
|
||||
* @apiresponse int topics Number of topics in forum
|
||||
* @apiresponse string url URL
|
||||
* @apiresponse int|null parentId Parent Node ID
|
||||
* @clientapiresponse object|null permissions Node permissions
|
||||
*/
|
||||
public function apiOutput( \IPS\Member $authorizedMember = NULL )
|
||||
{
|
||||
return array(
|
||||
$path = array();
|
||||
foreach( $this->parents() AS $parent )
|
||||
{
|
||||
$path[] = $parent->_title;
|
||||
}
|
||||
$path[] = $this->_title;
|
||||
|
||||
$return = array(
|
||||
'id' => $this->id,
|
||||
'name' => $this->_title,
|
||||
'path' => implode( ' > ', $path ),
|
||||
'topics' => $this->topics,
|
||||
'url' => (string) $this->url()
|
||||
'url' => (string) $this->url(),
|
||||
'parentId' => static::$databaseColumnParent ? $this->{static::$databaseColumnParent} : NULL
|
||||
);
|
||||
|
||||
if( $authorizedMember === NULL )
|
||||
{
|
||||
$return['permissions'] = $this->permissions();
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/* !Clubs */
|
||||
@@ -1742,6 +1805,7 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
$itemClass = static::$contentItemClass;
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'club_node_name', $this->_id ? $this->_title : \IPS\Member::loggedIn()->language()->addToStack( $itemClass::$title . '_pl' ), TRUE, array( 'maxLength' => 255 ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Editor( 'club_node_description', $this->_id ? \IPS\Member::loggedIn()->language()->get( static::$titleLangPrefix . $this->_id . '_desc' ) : NULL, FALSE, array( 'app' => 'forums', 'key' => 'Forums', 'autoSaveKey' => ( $this->id ? "forums-forum-{$this->id}" : "forums-new-forum" ), 'attachIds' => $this->id ? array( $this->id, NULL, 'description' ) : NULL, 'minimize' => 'forum_description_placeholder' ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'forum_can_view_others_club', $this->id ? $this->can_view_others : TRUE ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1758,6 +1822,19 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
$this->name_seo = \IPS\Http\Url\Friendly::seoTitle( $values['club_node_name'] );
|
||||
}
|
||||
|
||||
if( $this->can_view_others != $values['forum_can_view_others_club'] )
|
||||
{
|
||||
$this->can_view_others = $values['forum_can_view_others_club'];
|
||||
|
||||
if ( $this->_id )
|
||||
{
|
||||
$this->updateSearchIndexPermissions();
|
||||
}
|
||||
}
|
||||
|
||||
/* Use default priority for sitemaps */
|
||||
$this->ipseo_priority = -1;
|
||||
|
||||
if ( !$this->_id )
|
||||
{
|
||||
$this->save();
|
||||
@@ -1813,6 +1890,40 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
|
||||
return $simpleView;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the member's topic list view method
|
||||
*
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function getMemberListView()
|
||||
{
|
||||
$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 )
|
||||
{
|
||||
return \IPS\Settings::i()->forums_view_list_method;
|
||||
}
|
||||
|
||||
if ( ! $method )
|
||||
{
|
||||
try
|
||||
{
|
||||
$method = \IPS\Db::i()->select( 'method', 'forums_view_method', array( 'member_id=? and type=?', \IPS\Member::loggedIn()->member_id, 'list' ) )->first();
|
||||
}
|
||||
catch( \UnderFlowException $e )
|
||||
{
|
||||
$method = \IPS\Settings::i()->forums_view_list_method;
|
||||
}
|
||||
|
||||
/* Attempt to set the cookie again */
|
||||
\IPS\Request::i()->setCookie( 'forum_list_view', $method, ( new \IPS\DateTime )->add( new \DateInterval( 'P1Y' ) ) );
|
||||
}
|
||||
|
||||
return $method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the member's view method
|
||||
@@ -1833,7 +1944,7 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
{
|
||||
try
|
||||
{
|
||||
$method = \IPS\Db::i()->select( 'method', 'forums_view_method', array( 'member_id=?', \IPS\Member::loggedIn()->member_id ) )->first();
|
||||
$method = \IPS\Db::i()->select( 'method', 'forums_view_method', array( 'member_id=? and type=?', \IPS\Member::loggedIn()->member_id, 'index' ) )->first();
|
||||
}
|
||||
catch( \UnderFlowException $e )
|
||||
{
|
||||
@@ -1844,7 +1955,7 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
\IPS\Request::i()->setCookie( 'forum_view', $method, ( new \IPS\DateTime )->add( new \DateInterval( 'P1Y' ) ) );
|
||||
}
|
||||
|
||||
if ( ! $method or ( $chooseable != '*' AND ! in_array( $method, $chooseable ) ) )
|
||||
if ( ! $method or ( $chooseable != '*' AND ! \in_array( $method, $chooseable ) ) )
|
||||
{
|
||||
$method = \IPS\Settings::i()->forums_default_view;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user