Version 4.0.13.1

This commit is contained in:
Neo committed 2025-12-19 04:57:54 -08:00
1 parent f9e857d255
commit c6a86f0d9b
7517 files changed
+597400 -668041

No files matched your search

@@ -0,0 +1,43 @@
<?php
/**
* @brief Legacy 3.x findpost
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Board
* @since 09 Jul 2015
* @version SVN_VERSION_NUMBER
*/
namespace IPS\forums\modules\front\forums;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Legacy 3.x findpost
*/
class _findpost extends \IPS\Dispatcher\Controller
{
/**
* Route
*
* @return void
*/
protected function manage()
{
try
{
\IPS\Output::i()->redirect( \IPS\forums\Topic\Post::loadAndCheckPerms( \IPS\Request::i()->pid )->url(), NULL, 301 );
}
catch ( \OutOfRangeException $e )
{
\IPS\Output::i()->error( 'node_error', '2F284/1', 404, '' );
}
}
}
@@ -0,0 +1,541 @@
<?php
/**
* @brief Forum Index
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Board
* @since 08 Jan 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\forums\modules\front\forums;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Forum Index
*/
class _forums extends \IPS\Dispatcher\Controller
{
/**
* Route
*
* @return void
*/
protected function manage()
{
\IPS\forums\Forum::loadIntoMemory();
$forum = NULL;
try
{
$this->_forum( \IPS\forums\Forum::loadAndCheckPerms( \IPS\Request::i()->id ) );
}
catch ( \OutOfRangeException $e )
{
\IPS\Output::i()->error( 'node_error', '2F176/1', 404, '' );
}
}
/**
* Show Forum
*
* @param \IPS\forums\Forum $forum The forum to show
* @return void
*/
public function _forum( $forum )
{
/* Password protected */
if ( $form = $forum->passwordForm() )
{
\IPS\Output::i()->output = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forums', 'forums', 'front' ), 'forumPasswordPopup' ) );
return;
}
/* We can read? */
if ( $forum->sub_can_post and !$forum->permission_showtopic and !$forum->can('read') )
{
\IPS\Output::i()->error( $forum->errorMessage(), '1F176/3', 403, '' );
}
/* Theme */
$forum->setTheme();
/* Users can see topics posted by other users? */
$where = array();
if ( !$forum->can_view_others and !\IPS\Member::loggedIn()->modPermission( 'can_read_all_topics' ) )
{
$where[] = array( 'starter_id = ?', \IPS\Member::loggedIn()->member_id );
}
/* 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, NULL );
$table->tableTemplate = array( \IPS\Theme::i()->getTemplate( 'forums', 'forums', 'front' ), 'forumTable' );
$table->classes = array( 'cTopicList' );
$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' );
}
else
{
$table->rowsTemplate = array( \IPS\Theme::i()->getTemplate( 'forums', 'forums', 'front' ), '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() )
{
\IPS\Output::i()->breadcrumb = isset( \IPS\Output::i()->breadcrumb['module'] ) ? array( 'module' => \IPS\Output::i()->breadcrumb['module'] ) : array();
}
/* Redirect? */
if ( $forum->redirect_url )
{
$forum->redirect_hits++;
$forum->save();
\IPS\Output::i()->redirect( $forum->redirect_url );
}
/* Custom Search */
$filterOptions = array(
'all' => 'all_topics',
'open' => 'open_topics',
'popular' => 'popular_now',
'poll' => 'poll',
'locked' => 'locked_topics',
'moved' => 'moved_topics',
);
$timeFrameOptions = array(
'show_all' => 'show_all',
'today' => 'today',
'last_5_days' => 'last_5_days',
'last_7_days' => 'last_7_days',
'last_10_days' => 'last_10_days',
'last_15_days' => 'last_15_days',
'last_20_days' => 'last_20_days',
'last_25_days' => 'last_25_days',
'last_30_days' => 'last_30_days',
'last_60_days' => 'last_60_days',
'last_90_days' => 'last_90_days',
);
if ( \IPS\Member::loggedIn()->member_id )
{
$filterOptions['starter'] = $forum->forums_bitoptions['bw_enable_answers'] ? 'questions_i_asked' : 'topics_i_started';
$filterOptions['replied'] = $forum->forums_bitoptions['bw_enable_answers'] ? 'questions_i_posted_in' : 'topics_i_posted_in';
if ( \IPS\Member::loggedIn()->member_id AND \IPS\Member::loggedIn()->last_visit)
{
$timeFrameOptions['since_last_visit'] = \IPS\Member::loggedIn()->language()->addToStack('since_last_visit', FALSE, array( 'sprintf' => array( \IPS\DateTime::ts( \IPS\Member::loggedIn()->last_visit ) ) ) );
}
}
if ( $forum->forums_bitoptions['bw_enable_answers'] )
{
$table->filters = array(
'questions_with_best_answers' => 'topic_answered_pid>0',
'questions_without_best_answers' => 'topic_answered_pid=0',
);
}
/* Are we a moderator? */
if( \IPS\forums\Topic::modPermission( 'unhide', NULL, $forum ) )
{
$filterOptions['queued_topics'] = 'queued_topics';
$filterOptions['queued_posts'] = 'queued_posts';
}
$table->advancedSearch = array(
'topic_type' => array( \IPS\Helpers\Table\SEARCH_SELECT, array( 'options' => $filterOptions ) ),
'sort_by' => array( \IPS\Helpers\Table\SEARCH_SELECT, array( 'options' => array(
'last_post' => 'last_post',
'replies' => 'replies',
'views' => 'views',
'topic_title' => 'topic_title',
'last_poster' => 'last_poster',
'topic_started' => 'topic_started',
'topic_starter' => $forum->forums_bitoptions['bw_enable_answers'] ? 'question_asker' : 'topic_starter',
) )
),
'sort_direction'=> array( \IPS\Helpers\Table\SEARCH_SELECT, array( 'options' => array(
'asc' => 'asc',
'desc' => 'desc',
) )
),
'time_frame' => array( \IPS\Helpers\Table\SEARCH_SELECT, array( 'options' => $timeFrameOptions ) ),
);
$table->advancedSearchCallback = function( $table, $values )
{
/* Type */
switch ( $values['topic_type'] )
{
case 'open':
$table->where[] = array( 'state=?', 'open' );
break;
case 'popular':
$table->where[] = array( 'popular_time IS NOT NULL AND popular_time>?', time() );
break;
case 'poll':
$table->where[] = 'poll_state<>0';
break;
case 'locked':
$table->where[] = array( 'state=?', 'closed' );
break;
case 'moved':
$table->where[] = array( 'state=?', 'link' );
break;
case 'starter':
$table->where[] = array( 'starter_id=?', \IPS\Member::loggedIn()->member_id );
break;
case 'replied':
$table->joinComments = TRUE;
$table->where[] = array( 'forums_posts.author_id=?', \IPS\Member::loggedIn()->member_id );
break;
case 'answered':
$table->where[] = 'topic_answered_pid<>0';
break;
case 'unanswered':
$table->where[] = 'topic_answered_pid=0';
break;
case 'queued_topics':
$table->where[] = 'approved=0';
break;
case 'queued_posts':
$table->where[] = 'topic_queuedposts>0';
break;
}
/* Sort */
switch ( $values['sort_by'] )
{
case 'last_post':
case 'views':
$table->sortBy = $values['sort_by'];
break;
case 'replies':
$table->sortBy = 'posts';
break;
case 'topic_title':
$table->sortBy = 'title';
break;
case 'last_poster':
$table->sortBy = 'last_poster_name';
break;
case 'topic_started':
$table->sortBy = 'start_date';
break;
case 'topic_starter':
$table->sortBy = 'starter_name';
break;
}
$table->sortDirection = $values['sort_direction'];
/* Cutoff */
$days = NULL;
switch ( $values['time_frame'] )
{
case 'today':
$days = 1;
break;
case 'last_5_days':
$days = 5;
break;
case 'last_7_days':
$days = 7;
break;
case 'last_10_days':
$days = 10;
break;
case 'last_15_days':
$days = 15;
break;
case 'last_20_days':
$days = 20;
break;
case 'last_25_days':
$days = 25;
break;
case 'last_30_days':
$days = 30;
break;
case 'last_60_days':
$days = 60;
break;
case 'last_90_days':
$days = 90;
break;
case 'since_last_visit':
$table->where[] = array( 'forums_topics.last_post>?', \IPS\Member::loggedIn()->last_visit );
break;
}
if ( $days !== NULL )
{
$table->where[] = array( 'forums_topics.last_post>?', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . $days . 'D' ) ) );
}
};
\IPS\Request::i()->sort_direction = \IPS\Request::i()->sort_direction ?: mb_strtolower( $table->sortDirection );
/* Saved actions */
foreach ( \IPS\forums\SavedAction::actions( $forum ) as $action )
{
$table->savedActions[ $action->_id ] = $action->_title;
}
/* RSS */
if ( \IPS\Settings::i()->forums_rss and $forum->topics )
{
/* 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 ( $forum->forums_bitoptions['bw_enable_answers'] )
{
$rssTitle = \IPS\Member::loggedIn()->language()->addToStack( 'forum_rss_title_questions', FALSE, array( 'sprintf' => array( $forum->_title ) ) );
}
else
{
$rssTitle = \IPS\Member::loggedIn()->language()->addToStack( 'forum_rss_title_topics', FALSE, array( 'sprintf' => array( $forum->_title ) ) );
}
\IPS\Output::i()->rssFeeds[ $rssTitle ] = $rssUrl;
/* Or actually show RSS feed */
if ( isset( \IPS\Request::i()->rss ) )
{
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}" ) );
}
$document = \IPS\Xml\Rss::newDocument( $forum->url(), $rssTitle, $rssTitle );
/* We can'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' );
foreach ( $table->getRows( array() ) as $topic )
{
if ( ! $topic->hidden() )
{
$document->addItem( $topic->title, $topic->url(), $topic->content(), \IPS\DateTime::ts( $topic->last_post ), $topic->tid );
}
}
/* @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 ) );
/* Show Forum */
if ( isset( \IPS\Request::i()->advancedSearchForm ) )
{
\IPS\Output::i()->output = (string) $table;
return;
}
\IPS\Output::i()->contextualSearchOptions[ \IPS\Member::loggedIn()->language()->addToStack( 'search_contextual_item', FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->addToStack( 'forums_sg' ) ) ) ) ] = array( 'type' => 'forums_topic', 'nodes' => $forum->_id );
$forumOutput = '';
if ( $forum->forums_bitoptions['bw_enable_answers'] )
{
$featuredTopic = NULL;
foreach ( \IPS\forums\Topic::featured( 1, 'RAND()', $forum ) as $featuredTopic )
{
break;
}
$popularQuestions = \IPS\forums\Topic::getItemsWithPermission( array( array( 'forum_id=?', $forum->id ), array( 'start_date>?', \IPS\DateTime::ts( time() - ( 86400 * 30 ) )->getTimestamp() ), array( 'question_rating>0' ) ), 'question_rating DESC', 5 );
$newQuestionsWhere = array( array( 'forum_id=?', $forum->id ) );
if ( !\IPS\Settings::i()->forums_new_questions )
{
$newQuestionsWhere[] = array( 'topic_answered_pid=0' );
}
else
{
$newQuestionsWhere[] = array( '( forums_topics.posts IS NULL OR forums_topics.posts=1 )' );
}
$newQuestions = \IPS\forums\Topic::getItemsWithPermission( $newQuestionsWhere, 'start_date DESC', 5 );
$forumOutput = \IPS\Theme::i()->getTemplate( 'forums' )->qaForum( (string) $table, $popularQuestions, $newQuestions, $featuredTopic, $forum );
}
else if( $forum->sub_can_post )
{
$forumOutput = (string) $table;
}
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'forums' )->forumDisplay( $forum, $forumOutput );
}
/**
* Add Topic
*
* @return void
*/
protected function add()
{
if ( !isset( \IPS\Request::i()->id ) )
{
$this->_selectForum();
return;
}
try
{
$forum = \IPS\forums\Forum::loadAndCheckPerms( \IPS\Request::i()->id );
$forum->setTheme();
}
catch ( \OutOfRangeException $e )
{
\IPS\Output::i()->error( 'no_module_permission', '2F173/2', 403, 'no_module_permission_guest' );
}
if ( $forum->forums_bitoptions['bw_enable_answers'] )
{
\IPS\Member::loggedIn()->language()->words['topic_mainTab'] = \IPS\Member::loggedIn()->language()->addToStack( 'question_mainTab', FALSE );
}
$form = \IPS\forums\Topic::create( $forum );
$hasModOptions = false;
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
\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 );
if ( \IPS\forums\Topic::moderateNewItems( \IPS\Member::loggedIn() ) )
{
$formTemplate = \IPS\Theme::i()->getTemplate( 'forms', 'core' )->modQueueMessage( \IPS\Member::loggedIn()->warnings( 5, NULL, 'mq' ), \IPS\Member::loggedIn()->mod_posts ) . $formTemplate;
}
$title = $forum->forums_bitoptions['bw_enable_answers'] ? 'ask_new_question' : 'create_new_topic';
/* Online User Location */
$permissions = $forum->permissions();
\IPS\Session::i()->setLocation( $forum->url(), explode( ",", $permissions['perm_view'] ), 'loc_forums_creating_topic', array( "forums_forum_{$forum->id}" => TRUE ) );
\IPS\Output::i()->sidebar['enabled'] = FALSE;
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'submit' )->createTopic( $formTemplate, $forum, $title );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( $title );
if ( !\IPS\forums\Forum::theOnlyForum() )
{
try
{
foreach( $forum->parents() as $parent )
{
\IPS\Output::i()->breadcrumb[] = array( $parent->url(), $parent->_title );
}
}
catch( \UnderflowException $e ) {}
\IPS\Output::i()->breadcrumb[] = array( $forum->url(), $forum->_title );
}
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack( ( $forum->forums_bitoptions['bw_enable_answers'] ) ? 'ask_new_question' : 'create_new_topic' ) );
}
/**
* Create Category Selector
*
* @return void
*/
protected function createMenu()
{
$this->_selectForum();
}
/**
* Mark Read
*
* @return void
*/
protected function markRead()
{
\IPS\Session::i()->csrfCheck();
try
{
$forum = \IPS\forums\Forum::load( \IPS\Request::i()->id );
$returnTo = $forum;
if( \IPS\Request::i()->return )
{
$returnTo = \IPS\forums\Forum::load( \IPS\Request::i()->return );
}
if ( \IPS\Request::i()->fromForum )
{
\IPS\forums\Topic::markContainerRead( $forum, NULL, FALSE );
}
else
{
\IPS\forums\Topic::markContainerRead( $forum );
}
\IPS\Output::i()->redirect( ( \IPS\Request::i()->return OR \IPS\Request::i()->fromForum ) ? $returnTo->url() : \IPS\Http\Url::internal( 'app=forums&module=forums&controller=index', NULL, 'forums' ) );
}
catch ( \OutOfRangeException $e )
{
\IPS\Output::i()->error( 'no_module_permission', '2F173/3', 403, 'no_module_permission_guest' );
}
}
/**
* Shows the forum selector for creating a topic outside of specific forum
*
* @return void
*/
protected function _selectForum()
{
$form = new \IPS\Helpers\Form( 'select_forum', 'continue' );
$form->class = 'ipsForm_vertical ipsForm_noLabels';
$form->add( new \IPS\Helpers\Form\Node( 'forum', NULL, TRUE, array(
'url' => \IPS\Http\Url::internal( 'app=forums&module=forums&controller=forums&do=createMenu' ),
'class' => 'IPS\forums\Forum',
'permissionCheck' => function( $node )
{
if ( $node->can( 'view' ) )
{
if ( $node->can( 'add' ) )
{
return TRUE;
}
return FALSE;
}
return NULL;
},
) ) );
if ( $values = $form->values() )
{
\IPS\Output::i()->redirect( $values['forum']->url()->setQueryString( 'do', 'add' ) );
}
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'select_forum' );
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack( 'select_forum' ) );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'forums' )->forumSelector( $form );
}
}
Whitespace-only changes.
@@ -0,0 +1,73 @@
<?php
/**
* @brief index
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage
* @since 28 Jul 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\forums\modules\front\forums;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* index
*/
class _index extends \IPS\Dispatcher\Controller
{
/**
* Execute
*
* @return void
*/
public function execute()
{
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js('front_browse.js', 'gallery' ) );
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js('front_forum.js', 'forums' ) );
parent::execute();
}
/**
* Manage
*
* @return void
*/
protected function manage()
{
/* Load into memory */
\IPS\forums\Forum::loadIntoMemory();
/* Is there only one forum? */
if ( $theOnlyForum = \IPS\forums\Forum::theOnlyForum() )
{
$controller = new \IPS\forums\modules\front\forums\forums( $this->url );
return $controller->_forum( $theOnlyForum );
}
/* Prepare output */
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'global_core.js', 'core', 'global' ) );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'forums' );
\IPS\Output::i()->linkTags['canonical'] = (string) \IPS\Http\Url::internal( 'app=forums&module=forums&controller=index', 'front', 'forums' );
\IPS\Output::i()->metaTags['og:title'] = \IPS\Settings::i()->board_name;
\IPS\Output::i()->metaTags['og:type'] = 'website';
\IPS\Output::i()->metaTags['og:url'] = (string) \IPS\Http\Url::internal( 'app=forums&module=forums&controller=index', 'front', 'forums' );
/* Set Online Location */
$permissions = \IPS\Dispatcher::i()->module->permissions();
\IPS\Session::i()->setLocation( \IPS\Http\Url::internal( 'app=forums&module=forums&controller=index', 'front', 'forums' ), explode( ',', $permissions['perm_view'] ), 'loc_forums_index' );
/* Display */
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'index' )->index();
}
}
@@ -0,0 +1,720 @@
<?php
/**
* @brief Topic View
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Board
* @since 08 Jan 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\forums\modules\front\forums;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Topic View
*/
class _topic extends \IPS\Content\Controller
{
/**
* [Content\Controller] Class
*/
protected static $contentModel = 'IPS\forums\Topic';
/**
* Execute
*
* @return void
*/
public function execute()
{
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js('front_topic.js', 'forums' ) );
parent::execute();
}
/**
* View Topic
*
* @return void
*/
protected function manage()
{
/* Load topic */
\IPS\forums\Forum::loadIntoMemory();
$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() )
{
$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 )
{
$forum = NULL;
try
{
$topic = \IPS\forums\Topic::load( \IPS\Request::i()->id );
$forum = $topic->container();
if ( $forum->can('view') and !$forum->loggedInMemberHasPasswordAccess() )
{
\IPS\Output::i()->redirect( $forum->url()->setQueryString( 'topic', \IPS\Request::i()->id ) );
}
if ( !$topic->canView() )
{
\IPS\Output::i()->error( $forum ? $forum->errorMessage() : 'node_error_no_perm', '2F173/H', 403, '' );
}
}
catch ( \OutOfRangeException $e )
{
/* Nope, just a generic no access error */
\IPS\Output::i()->error( 'node_error', '2F173/1', 404, '' );
}
}
/* Legacy findpost redirect */
if ( \IPS\Request::i()->findpost )
{
\IPS\Output::i()->redirect( $topic->url()->setQueryString( array( 'do' => 'findComment', 'comment' => \IPS\Request::i()->findpost ) ), NULL, 301 );
}
elseif ( \IPS\Request::i()->p )
{
\IPS\Output::i()->redirect( $topic->url()->setQueryString( array( 'do' => 'findComment', 'comment' => \IPS\Request::i()->p ) ), NULL, 301 );
}
if ( \IPS\Request::i()->view )
{
$this->_doViewCheck();
}
/* AJAX hover preview? */
if ( \IPS\Request::i()->isAjax() and \IPS\Request::i()->preview )
{
$firstPost = $topic->comments( 1 );
$topicOverview = array( 'firstPost' => array( $topic->isQuestion() ? 'question_mainTab' : 'first_post', $firstPost ) );
if ( $topic->posts > 1 )
{
$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 )
{
$firstUnread = $topic->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 ) );
}
}
}
if ( $topic->isQuestion() and $topic->topic_answered_pid )
{
$topicOverview['bestAnswer'] = array( 'best_answer_post', \IPS\forums\Topic\Post::load( $topic->topic_answered_pid ) );
}
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'forums' )->topicHover( $topic, $topicOverview ) );
return;
}
$topic->container()->setTheme();
/* Watch for votes */
if ( $poll = $topic->getPoll() )
{
$poll->attach( $topic );
}
/* One for the brits */
if ( mb_strpos( $topic->title, base64_decode( 'c3BhbmlzaA==' ) ) !== FALSE and $topic->isQuestion() )
{
\IPS\Output::i()->output .= base64_decode( 'PCEtLSBOTyBPTkUgRVhQRUNUUyBUSEUgU1BBTklTSCBJTlFVSVNJVElPTiAtLT4=' );
}
/* How are we sorting posts? */
$question = NULL;
$offset = NULL;
$order = 'date';
$orderDirection = 'asc';
$where = NULL;
if( \IPS\forums\Topic::modPermission( 'unhide', NULL, $topic->container() ) AND \IPS\Request::i()->queued_posts )
{
$where = 'queued=1';
$queuedPagesCount = ceil( \IPS\Db::i()->select( 'COUNT(*)', 'forums_posts', array( 'topic_id=? AND queued=1', $topic->id ) )->first() / $topic->getCommentsPerPage() );
$pagination = ( $queuedPagesCount > 1 ) ? $topic->commentPagination( array( 'queued_posts', 'sortby' ), 'pagination', $queuedPagesCount ) : NULL;
}
else
{
if ( $topic->isQuestion() )
{
$question = $topic->comments( 1, 0 );
$page = ( isset( \IPS\Request::i()->page ) ) ? intval( \IPS\Request::i()->page ) : 1;
if( $page < 1 )
{
$page = 1;
}
$offset = ( ( $page - 1 ) * $topic::getCommentsPerPage() ) + 1;
if ( ( !isset( \IPS\Request::i()->sortby ) or \IPS\Request::i()->sortby != 'date' ) )
{
if ( $topic->isArchived() )
{
$order = "archive_is_first desc, archive_bwoptions";
$orderDirection = 'desc';
}
else
{
$order = "new_topic DESC, post_bwoptions DESC, post_field_int DESC, post_date";
$orderDirection = 'ASC';
}
}
}
$pagination = ( $topic->commentPageCount() > 1 ) ? $topic->commentPagination( array( 'sortby' ) ) : NULL;
}
$comments = $topic->comments( NUll, $offset, $order, $orderDirection, NULL, NULL, NULL, $where );
$current = current( $comments );
reset( $comments );
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 = strip_tags( $topic->isQuestion() ? $question->post : $current->post );
\IPS\Output::i()->metaTags['description'] = \IPS\Output::i()->metaTags['og:description'] = ( mb_strlen( $metaDescription ) > 160 ? ( mb_substr( $metaDescription, 0, 157 ) . '...' ) : $metaDescription );
/* Did we request a specific post? If so, reset descriptions. */
if( isset( $_SESSION['_findComment'] ) )
{
$commentId = $_SESSION['_findComment'];
unset( $_SESSION['_findComment'] );
try
{
$comment = \IPS\forums\Topic\Post::loadAndCheckPerms( $commentId );
\IPS\Output::i()->metaTags['description'] = \IPS\Output::i()->metaTags['og:description'] = strip_tags( $comment->content() );
}
catch( \Exception $e ){}
}
/* Mark read */
if( !$topic->isLastPage() )
{
$maxTime = 0;
foreach( $comments as $comment )
{
$maxTime = ( $comment->mapped('date') > $maxTime ) ? $comment->mapped('date') : $maxTime;
}
$topic->markRead( NULL, $maxTime );
}
$votes = array();
$topicVotes = array();
/* Get post ratings for this user */
if ( $topic->isQuestion() && \IPS\Member::loggedIn()->member_id )
{
$votes = $topic->answerVotes( \IPS\Member::loggedIn() );
$topicVotes = $topic->votes();
}
if ( $topic->isQuestion() )
{
\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();
}
catch( \Exception $e )
{
$nextUnread = NULL;
}
/* Show topic */
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'topics' )->topic( $topic, $comments, $question, $votes, $nextUnread, $pagination, $topicVotes );
}
/**
* Check our view method and act accordingly (redirect if appropriate)
*
* @return void
*/
protected function _doViewCheck()
{
try
{
$class = static::$contentModel;
$topic = $class::loadAndCheckPerms( \IPS\Request::i()->id );
switch( \IPS\Request::i()->view )
{
case 'getnewpost':
\IPS\Output::i()->redirect( $topic->url( 'getNewComment' ) );
break;
case 'getlastpost':
\IPS\Output::i()->redirect( $topic->url( 'getLastComment' ) );
break;
}
}
catch( \OutOfRangeException $e )
{
\IPS\Output::i()->error( 'node_error', '2F173/F', 403, '' );
}
}
/**
* Edit topic
*
* @return void
*/
public function edit()
{
try
{
$class = static::$contentModel;
$topic = $class::loadAndCheckPerms( \IPS\Request::i()->id );
$forum = $topic->container();
$forum->setTheme();
}
catch ( \OutOfRangeException $e )
{
\IPS\Output::i()->error( 'no_module_permission', '2F173/D', 403, 'no_module_permission_guest' );
}
if ( $forum->forums_bitoptions['bw_enable_answers'] )
{
\IPS\Member::loggedIn()->language()->words['topic_mainTab'] = \IPS\Member::loggedIn()->language()->addToStack( 'question_mainTab', FALSE );
}
if ( !$topic->canEdit() )
{
\IPS\Output::i()->error( 'node_noperm_edit', '2F173/E', 403, '' );
}
$formElements = $class::formElements( $topic, $forum );
$hasModOptions = FALSE;
if ( $class::modPermission( 'lock', NULL, $forum ) )
{
$hasModOptions = TRUE;
}
$form = new \IPS\Helpers\Form( 'form', \IPS\Member::loggedIn()->language()->checkKeyExists( $class::$formLangPrefix . '_save' ) ? $class::$formLangPrefix . '_save' : 'save' );
$form->class = 'ipsForm_vertical';
if ( isset( $formElements['poll'] ) )
{
$form->addTab( $class::$formLangPrefix . 'mainTab' );
}
foreach( $formElements AS $k => $element )
{
if ( $k === 'poll' )
{
$form->addTab( $class::$formLangPrefix . 'pollTab' );
}
$form->add( $element );
}
if ( $values = $form->values() )
{
$topic->processForm( $values );
$topic->save();
$topic->processAfterEdit( $values );
\IPS\Output::i()->redirect( $topic->url() );
}
$formTemplate = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'submit', 'forums' ) ), 'createTopicForm' ), $forum, $hasModOptions );
$title = $forum->forums_bitoptions['bw_enable_answers'] ? 'edit_question' : 'edit_topic';
\IPS\Output::i()->sidebar['enabled'] = FALSE;
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'submit' )->createTopic( $formTemplate, $forum, $title );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( $title );
if ( !\IPS\forums\Forum::theOnlyForum() )
{
try
{
foreach( $forum->parents() AS $parent )
{
\IPS\Output::i()->breadcrumb[] = array( $parent->url(), $parent->_title );
}
\IPS\Output::i()->breadcrumb[] = array( $forum->url(), $forum->_title );
}
catch( \Exception $e ) {}
}
\IPS\Output::i()->breadcrumb[] = array( $topic->url(), $topic->mapped('title') );
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack( $title ) );
}
/**
* Unarchive
*
* @return void
*/
public function unarchive()
{
try
{
$topic = \IPS\forums\Topic::loadAndCheckPerms( \IPS\Request::i()->id );
if ( !$topic->canUnarchive() )
{
throw new \OutOfRangeException;
}
}
catch ( \OutOfRangeException $e )
{
\IPS\Output::i()->error( 'node_error', '2F173/B', 404, '' );
}
$topic->topic_archive_status = \IPS\forums\Topic::ARCHIVE_RESTORE;
$topic->save();
\IPS\Output::i()->redirect( $topic->url() );
}
/**
* Rate Question
*
* @return void
*/
public function rateQuestion()
{
\IPS\Session::i()->csrfCheck();
try
{
$question = \IPS\forums\Topic::loadAndCheckPerms( \IPS\Request::i()->id );
}
catch ( \OutOfRangeException $e )
{
\IPS\Output::i()->error( 'node_error', '2F173/8', 404, '' );
}
if ( !$question->canVote() )
{
\IPS\Output::i()->error( 'no_module_permission', '2F173/9', 403, '' );
}
$rating = intval( \IPS\Request::i()->rating );
if ( $rating !== 1 and $rating !== -1 )
{
\IPS\Output::i()->error( 'form_bad_value', '2F173/A', 403, '' );
}
\IPS\Db::i()->insert( 'forums_question_ratings', array(
'topic' => $question->tid,
'forum' => $question->forum_id,
'member' => \IPS\Member::loggedIn()->member_id,
'rating' => $rating,
'date' => time()
), TRUE );
$question->question_rating = \IPS\Db::i()->select( 'SUM(rating)', 'forums_question_ratings', array( 'topic=?', $question->tid ) )->first();
$question->save();
\IPS\Output::i()->redirect( $question->url() );
}
/**
* Rate Answer
*
* @return void
*/
public function rateAnswer()
{
\IPS\Session::i()->csrfCheck();
try
{
$question = \IPS\forums\Topic::loadAndCheckPerms( \IPS\Request::i()->id );
$answer = \IPS\forums\Topic\Post::loadAndCheckPerms( \IPS\Request::i()->answer );
}
catch ( \Exception $e )
{
\IPS\Output::i()->error( 'node_error', '2F173/4', 404, '' );
}
if ( !$answer->item()->can('read') or !$answer->canVote() )
{
\IPS\Output::i()->error( 'no_module_permission', '2F173/5', 403, '' );
}
$rating = intval( \IPS\Request::i()->rating );
if ( $rating !== 1 and $rating !== -1 )
{
\IPS\Output::i()->error( 'form_bad_value', '2F173/6', 403, '' );
}
\IPS\Db::i()->insert( 'forums_answer_ratings', array(
'post' => $answer->pid,
'topic' => $question->tid,
'member' => \IPS\Member::loggedIn()->member_id,
'rating' => $rating,
'date' => time()
), TRUE );
$answer->post_field_int = \IPS\Db::i()->select( 'SUM(rating)', 'forums_answer_ratings', array( 'post=?', $answer->pid ) )->first();
$answer->save();
if ( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->json( array( 'votes' => $answer->post_field_int, 'canVoteUp' => $answer->canVote(1), 'canVoteDown' => $answer->canVote(-1) ) );
}
else
{
\IPS\Output::i()->redirect( $answer->url() );
}
}
/**
* Set Best Answer
*
* @return void
*/
public function bestAnswer()
{
\IPS\Session::i()->csrfCheck();
try
{
$topic = \IPS\forums\Topic::loadAndCheckPerms( \IPS\Request::i()->id );
if ( !$topic->canSetBestAnswer() )
{
throw new \OutOfRangeException;
}
$post = \IPS\forums\Topic\Post::loadAndCheckPerms( \IPS\Request::i()->answer );
if ( $post->item() != $topic )
{
throw new \OutOfRangeException;
}
}
catch ( \OutOfRangeException $e )
{
\IPS\Output::i()->error( 'node_error', '2F173/7', 404, '' );
}
if ( $topic->topic_answered_pid )
{
try
{
$oldBestAnswer = \IPS\forums\Topic\Post::load( $topic->topic_answered_pid );
$oldBestAnswer->post_bwoptions['best_answer'] = FALSE;
$oldBestAnswer->save();
}
catch ( \Exception $e ) {}
}
$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() );
}
/**
* Unset Best Answer
*
* @return void
*/
public function unsetBestAnswer()
{
\IPS\Session::i()->csrfCheck();
try
{
$topic = \IPS\forums\Topic::loadAndCheckPerms( \IPS\Request::i()->id );
if ( !$topic->canSetBestAnswer() )
{
throw new \OutOfRangeException;
}
}
catch ( \OutOfRangeException $e )
{
\IPS\Output::i()->error( 'node_error', '2F173/G', 404, '' );
}
if ( $topic->topic_answered_pid )
{
try
{
$post = \IPS\forums\Topic\Post::load( $topic->topic_answered_pid );
$post->post_bwoptions['best_answer'] = FALSE;
$post->save();
if ( \IPS\Member::loggedIn()->modPermission('can_set_best_answer') )
{
\IPS\Session::i()->modLog( 'modlog__best_answer_unset', array( $topic->topic_answered_pid => FALSE ), $topic );
}
}
catch ( \Exception $e ) {}
}
$topic->topic_answered_pid = FALSE;
$topic->save();
\IPS\Output::i()->redirect( $topic->url() );
}
/**
* Saved Action
*
* @return void
*/
public function savedAction()
{
try
{
\IPS\Session::i()->csrfCheck();
$topic = \IPS\forums\Topic::loadAndCheckPerms( \IPS\Request::i()->id );
$action = \IPS\forums\SavedAction::load( \IPS\Request::i()->action );
$action->runOn( $topic );
/* Log */
\IPS\Session::i()->modLog( 'modlog__saved_action', array( 'forums_mmod_' . $action->mm_id => TRUE, $topic->url()->__toString() => FALSE, $topic->mapped( 'title' ) => FALSE ), $topic );
\IPS\Output::i()->redirect( $topic->url() );
}
catch ( \LogicException $e )
{
}
}
/**
* Mark Topic Read
*
* @return void
*/
public function markRead()
{
\IPS\Session::i()->csrfCheck();
try
{
$topic = \IPS\forums\Topic::load( \IPS\Request::i()->id );
$topic->markRead();
if ( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->json( "OK" );
}
else
{
\IPS\Output::i()->redirect( $topic->url() );
}
}
catch ( \OutOfRangeException $e )
{
\IPS\Output::i()->error( 'no_module_permission', '2F173/C', 403, 'no_module_permission_guest' );
}
}
/**
* Edit Comment/Review
*
* @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 _edit( $commentClass, $comment, $item )
{
\IPS\Member::loggedIn()->language()->words['edit_comment'] = \IPS\Member::loggedIn()->language()->addToStack( 'edit_reply', FALSE );
return parent::_edit( $commentClass, $comment, $item );
}
/**
* Stuff that applies to both comments and reviews
*
* @param string $method Desired method
* @param array $args Arguments
* @return void
*/
public function __call( $method, $args )
{
$class = static::$contentModel;
try
{
$item = $class::load( \IPS\Request::i()->id );
if ( !$item->canView() )
{
$forum = $item->container();
\IPS\Output::i()->error( $forum ? $forum->errorMessage() : 'node_error_no_perm', '2F173/K', 403, '' );
}
if ( $item->isArchived() )
{
$class::$commentClass = $class::$archiveClass;
}
return parent::__call( $method, $args );
}
catch( \OutOfRangeException $e )
{
if ( isset( \IPS\Request::i()->do ) AND \IPS\Request::i()->do === 'findComment' AND isset( \IPS\Request::i()->comment ) )
{
try
{
$comment = \IPS\forums\Topic\Post::load( \IPS\Request::i()->comment );
$topic = \IPS\forums\Topic::load( $comment->topic_id );
\IPS\Output::i()->redirect( $topic->url()->setQueryString( array( 'do' => 'findComment', 'comment' => \IPS\Request::i()->comment ) ), NULL, 301 );
}
catch( \Exception $e )
{
\IPS\Output::i()->error( 'node_error', '2F173/M', 404, '' );
}
}
}
catch ( \Exception $e )
{
\IPS\Output::i()->error( 'node_error', '2F173/I', 404, '' );
}
}
}
Whitespace-only changes.