Version 4.7.23

This commit is contained in:
Neo committed 2025-12-19 16:21:27 -08:00
1 parent 7124a02564
commit 25ddeb65d6
1791 files changed
+76990 -44452

No files matched your search

@@ -646,7 +646,7 @@ class _forums extends \IPS\Dispatcher\Controller
$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'] ) ) );
$canHide = ( \IPS\Member::loggedIn()->group['g_hide_own_posts'] == '1' or \in_array( 'IPS\forums\Topic', 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
@@ -116,7 +116,6 @@ class _index extends \IPS\Dispatcher\Controller
if ( \IPS\forums\Forum::isSimpleView() )
{
$where = array();
if ( \IPS\forums\Forum::customPermissionNodes() )
{
$where = array( 'container' => array( array( 'forums_forums.password IS NULL' ) ) );
@@ -142,6 +141,7 @@ class _index extends \IPS\Dispatcher\Controller
/* Inline forum IDs? */
if ( \count( $ids ) )
{
$toUnset = [];
foreach( $ids as $id )
{
try
@@ -163,7 +163,16 @@ class _index extends \IPS\Dispatcher\Controller
$forumIds[] = $forum->id;
}
}
catch( \Exception $ex ) { }
catch( \Exception $ex ) {
$toUnset[] = $id;
}
}
/* Redirect to a page with valid forum ids */
if( $ids and count($forumIds ) AND $toUnset )
{
$newUrl = $this->url;
$newUrl = $newUrl->setQueryString( 'forumId', implode( ',', array_diff( $ids, $toUnset ) ) );
\IPS\Output::i()->redirect( $newUrl );
}
if ( \count( $forumIds ) )
@@ -354,7 +354,7 @@ class _topic extends \IPS\Content\Controller
}
/* Sidebar? */
if ( $topic->showSummaryOnDesktop() == 'sidebar' )
if ( !$topic->isArchived() AND $topic->showSummaryOnDesktop() == 'sidebar' )
{
\IPS\Output::i()->sidebar['contextual'] = \IPS\Theme::i()->getTemplate( 'topics' )->activity( $topic, 'sidebar' );
}
@@ -372,7 +372,10 @@ class _topic extends \IPS\Content\Controller
/* Add Json-LD */
$isQuestion = ( $topic->isQuestion() or $topic->isSolved() );
if ( $isQuestion )
/* The purpose of QAPage is to provide data on the question and suggested answer (if avaiable), or all comments if there is no answer.
However, a very large topic that has not been solved, is likely to confuse Google ("The QAPage type indicates that the page is focused on a specific question and its answer(s)"),
so if the topic is very long, we will only show this metadata if the topic has been solved. */
if ( $isQuestion and ( $topic->posts < \IPS\LARGE_TOPIC_REPLIES or $topic->isSolved() ) )
{
\IPS\Output::i()->jsonLd['topic'] = array(
'@context' => "http://schema.org",
@@ -381,17 +384,23 @@ class _topic extends \IPS\Content\Controller
'url' => (string) $topic->url(),
'mainEntity' => [
'@type' => "Question",
'answerCount' => $topic->posts ? $topic->posts - 1 : 0,
'name' => $topic->title,
'text' => $topic->comments( 1, 0 )->truncated( TRUE, NULL ),
'answerCount' => $topic->posts ? $topic->posts - 1 : 0,
'dateCreated' => \IPS\DateTime::ts( $topic->start_date )->format( \IPS\DateTime::ISO8601 ),
'author' => [
'@type' => 'Person',
'name' => $topic->author()->name
'@type' => 'Person',
'name' => $topic->author()->name,
'image' => $topic->author()->get_photo( TRUE, TRUE )
]
]
);
if( $topic->author()->member_id )
{
\IPS\Output::i()->jsonLd['topic']['mainEntity']['author']['url'] = (string) $topic->author()->url();
}
if( $topic->topic_answered_pid )
{
try
@@ -437,6 +446,32 @@ class _topic extends \IPS\Content\Controller
}
catch( \OutOfRangeException $e ){}
}
else if ( $topic->posts > 1 )
{
/* We have no accepted answer, but we have replies, so google still wants to see here some meta data, so let's show the last comment https://developers.google.com/search/docs/appearance/structured-data/qapage#answercount */
try
{
$lastComment = $topic->comments( 1, 0, 'date', 'desc' );
/* Set up our column names */
$authorIdColumn = $lastComment::$databaseColumnMap['author'];
$dateColumn = $lastComment::$databaseColumnMap['date'];
\IPS\Output::i()->jsonLd['topic']['mainEntity']['suggestedAnswer'] = array(
'@type' => 'Answer',
'text' => $lastComment->truncated( TRUE, NULL ),
'url' => (string) $lastComment->url(),
'dateCreated' => \IPS\DateTime::ts( $lastComment->$dateColumn )->format( \IPS\DateTime::ISO8601 ),
'upvoteCount' => ( $topic->isArchived() ) ? $lastComment->field_int : $lastComment->post_field_int,
'author' => array(
'@type' => 'Person',
'name' => \IPS\Member::load( $lastComment->$authorIdColumn )->name,
'image' => \IPS\Member::load( $lastComment->$authorIdColumn )->get_photo( TRUE, TRUE )
),
);
}
catch( \OutOfRangeException $e ){}
}
}
else
{
@@ -587,15 +622,19 @@ class _topic extends \IPS\Content\Controller
'@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'] );
if( !$topic->isArchived() )
{
\IPS\Output::i()->jsonLd['topic']['interactionStatistic'][] = [
'@type' => 'InteractionCounter',
'interactionType' => "http://schema.org/FollowAction",
'userInteractionCount' => $topic->followersCount()
];
}
/* Add og:image meta tags */
if( count( $file = $topic->imageAttachments(1 ) ) )
{
@@ -873,6 +912,7 @@ class _topic extends \IPS\Content\Controller
}
/* Rebuild count */
/* @note SELECT_FROM_WRITE_SERVER race condition added in 2fe7e3e434068a6a845106fbefd08821d05e60e4 */
$question->question_rating = \IPS\Db::i()->select( 'SUM(rating)', 'forums_question_ratings', array( 'topic=?', $question->tid ), NULL, NULL, NULL, NULL, \IPS\Db::SELECT_FROM_WRITE_SERVER )->first();
$question->save();
@@ -898,13 +938,14 @@ class _topic extends \IPS\Content\Controller
{
\IPS\Output::i()->error( 'node_error', '2F173/4', 404, '' );
}
if ( !$answer->item()->can('read') or !$answer->canVote() )
$rating = \intval( \IPS\Request::i()->rating );
if ( !$answer->item()->can('read') or !$answer->canVote( $rating ) )
{
\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, '' );
@@ -927,6 +968,7 @@ class _topic extends \IPS\Content\Controller
), TRUE );
}
/* @note SELECT_FROM_WRITE_SERVER race condition added in 9f4aa84545f6f9838143253050520180dfce5ef2 */
$answer->post_field_int = (int) \IPS\Db::i()->select( 'SUM(rating)', 'forums_answer_ratings', array( 'post=?', $answer->pid ), NULL, NULL, NULL, NULL, \IPS\Db::SELECT_FROM_WRITE_SERVER )->first();
$answer->save();
@@ -1316,20 +1358,4 @@ 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();
}
}