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\modules\front\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;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
namespace IPS\forums\modules\front\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;
|
||||
@@ -23,13 +23,15 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
*/
|
||||
class _forums extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
protected $themeGroup = NULL;
|
||||
|
||||
/**
|
||||
* Route
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
{
|
||||
{
|
||||
$forum = NULL;
|
||||
try
|
||||
{
|
||||
@@ -49,6 +51,10 @@ class _forums extends \IPS\Dispatcher\Controller
|
||||
*/
|
||||
public function _forum( $forum )
|
||||
{
|
||||
$this->themeGroup = \IPS\Theme::i()->getTemplate( 'forums', 'forums', 'front' );
|
||||
|
||||
$forum->clubCheckRules();
|
||||
|
||||
/* Is simple mode on? If so, redirect to the index page */
|
||||
if ( \IPS\forums\Forum::isSimpleView( $forum ) )
|
||||
{
|
||||
@@ -77,31 +83,40 @@ class _forums extends \IPS\Dispatcher\Controller
|
||||
|
||||
/* Users can see topics posted by other users? */
|
||||
$where = array();
|
||||
if ( !$forum->can_view_others and !\IPS\Member::loggedIn()->modPermission( 'can_read_all_topics' ) )
|
||||
if ( !$forum->memberCanAccessOthersTopics( \IPS\Member::loggedIn() ) )
|
||||
{
|
||||
$where[] = array( 'starter_id = ?', \IPS\Member::loggedIn()->member_id );
|
||||
}
|
||||
|
||||
|
||||
$getReactions = $getFirstComment = $getFollowerCount = (boolean) ( \IPS\forums\Forum::getMemberListView() === 'snippet' );
|
||||
|
||||
/* Init table (it won't show anything until after the password check, but it sets navigation and titles) */
|
||||
$table = new \IPS\Helpers\Table\Content( 'IPS\forums\Topic', $forum->url(), $where, $forum, NULL, 'view', isset( \IPS\Request::i()->rss ) ? FALSE : TRUE, isset( \IPS\Request::i()->rss ) ? FALSE : TRUE );
|
||||
$table = new \IPS\Helpers\Table\Content( 'IPS\forums\Topic', $forum->url(), $where, $forum, NULL, 'view', isset( \IPS\Request::i()->rss ) ? FALSE : TRUE, isset( \IPS\Request::i()->rss ) ? FALSE : TRUE, NULL, $getFirstComment, $getFollowerCount, $getReactions );
|
||||
$table->tableTemplate = array( \IPS\Theme::i()->getTemplate( 'forums', 'forums', 'front' ), 'forumTable' );
|
||||
$table->classes = array( 'cTopicList' );
|
||||
$table->limit = \IPS\Settings::i()->forums_topics_per_page;
|
||||
$table->title = \IPS\Member::loggedIn()->language()->addToStack( ( $forum->forums_bitoptions['bw_enable_answers'] ) ? 'count_questions_in_forum' : 'count_topics_in_forum', FALSE, array( 'pluralize' => array( $forum->topics ) ) );
|
||||
if ( $forum->forums_bitoptions['bw_enable_answers'] )
|
||||
{
|
||||
$table->rowsTemplate = array( \IPS\Theme::i()->getTemplate( 'forums', 'forums', 'front' ), 'questionRow' );
|
||||
$table->rowsTemplate = array( $this->themeGroup, 'questionRow' );
|
||||
}
|
||||
else
|
||||
{
|
||||
$table->rowsTemplate = array( \IPS\Theme::i()->getTemplate( 'forums', 'forums', 'front' ), 'topicRow' );
|
||||
if ( \IPS\forums\Forum::getMemberListView() == 'snippet' )
|
||||
{
|
||||
$table->rowsTemplate = array( $this->themeGroup, 'topicRowSnippet' );
|
||||
}
|
||||
else
|
||||
{
|
||||
$table->rowsTemplate = array( $this->themeGroup, 'topicRow' );
|
||||
}
|
||||
}
|
||||
$table->hover = TRUE;
|
||||
$table->sortOptions['num_replies'] = $table->sortOptions['num_comments'];
|
||||
unset( $table->sortOptions['num_comments'] );
|
||||
|
||||
/* If there's only one forum we actually don't want the nav */
|
||||
if ( \IPS\forums\Forum::theOnlyForum() )
|
||||
/* If there's only one forum and we're not in a club, we actually don't want the nav */
|
||||
if ( \IPS\forums\Forum::theOnlyForum() AND !$forum->club() )
|
||||
{
|
||||
\IPS\Output::i()->breadcrumb = isset( \IPS\Output::i()->breadcrumb['module'] ) ? array( 'module' => \IPS\Output::i()->breadcrumb['module'] ) : array();
|
||||
}
|
||||
@@ -158,6 +173,15 @@ class _forums extends \IPS\Dispatcher\Controller
|
||||
|
||||
$table->sortOptions['question_rating'] = 'forums_topics.question_rating';
|
||||
}
|
||||
else if ( $forum->forums_bitoptions['bw_enable_answers_moderator'] )
|
||||
{
|
||||
$table->filters = array(
|
||||
'solved_topics' => 'topic_answered_pid>0',
|
||||
'unsolved_topics' => 'topic_answered_pid=0',
|
||||
);
|
||||
|
||||
$table->sortOptions['question_rating'] = 'forums_topics.question_rating';
|
||||
}
|
||||
|
||||
/* Are we a moderator? */
|
||||
if( \IPS\forums\Topic::modPermission( 'unhide', NULL, $forum ) )
|
||||
@@ -318,6 +342,14 @@ class _forums extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
/* Show the link */
|
||||
$rssUrl = \IPS\Http\Url::internal( "app=forums&module=forums&controller=forums&id={$forum->_id}&rss=1", 'front', 'forums_rss', array( $forum->name_seo ) );
|
||||
|
||||
if ( \IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
$key = md5( ( \IPS\Member::loggedIn()->members_pass_hash ?: \IPS\Member::loggedIn()->email ) . \IPS\Member::loggedIn()->members_pass_salt );
|
||||
|
||||
$rssUrl = $rssUrl->setQueryString( array( 'member' => \IPS\Member::loggedIn()->member_id , 'key' => $key ) );
|
||||
}
|
||||
|
||||
if ( $forum->forums_bitoptions['bw_enable_answers'] )
|
||||
{
|
||||
$rssTitle = \IPS\Member::loggedIn()->language()->addToStack( 'forum_rss_title_questions', FALSE, array( 'escape' => true, 'sprintf' => array( $forum->_title ) ) );
|
||||
@@ -327,49 +359,17 @@ class _forums extends \IPS\Dispatcher\Controller
|
||||
$rssTitle = \IPS\Member::loggedIn()->language()->addToStack( 'forum_rss_title_topics', FALSE, array( 'escape' => true, 'sprintf' => array( $forum->_title ) ) );
|
||||
}
|
||||
\IPS\Output::i()->rssFeeds[ $rssTitle ] = $rssUrl;
|
||||
|
||||
/* Or actually show RSS feed */
|
||||
if ( isset( \IPS\Request::i()->rss ) )
|
||||
{
|
||||
/* Set the title, either topics or questions */
|
||||
if ( $forum->forums_bitoptions['bw_enable_answers'] )
|
||||
{
|
||||
$rssTitle = sprintf( \IPS\Member::loggedIn()->language()->get( 'forum_rss_title_questions'), \IPS\Member::loggedIn()->language()->get( "forums_forum_{$forum->id}" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$rssTitle = sprintf( \IPS\Member::loggedIn()->language()->get( 'forum_rss_title_topics'), \IPS\Member::loggedIn()->language()->get( "forums_forum_{$forum->id}" ) );
|
||||
}
|
||||
|
||||
/* Don't include "moved" links in the RSS feed, as there is no content to include ( $topic->content() results in BadMethodCallException) */
|
||||
$table->where[] = array( 'forums_topics.moved_to IS NULL' );
|
||||
|
||||
/* Can we view the content (permission_showtopic may allow us to view the list, but not the content)? */
|
||||
$canViewContent = $forum->can('read');
|
||||
|
||||
/* Build the document */
|
||||
$document = \IPS\Xml\Rss::newDocument( $forum->url(), $rssTitle, $rssTitle );
|
||||
foreach ( $table->getRows( array() ) as $topic )
|
||||
{
|
||||
if ( !$topic->hidden() )
|
||||
{
|
||||
try
|
||||
{
|
||||
$document->addItem( $topic->title, $topic->url(), $canViewContent ? $topic->content() : NULL, \IPS\DateTime::ts( $topic->start_date ), $topic->tid );
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
}
|
||||
}
|
||||
|
||||
/* Display - note application/rss+xml is not a registered IANA mime-type so we need to stick with text/xml for RSS */
|
||||
\IPS\Output::i()->sendOutput( $document->asXML(), 200, 'text/xml' );
|
||||
}
|
||||
}
|
||||
|
||||
/* Online User Location */
|
||||
$permissions = $forum->permissions();
|
||||
\IPS\Session::i()->setLocation( $forum->url(), explode( ",", $permissions['perm_view'] ), 'loc_forums_viewing_forum', array( "forums_forum_{$forum->id}" => TRUE ) );
|
||||
|
||||
|
||||
if ( \IPS\forums\Forum::getMemberView() === 'grid' )
|
||||
{
|
||||
\IPS\forums\Forum::populateFollowerCounts( $forum );
|
||||
}
|
||||
|
||||
/* Show Forum */
|
||||
if ( isset( \IPS\Request::i()->advancedSearchForm ) )
|
||||
{
|
||||
@@ -408,8 +408,8 @@ class _forums extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
$forumOutput = (string) $table;
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'forums' )->forumDisplay( $forum, $forumOutput );
|
||||
|
||||
\IPS\Output::i()->output = $this->themeGroup->forumDisplay( $forum, $forumOutput );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -465,20 +465,24 @@ class _forums extends \IPS\Dispatcher\Controller
|
||||
$form = \IPS\forums\Topic::create( $forum );
|
||||
|
||||
$hasModOptions = false;
|
||||
|
||||
|
||||
$canHide = ( \IPS\Member::loggedIn()->group['g_hide_own_posts'] == '1' or \in_array( 'IPS\forums\Topics', explode( ',', \IPS\Member::loggedIn()->group['g_hide_own_posts'] ) ) );
|
||||
if ( \IPS\forums\Topic::modPermission( 'lock', NULL, $forum ) or
|
||||
\IPS\forums\Topic::modPermission( 'pin', NULL, $forum ) or
|
||||
\IPS\forums\Topic::modPermission( 'hide', NULL, $forum ) or
|
||||
$canHide or
|
||||
\IPS\forums\Topic::modPermission( 'feature', NULL, $forum ) )
|
||||
{
|
||||
$hasModOptions = TRUE;
|
||||
}
|
||||
|
||||
$formTemplate = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'submit', 'forums' ) ), 'createTopicForm' ), $forum, $hasModOptions, NULL );
|
||||
$formTemplate = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'submit', 'forums' ), 'createTopicForm' ), $forum, $hasModOptions, NULL );
|
||||
|
||||
if ( \IPS\forums\Topic::moderateNewItems( \IPS\Member::loggedIn(), $forum ) )
|
||||
$guestPostBeforeRegister = ( !\IPS\Member::loggedIn()->member_id ) ? !$forum->can( 'add', \IPS\Member::loggedIn(), FALSE ) : NULL;
|
||||
$modQueued = \IPS\forums\Topic::moderateNewItems( \IPS\Member::loggedIn(), $forum, $guestPostBeforeRegister );
|
||||
if ( $guestPostBeforeRegister or $modQueued )
|
||||
{
|
||||
$formTemplate = \IPS\Theme::i()->getTemplate( 'forms', 'core' )->modQueueMessage( \IPS\Member::loggedIn()->warnings( 5, NULL, 'mq' ), \IPS\Member::loggedIn()->mod_posts ) . $formTemplate;
|
||||
$formTemplate = \IPS\Theme::i()->getTemplate( 'forms', 'core' )->postingInformation( $guestPostBeforeRegister, $modQueued, TRUE ) . $formTemplate;
|
||||
}
|
||||
|
||||
$title = $forum->forums_bitoptions['bw_enable_answers'] ? 'ask_new_question' : 'create_new_topic';
|
||||
@@ -564,6 +568,27 @@ class _forums extends \IPS\Dispatcher\Controller
|
||||
\IPS\Output::i()->error( 'no_module_permission', '2F173/3', 403, 'no_module_permission_guest' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the viewing method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setMethod()
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
$method = ( isset( \IPS\Request::i()->method ) ) ? \IPS\Request::i()->method : \IPS\Settings::i()->forums_default_view;
|
||||
|
||||
\IPS\Request::i()->setCookie( 'forum_list_view', $method, ( new \IPS\DateTime )->add( new \DateInterval( 'P1Y' ) ) );
|
||||
|
||||
if ( \IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
\IPS\Db::i()->replace( 'forums_view_method', array( 'member_id' => \IPS\Member::loggedIn()->member_id, 'method' => $method, 'type' => 'list' ) );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\forums\Forum::load( \IPS\Request::i()->id )->url() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the forum selector for creating a topic outside of specific forum
|
||||
@@ -603,4 +628,4 @@ class _forums extends \IPS\Dispatcher\Controller
|
||||
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack( 'select_forum' ) );
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'forums' )->forumSelector( $form );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@
|
||||
namespace IPS\forums\modules\front\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;
|
||||
@@ -116,7 +116,7 @@ class _index extends \IPS\Dispatcher\Controller
|
||||
if ( \IPS\forums\Forum::isSimpleView() )
|
||||
{
|
||||
$where = array( 'container' => array( array( 'forums_forums.password IS NULL' ) ) );
|
||||
if ( !\IPS\Settings::i()->club_nodes_in_apps )
|
||||
if ( !\IPS\Settings::i()->club_nodes_in_apps OR !\IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'core', 'clubs', 'front' ) ) )
|
||||
{
|
||||
$where['container'][] = array( 'forums_forums.club_id IS NULL' );
|
||||
}
|
||||
@@ -134,7 +134,7 @@ class _index extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
|
||||
/* Inline forum IDs? */
|
||||
if ( count( $ids ) )
|
||||
if ( \count( $ids ) )
|
||||
{
|
||||
foreach( $ids as $id )
|
||||
{
|
||||
@@ -142,7 +142,7 @@ class _index extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
if ( $id == 'clubs' )
|
||||
{
|
||||
$parentIds['clubs'] = 'clubs';
|
||||
$map['clubs'] = 'clubs';
|
||||
foreach ( \IPS\forums\Forum::clubNodes() as $child )
|
||||
{
|
||||
$forumIds[ $child->id ] = $child->id;
|
||||
@@ -160,7 +160,7 @@ class _index extends \IPS\Dispatcher\Controller
|
||||
catch( \Exception $ex ) { }
|
||||
}
|
||||
|
||||
if ( count( $forumIds ) )
|
||||
if ( \count( $forumIds ) )
|
||||
{
|
||||
$where['container'][] = array( \IPS\Db::i()->in( 'forums_forums.id', array_filter( $forumIds ) ) );
|
||||
}
|
||||
@@ -181,7 +181,7 @@ class _index extends \IPS\Dispatcher\Controller
|
||||
|
||||
if( \IPS\forums\Forum::theOnlyForum() === NULL )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['contextual'] = \IPS\Theme::i()->getTemplate( 'index' )->simplifiedViewSidebar( $forumIds );
|
||||
\IPS\Output::i()->sidebar['contextual'] = \IPS\Theme::i()->getTemplate( 'index' )->simplifiedViewSidebar( $forumIds, $map );
|
||||
}
|
||||
|
||||
if ( isset( $where['container'] ) )
|
||||
@@ -192,7 +192,12 @@ class _index extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Standard view */
|
||||
/* Merge in follower counts to the immediately visible forums */
|
||||
if ( \IPS\forums\Forum::getMemberView() === 'grid' )
|
||||
{
|
||||
\IPS\forums\Forum::populateFollowerCounts();
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'index' )->index();
|
||||
}
|
||||
}
|
||||
@@ -212,7 +217,7 @@ class _index extends \IPS\Dispatcher\Controller
|
||||
|
||||
if ( \IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
\IPS\Db::i()->replace( 'forums_view_method', array( 'member_id' => \IPS\Member::loggedIn()->member_id, 'method' => $method ) );
|
||||
\IPS\Db::i()->replace( 'forums_view_method', array( 'member_id' => \IPS\Member::loggedIn()->member_id, 'method' => $method, 'type' => 'index' ) );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=forums&module=forums&controller=index', 'front', 'forums' ) );
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
namespace IPS\forums\modules\front\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;
|
||||
@@ -42,21 +42,14 @@ class _topic extends \IPS\Content\Controller
|
||||
/**
|
||||
* View Topic
|
||||
*
|
||||
* @return void
|
||||
* @return void
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function manage()
|
||||
{
|
||||
/* Load topic */
|
||||
$topic = parent::manage();
|
||||
\IPS\Member::loggedIn()->language()->words['submit_comment'] = \IPS\Member::loggedIn()->language()->addToStack( 'submit_reply', FALSE );
|
||||
|
||||
/* If there's only one forum we actually don't want the nav */
|
||||
if ( \IPS\forums\Forum::theOnlyForum() or \IPS\forums\Forum::isSimpleView() )
|
||||
{
|
||||
$topicBreadcrumb = array_pop( \IPS\Output::i()->breadcrumb );
|
||||
\IPS\Output::i()->breadcrumb = isset( \IPS\Output::i()->breadcrumb['module'] ) ? array( 'module' => \IPS\Output::i()->breadcrumb['module'] ) : array();
|
||||
\IPS\Output::i()->breadcrumb[] = $topicBreadcrumb;
|
||||
}
|
||||
|
||||
/* If it failed, it might be because we want a password */
|
||||
if ( $topic === NULL )
|
||||
@@ -91,6 +84,16 @@ class _topic extends \IPS\Content\Controller
|
||||
}
|
||||
}
|
||||
|
||||
$topic->container()->clubCheckRules();
|
||||
|
||||
/* If there's only one forum and we're not in a club, we actually don't want the nav */
|
||||
if ( !$topic->container()->club() AND ( \IPS\forums\Forum::theOnlyForum() or \IPS\forums\Forum::isSimpleView() ) )
|
||||
{
|
||||
$topicBreadcrumb = array_pop( \IPS\Output::i()->breadcrumb );
|
||||
\IPS\Output::i()->breadcrumb = isset( \IPS\Output::i()->breadcrumb['module'] ) ? array( 'module' => \IPS\Output::i()->breadcrumb['module'] ) : array();
|
||||
\IPS\Output::i()->breadcrumb[] = $topicBreadcrumb;
|
||||
}
|
||||
|
||||
/* Legacy findpost redirect */
|
||||
if ( \IPS\Request::i()->findpost )
|
||||
{
|
||||
@@ -110,6 +113,18 @@ class _topic extends \IPS\Content\Controller
|
||||
$this->_doViewCheck();
|
||||
}
|
||||
|
||||
/* If the topic is locked and scheduled to unlock already, or vice versa, do that */
|
||||
if( $topic->locked() && $topic->topic_open_time && $topic->topic_open_time < time() )
|
||||
{
|
||||
$topic->state = 'open';
|
||||
$topic->save();
|
||||
}
|
||||
elseif( !$topic->locked() && $topic->topic_close_time && $topic->topic_close_time < time() )
|
||||
{
|
||||
$topic->state = 'closed';
|
||||
$topic->save();
|
||||
}
|
||||
|
||||
/* If this is an AJAX request fetch the comment form now. The HTML will be cached so calling here and then again in the template has no overhead
|
||||
and this is necessary if you entered into a topic with &queued_posts=1, approve the posts, then try to reply. Otherwise, clicking into the
|
||||
editor produces an error when the getUploader=1 call occurs, and submitting a reply results in an error. */
|
||||
@@ -127,33 +142,51 @@ class _topic extends \IPS\Content\Controller
|
||||
{
|
||||
$postClass = '\IPS\forums\Topic\ArchivedPost';
|
||||
}
|
||||
|
||||
$firstPost = $postClass::load( $topic->topic_firstpost );
|
||||
|
||||
$topicOverview = array( 'firstPost' => array( $topic->isQuestion() ? 'question_mainTab' : 'first_post', $firstPost ) );
|
||||
|
||||
if ( $topic->posts > 1 )
|
||||
/* If this topic was moved or merged, load that up in case someone loads the preview after that happens but before they reload the page */
|
||||
$previewTopic = $topic;
|
||||
if ( \in_array( $topic->state, array( 'merged', 'link' ) ) )
|
||||
{
|
||||
$latestPost = $topic->comments( 1, 0, 'date', 'DESC' );
|
||||
$topicOverview['latestPost'] = array( $topic->isQuestion() ? 'latest_answer' : 'latest_post', $latestPost );
|
||||
|
||||
$timeLastRead = $topic->timeLastRead();
|
||||
if ( $timeLastRead instanceof \IPS\DateTime AND $topic->unread() !== 0 )
|
||||
$movedTo = explode( '&', $topic->moved_to );
|
||||
|
||||
try
|
||||
{
|
||||
$firstUnread = $topic->comments( 1, NULL, 'date', 'asc', NULL, NULL, $timeLastRead );
|
||||
$previewTopic = \IPS\forums\Topic::loadAndCheckPerms( $movedTo[0] );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
{
|
||||
/* I can't help you */
|
||||
\IPS\Output::i()->error( 'node_error', '2F173/Q', 404, '' );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$firstPost = $postClass::load( $previewTopic->topic_firstpost );
|
||||
|
||||
$topicOverview = array( 'firstPost' => array( $previewTopic->isQuestion() ? 'question_mainTab' : 'first_post', $firstPost ) );
|
||||
|
||||
if ( $previewTopic->posts > 1 )
|
||||
{
|
||||
$latestPost = $previewTopic->comments( 1, 0, 'date', 'DESC' );
|
||||
$topicOverview['latestPost'] = array( $previewTopic->isQuestion() ? 'latest_answer' : 'latest_post', $latestPost );
|
||||
|
||||
$timeLastRead = $previewTopic->timeLastRead();
|
||||
if ( $timeLastRead instanceof \IPS\DateTime AND $previewTopic->unread() !== 0 )
|
||||
{
|
||||
$firstUnread = $previewTopic->comments( 1, NULL, 'date', 'asc', NULL, NULL, $timeLastRead );
|
||||
if( $firstUnread instanceof \IPS\forums\Topic\Post AND $firstUnread->date !== $latestPost->date AND $firstUnread->date !== $firstPost->date )
|
||||
{
|
||||
$topicOverview['firstUnread'] = array( 'first_unread_post_hover', $topic->comments( 1, NULL, 'date', 'asc', NULL, NULL, $timeLastRead ) );
|
||||
$topicOverview['firstUnread'] = array( 'first_unread_post_hover', $previewTopic->comments( 1, NULL, 'date', 'asc', NULL, NULL, $timeLastRead ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $topic->isQuestion() and $topic->topic_answered_pid )
|
||||
if ( $previewTopic->isQuestion() and $previewTopic->topic_answered_pid )
|
||||
{
|
||||
$topicOverview['bestAnswer'] = array( 'best_answer_post', \IPS\forums\Topic\Post::load( $topic->topic_answered_pid ) );
|
||||
$topicOverview['bestAnswer'] = array( 'best_answer_post', \IPS\forums\Topic\Post::load( $previewTopic->topic_answered_pid ) );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'forums' )->topicHover( $topic, $topicOverview ) );
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'forums' )->topicHover( $previewTopic, $topicOverview ) );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -201,7 +234,7 @@ class _topic extends \IPS\Content\Controller
|
||||
}
|
||||
catch ( \UnderflowException $e ) { }
|
||||
|
||||
$page = ( isset( \IPS\Request::i()->page ) ) ? intval( \IPS\Request::i()->page ) : 1;
|
||||
$page = ( isset( \IPS\Request::i()->page ) ) ? \intval( \IPS\Request::i()->page ) : 1;
|
||||
|
||||
if( $page < 1 )
|
||||
{
|
||||
@@ -230,18 +263,13 @@ class _topic extends \IPS\Content\Controller
|
||||
$current = current( $comments );
|
||||
reset( $comments );
|
||||
|
||||
if( !count( $comments ) AND !$topic->isQuestion() )
|
||||
if( !\count( $comments ) AND !$topic->isQuestion() )
|
||||
{
|
||||
\IPS\Output::i()->error( 'no_posts_returned', '2F173/L', 404, '' );
|
||||
}
|
||||
|
||||
/* On pages 2 and more, it will show the first post on that page, and that is fine as the title has - Page 2 in it meaning its a different page */
|
||||
$metaDescription = $topic->metaDescription( isset( $_SESSION['_findComment'] ) ? NULL : ( $topic->isQuestion() ? $question->content() : $current->content() ) );
|
||||
|
||||
\IPS\Output::i()->metaTags['description'] = \IPS\Output::i()->metaTags['og:description'] = $metaDescription;
|
||||
|
||||
/* Mark read */
|
||||
if( !$topic->isLastPage() )
|
||||
if( !$topic->isLastPage() AND $topic->unread() !== 0 )
|
||||
{
|
||||
$maxTime = 0;
|
||||
|
||||
@@ -250,7 +278,10 @@ class _topic extends \IPS\Content\Controller
|
||||
$maxTime = ( $comment->mapped('date') > $maxTime ) ? $comment->mapped('date') : $maxTime;
|
||||
}
|
||||
|
||||
$topic->markRead( NULL, $maxTime );
|
||||
if( $topic->timeLastRead() === NULL OR $maxTime > $topic->timeLastRead()->getTimestamp() )
|
||||
{
|
||||
$topic->markRead( NULL, $maxTime );
|
||||
}
|
||||
}
|
||||
|
||||
$votes = array();
|
||||
@@ -267,79 +298,63 @@ class _topic extends \IPS\Content\Controller
|
||||
{
|
||||
\IPS\Member::loggedIn()->language()->words[ 'topic__comment_placeholder' ] = \IPS\Member::loggedIn()->language()->addToStack( 'question__comment_placeholder', FALSE );
|
||||
}
|
||||
|
||||
|
||||
/* Online User Location */
|
||||
\IPS\Session::i()->setLocation( $topic->url(), ( $topic->container()->password or !$topic->container()->can_view_others or $topic->container()->min_posts_view ) ? 0 : $topic->onlineListPermissions(), 'loc_forums_viewing_topic', array( $topic->title => FALSE ) );
|
||||
|
||||
/* Next unread */
|
||||
try
|
||||
{
|
||||
$nextUnread = $topic->nextUnread();
|
||||
$nextUnread = $topic->containerHasUnread();
|
||||
}
|
||||
catch( \Exception $e )
|
||||
{
|
||||
$nextUnread = NULL;
|
||||
}
|
||||
|
||||
/* Add Json-LD */
|
||||
\IPS\Output::i()->jsonLd['topic'] = array(
|
||||
'@context' => "http://schema.org",
|
||||
'@type' => $topic->isQuestion() ? 'Question' : 'DiscussionForumPosting',
|
||||
'url' => (string) $topic->url(),
|
||||
'discussionUrl' => (string) $topic->url(),
|
||||
'name' => $topic->mapped('title'),
|
||||
'headline' => $topic->mapped('title'),
|
||||
'text' => strip_tags( $topic->isQuestion() ? $question->truncated() : $current->truncated() ),
|
||||
'dateCreated' => \IPS\DateTime::ts( $topic->start_date )->format( \IPS\DateTime::ISO8601 ),
|
||||
'datePublished' => \IPS\DateTime::ts( $topic->start_date )->format( \IPS\DateTime::ISO8601 ),
|
||||
'pageStart' => 1,
|
||||
'pageEnd' => $topic->commentPageCount(),
|
||||
/* Image is required, but we don't have "topic images", so we'll use topic starter's profile photo for now */
|
||||
'image' => (string) \IPS\Http\Url::external( \IPS\Member::load( $topic->starter_id )->get_photo() )->setScheme( \IPS\Request::i()->isSecure() ? 'https' : 'http' ),
|
||||
'author' => array(
|
||||
'@type' => 'Person',
|
||||
'name' => $topic->starter_name ?: \IPS\Member::load( $topic->starter_id )->name,
|
||||
'image' => \IPS\Member::load( $topic->starter_id )->get_photo()
|
||||
),
|
||||
'interactionStatistic' => array(
|
||||
array(
|
||||
'@type' => 'InteractionCounter',
|
||||
'interactionType' => "http://schema.org/ViewAction",
|
||||
'userInteractionCount' => $topic->views
|
||||
),
|
||||
array(
|
||||
'@type' => 'InteractionCounter',
|
||||
'interactionType' => "http://schema.org/CommentAction",
|
||||
'userInteractionCount' => $topic->posts
|
||||
),
|
||||
array(
|
||||
'@type' => 'InteractionCounter',
|
||||
'interactionType' => "http://schema.org/FollowAction",
|
||||
'userInteractionCount' => \IPS\forums\Topic::containerFollowerCount( $topic->container() )
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
/* Are ratings allowed? */
|
||||
if( !$topic->isArchived() AND $topic->container()->forum_allow_rating AND $topic->averageRating() )
|
||||
/* Sidebar? */
|
||||
if ( $topic->showSummaryOnDesktop() == 'sidebar' )
|
||||
{
|
||||
\IPS\Output::i()->jsonLd['topic']['aggregateRating'] = array(
|
||||
'@type' => 'AggregateRating',
|
||||
'ratingValue' => $topic->averageRating(),
|
||||
'ratingCount' => $topic->numberOfRatings(),
|
||||
);
|
||||
\IPS\Output::i()->sidebar['contextual'] = \IPS\Theme::i()->getTemplate( 'topics' )->activity( $topic, 'sidebar' );
|
||||
}
|
||||
|
||||
/* Add Json-LD */
|
||||
$isQuestion = ( $topic->isQuestion() or $topic->isSolved() );
|
||||
\IPS\Output::i()->jsonLd['topic'] = array(
|
||||
'@context' => "http://schema.org",
|
||||
'@type' => $isQuestion ? 'Question' : 'DiscussionForumPosting',
|
||||
'@id' => (string) $topic->url(),
|
||||
'isPartOf' => array(
|
||||
'@id' => \IPS\Settings::i()->base_url . '#website'
|
||||
),
|
||||
'publisher' => array(
|
||||
'@id' => \IPS\Settings::i()->base_url . '#organization'
|
||||
),
|
||||
'url' => (string) $topic->url(),
|
||||
'discussionUrl' => (string) $topic->url(),
|
||||
'mainEntityOfPage' => array(
|
||||
'@type' => 'WebPage',
|
||||
'@id' => (string) $topic->url()
|
||||
)
|
||||
);
|
||||
|
||||
/* Do we have a real author */
|
||||
if( $topic->starter_id )
|
||||
{
|
||||
\IPS\Output::i()->jsonLd['topic']['author']['url'] = (string) \IPS\Member::load( $topic->starter_id )->url();
|
||||
\IPS\Output::i()->jsonLd['topic']['author']['url'] = (string) \IPS\Member::load( $topic->starter_id )->url();
|
||||
|
||||
\IPS\Output::i()->jsonLd['topic']['publisher']['member'] = array(
|
||||
'@type' => "Person",
|
||||
'name' => \IPS\Member::load( $topic->starter_id )->name,
|
||||
'image' => (string) \IPS\Member::load( $topic->starter_id )->get_photo(),
|
||||
'url' => (string) \IPS\Member::load( $topic->starter_id )->url(),
|
||||
);
|
||||
}
|
||||
|
||||
if( $topic->isQuestion() )
|
||||
if( $isQuestion )
|
||||
{
|
||||
\IPS\Output::i()->jsonLd['topic']['answerCount'] = $topic->posts ? $topic->posts - 1 : 0;
|
||||
\IPS\Output::i()->jsonLd['topic']['upvoteCount'] = intval( $topic->question_rating );
|
||||
\IPS\Output::i()->jsonLd['topic']['upvoteCount'] = \intval( $topic->question_rating );
|
||||
|
||||
if( $topic->topic_answered_pid )
|
||||
{
|
||||
@@ -349,9 +364,8 @@ class _topic extends \IPS\Content\Controller
|
||||
|
||||
\IPS\Output::i()->jsonLd['topic']['acceptedAnswer'] = array(
|
||||
'@type' => 'Answer',
|
||||
'text' => strip_tags( $answer->truncated() ),
|
||||
'text' => $answer->truncated( TRUE, NULL ),
|
||||
'url' => (string) $answer->url(),
|
||||
'mainEntityOfPage' => (string) $topic->url(),
|
||||
'dateCreated' => \IPS\DateTime::ts( $answer->post_date )->format( \IPS\DateTime::ISO8601 ),
|
||||
'upvoteCount' => $answer->post_field_int,
|
||||
'author' => array(
|
||||
@@ -376,17 +390,24 @@ class _topic extends \IPS\Content\Controller
|
||||
$i = 0;
|
||||
foreach( $comments as $comment )
|
||||
{
|
||||
// Don't include the first post as a "comment"
|
||||
if( $comment->pid == $topic->topic_firstpost )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$url = $topic->url()->setPage( 'page', \IPS\Request::i()->page );
|
||||
\IPS\Output::i()->jsonLd['topic']['comment'][ $i ] = array(
|
||||
'@type' => 'Comment',
|
||||
'url' => (string) $comment->url(),
|
||||
'@id' => (string) $url->setFragment( 'comment-' . $comment->pid ),
|
||||
'url' => (string) $url->setFragment( 'comment-' . $comment->pid ),
|
||||
'author' => array(
|
||||
'@type' => 'Person',
|
||||
'name' => $comment->author_name ?: \IPS\Member::load( $comment->author_id )->name,
|
||||
'image' => \IPS\Member::load( $comment->author_id )->get_photo()
|
||||
),
|
||||
'dateCreated' => \IPS\DateTime::ts( $comment->post_date )->format( \IPS\DateTime::ISO8601 ),
|
||||
'text' => strip_tags( $comment->truncated() ),
|
||||
'mainEntityOfPage' => (string) $topic->url(),
|
||||
'text' => $comment->truncated( TRUE, NULL ),
|
||||
);
|
||||
|
||||
if( $comment->author_id )
|
||||
@@ -398,7 +419,43 @@ class _topic extends \IPS\Content\Controller
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Output::i()->jsonLd['topic'] = array_merge_recursive( array(
|
||||
'name' => $topic->mapped('title'),
|
||||
'headline' => $topic->mapped('title'),
|
||||
'text' => $topic->isQuestion() ? $question->truncated( TRUE, NULL ) : $current->truncated( TRUE, NULL ),
|
||||
'dateCreated' => \IPS\DateTime::ts( $topic->start_date )->format( \IPS\DateTime::ISO8601 ),
|
||||
'datePublished' => \IPS\DateTime::ts( $topic->start_date )->format( \IPS\DateTime::ISO8601 ),
|
||||
'dateModified' => \IPS\DateTime::ts( $topic->last_post )->format( \IPS\DateTime::ISO8601 ),
|
||||
'pageStart' => 1,
|
||||
'pageEnd' => $topic->commentPageCount(),
|
||||
/* Image is required, but we don't have "topic images", so we'll use topic starter's profile photo for now */
|
||||
'image' => (string) \IPS\Member::load( $topic->starter_id )->get_photo(),
|
||||
'author' => array(
|
||||
'@type' => 'Person',
|
||||
'name' => $topic->starter_name ?: \IPS\Member::load( $topic->starter_id )->name,
|
||||
'image' => \IPS\Member::load( $topic->starter_id )->get_photo()
|
||||
),
|
||||
'interactionStatistic' => array(
|
||||
array(
|
||||
'@type' => 'InteractionCounter',
|
||||
'interactionType' => "http://schema.org/ViewAction",
|
||||
'userInteractionCount' => $topic->views
|
||||
),
|
||||
array(
|
||||
'@type' => 'InteractionCounter',
|
||||
'interactionType' => "http://schema.org/CommentAction",
|
||||
'userInteractionCount' => $topic->posts - 1 // We subtract one to account for the "first post"
|
||||
),
|
||||
array(
|
||||
'@type' => 'InteractionCounter',
|
||||
'interactionType' => "http://schema.org/FollowAction",
|
||||
'userInteractionCount' => $topic->followersCount()
|
||||
),
|
||||
)
|
||||
), \IPS\Output::i()->jsonLd['topic'] );
|
||||
|
||||
/* Show topic */
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'topics.css', 'forums' ) );
|
||||
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'topics' )->topic( $topic, $comments, $question, $votes, $nextUnread, $pagination, $topicVotes );
|
||||
}
|
||||
|
||||
@@ -474,9 +531,8 @@ class _topic extends \IPS\Content\Controller
|
||||
$formElements = $class::formElements( $topic, $forum );
|
||||
|
||||
$hasModOptions = FALSE;
|
||||
|
||||
/* We used to just check against the ability to lock, however this may not be enough - a moderator could pin, for example, but not lock */
|
||||
foreach( array( 'lock', 'pin', 'hide', 'feature' ) AS $perm )
|
||||
foreach( array( 'lock', 'pin', 'feature' ) AS $perm )
|
||||
{
|
||||
if ( $class::modPermission( $perm, NULL, $forum ) )
|
||||
{
|
||||
@@ -484,19 +540,33 @@ class _topic extends \IPS\Content\Controller
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( $topic->canHide() )
|
||||
{
|
||||
$hasModOptions = TRUE;
|
||||
}
|
||||
|
||||
$form = $topic->buildEditForm();
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
if ( $topic->canEdit() )
|
||||
{
|
||||
{
|
||||
$titleField = $topic::$databaseColumnMap['title'];
|
||||
$oldTitle = $topic->$titleField;
|
||||
|
||||
$topic->processForm( $values );
|
||||
$topic->save();
|
||||
$topic->processAfterEdit( $values );
|
||||
|
||||
/* Moderator log */
|
||||
\IPS\Session::i()->modLog( 'modlog__item_edit', array( $topic::$title => FALSE, $topic->url()->__toString() => FALSE, $topic::$title => TRUE, $topic->mapped( 'title' ) => FALSE ), $topic );
|
||||
$toLog = array( $topic::$title => FALSE, $topic->url()->__toString() => FALSE, $topic::$title => TRUE, $topic->mapped( 'title' ) => FALSE );
|
||||
|
||||
if ( $oldTitle != $topic->$titleField )
|
||||
{
|
||||
$toLog[ $oldTitle ] = false;
|
||||
}
|
||||
|
||||
\IPS\Session::i()->modLog( 'modlog__item_edit', $toLog, $topic );
|
||||
|
||||
\IPS\Output::i()->redirect( $topic->url() );
|
||||
}
|
||||
@@ -506,7 +576,7 @@ class _topic extends \IPS\Content\Controller
|
||||
}
|
||||
}
|
||||
|
||||
$formTemplate = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'submit', 'forums' ) ), 'createTopicForm' ), $forum, $hasModOptions, $topic );
|
||||
$formTemplate = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'submit', 'forums' ), 'createTopicForm' ), $forum, $hasModOptions, $topic );
|
||||
|
||||
$title = $forum->forums_bitoptions['bw_enable_answers'] ? 'edit_question' : 'edit_topic';
|
||||
|
||||
@@ -614,7 +684,7 @@ class _topic extends \IPS\Content\Controller
|
||||
}
|
||||
|
||||
/* Voting up or down? */
|
||||
$rating = intval( \IPS\Request::i()->rating );
|
||||
$rating = \intval( \IPS\Request::i()->rating );
|
||||
if ( $rating !== 1 and $rating !== -1 )
|
||||
{
|
||||
\IPS\Output::i()->error( 'form_bad_value', '2F173/A', 403, '' );
|
||||
@@ -626,13 +696,15 @@ class _topic extends \IPS\Content\Controller
|
||||
\IPS\Output::i()->error( 'no_module_permission', '2F173/9', 403, '' );
|
||||
}
|
||||
|
||||
/* If we have an existing vote, we're just undoing that, otherwise, insert the vote */
|
||||
/* If we have an existing vote, remove it first */
|
||||
$ratings = $question->votes();
|
||||
if ( isset( $ratings[ \IPS\Member::loggedIn()->member_id ] ) )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'forums_question_ratings', array( 'topic=? AND member=?', $question->tid, \IPS\Member::loggedIn()->member_id ) );
|
||||
\IPS\Db::i()->delete( 'forums_question_ratings', array( 'topic=? AND `member`=?', $question->tid, \IPS\Member::loggedIn()->member_id ) );
|
||||
}
|
||||
else
|
||||
|
||||
/* Revoting for the same thing you already voted for should remove your vote - so don't insert if we voted for the same thing we did before */
|
||||
if ( !isset( $ratings[ \IPS\Member::loggedIn()->member_id ] ) OR $ratings[ \IPS\Member::loggedIn()->member_id ] != $rating )
|
||||
{
|
||||
\IPS\Db::i()->insert( 'forums_question_ratings', array(
|
||||
'topic' => $question->tid,
|
||||
@@ -675,19 +747,19 @@ class _topic extends \IPS\Content\Controller
|
||||
\IPS\Output::i()->error( 'no_module_permission', '2F173/5', 403, '' );
|
||||
}
|
||||
|
||||
$rating = intval( \IPS\Request::i()->rating );
|
||||
$rating = \intval( \IPS\Request::i()->rating );
|
||||
if ( $rating !== 1 and $rating !== -1 )
|
||||
{
|
||||
\IPS\Output::i()->error( 'form_bad_value', '2F173/6', 403, '' );
|
||||
}
|
||||
|
||||
/* Have we already rated ? */
|
||||
try
|
||||
{
|
||||
$rating = \IPS\Db::i()->select( '*', 'forums_answer_ratings', array( 'topic=? AND post=? AND member=?', $question->tid, $answer->pid, \IPS\Member::loggedIn()->member_id ) )->first();
|
||||
\IPS\Db::i()->delete( 'forums_answer_ratings', array( 'topic=? AND post=? AND member=?', $question->tid, $answer->pid, \IPS\Member::loggedIn()->member_id ) );
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
$ratings = $question->answerVotes( \IPS\Member::loggedIn() );
|
||||
|
||||
/* If we've already rated the answer, remove that first */
|
||||
\IPS\Db::i()->delete( 'forums_answer_ratings', array( 'topic=? AND post=? AND `member`=?', $question->tid, $answer->pid, \IPS\Member::loggedIn()->member_id ) );
|
||||
|
||||
/* Revoting for the same thing you already voted for should remove your vote - so don't insert if we voted for the same thing we did before */
|
||||
if ( !isset( $ratings[ $answer->pid ] ) OR $ratings[ $answer->pid ] != $rating )
|
||||
{
|
||||
\IPS\Db::i()->insert( 'forums_answer_ratings', array(
|
||||
'post' => $answer->pid,
|
||||
@@ -723,12 +795,13 @@ class _topic extends \IPS\Content\Controller
|
||||
try
|
||||
{
|
||||
$topic = \IPS\forums\Topic::loadAndCheckPerms( \IPS\Request::i()->id );
|
||||
$post = \IPS\forums\Topic\Post::loadAndCheckPerms( \IPS\Request::i()->answer );
|
||||
|
||||
if ( !$topic->canSetBestAnswer() )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
|
||||
$post = \IPS\forums\Topic\Post::loadAndCheckPerms( \IPS\Request::i()->answer );
|
||||
if ( $post->item() != $topic )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
@@ -738,31 +811,23 @@ class _topic extends \IPS\Content\Controller
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2F173/7', 404, '' );
|
||||
}
|
||||
|
||||
if ( $topic->topic_answered_pid )
|
||||
|
||||
$topic->toggleSolveComment( $post->pid, TRUE );
|
||||
|
||||
if( $post->author()->member_id != \IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
try
|
||||
{
|
||||
$oldBestAnswer = \IPS\forums\Topic\Post::load( $topic->topic_answered_pid );
|
||||
$oldBestAnswer->post_bwoptions['best_answer'] = FALSE;
|
||||
$oldBestAnswer->save();
|
||||
}
|
||||
catch ( \Exception $e ) {}
|
||||
$notification = new \IPS\Notification( \IPS\Application::load( 'core' ), 'best_answer', $topic, array( $post ), array( $post->author()->member_id ) );
|
||||
$notification->recipients->attach( $post->author() );
|
||||
$notification->send();
|
||||
}
|
||||
|
||||
$post->post_bwoptions['best_answer'] = TRUE;
|
||||
$post->save();
|
||||
|
||||
$topic->topic_answered_pid = $post->pid;
|
||||
$topic->save();
|
||||
|
||||
/* Log */
|
||||
if ( \IPS\Member::loggedIn()->modPermission('can_set_best_answer') )
|
||||
{
|
||||
\IPS\Session::i()->modLog( 'modlog__best_answer_set', array( $post->pid => FALSE ), $topic );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( $topic->url() );
|
||||
\IPS\Output::i()->redirect( $post->url() );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -777,6 +842,8 @@ class _topic extends \IPS\Content\Controller
|
||||
try
|
||||
{
|
||||
$topic = \IPS\forums\Topic::loadAndCheckPerms( \IPS\Request::i()->id );
|
||||
$post = \IPS\forums\Topic\Post::loadAndCheckPerms( \IPS\Request::i()->answer );
|
||||
|
||||
if ( !$topic->canSetBestAnswer() )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
@@ -786,14 +853,17 @@ class _topic extends \IPS\Content\Controller
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2F173/G', 404, '' );
|
||||
}
|
||||
|
||||
|
||||
if ( $post->item() != $topic )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
|
||||
if ( $topic->topic_answered_pid )
|
||||
{
|
||||
try
|
||||
{
|
||||
$post = \IPS\forums\Topic\Post::load( $topic->topic_answered_pid );
|
||||
$post->post_bwoptions['best_answer'] = FALSE;
|
||||
$post->save();
|
||||
$topic->toggleSolveComment( $post->pid, FALSE );
|
||||
|
||||
if ( \IPS\Member::loggedIn()->modPermission('can_set_best_answer') )
|
||||
{
|
||||
@@ -803,10 +873,7 @@ class _topic extends \IPS\Content\Controller
|
||||
catch ( \Exception $e ) {}
|
||||
}
|
||||
|
||||
$topic->topic_answered_pid = FALSE;
|
||||
$topic->save();
|
||||
|
||||
\IPS\Output::i()->redirect( $topic->url() );
|
||||
\IPS\Output::i()->redirect( $post->url() );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -885,7 +952,47 @@ class _topic extends \IPS\Content\Controller
|
||||
|
||||
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'widgets', 'forums', 'front' )->poll( $topic, $poll );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Show a single comment requested by ajax
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function ajaxShowComment()
|
||||
{
|
||||
try
|
||||
{
|
||||
if ( ! \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
throw new \BadMethodCallException();
|
||||
}
|
||||
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
try
|
||||
{
|
||||
$topic = \IPS\forums\Topic::loadAndCheckPerms( \IPS\Request::i()->id );
|
||||
}
|
||||
catch( \OutOfRangeException $ex )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2F173/N', 403, '' );
|
||||
}
|
||||
|
||||
$comment = \IPS\forums\Topic\Post::load( \IPS\Request::i()->showComment );
|
||||
|
||||
if ( ! $comment->canView() )
|
||||
{
|
||||
throw new \BadMethodCallException();
|
||||
}
|
||||
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->blankTemplate( \IPS\Theme::i()->getTemplate( 'global', 'core' )->commentContainer( $topic, $comment ), 200, 'text/html' ) );
|
||||
}
|
||||
catch( \Exception $e )
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a Comment / Review (do=findComment/findReview)
|
||||
*
|
||||
@@ -949,7 +1056,7 @@ class _topic extends \IPS\Content\Controller
|
||||
$page = ceil( $commentPosition / $perPage );
|
||||
if ( $page != 1 )
|
||||
{
|
||||
$url = $url->setQueryString( 'page', $page );
|
||||
$url = $url->setPage( 'page', $page );
|
||||
}
|
||||
|
||||
/* And redirect */
|
||||
@@ -1042,4 +1149,20 @@ class _topic extends \IPS\Content\Controller
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Split Comment
|
||||
*
|
||||
* @param string $commentClass The comment/review class
|
||||
* @param \IPS\Content\Comment $comment The comment/review
|
||||
* @param \IPS\Content\Item $item The item
|
||||
* @return void
|
||||
* @throws \LogicException
|
||||
*/
|
||||
protected function _split( $commentClass, $comment, $item )
|
||||
{
|
||||
parent::_split( $commentClass, $comment, $item );
|
||||
|
||||
$item->rebuildPopularTime();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user