Version 4.6.0
This commit is contained in:
1 parent
f79dcf067a
commit
517a5e1f70
2036 files changed
+110041
-26162
No files matched your search
@@ -25,7 +25,8 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
{
|
||||
use \IPS\Content\ClubContainer;
|
||||
use \IPS\Node\Colorize;
|
||||
|
||||
use \IPS\Node\Statistics;
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Multiton Store
|
||||
*/
|
||||
@@ -304,7 +305,7 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
*/
|
||||
public function get__sortBy()
|
||||
{
|
||||
return $this->sort_key;
|
||||
return $this->sort_key ?: 'last_post';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -352,6 +353,7 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
$this->last_title = $topic->title;
|
||||
$this->seo_last_title = \IPS\Http\Url\Friendly::seoTitle( $this->last_title );
|
||||
$this->last_id = $topic->tid;
|
||||
$this->last_poster_anon = $topic->last_poster_anon;
|
||||
return;
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
@@ -361,6 +363,7 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
$this->last_poster_name = '';
|
||||
$this->last_title = NULL;
|
||||
$this->last_id = NULL;
|
||||
$this->last_poster_anon = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -372,21 +375,24 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
$this->last_title = $comment->item()->title;
|
||||
$this->seo_last_title = \IPS\Http\Url\Friendly::seoTitle( $this->last_title );
|
||||
$this->last_id = $comment->item()->tid;
|
||||
$this->last_poster_anon = $comment->isAnonymous();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get last comment time
|
||||
*
|
||||
* @note This should return the last comment time for this node only, not for children nodes
|
||||
* @param \IPS\Member|NULL $member MemberObject
|
||||
* @return \IPS\DateTime|NULL
|
||||
*/
|
||||
public function getLastCommentTime()
|
||||
public function getLastCommentTime( \IPS\Member $member = NULL )
|
||||
{
|
||||
if( !$this->memberCanAccessOthersTopics( \IPS\Member::loggedIn() ) )
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
if( !$this->memberCanAccessOthersTopics( $member ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$select = \IPS\Db::i()->select('*', 'forums_posts', array("forums_posts.queued=0 AND forums_topics.forum_id={$this->id} AND forums_topics.approved=1 AND forums_topics.starter_id=?", \IPS\Member::loggedIn()->member_id), 'forums_posts.post_date DESC', 1)->join('forums_topics', 'forums_topics.tid=forums_posts.topic_id')->first();
|
||||
$select = \IPS\Db::i()->select('*', 'forums_posts', array("forums_posts.queued=0 AND forums_topics.forum_id={$this->id} AND forums_topics.approved=1 AND forums_topics.starter_id=?", $member->member_id), 'forums_posts.post_date DESC', 1)->join('forums_topics', 'forums_topics.tid=forums_posts.topic_id')->first();
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
{
|
||||
@@ -697,21 +703,24 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
|
||||
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->member_id === \IPS\Member::loggedIn()->member_id )
|
||||
if ( static::hasPasswordForums() )
|
||||
{
|
||||
foreach ( \IPS\Request::i()->cookie as $k => $v )
|
||||
$whereString = 'password=? OR ' . \IPS\Db::i()->findInSet( 'forums_forums.password_override', $member->groups );
|
||||
$whereParams = array( NULL );
|
||||
if ( $member->member_id === \IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
if ( mb_substr( $k, 0, 13 ) === 'ipbforumpass_' )
|
||||
foreach ( \IPS\Request::i()->cookie as $k => $v )
|
||||
{
|
||||
$whereString .= ' OR ( forums_forums.id=? AND MD5(forums_forums.password)=? )';
|
||||
$whereParams[] = (int) mb_substr( $k, 13 );
|
||||
$whereParams[] = $v;
|
||||
if ( mb_substr( $k, 0, 13 ) === 'ipbforumpass_' )
|
||||
{
|
||||
$whereString .= ' OR ( forums_forums.id=? AND MD5(forums_forums.password)=? )';
|
||||
$whereParams[] = (int) mb_substr( $k, 13 );
|
||||
$whereParams[] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
$where[] = array_merge( array( '( ' . $whereString . ' )' ), $whereParams );
|
||||
}
|
||||
$where[] = array_merge( array( '( ' . $whereString . ' )' ), $whereParams );
|
||||
}
|
||||
|
||||
return parent::loadIntoMemory( $permissionCheck, $member, $where );
|
||||
@@ -897,7 +906,8 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
'category' => array(
|
||||
"form_{$id}_tab_forum_display",
|
||||
'forum_rules_title',
|
||||
'forum_rules_text'
|
||||
'forum_rules_text',
|
||||
'forum_use_feature_color'
|
||||
),
|
||||
'redirect' => array(
|
||||
'forum_password_on',
|
||||
@@ -938,14 +948,14 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
$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\Upload( 'forum_card_image', $this->card_image ? \IPS\File::get( 'forums_Cards', $this->card_image ) : NULL, FALSE, array( 'image' => array( 'maxWidth' => 800, 'maxHeight' => 800 ), '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' ) );
|
||||
$form->add( new \IPS\Helpers\Form\CheckboxSet( '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 )
|
||||
{
|
||||
$themes = array( 0 => 'forum_skin_id_default' );
|
||||
@@ -1018,8 +1028,8 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
$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' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'forum_qa_rate_questions', $this->id ? ( ( $this->qa_rate_questions == '*' or $this->qa_rate_questions === NULL ) ? '*' : explode( ',', $this->qa_rate_questions ) ) : '*', FALSE, array( 'options' => $groupsNoGuests, 'unlimited' => '*', 'multiple' => TRUE ), NULL, NULL, NULL, 'forum_qa_rate_questions' ) );
|
||||
$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\CheckboxSet( 'forum_qa_rate_questions', $this->id ? ( ( $this->qa_rate_questions == '*' or $this->qa_rate_questions === NULL ) ? '*' : explode( ',', $this->qa_rate_questions ) ) : '*', FALSE, array( 'options' => $groupsNoGuests, 'unlimited' => '*', 'multiple' => TRUE, 'impliedUnlimited' => TRUE ), NULL, NULL, NULL, 'forum_qa_rate_questions' ) );
|
||||
$form->add( new \IPS\Helpers\Form\CheckboxSet( '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, 'impliedUnlimited' => 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' ) );
|
||||
@@ -1048,6 +1058,7 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'forum_preview_posts', $previewPosts, FALSE, array( 'options' => array( 'topics' => 'forum_preview_posts_topics', 'posts' => 'forum_preview_posts_posts' ) ), NULL, NULL, NULL, 'forum_preview_posts' ) );
|
||||
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'forum_preview_posts_qa', $previewPosts, FALSE, array( 'options' => array( 'topics' => 'forum_preview_posts_questions', 'posts' => 'forum_preview_posts_answers' ) ), NULL, NULL, NULL, 'forum_preview_posts_qa' ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'forum_inc_postcount', $this->id ? $this->inc_postcount : TRUE, FALSE, array() ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'allow_anonymous', $this->id ? $this->allow_anonymous : FALSE, FALSE, array() ) );
|
||||
$form->addHeader( 'polls' );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'forum_allow_poll', $this->id ? $this->allow_poll : TRUE, FALSE, array() ) );
|
||||
$form->addHeader( 'posting_requirements' );
|
||||
@@ -1290,6 +1301,8 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
*/
|
||||
public function postSaveForm( $values )
|
||||
{
|
||||
unset( \IPS\Data\Store::i()->forumsHavePasswords );
|
||||
|
||||
\IPS\File::claimAttachments( 'forums-new-forum', $this->id, NULL, 'description', TRUE );
|
||||
\IPS\File::claimAttachments( 'forums-new-permerror', $this->id, NULL, 'permerror', TRUE );
|
||||
\IPS\File::claimAttachments( 'forums-new-rules', $this->id, NULL, 'rules', TRUE );
|
||||
@@ -1343,7 +1356,9 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
\IPS\File::get( 'forums_Icons', $this->icon )->delete();
|
||||
}
|
||||
catch( \Exception $ex ) { }
|
||||
|
||||
|
||||
unset( \IPS\Data\Store::i()->forumsHavePasswords );
|
||||
|
||||
parent::delete();
|
||||
|
||||
foreach ( array( 'rules_title' => "forums_forum_{$this->id}_rulestitle", 'rules_text' => "forums_forum_{$this->id}_rules", 'permission_custom_error' => "forums_forum_{$this->id}_permerror" ) as $fieldKey => $langKey )
|
||||
@@ -1386,6 +1401,7 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
|
||||
$oldId = $this->id;
|
||||
$oldIcon = $this->icon;
|
||||
$oldGridImage = $this->card_image;
|
||||
|
||||
$this->show_rules = 0;
|
||||
|
||||
@@ -1412,6 +1428,22 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
|
||||
$this->save();
|
||||
}
|
||||
|
||||
if ( $oldGridImage )
|
||||
{
|
||||
try
|
||||
{
|
||||
$gridImg = \IPS\File::get( 'forums_Cards', $oldGridImage );
|
||||
$newImage = \IPS\File::create( 'forums_Cards', $gridImg->originalFilename, $gridImg->contents() );
|
||||
$this->card_image = (string) $newImage;
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
$this->card_image = NULL;
|
||||
}
|
||||
|
||||
$this->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1449,7 +1481,7 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
{
|
||||
$forumsTheMemberIsModeratorOf = $member->modPermission('forums');
|
||||
|
||||
if ( $forumsTheMemberIsModeratorOf === TRUE ) // All forums
|
||||
if ( $forumsTheMemberIsModeratorOf === TRUE OR $forumsTheMemberIsModeratorOf == -1 ) // All forums
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1490,7 +1522,12 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
{
|
||||
foreach ( \IPS\Db::i()->select( '*', 'core_moderators' ) as $moderator )
|
||||
{
|
||||
if ( $moderator['perms'] === '*' or \in_array( 'can_read_all_topics', explode( ',', $moderator['perms'] ) ) )
|
||||
$json = json_decode( $moderator['perms'], TRUE );
|
||||
|
||||
if ( $moderator['perms'] === '*' OR
|
||||
(
|
||||
!empty( $json['can_read_all_topics'] ) AND ( isset( $json['forums'] ) AND ( $json['forums'] === -1 OR \in_array( $this->_id, $json['forums'] ) ) )
|
||||
) )
|
||||
{
|
||||
if( $moderator['type'] === 'g' )
|
||||
{
|
||||
@@ -1503,7 +1540,7 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$return = ( $normal == '*' ) ? array_unique( $return ) : array_intersect( explode( ',', $normal ), array_unique( $return ) );
|
||||
|
||||
if( \count( $members ) )
|
||||
@@ -1761,9 +1798,10 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
* @apiresponse int id ID number
|
||||
* @apiresponse string name Forum name
|
||||
* @apiresponse string path Forum name including parents (e.g. "Example Category > Example Forum")
|
||||
* @apiresponse string type The type of forum: "discussions", "questions", "category", or "redirect"
|
||||
* @apiresponse int topics Number of topics in forum
|
||||
* @apiresponse string url URL
|
||||
* @apiresponse int|null parentId Parent Node ID
|
||||
* @apiresponse int|null parentId Parent Node ID
|
||||
* @clientapiresponse object|null permissions Node permissions
|
||||
*/
|
||||
public function apiOutput( \IPS\Member $authorizedMember = NULL )
|
||||
@@ -1775,12 +1813,27 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
}
|
||||
$path[] = $this->_title;
|
||||
|
||||
$type = 'discussions';
|
||||
if ( $this->redirect_url )
|
||||
{
|
||||
$type = 'redirect';
|
||||
}
|
||||
elseif ( !$this->sub_can_post )
|
||||
{
|
||||
$type = 'category';
|
||||
}
|
||||
elseif ( $this->forums_bitoptions['bw_enable_answers'] )
|
||||
{
|
||||
$type = 'questions';
|
||||
}
|
||||
|
||||
$return = array(
|
||||
'id' => $this->id,
|
||||
'name' => $this->_title,
|
||||
'path' => implode( ' > ', $path ),
|
||||
'topics' => $this->topics,
|
||||
'url' => (string) $this->url(),
|
||||
'id' => $this->id,
|
||||
'name' => $this->_title,
|
||||
'path' => implode( ' > ', $path ),
|
||||
'type' => $type,
|
||||
'topics' => $this->topics,
|
||||
'url' => (string) $this->url(),
|
||||
'parentId' => static::$databaseColumnParent ? $this->{static::$databaseColumnParent} : NULL
|
||||
);
|
||||
|
||||
@@ -1963,6 +2016,21 @@ class _Forum extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
return $method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return if this forum has a password set or not
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function hasPasswordForums()
|
||||
{
|
||||
if ( ! isset( \IPS\Data\Store::i()->forumsHavePasswords ) )
|
||||
{
|
||||
\IPS\Data\Store::i()->forumsHavePasswords = (bool) \IPS\Db::i()->select( 'COUNT(*)', 'forums_forums', array( 'password IS NOT NULL' ) )->first();
|
||||
}
|
||||
|
||||
return \IPS\Data\Store::i()->forumsHavePasswords;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get URL
|
||||
*
|
||||
|
||||
@@ -109,12 +109,21 @@ class _ArchivedPost extends Post
|
||||
* @param \IPS\Member $member The memner
|
||||
* @return int
|
||||
*/
|
||||
public static function memberPostCount( \IPS\Member $member )
|
||||
public static function memberPostCount( \IPS\Member $member, bool $includeNonPostCountIncreasing = FALSE, bool $includeHiddenAndPendingApproval = TRUE )
|
||||
{
|
||||
return static::db()->select( 'COUNT(*)', 'forums_archive_posts', array(
|
||||
array( 'archive_author_id=?', $member->member_id ),
|
||||
array( \IPS\Db::i()->in( 'archive_forum_id', iterator_to_array( \IPS\Db::i()->select( 'id', 'forums_forums', 'inc_postcount=0' ) ), TRUE ) )
|
||||
) )->first();
|
||||
$where = [];
|
||||
$where[] = [ 'archive_author_id=?', $member->member_id ];
|
||||
|
||||
if ( !$includeNonPostCountIncreasing )
|
||||
{
|
||||
$where[] = [ \IPS\Db::i()->in( 'archive_forum_id', iterator_to_array( \IPS\Db::i()->select( 'id', 'forums_forums', 'inc_postcount=0' ) ) ) ];
|
||||
}
|
||||
if ( !$includeHiddenAndPendingApproval )
|
||||
{
|
||||
$where[] = [ 'archive_queued=0' ];
|
||||
}
|
||||
|
||||
return \IPS\Db::i()->select( 'COUNT(*)', 'forums_posts', $where )->first();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,9 +21,9 @@ if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
/**
|
||||
* Post Model
|
||||
*/
|
||||
class _Post extends \IPS\Content\Comment implements \IPS\Content\EditHistory, \IPS\Content\Hideable, \IPS\Content\Shareable, \IPS\Content\Searchable, \IPS\Content\Embeddable
|
||||
class _Post extends \IPS\Content\Comment implements \IPS\Content\EditHistory, \IPS\Content\Hideable, \IPS\Content\Shareable, \IPS\Content\Searchable, \IPS\Content\Embeddable, \IPS\Content\Anonymous
|
||||
{
|
||||
use \IPS\Content\Reactable, \IPS\Content\Reportable;
|
||||
use \IPS\Content\Reactable, \IPS\Content\Reportable, \IPS\Content\Recognizable;
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Multiton Store
|
||||
@@ -75,7 +75,8 @@ class _Post extends \IPS\Content\Comment implements \IPS\Content\EditHistory, \I
|
||||
'edit_member_name' => 'edit_name',
|
||||
'edit_reason' => 'post_edit_reason',
|
||||
'hidden' => 'queued',
|
||||
'first' => 'new_topic'
|
||||
'first' => 'new_topic',
|
||||
'is_anon' => 'post_field_t2'
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -178,25 +179,27 @@ class _Post extends \IPS\Content\Comment implements \IPS\Content\EditHistory, \I
|
||||
* @param \IPS\Member $member The memner
|
||||
* @return int
|
||||
*/
|
||||
public static function memberPostCount( \IPS\Member $member )
|
||||
public static function memberPostCount( \IPS\Member $member, bool $includeNonPostCountIncreasing = FALSE, bool $includeHiddenAndPendingApproval = TRUE )
|
||||
{
|
||||
return \IPS\Db::i()->select( 'COUNT(*)', 'forums_posts', array(
|
||||
'author_id=? AND forums_topics.forum_id IN(?)',
|
||||
$member->member_id,
|
||||
\IPS\Db::i()->select( 'id', 'forums_forums', 'inc_postcount=1' )
|
||||
) )->join( 'forums_topics', 'tid=topic_id' )->first() ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Post count for member
|
||||
*
|
||||
* @param \IPS\Member $member The memner
|
||||
* @return int
|
||||
*/
|
||||
public static function rawMemberPostCount( \IPS\Member $member )
|
||||
{
|
||||
/* Explicitly calling to the parent so we don't filter by forum ID */
|
||||
return parent::memberPostCount( $member );
|
||||
$where = [];
|
||||
$where[] = [ 'author_id=?', $member->member_id ];
|
||||
|
||||
if ( !$includeNonPostCountIncreasing )
|
||||
{
|
||||
$where[] = [ 'forums_topics.forum_id IN(?)', \IPS\Db::i()->select( 'id', 'forums_forums', 'inc_postcount=1' ) ];
|
||||
}
|
||||
if ( !$includeHiddenAndPendingApproval )
|
||||
{
|
||||
$where[] = [ 'queued=0' ];
|
||||
}
|
||||
|
||||
$query = \IPS\Db::i()->select( 'COUNT(*)', 'forums_posts', $where );
|
||||
if ( !$includeNonPostCountIncreasing )
|
||||
{
|
||||
$query = $query->join( 'forums_topics', 'tid=topic_id' );
|
||||
}
|
||||
|
||||
return $query->first();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -240,7 +243,7 @@ class _Post extends \IPS\Content\Comment implements \IPS\Content\EditHistory, \I
|
||||
* @param array $reactions Reaction Data
|
||||
* @return string
|
||||
*/
|
||||
public static function searchResult( array $indexData, array $authorData, array $itemData, array $containerData = NULL, array $reputationData, $reviewRating, $iPostedIn, $view, $asItem, $canIgnoreComments=FALSE, $template=NULL, $reactions=array() )
|
||||
public static function searchResult( array $indexData, array $authorData, array $itemData, ?array $containerData, array $reputationData, $reviewRating, $iPostedIn, $view, $asItem, $canIgnoreComments=FALSE, $template=NULL, $reactions=array() )
|
||||
{
|
||||
/* Password protected */
|
||||
if (
|
||||
@@ -405,6 +408,11 @@ class _Post extends \IPS\Content\Comment implements \IPS\Content\EditHistory, \I
|
||||
*/
|
||||
public static function _indefiniteArticle( array $containerData = NULL, \IPS\Lang $lang = NULL )
|
||||
{
|
||||
if ( !$containerData )
|
||||
{
|
||||
return parent::_indefiniteArticle( $containerData, $lang );
|
||||
}
|
||||
|
||||
$bitOptions = ( $containerData['forums_bitoptions'] instanceof \IPS\Patterns\Bitwise ) ? $containerData['forums_bitoptions'] : new \IPS\Patterns\Bitwise( array( 'forums_bitoptions' => $containerData['forums_bitoptions'] ), \IPS\forums\Forum::$bitOptions['forums_bitoptions'] );
|
||||
|
||||
if ( $bitOptions['bw_enable_answers'] )
|
||||
@@ -424,20 +432,32 @@ class _Post extends \IPS\Content\Comment implements \IPS\Content\EditHistory, \I
|
||||
* @param array|NULL $containerData Basic data about the container. Only includes columns returned by container::basicDataColumns()
|
||||
* @param \IPS\Lang|NULL $lang The language to use, or NULL for the language of the currently logged in member
|
||||
* @param array $options Options to pass to \IPS\Lang::addToStack
|
||||
* @param integer|boolean $count Count of things; if int > 1, uses pluralized version of definite article
|
||||
* @return string
|
||||
*/
|
||||
public static function _definiteArticle( array $containerData = NULL, \IPS\Lang $lang = NULL, $options = array() )
|
||||
public static function _definiteArticle( array $containerData = NULL, \IPS\Lang $lang = NULL, $options = array(), $count = FALSE )
|
||||
{
|
||||
if ( !$containerData )
|
||||
{
|
||||
return parent::_definiteArticle( $containerData, $lang, $options );
|
||||
}
|
||||
|
||||
$bitOptions = ( $containerData['forums_bitoptions'] instanceof \IPS\Patterns\Bitwise ) ? $containerData['forums_bitoptions'] : new \IPS\Patterns\Bitwise( array( 'forums_bitoptions' => $containerData['forums_bitoptions'] ), \IPS\forums\Forum::$bitOptions['forums_bitoptions'] );
|
||||
|
||||
if ( $bitOptions['bw_enable_answers'] )
|
||||
{
|
||||
$lang = $lang ?: \IPS\Member::loggedIn()->language();
|
||||
if( \is_int( $count ) )
|
||||
{
|
||||
$options['pluralize'] = array( $count );
|
||||
return $lang->addToStack( '__defart_answer_plural', FALSE, $options );
|
||||
}
|
||||
|
||||
return $lang->addToStack( '__defart_answer', FALSE, $options );
|
||||
}
|
||||
else
|
||||
{
|
||||
return parent::_definiteArticle( $containerData, $lang, $options );
|
||||
return parent::_definiteArticle( $containerData, $lang, $options, $count );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,9 +33,10 @@ class _Topic extends \IPS\Content\Item implements
|
||||
\IPS\Content\Ratings,
|
||||
\IPS\Content\Searchable,
|
||||
\IPS\Content\Embeddable,
|
||||
\IPS\Content\MetaData
|
||||
\IPS\Content\MetaData,
|
||||
\IPS\Content\Anonymous
|
||||
{
|
||||
use \IPS\Content\Reactable, \IPS\Content\Reportable, \IPS\Content\Statistics, \IPS\Content\Solvable;
|
||||
use \IPS\Content\Reactable, \IPS\Content\Reportable, \IPS\Content\Statistics, \IPS\Content\Solvable { toggleSolveComment as protected _toggleSolveComment; }
|
||||
|
||||
/**
|
||||
* @brief Not archived
|
||||
@@ -119,7 +120,9 @@ class _Topic extends \IPS\Content\Item implements
|
||||
'state' => 'state',
|
||||
'updated' => 'last_post',
|
||||
'meta_data' => 'topic_meta_data',
|
||||
'solved_comment_id' => 'topic_answered_pid'
|
||||
'solved_comment_id' => 'topic_answered_pid',
|
||||
'is_anon' => 'is_anon',
|
||||
'last_comment_anon' => 'last_poster_anon',
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -332,23 +335,27 @@ class _Topic extends \IPS\Content\Item implements
|
||||
{
|
||||
$joinContainer = TRUE;
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
|
||||
$whereString = 'forums_forums.password=? OR ' . \IPS\Db::i()->findInSet( 'forums_forums.password_override', $member->groups );
|
||||
$whereParams = array( NULL );
|
||||
if ( \IPS\Dispatcher::hasInstance() AND $member->member_id === \IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
foreach ( \IPS\Request::i()->cookie as $k => $v )
|
||||
$containerClass = static::$containerNodeClass;
|
||||
|
||||
if ( $containerClass::hasPasswordForums() )
|
||||
{
|
||||
$whereString = 'forums_forums.password=? OR ' . \IPS\Db::i()->findInSet( 'forums_forums.password_override', $member->groups );
|
||||
$whereParams = array( NULL );
|
||||
if ( \IPS\Dispatcher::hasInstance() AND $member->member_id === \IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
if ( mb_substr( $k, 0, 13 ) === 'ipbforumpass_' )
|
||||
foreach ( \IPS\Request::i()->cookie as $k => $v )
|
||||
{
|
||||
$whereString .= ' OR ( forums_forums.id=? AND MD5(forums_forums.password)=? )';
|
||||
$whereParams[] = (int) mb_substr( $k, 13 );
|
||||
$whereParams[] = $v;
|
||||
if ( mb_substr( $k, 0, 13 ) === 'ipbforumpass_' )
|
||||
{
|
||||
$whereString .= ' OR ( forums_forums.id=? AND MD5(forums_forums.password)=? )';
|
||||
$whereParams[] = (int) mb_substr( $k, 13 );
|
||||
$whereParams[] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$where['container'][] = array_merge( array( '( ' . $whereString . ' )' ), $whereParams );
|
||||
}
|
||||
|
||||
$where['container'][] = array_merge( array( '( ' . $whereString . ' )' ), $whereParams );
|
||||
}
|
||||
|
||||
/* Don't show topics from forums in which topics only show to the poster */
|
||||
@@ -370,7 +377,7 @@ class _Topic extends \IPS\Content\Item implements
|
||||
$where['item'][] = array( 'forums_topics.starter_id=?', $member->member_id );
|
||||
}
|
||||
}
|
||||
elseif ( !$member->modPermission('can_read_all_topics') or ( $member->modPermission('forums') !== TRUE and !\in_array( $skipPermission->_id, $member->modPermission('forums') ) ) )
|
||||
elseif ( !$member->modPermission('can_read_all_topics') or ( \is_array( $member->modPermission('forums') ) and !\in_array( $skipPermission->_id, $member->modPermission('forums') ) ) )
|
||||
{
|
||||
$where['item'][] = array( 'forums_topics.starter_id=?', $member->member_id );
|
||||
}
|
||||
@@ -674,17 +681,16 @@ class _Topic extends \IPS\Content\Item implements
|
||||
/* Moderator actions */
|
||||
if ( isset( $values['topic_create_state'] ) )
|
||||
{
|
||||
if ( $this->canHide() )
|
||||
if( \in_array( 'hide', $values['topic_create_state'] ) )
|
||||
{
|
||||
if( \in_array( 'hide', $values['topic_create_state'] ) )
|
||||
if ( $this->canHide() )
|
||||
{
|
||||
$this->hide( NULL );
|
||||
}
|
||||
/* Only unhide if the topic is not pending approval */
|
||||
elseif( $this->hidden() !== 1 )
|
||||
{
|
||||
$this->unhide( NULL );
|
||||
}
|
||||
}
|
||||
elseif( $this->hidden() and $this->hidden() !== 1 and $this->canUnhide() )
|
||||
{
|
||||
$this->unhide( NULL );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1040,12 +1046,15 @@ class _Topic extends \IPS\Content\Item implements
|
||||
{
|
||||
parent::delete();
|
||||
|
||||
try
|
||||
if( \in_array( $this->archive_status, array( static::ARCHIVE_DONE, static::ARCHIVE_WORKING, static::ARCHIVE_RESTORE ) ) )
|
||||
{
|
||||
\IPS\forums\Topic\ArchivedPost::db()->delete( 'forums_archive_posts', array( 'archive_topic_id=?', $this->tid ) );
|
||||
try
|
||||
{
|
||||
\IPS\forums\Topic\ArchivedPost::db()->delete( 'forums_archive_posts', array( 'archive_topic_id=?', $this->tid ) );
|
||||
}
|
||||
/* catch db exceptions if e.g. if the connection credentials didn't work or if the database doesn't exist anymore */
|
||||
catch ( \IPS\Db\Exception $e ){}
|
||||
}
|
||||
/* catch db exceptions if e.g. if the connection credentials didn't work or if the database doesn't exist anymore */
|
||||
catch ( \IPS\Db\Exception $e ){}
|
||||
|
||||
\IPS\Db::i()->delete( 'forums_question_ratings', array( 'topic=?', $this->tid ) );
|
||||
\IPS\Db::i()->delete( 'forums_answer_ratings', array( 'topic=?', $this->tid ) );
|
||||
@@ -1314,7 +1323,25 @@ class _Topic extends \IPS\Content\Item implements
|
||||
*/
|
||||
public function containerAllowsMemberSolvable()
|
||||
{
|
||||
return $this->container()->forums_bitoptions['bw_enable_answers_member'];
|
||||
return ( $this->containerAllowsSolvable() AND $this->container()->forums_bitoptions['bw_enable_answers_member'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the solve value of a comment
|
||||
*
|
||||
* @param int $commentId The comment ID
|
||||
* @param boolean $value TRUE/FALSE value
|
||||
* @param \IPS\Member $member The member (null for currently logged in member)
|
||||
*/
|
||||
public function toggleSolveComment( $commentId, $value, \IPS\Member $member = NULL )
|
||||
{
|
||||
if ( $value )
|
||||
{
|
||||
$post = \IPS\forums\Topic\Post::load( $commentId );
|
||||
$post->author()->achievementAction( 'forums', 'AnswerMarkedBest', $post );
|
||||
}
|
||||
|
||||
return $this->_toggleSolveComment( $commentId, $value, $member );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1533,21 +1560,34 @@ class _Topic extends \IPS\Content\Item implements
|
||||
* @param array $containerData Basic data about the container. Only includes columns returned by container::basicDataColumns()
|
||||
* @param \IPS\Lang|NULL $lang The language to use, or NULL for the language of the currently logged in member
|
||||
* @param array $options Options to pass to \IPS\Lang::addToStack
|
||||
* @param integer|boolean $count Number of items. If not false, pluralized version of phrase will be used.
|
||||
* @return string
|
||||
*/
|
||||
public static function _definiteArticle( array $containerData = NULL, \IPS\Lang $lang = NULL, $options = array() )
|
||||
public static function _definiteArticle( array $containerData = NULL, \IPS\Lang $lang = NULL, $options = array(), $count = FALSE )
|
||||
{
|
||||
$bitOptions = ( $containerData['forums_bitoptions'] instanceof \IPS\Patterns\Bitwise ) ? $containerData['forums_bitoptions'] : new \IPS\Patterns\Bitwise( array( 'forums_bitoptions' => $containerData['forums_bitoptions'] ), \IPS\forums\Forum::$bitOptions['forums_bitoptions'] );
|
||||
if( $containerData !== NULL )
|
||||
{
|
||||
$bitOptions = ( $containerData['forums_bitoptions'] instanceof \IPS\Patterns\Bitwise ) ? $containerData['forums_bitoptions'] : new \IPS\Patterns\Bitwise( array( 'forums_bitoptions' => $containerData['forums_bitoptions'] ), \IPS\forums\Forum::$bitOptions['forums_bitoptions'] );
|
||||
|
||||
if ( $bitOptions['bw_enable_answers'] )
|
||||
{
|
||||
$lang = $lang ?: \IPS\Member::loggedIn()->language();
|
||||
|
||||
if( $count === TRUE || \is_int( $count ) )
|
||||
{
|
||||
if( \is_int( $count ) )
|
||||
{
|
||||
$options['pluralize'] = array( $count );
|
||||
}
|
||||
|
||||
return $lang->addToStack( '__defart_question_plural', FALSE, $options );
|
||||
}
|
||||
|
||||
return $lang->addToStack( '__defart_question', FALSE, $options );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $bitOptions['bw_enable_answers'] )
|
||||
{
|
||||
$lang = $lang ?: \IPS\Member::loggedIn()->language();
|
||||
return $lang->addToStack( '__defart_question', FALSE, $options );
|
||||
}
|
||||
else
|
||||
{
|
||||
return parent::_definiteArticle( $containerData, $lang, $options );
|
||||
}
|
||||
return parent::_definiteArticle( $containerData, $lang, $options, $count );
|
||||
}
|
||||
|
||||
/* !Sitemap */
|
||||
@@ -2149,8 +2189,6 @@ class _Topic extends \IPS\Content\Item implements
|
||||
|
||||
/* ! Reactions */
|
||||
|
||||
public $reputation = array();
|
||||
|
||||
/**
|
||||
* Reaction type
|
||||
*
|
||||
@@ -2265,4 +2303,34 @@ class _Topic extends \IPS\Content\Item implements
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* We need to force an index so that super long topics load when fetching IDs before running the main query
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
/**
|
||||
* We need to force an index so that super long topics load when fetching IDs before running the main query
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function forceIndexForPaginatedIds()
|
||||
{
|
||||
if ( ! $this->isArchived() )
|
||||
{
|
||||
return 'first_post';
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* WHERE clause for getting items for ACP overview statistics
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function overviewStatisticsWhere()
|
||||
{
|
||||
return array( array( \IPS\Db::i()->in( 'state', array( 'link', 'merged' ), TRUE ) ) );
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user