Version 4.3.0
This commit is contained in:
1 parent
96997ddd8e
commit
fe1acf984a
1349 files changed
+116159
-67711
No files matched your search
@@ -117,7 +117,6 @@ class _forums extends \IPS\Node\Controller
|
||||
return parent::permissions();
|
||||
}
|
||||
|
||||
|
||||
protected function form()
|
||||
{
|
||||
parent::form();
|
||||
|
||||
@@ -43,7 +43,7 @@ class _settings extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
|
||||
$activeTab = \IPS\Request::i()->tab ?: 'settings';
|
||||
$activeTabContents = call_user_func( array( $this, 'manage' . ucfirst( $activeTab ) ) );
|
||||
$activeTabContents = call_user_func( array( $this, 'manage' . mb_ucfirst( $activeTab ) ) );
|
||||
|
||||
if( \IPS\Request::i()->isAjax() and !isset( \IPS\Request::i()->ajaxValidate ) )
|
||||
{
|
||||
@@ -437,12 +437,19 @@ class _settings extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
|
||||
/* Do we need to unarchive some? */
|
||||
$whereClause = \IPS\Db::i()->compileWhereClause( \IPS\Application::load('forums')->archiveWhere( $rules ) );
|
||||
$_whereClause = array( 'topic_archive_status=? AND !( ' . $whereClause['clause'] . ')' );
|
||||
$_whereClause[] = \IPS\forums\Topic::ARCHIVE_DONE;
|
||||
foreach ( $whereClause['binds'] as $bind )
|
||||
if( $values['archive_on'] )
|
||||
{
|
||||
$_whereClause[] = $bind;
|
||||
$whereClause = \IPS\Db::i()->compileWhereClause( \IPS\Application::load('forums')->archiveWhere( $rules ) );
|
||||
$_whereClause = array( 'topic_archive_status=? AND !( ' . $whereClause['clause'] . ')' );
|
||||
$_whereClause[] = \IPS\forums\Topic::ARCHIVE_DONE;
|
||||
foreach ( $whereClause['binds'] as $bind )
|
||||
{
|
||||
$_whereClause[] = $bind;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$_whereClause = array( 'topic_archive_status NOT IN(' . \IPS\forums\Topic::ARCHIVE_NOT . ',' . \IPS\forums\Topic::ARCHIVE_EXCLUDE . ')' );
|
||||
}
|
||||
|
||||
/* Make sure the unarchive task is enabled - it will disable itself if there is no work to do */
|
||||
@@ -461,7 +468,7 @@ class _settings extends \IPS\Dispatcher\Controller
|
||||
|
||||
/* Log and redirect */
|
||||
\IPS\Session::i()->log( 'acplogs__archive_settings' );
|
||||
if ( \IPS\Db::i()->select( 'COUNT(*)', 'forums_topics', $values['archive_on'] ? $_whereClause : array( 'topic_archive_status=?', \IPS\forums\Topic::ARCHIVE_DONE ) )->first() )
|
||||
if ( \IPS\Db::i()->select( 'COUNT(*)', 'forums_topics', $_whereClause )->first() )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=forums&module=forums&controller=settings&do=unarchive' ) );
|
||||
}
|
||||
@@ -590,10 +597,19 @@ class _settings extends \IPS\Dispatcher\Controller
|
||||
} ) );
|
||||
|
||||
$form->addHeader('topic_settings');
|
||||
$popularNowMaximum = 14400000;
|
||||
$form->add( new \IPS\Helpers\Form\Custom( 'forums_popular_now', json_decode( \IPS\Settings::i()->forums_popular_now, TRUE ), FALSE, array(
|
||||
'getHtml' => function( $obj )
|
||||
'getHtml' => function( $obj ) use ( $popularNowMaximum )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate('settings')->popularNow( $obj->name, $obj->value );
|
||||
return \IPS\Theme::i()->getTemplate('settings')->popularNow( $obj->name, $obj->value, $popularNowMaximum );
|
||||
},
|
||||
/* If popular now time is greater than 10,000 days */
|
||||
'validate' => function( $obj ) use ( $popularNowMaximum )
|
||||
{
|
||||
if( $obj->value['minutes'] > $popularNowMaximum )
|
||||
{
|
||||
throw new \LengthException( \IPS\Member::loggedIn()->language()->addToStack('form_number_max', FALSE, array( 'sprintf' => array( $popularNowMaximum ) ) ) );
|
||||
}
|
||||
}
|
||||
) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'forums_posts_per_page', \IPS\Settings::i()->forums_posts_per_page , TRUE, array( 'min' => 2, 'max' => 250 ) ) );
|
||||
|
||||
@@ -31,20 +31,63 @@ class _posts extends \IPS\Dispatcher\Controller
|
||||
protected function manage()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'posts_manage' );
|
||||
|
||||
$chart = new \IPS\Helpers\Chart\Database( \IPS\Http\Url::internal( "app=forums&module=stats&controller=posts" ), 'forums_posts', 'post_date', '', array(
|
||||
'isStacked' => FALSE,
|
||||
'backgroundColor' => '#ffffff',
|
||||
'colors' => array( '#10967e' ),
|
||||
'hAxis' => array( 'gridlines' => array( 'color' => '#f5f5f5' ) ),
|
||||
'lineWidth' => 1,
|
||||
'areaOpacity' => 0.4
|
||||
) );
|
||||
$chart->addSeries( \IPS\Member::loggedIn()->language()->addToStack( 'stats_new_posts' ), 'number', 'COUNT(*)', FALSE );
|
||||
$chart->title = \IPS\Member::loggedIn()->language()->addToStack( 'stats_posts_title' );
|
||||
$chart->availableTypes = array( 'AreaChart', 'ColumnChart', 'BarChart' );
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'menu__forums_stats_posts' );
|
||||
\IPS\Output::i()->output = (string) $chart;
|
||||
|
||||
$tabs = array( 'total' => 'stats_posts_tab_total', 'byforum' => 'stats_posts_tab_byforum' );
|
||||
$activeTab = ( isset( \IPS\Request::i()->tab ) and array_key_exists( \IPS\Request::i()->tab, $tabs ) ) ? \IPS\Request::i()->tab : 'total';
|
||||
|
||||
if ( $activeTab === 'total' )
|
||||
{
|
||||
$chart = new \IPS\Helpers\Chart\Database( \IPS\Http\Url::internal( "app=forums&module=stats&controller=posts" ), 'forums_posts', 'post_date', '', array(
|
||||
'isStacked' => FALSE,
|
||||
'backgroundColor' => '#ffffff',
|
||||
'colors' => array( '#10967e' ),
|
||||
'hAxis' => array( 'gridlines' => array( 'color' => '#f5f5f5' ) ),
|
||||
'lineWidth' => 1,
|
||||
'areaOpacity' => 0.4
|
||||
) );
|
||||
$chart->addSeries( \IPS\Member::loggedIn()->language()->addToStack( 'stats_new_posts' ), 'number', 'COUNT(*)', FALSE );
|
||||
$chart->title = \IPS\Member::loggedIn()->language()->addToStack( 'stats_posts_title' );
|
||||
$chart->availableTypes = array( 'AreaChart', 'ColumnChart', 'BarChart' );
|
||||
}
|
||||
else
|
||||
{
|
||||
$chart = new \IPS\Helpers\Chart\Database( \IPS\Http\Url::internal( "app=forums&module=stats&controller=posts&tab=" . $activeTab ), 'forums_posts', 'post_date', '', array(
|
||||
'isStacked' => FALSE,
|
||||
'backgroundColor' => '#ffffff',
|
||||
'hAxis' => array( 'gridlines' => array( 'color' => '#f5f5f5' ) ),
|
||||
'lineWidth' => 1,
|
||||
'areaOpacity' => 0.4,
|
||||
'chartArea' => array( 'width' => '70%', 'left' => '5%' ),
|
||||
'height' => 400,
|
||||
'trendlines' => array( 0 => array( 'type' => 'exponential', 'color' => '#000', 'lineWidth' => 2, 'opacity' => 0.3 ) )
|
||||
),
|
||||
'ColumnChart',
|
||||
'monthly',
|
||||
array( 'start' => ( new \IPS\DateTime )->sub( new \DateInterval('P90D') ), 'end' => new \IPS\DateTime ),
|
||||
array(),
|
||||
'byforum'
|
||||
);
|
||||
|
||||
$chart->title = \IPS\Member::loggedIn()->language()->addToStack( 'stats_posts_title_byforum' );
|
||||
$chart->availableTypes = array( 'ColumnChart' );
|
||||
|
||||
$chart->groupBy = 'forum_id';
|
||||
$chart->joins = array( array( 'forums_topics', 'forums_topics.tid=forums_posts.topic_id' ) );
|
||||
|
||||
foreach( \IPS\Db::i()->select( '*', 'forums_forums', array( 'posts>?', 0 ) ) as $forum )
|
||||
{
|
||||
$chart->addSeries( \IPS\Member::loggedIn()->language()->addToStack( 'forums_forum_' . $forum['id'] ), 'number', 'COUNT(*)', TRUE, $forum['id'] );
|
||||
}
|
||||
}
|
||||
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->output = (string) $chart;
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__forums_stats_posts');
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->tabs( $tabs, $activeTab, (string) $chart, \IPS\Http\Url::internal( "app=forums&module=stats&controller=posts" ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,20 +31,65 @@ class _topics extends \IPS\Dispatcher\Controller
|
||||
protected function manage()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'topics_manage' );
|
||||
|
||||
$chart = new \IPS\Helpers\Chart\Database( \IPS\Http\Url::internal( "app=forums&module=stats&controller=topics" ), 'forums_topics', 'start_date', '', array(
|
||||
'isStacked' => FALSE,
|
||||
'backgroundColor' => '#ffffff',
|
||||
'colors' => array( '#10967e' ),
|
||||
'hAxis' => array( 'gridlines' => array( 'color' => '#f5f5f5' ) ),
|
||||
'lineWidth' => 1,
|
||||
'areaOpacity' => 0.4
|
||||
) );
|
||||
$chart->addSeries( \IPS\Member::loggedIn()->language()->addToStack( 'stats_new_topics' ), 'number', 'COUNT(*)', FALSE );
|
||||
$chart->title = \IPS\Member::loggedIn()->language()->addToStack( 'stats_topics_title' );
|
||||
$chart->availableTypes = array( 'AreaChart', 'ColumnChart', 'BarChart' );
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'menu__forums_stats_topics' );
|
||||
\IPS\Output::i()->output = (string) $chart;
|
||||
$tabs = array( 'total' => 'stats_topics_tab_total', 'byforum' => 'stats_topics_tab_byforum' );
|
||||
$activeTab = ( isset( \IPS\Request::i()->tab ) and array_key_exists( \IPS\Request::i()->tab, $tabs ) ) ? \IPS\Request::i()->tab : 'total';
|
||||
|
||||
if ( $activeTab === 'total' )
|
||||
{
|
||||
$chart = new \IPS\Helpers\Chart\Database( \IPS\Http\Url::internal( "app=forums&module=stats&controller=topics" ), 'forums_topics', 'start_date', '', array(
|
||||
'isStacked' => FALSE,
|
||||
'backgroundColor' => '#ffffff',
|
||||
'colors' => array( '#10967e' ),
|
||||
'hAxis' => array( 'gridlines' => array( 'color' => '#f5f5f5' ) ),
|
||||
'lineWidth' => 1,
|
||||
'areaOpacity' => 0.4
|
||||
),
|
||||
'AreaChart'
|
||||
);
|
||||
|
||||
$chart->addSeries( \IPS\Member::loggedIn()->language()->addToStack( 'stats_new_topics' ), 'number', 'COUNT(*)', FALSE );
|
||||
$chart->title = \IPS\Member::loggedIn()->language()->addToStack( 'stats_topics_title' );
|
||||
$chart->availableTypes = array( 'AreaChart', 'ColumnChart', 'BarChart' );
|
||||
}
|
||||
else
|
||||
{
|
||||
$chart = new \IPS\Helpers\Chart\Database( \IPS\Http\Url::internal( "app=forums&module=stats&controller=topics&tab=" . $activeTab ), 'forums_topics', 'start_date', '', array(
|
||||
'isStacked' => FALSE,
|
||||
'backgroundColor' => '#ffffff',
|
||||
'hAxis' => array( 'gridlines' => array( 'color' => '#f5f5f5' ) ),
|
||||
'lineWidth' => 1,
|
||||
'areaOpacity' => 0.4,
|
||||
'chartArea' => array( 'width' => '70%', 'left' => '5%' ),
|
||||
'height' => 400,
|
||||
'trendlines' => array( 0 => array( 'type' => 'exponential', 'color' => '#000', 'lineWidth' => 2, 'opacity' => 0.3 ) )
|
||||
),
|
||||
'ColumnChart',
|
||||
'monthly',
|
||||
array( 'start' => ( new \IPS\DateTime )->sub( new \DateInterval('P90D') ), 'end' => new \IPS\DateTime ),
|
||||
array(),
|
||||
'byforum'
|
||||
);
|
||||
|
||||
$chart->title = \IPS\Member::loggedIn()->language()->addToStack( 'stats_topics_title_byforum' );
|
||||
$chart->availableTypes = array( 'ColumnChart' );
|
||||
|
||||
$chart->groupBy = 'forum_id';
|
||||
|
||||
foreach( \IPS\Db::i()->select( '*', 'forums_forums', array( 'topics>?', 0 ) ) as $forum )
|
||||
{
|
||||
$chart->addSeries( \IPS\Member::loggedIn()->language()->addToStack( 'forums_forum_' . $forum['id'] ), 'number', 'COUNT(*)', TRUE, $forum['id'] );
|
||||
}
|
||||
}
|
||||
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->output = (string) $chart;
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__forums_stats_topics');
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->tabs( $tabs, $activeTab, (string) $chart, \IPS\Http\Url::internal( "app=forums&module=stats&controller=topics" ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,7 @@ class _forums extends \IPS\Dispatcher\Controller
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
{
|
||||
{
|
||||
$forum = NULL;
|
||||
try
|
||||
{
|
||||
@@ -61,7 +61,7 @@ class _forums extends \IPS\Dispatcher\Controller
|
||||
/* Password protected */
|
||||
if ( $form = $forum->passwordForm() )
|
||||
{
|
||||
\IPS\Output::i()->title = $forum->_stripTagsTitle;
|
||||
\IPS\Output::i()->title = $forum->_title;
|
||||
\IPS\Output::i()->output = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forums', 'forums', 'front' ), 'forumPasswordPopup' ), $forum );
|
||||
return;
|
||||
}
|
||||
@@ -320,11 +320,11 @@ class _forums extends \IPS\Dispatcher\Controller
|
||||
$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->_stripTagsTitle ) ) );
|
||||
$rssTitle = \IPS\Member::loggedIn()->language()->addToStack( 'forum_rss_title_questions', FALSE, array( 'escape' => true, 'sprintf' => array( $forum->_title ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$rssTitle = \IPS\Member::loggedIn()->language()->addToStack( 'forum_rss_title_topics', FALSE, array( 'sprintf' => array( $forum->_stripTagsTitle ) ) );
|
||||
$rssTitle = \IPS\Member::loggedIn()->language()->addToStack( 'forum_rss_title_topics', FALSE, array( 'escape' => true, 'sprintf' => array( $forum->_title ) ) );
|
||||
}
|
||||
\IPS\Output::i()->rssFeeds[ $rssTitle ] = $rssUrl;
|
||||
|
||||
@@ -411,6 +411,28 @@ class _forums extends \IPS\Dispatcher\Controller
|
||||
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'forums' )->forumDisplay( $forum, $forumOutput );
|
||||
}
|
||||
|
||||
/**
|
||||
* Show Club Forums
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function clubs()
|
||||
{
|
||||
if ( !\IPS\Settings::i()->club_nodes_in_apps )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2F176/4', 404, '' );
|
||||
}
|
||||
|
||||
if ( \IPS\forums\Forum::isSimpleView() )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=forums&module=forums&controller=index&forumId=clubs', 'front', 'forums' ), '', 302 );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack('club_node_forums') );
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('club_node_forums');
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'forums' )->clubForums();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Topic
|
||||
@@ -454,7 +476,7 @@ class _forums extends \IPS\Dispatcher\Controller
|
||||
|
||||
$formTemplate = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'submit', 'forums' ) ), 'createTopicForm' ), $forum, $hasModOptions, NULL );
|
||||
|
||||
if ( \IPS\forums\Topic::moderateNewItems( \IPS\Member::loggedIn() ) )
|
||||
if ( \IPS\forums\Topic::moderateNewItems( \IPS\Member::loggedIn(), $forum ) )
|
||||
{
|
||||
$formTemplate = \IPS\Theme::i()->getTemplate( 'forms', 'core' )->modQueueMessage( \IPS\Member::loggedIn()->warnings( 5, NULL, 'mq' ), \IPS\Member::loggedIn()->mod_posts ) . $formTemplate;
|
||||
}
|
||||
@@ -568,7 +590,8 @@ class _forums extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
},
|
||||
'clubs' => \IPS\Settings::i()->club_nodes_in_apps
|
||||
) ) );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
|
||||
@@ -95,7 +95,14 @@ class _index extends \IPS\Dispatcher\Controller
|
||||
|
||||
/* 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' );
|
||||
if ( \IPS\forums\Forum::isSimpleView() )
|
||||
{
|
||||
\IPS\Output::i()->title = ( isset( \IPS\Request::i()->page ) AND \IPS\Request::i()->page > 1 ) ? \IPS\Member::loggedIn()->language()->addToStack( 'title_with_page_number', FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->addToStack( 'forums' ), \IPS\Request::i()->page ) ) ) : \IPS\Member::loggedIn()->language()->addToStack( 'forums' );
|
||||
}
|
||||
else
|
||||
{
|
||||
\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';
|
||||
@@ -108,9 +115,12 @@ class _index extends \IPS\Dispatcher\Controller
|
||||
/* Display */
|
||||
if ( \IPS\forums\Forum::isSimpleView() )
|
||||
{
|
||||
$where = array( 'container' => array( array( 'forums_forums.password IS NULL AND forums_forums.can_view_others=1 AND forums_forums.club_id IS NULL' ) ) );
|
||||
$where = array( 'container' => array( array( 'forums_forums.password IS NULL' ) ) );
|
||||
if ( !\IPS\Settings::i()->club_nodes_in_apps )
|
||||
{
|
||||
$where['container'][] = array( 'forums_forums.club_id IS NULL' );
|
||||
}
|
||||
$forumIds = array();
|
||||
$parentIds = array();
|
||||
$map = array();
|
||||
$ids = array();
|
||||
|
||||
@@ -130,50 +140,32 @@ class _index extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
try
|
||||
{
|
||||
/* Panic not, they are all loaded into memory at this point */
|
||||
$forum = \IPS\forums\Forum::load( $id );
|
||||
|
||||
if ( $forum->hasChildren() )
|
||||
if ( $id == 'clubs' )
|
||||
{
|
||||
/* This is a root category, so fetch all children */
|
||||
$this->getParentIds( $forum, $parentIds );
|
||||
$forumIds[] = $forum->id;
|
||||
$parentIds['clubs'] = 'clubs';
|
||||
foreach ( \IPS\forums\Forum::clubNodes() as $child )
|
||||
{
|
||||
$forumIds[ $child->id ] = $child->id;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
/* Panic not, they are all loaded into memory at this point */
|
||||
$forum = \IPS\forums\Forum::load( $id );
|
||||
|
||||
$map[ $forum->parent_id ][] = $forum->_id;
|
||||
$forumIds[] = $forum->id;
|
||||
}
|
||||
}
|
||||
catch( \Exception $ex ) { }
|
||||
}
|
||||
|
||||
/* Now remove all children that are in the same category */
|
||||
foreach( $map as $parent => $children )
|
||||
{
|
||||
if ( in_array( $parent, $parentIds ) )
|
||||
{
|
||||
$forumIds = array_diff( $forumIds, $children );
|
||||
}
|
||||
}
|
||||
|
||||
$or = array();
|
||||
if ( count( $forumIds ) )
|
||||
{
|
||||
$or[] = \IPS\Db::i()->in( 'forums_forums.id', array_filter( $forumIds ) );
|
||||
}
|
||||
|
||||
if ( count( $parentIds ) )
|
||||
{
|
||||
$or[] = \IPS\Db::i()->in( 'forums_forums.parent_id', array_filter( $parentIds ) );
|
||||
}
|
||||
|
||||
if ( count( $or ) )
|
||||
{
|
||||
$where['container'][] = array( '(' . implode( ' OR ', $or ) . ')' );
|
||||
$where['container'][] = array( \IPS\Db::i()->in( 'forums_forums.id', array_filter( $forumIds ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Simplified view */
|
||||
$table = new \IPS\Helpers\Table\Content( 'IPS\forums\Topic', \IPS\Http\Url::internal( 'app=forums&module=forums&controller=index', 'front', 'forums' ), $where, NULL, NULL, 'read' );
|
||||
$table->tableTemplate = array( \IPS\Theme::i()->getTemplate( 'index' ), 'simplifiedForumTable' );
|
||||
@@ -189,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, $parentIds );
|
||||
\IPS\Output::i()->sidebar['contextual'] = \IPS\Theme::i()->getTemplate( 'index' )->simplifiedViewSidebar( $forumIds );
|
||||
}
|
||||
|
||||
if ( isset( $where['container'] ) )
|
||||
@@ -204,32 +196,7 @@ class _index extends \IPS\Dispatcher\Controller
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'index' )->index();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively collect parents
|
||||
*
|
||||
* @param \IPS\forums\Forum $forum Forum object
|
||||
* @param array $parentIds ParentIds to use
|
||||
* @return void
|
||||
*/
|
||||
protected function getParentIds( $forum, &$parentIds )
|
||||
{
|
||||
if ( $forum->hasChildren() )
|
||||
{
|
||||
$parentIds[ $forum->id ] = $forum->id;
|
||||
|
||||
foreach( $forum->children() as $child )
|
||||
{
|
||||
if ( $child->hasChildren() )
|
||||
{
|
||||
$parentIds[ $child->id ] = $child->id;
|
||||
|
||||
$this->getParentIds( $child, $parentIds );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the viewing method
|
||||
*
|
||||
@@ -237,6 +204,8 @@ class _index extends \IPS\Dispatcher\Controller
|
||||
*/
|
||||
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_view', $method, ( new \IPS\DateTime )->add( new \DateInterval( 'P1Y' ) ) );
|
||||
|
||||
@@ -234,27 +234,11 @@ class _topic extends \IPS\Content\Controller
|
||||
{
|
||||
\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->isQuestion() ? $question->post : $current->post;
|
||||
|
||||
/* Did we request a specific post? If so, reset descriptions. */
|
||||
if( isset( $_SESSION['_findComment'] ) )
|
||||
{
|
||||
$commentId = $_SESSION['_findComment'];
|
||||
unset( $_SESSION['_findComment'] );
|
||||
$metaDescription = $topic->metaDescription( isset( $_SESSION['_findComment'] ) ? NULL : ( $topic->isQuestion() ? $question->content() : $current->content() ) );
|
||||
|
||||
try
|
||||
{
|
||||
$comment = \IPS\forums\Topic\Post::loadAndCheckPerms( $commentId );
|
||||
|
||||
$metaDescription = $comment->content();
|
||||
}
|
||||
catch( \Exception $e ){}
|
||||
}
|
||||
|
||||
$metaDescription = strip_tags( $metaDescription );
|
||||
\IPS\Output::i()->metaTags['description'] = \IPS\Output::i()->metaTags['og:description'] = mb_strlen( $metaDescription ) > 160 ? ( mb_substr( $metaDescription, 0, 157 ) . '...' ) : $metaDescription;
|
||||
\IPS\Output::i()->metaTags['description'] = \IPS\Output::i()->metaTags['og:description'] = $metaDescription;
|
||||
|
||||
/* Mark read */
|
||||
if( !$topic->isLastPage() )
|
||||
@@ -303,19 +287,18 @@ class _topic extends \IPS\Content\Controller
|
||||
'@type' => $topic->isQuestion() ? 'Question' : 'DiscussionForumPosting',
|
||||
'url' => (string) $topic->url(),
|
||||
'discussionUrl' => (string) $topic->url(),
|
||||
'name' => htmlspecialchars( $topic->mapped('title'), ENT_QUOTES | \IPS\HTMLENTITIES, 'UTF-8', FALSE ),
|
||||
'headline' => htmlspecialchars( $topic->mapped('title'), ENT_QUOTES | \IPS\HTMLENTITIES, 'UTF-8', FALSE ),
|
||||
'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' => \IPS\Member::load( $topic->starter_id )->get_photo(),
|
||||
'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' => htmlspecialchars( $topic->starter_name ?: \IPS\Member::load( $topic->starter_id )->name, ENT_QUOTES | \IPS\HTMLENTITIES, 'UTF-8', FALSE ),
|
||||
'url' => (string) \IPS\Member::load( $topic->starter_id )->url(),
|
||||
'name' => $topic->starter_name ?: \IPS\Member::load( $topic->starter_id )->name,
|
||||
'image' => \IPS\Member::load( $topic->starter_id )->get_photo()
|
||||
),
|
||||
'interactionStatistic' => array(
|
||||
@@ -337,6 +320,22 @@ class _topic extends \IPS\Content\Controller
|
||||
)
|
||||
);
|
||||
|
||||
/* Are ratings allowed? */
|
||||
if( !$topic->isArchived() AND $topic->container()->forum_allow_rating AND $topic->averageRating() )
|
||||
{
|
||||
\IPS\Output::i()->jsonLd['topic']['aggregateRating'] = array(
|
||||
'@type' => 'AggregateRating',
|
||||
'ratingValue' => $topic->averageRating(),
|
||||
'ratingCount' => $topic->numberOfRatings(),
|
||||
);
|
||||
}
|
||||
|
||||
/* 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();
|
||||
}
|
||||
|
||||
if( $topic->isQuestion() )
|
||||
{
|
||||
\IPS\Output::i()->jsonLd['topic']['answerCount'] = $topic->posts ? $topic->posts - 1 : 0;
|
||||
@@ -357,11 +356,15 @@ class _topic extends \IPS\Content\Controller
|
||||
'upvoteCount' => $answer->post_field_int,
|
||||
'author' => array(
|
||||
'@type' => 'Person',
|
||||
'name' => htmlspecialchars( $answer->author_name ?: \IPS\Member::load( $answer->author_id )->name, ENT_QUOTES | \IPS\HTMLENTITIES, 'UTF-8', FALSE ),
|
||||
'url' => (string) \IPS\Member::load( $answer->author_id )->url(),
|
||||
'name' => $answer->author_name ?: \IPS\Member::load( $answer->author_id )->name,
|
||||
'image' => \IPS\Member::load( $answer->author_id )->get_photo()
|
||||
),
|
||||
);
|
||||
|
||||
if( $answer->author_id )
|
||||
{
|
||||
\IPS\Output::i()->jsonLd['topic']['acceptedAnswer']['author']['url'] = (string) \IPS\Member::load( $answer->author_id )->url();
|
||||
}
|
||||
}
|
||||
catch( \OutOfRangeException $e ){}
|
||||
}
|
||||
@@ -370,21 +373,28 @@ class _topic extends \IPS\Content\Controller
|
||||
{
|
||||
\IPS\Output::i()->jsonLd['topic']['comment'] = array();
|
||||
|
||||
$i = 0;
|
||||
foreach( $comments as $comment )
|
||||
{
|
||||
\IPS\Output::i()->jsonLd['topic']['comment'][] = array(
|
||||
\IPS\Output::i()->jsonLd['topic']['comment'][ $i ] = array(
|
||||
'@type' => 'Comment',
|
||||
'url' => (string) $comment->url(),
|
||||
'author' => array(
|
||||
'@type' => 'Person',
|
||||
'name' => htmlspecialchars( $comment->author_name ?: \IPS\Member::load( $comment->author_id )->name, ENT_QUOTES | \IPS\HTMLENTITIES, 'UTF-8', FALSE ),
|
||||
'url' => (string) \IPS\Member::load( $comment->author_id )->url(),
|
||||
'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(),
|
||||
);
|
||||
|
||||
if( $comment->author_id )
|
||||
{
|
||||
\IPS\Output::i()->jsonLd['topic']['comment'][ $i ]['author']['url'] = (string) \IPS\Member::load( $comment->author_id )->url();
|
||||
}
|
||||
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -445,9 +455,20 @@ class _topic extends \IPS\Content\Controller
|
||||
\IPS\Member::loggedIn()->language()->words['topic_mainTab'] = \IPS\Member::loggedIn()->language()->addToStack( 'question_mainTab', FALSE );
|
||||
}
|
||||
|
||||
if ( !$topic->canEdit() and !\IPS\Request::i()->form_submitted ) // We check if the form has been submitted to prevent the user loosing their content
|
||||
// We check if the form has been submitted to prevent the user loosing their content
|
||||
if ( isset( \IPS\Request::i()->form_submitted ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'edit_no_perm_err', '2F173/E', 403, '' );
|
||||
if ( ! $topic->couldEdit() )
|
||||
{
|
||||
\IPS\Output::i()->error( 'edit_no_perm_err', '2F173/E', 403, '' );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ! $topic->canEdit() )
|
||||
{
|
||||
\IPS\Output::i()->error( 'edit_no_perm_err', '2F173/E', 403, '' );
|
||||
}
|
||||
}
|
||||
|
||||
$formElements = $class::formElements( $topic, $forum );
|
||||
@@ -864,6 +885,77 @@ class _topic extends \IPS\Content\Controller
|
||||
|
||||
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'widgets', 'forums', 'front' )->poll( $topic, $poll );
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a Comment / Review (do=findComment/findReview)
|
||||
*
|
||||
* @param string $commentClass The comment/review class
|
||||
* @param \IPS\Content\Comment $comment The comment/review
|
||||
* @param \IPS\Content\Item $item The item
|
||||
* @return void
|
||||
*/
|
||||
public function _find( $commentClass, $comment, $item )
|
||||
{
|
||||
/* For normal topics (i.e. not questions), we can handle this normally */
|
||||
if ( !$item->isQuestion() )
|
||||
{
|
||||
return parent::_find( $commentClass, $comment, $item );
|
||||
}
|
||||
|
||||
/* Otherwise we need to get the position ordered by votes... */
|
||||
if ( $item->isArchived() )
|
||||
{
|
||||
$where = array( array( 'archive_topic_id=?', $item->tid ) );
|
||||
if ( !$item->canViewHiddenComments() )
|
||||
{
|
||||
$hiddenWhereClause = "(archive_queued != -2 AND archive_queued != -1 AND archive_queued != 1)";
|
||||
|
||||
if ( \IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
$where[] = array( "( {$hiddenWhereClause} OR ( archive_queued=1 AND archive_author_id=" . \IPS\Member::loggedIn()->member_id . '))' );
|
||||
}
|
||||
else
|
||||
{
|
||||
$where[] = array( $hiddenWhereClause );
|
||||
}
|
||||
}
|
||||
$answers = \IPS\Db::i()->select( 'archive_id, @rownum := @rownum + 1 AS position', 'forums_archive_posts', $where, 'archive_is_first DESC, archive_bwoptions DESC, archive_field_int DESC, archive_content_date' )->join( array( '(SELECT @rownum := 0)', 'r' ), NULL, 'JOIN' );
|
||||
$commentPosition = \IPS\Db::i()->select( 'position', $answers, array( 'archive_id=?', $comment->id ) )->first() - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$where = array( array( 'topic_id=?', $item->tid ) );
|
||||
if ( !$item->canViewHiddenComments() )
|
||||
{
|
||||
$hiddenWhereClause = "(queued != -2 AND queued != -1 AND queued != 1)";
|
||||
|
||||
if ( \IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
$where[] = array( "( {$hiddenWhereClause} OR ( queued=1 AND author_id=" . \IPS\Member::loggedIn()->member_id . '))' );
|
||||
}
|
||||
else
|
||||
{
|
||||
$where[] = array( $hiddenWhereClause );
|
||||
}
|
||||
}
|
||||
|
||||
$answers = \IPS\Db::i()->select( 'pid, @rownum := @rownum + 1 AS position', 'forums_posts', $where, 'new_topic DESC, post_bwoptions DESC, post_field_int DESC, post_date' )->join( array( '(SELECT @rownum := 0)', 'r' ), NULL, 'JOIN' );
|
||||
$commentPosition = \IPS\Db::i()->select( 'position', $answers, array( 'pid=?', $comment->pid ) )->first() - 1;
|
||||
}
|
||||
|
||||
/* Now work out what page that makes it */
|
||||
$url = $item->url();
|
||||
$perPage = $item::getCommentsPerPage();
|
||||
$page = ceil( $commentPosition / $perPage );
|
||||
if ( $page != 1 )
|
||||
{
|
||||
$url = $url->setQueryString( 'page', $page );
|
||||
}
|
||||
|
||||
/* And redirect */
|
||||
$idField = $commentClass::$databaseColumnId;
|
||||
\IPS\Output::i()->redirect( $url->setFragment( 'comment-' . $comment->$idField ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit Comment/Review
|
||||
@@ -914,7 +1006,8 @@ class _topic extends \IPS\Content\Controller
|
||||
{
|
||||
try
|
||||
{
|
||||
$comment = \IPS\forums\Topic\Post::load( \IPS\Request::i()->comment );
|
||||
$commentClass = $class::$commentClass;
|
||||
$comment = $commentClass::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 );
|
||||
@@ -930,4 +1023,22 @@ class _topic extends \IPS\Content\Controller
|
||||
\IPS\Output::i()->error( 'node_error', '2F173/I', 404, '' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Form for splitting
|
||||
*
|
||||
* @param \IPS\Content\Item $item The item
|
||||
* @return \IPS\Helpers\Form
|
||||
*/
|
||||
protected function _splitForm( \IPS\Content\Item $item )
|
||||
{
|
||||
$form = parent::_splitForm( $item );
|
||||
|
||||
if ( isset( $form->elements['']['topic_create_state'] ) )
|
||||
{
|
||||
unset( $form->elements['']['topic_create_state'] );
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user