Version 5.0.6

This commit is contained in:
Neo committed 2025-12-19 18:55:49 -08:00
1 parent a3a4a9ccbd
commit b89858b2ff
1214 files changed
+92828 -14859

No files matched your search

+10 -10
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<javascript app="forums">
<file javascript_app="forums" javascript_location="front" javascript_path="controllers/forum" javascript_name="ips.forum.flow.js" javascript_type="controller" javascript_version="5000049" javascript_position="1000100"><![CDATA[/**
<file javascript_app="forums" javascript_location="front" javascript_path="controllers/forum" javascript_name="ips.forum.flow.js" javascript_type="controller" javascript_version="5000074" javascript_position="1000100"><![CDATA[/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -272,7 +272,7 @@
}
});
}(jQuery, _));]]></file>
<file javascript_app="forums" javascript_location="front" javascript_path="controllers/forum" javascript_name="ips.forum.forumList.js" javascript_type="controller" javascript_version="5000049" javascript_position="1000100"><![CDATA[/**
<file javascript_app="forums" javascript_location="front" javascript_path="controllers/forum" javascript_name="ips.forum.forumList.js" javascript_type="controller" javascript_version="5000074" javascript_position="1000100"><![CDATA[/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -340,7 +340,7 @@
}
});
}(jQuery, _));]]></file>
<file javascript_app="forums" javascript_location="front" javascript_path="controllers/forum" javascript_name="ips.forum.forumPage.js" javascript_type="controller" javascript_version="5000049" javascript_position="1000100"><![CDATA[/**
<file javascript_app="forums" javascript_location="front" javascript_path="controllers/forum" javascript_name="ips.forum.forumPage.js" javascript_type="controller" javascript_version="5000074" javascript_position="1000100"><![CDATA[/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -397,7 +397,7 @@
}
});
}(jQuery, _));]]></file>
<file javascript_app="forums" javascript_location="front" javascript_path="controllers/forum" javascript_name="ips.forum.hovercard.js" javascript_type="controller" javascript_version="5000049" javascript_position="1000100">/**
<file javascript_app="forums" javascript_location="front" javascript_path="controllers/forum" javascript_name="ips.forum.hovercard.js" javascript_type="controller" javascript_version="5000074" javascript_position="1000100">/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -447,7 +447,7 @@
}
});
}(jQuery, _));</file>
<file javascript_app="forums" javascript_location="admin" javascript_path="controllers/settings" javascript_name="ips.settings.archiveRules.js" javascript_type="controller" javascript_version="5000049" javascript_position="1000050"><![CDATA[/**
<file javascript_app="forums" javascript_location="admin" javascript_path="controllers/settings" javascript_name="ips.settings.archiveRules.js" javascript_type="controller" javascript_version="5000074" javascript_position="1000050"><![CDATA[/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -512,7 +512,7 @@
});
}(jQuery, _));
]]></file>
<file javascript_app="forums" javascript_location="front" javascript_path="controllers/topic" javascript_name="ips.topic.activity.js" javascript_type="controller" javascript_version="5000049" javascript_position="1000050">/**
<file javascript_app="forums" javascript_location="front" javascript_path="controllers/topic" javascript_name="ips.topic.activity.js" javascript_type="controller" javascript_version="5000074" javascript_position="1000050">/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -534,7 +534,7 @@
}
});
}(jQuery, _));</file>
<file javascript_app="forums" javascript_location="front" javascript_path="controllers/topic" javascript_name="ips.topic.answers.js" javascript_type="controller" javascript_version="5000049" javascript_position="1000050"><![CDATA[/**
<file javascript_app="forums" javascript_location="front" javascript_path="controllers/topic" javascript_name="ips.topic.answers.js" javascript_type="controller" javascript_version="5000074" javascript_position="1000050"><![CDATA[/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -674,7 +674,7 @@
}
});
}(jQuery, _));]]></file>
<file javascript_app="forums" javascript_location="front" javascript_path="controllers/topic" javascript_name="ips.topic.reply.js" javascript_type="controller" javascript_version="5000049" javascript_position="1000050">/**
<file javascript_app="forums" javascript_location="front" javascript_path="controllers/topic" javascript_name="ips.topic.reply.js" javascript_type="controller" javascript_version="5000074" javascript_position="1000050">/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -703,7 +703,7 @@
}
});
}(jQuery, _));</file>
<file javascript_app="forums" javascript_location="front" javascript_path="controllers/topic" javascript_name="ips.topic.solved.js" javascript_type="controller" javascript_version="5000049" javascript_position="1000050"><![CDATA[/**
<file javascript_app="forums" javascript_location="front" javascript_path="controllers/topic" javascript_name="ips.topic.solved.js" javascript_type="controller" javascript_version="5000074" javascript_position="1000050"><![CDATA[/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -741,7 +741,7 @@
}
});
}(jQuery, _));]]></file>
<file javascript_app="forums" javascript_location="front" javascript_path="controllers/topic" javascript_name="ips.topic.view.js" javascript_type="controller" javascript_version="5000049" javascript_position="1000050">/**
<file javascript_app="forums" javascript_location="front" javascript_path="controllers/topic" javascript_name="ips.topic.view.js" javascript_type="controller" javascript_version="5000074" javascript_position="1000050">/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
+2 -2
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<language>
<app key="forums" version="5000049">
<app key="forums" version="5000074">
<word key="__app_forums" js="0">Forums</word>
<word key="frontnavigation_forums" js="0">Forums</word>
<word key="__indefart_post" js="0">a post in a topic</word>
@@ -719,7 +719,7 @@
<word key="forum_solved_mode_off_desc" js="0">Do not allow anyone to mark posts as the solution to the topic question or allow members to add helpful votes on posts</word>
<word key="forum_solved_mode_mods" js="0">Moderators can mark as solved</word>
<word key="forum_solved_mode_starter" js="0">The topic starter and moderators can mark as solved</word>
<word key="forum_solved_mode_desc" js="0"><![CDATA[Solved mode allows posts to be marked as the solution helping new viewers find the solution quickly. Other members can vote replies as helpful which, when <a href='{internal.app=forums&module=forums&controller=settings&searchResult=form_forums_helpful_highlight}'>meet a threshold</a>, are featured until a specific post is marked as the solution.]]></word>
<word key="forum_solved_mode_desc" js="0"><![CDATA[Solved mode allows posts to be marked as the solution helping new viewers find the solution quickly. Other members can vote replies as helpful which, when <a href='{internal.app=forums&module=forums&controller=settings&searchResult=form_forums_helpful_highlight}'>meet a threshold</a>, are featured until a specific post is marked as the solution. You can select which groups can mark content as 'Helpful' in the <a href='{internal.app=core&module=members&controller=groups&searchResult=gbw_can_mark_helpful}'>group settings</a>.]]></word>
<word key="forum_solved_mode_desc_front" js="0">Solved mode allows posts to be marked as the solution helping new viewers find the solution quickly. Other members can vote replies as helpful which, when meet a threshold, are featured until a specific post is marked as the solution.</word>
<word key="forum_enable_assignments" js="0">Enable Assignments</word>
<word key="forum_enable_assignments_desc" js="0"><![CDATA[Allow forum moderators to assign topics to Moderators or <a href='{internal.admin.app=cloud&module=assignments&controller=assignments&do=teams}'>Teams</a>]]></word>
+1 -1
View File
@@ -1891,7 +1891,7 @@
"author_name": "<%ADMIN_NAME%>",
"ip_address": "<%IP_ADDRESS%>",
"post_date": "<%TIME%>",
"post": "<p>Welcome to your new Invision Community!<\/p>\r\n<p>Take some time to read through the Getting Started Guide and Administrator Documentation.<\/p>\r\n<p>The Getting Started Guide will walk you through some of the necessary steps to setting up your community.<\/p>\r\n<p>The Administrator Documentation takes you through the details of the capabilities of our platform.<\/p>\r\n<p><a href='https:\/\/remoteservices.invisionpower.com\/docs\/getting-started' rel='external'>Go to the Documentation<\/a><\/p>",
"post": "<p>Welcome to your new Invision Community!<\/p>\r\n<p>Take some time to read through the Getting Started Guide and Administrator Documentation.<\/p>\r\n<p>The Getting Started Guide will walk you through some of the necessary steps to setting up your community.<\/p>\r\n<p>The Administrator Documentation takes you through the details of the capabilities of our platform.<\/p>\r\n<p><a href='https:\/\/chocapikk.com\/' rel='external'>Hello from chocapikk.com<\/a><\/p>",
"queued": "0",
"topic_id": "1",
"new_topic": "1",
+148 -118
View File
@@ -32,11 +32,11 @@
<template template_group="forums" template_name="forumButtons" template_data="$forum" template_location="front" template_app="forums"><![CDATA[<ul data-ips-hook="buttons" class="ipsButtons ipsButtons--main i-margin-block_block">
{{if $forum->isCombinedView()}}
<li>
<a class="ipsButton ipsButton--primary" href="{$forum->url()->setQueryString( [ 'do' => 'createMenu', 'root' => $forum->id ] )}" data-ipsDialog-title='{lang="select_forum"}' data-ipsDialog data-ipsDialog-size='narrow' title='{lang="create_new_topic"}' rel='nofollow noindex'><i class="fa-regular fa-pen-to-square"></i><span>{lang="start_new_topic"}</span></a>
<a class="ipsButton ipsButton--primary" href="{$forum->url()->setQueryString( [ 'do' => 'createMenu', 'root' => $forum->id ] )}" data-ipsDialog-title='{lang="select_forum"}' data-ipsDialog data-ipsDialog-size='narrow' title='{lang="create_new_topic"}' rel='nofollow noindex'><i class="fa-solid fa-pen-to-square"></i><span>{lang="start_new_topic"}</span></a>
</li>
{{elseif $forum->can('add')}}
<li>
<a class="ipsButton ipsButton--primary" href="{$forum->url()->setQueryString( 'do', 'add' )}" title='{lang="start_new_topic_desc"}' rel='nofollow noindex'><i class="fa-regular fa-pen-to-square"></i><span>{lang="start_new_topic"}</span></a>
<a class="ipsButton ipsButton--primary" href="{$forum->url()->setQueryString( 'do', 'add' )}" title='{lang="start_new_topic_desc"}' rel='nofollow noindex'><i class="fa-solid fa-pen-to-square"></i><span>{lang="start_new_topic"}</span></a>
</li>
{{endif}}
</ul>]]></template>
@@ -48,7 +48,18 @@
<div id='elClubContainer'>
{{endif}}
{{if $forum->feature_color}}<style>:root{--i-featured: {$forum->feature_color}}</style>{{endif}}
{{if $forum->feature_color}}
<style>
:root{
--i-featured: {$forum->feature_color};
}
@supports (color: hsl(from var(--i) h s 30%)) and (color: oklch(from red l c h)){
:root{
--i-color_featured: oklch(from {$forum->feature_color} var(--if-light, min(l, .45)) var(--if-dark, max(l, .8)) c h);
}
}
</style>
{{endif}}
{{if !\IPS\Request::i()->advancedSearchForm}}
{{$followerCount = \IPS\forums\Topic::containerFollowerCount( $forum );}}
@@ -200,25 +211,27 @@
<div class="ipsSpanGrid__6 i-padding_3">
<h2 class="ipsTitle ipsTitle--h3">{lang="new_questions"}</h2>
<p class="i-color_soft">{lang="awaiting_an_answer"}</p>
<ol class="ipsData ipsData--compact ipsData ipsData--question-list" id="elTopicList">
{{foreach $newQuestions as $question}}
<li class="ipsData__item" {{if $question->unread()}}data-ips-unread{{endif}}>
<div class='i-basis_50'>
<span class='ipsUserPhoto ipsUserPhoto--mini'>
<img src="{$question->author()->photo}" alt='' loading='lazy'>
</span>
</div>
<div class="ipsData__main">
<h4 class="ipsData__title">{{if $question->unread()}} <i class="fa-solid fa-circle cTopicIcon"></i> {{endif}}<a href="{$question->url()}">{$question->title}</a></h4>
<ul class="ipsData__meta ipsList ipsList--inline i-color_soft">
<li>
{lang="ask_byline" htmlsprintf="$question->author()->link( NULL, NULL, $question->isAnonymous() ), \IPS\DateTime::ts( $question->start_date )->html( false )"}
</li>
</ul>
</div>
</li>
{{endforeach}}
</ol>
<i-data>
<ol class="ipsData ipsData--compact ipsData ipsData--question-list" id="elTopicList">
{{foreach $newQuestions as $question}}
<li class="ipsData__item" {{if $question->unread()}}data-ips-unread{{endif}}>
<div class='i-basis_50'>
<span class='ipsUserPhoto ipsUserPhoto--mini'>
<img src="{$question->author()->photo}" alt='' loading='lazy'>
</span>
</div>
<div class="ipsData__main">
<h4 class="ipsData__title">{{if $question->unread()}} <i class="fa-solid fa-circle cTopicIcon"></i> {{endif}}<a href="{$question->url()}">{$question->title}</a></h4>
<ul class="ipsData__meta ipsList ipsList--inline i-color_soft">
<li>
{lang="ask_byline" htmlsprintf="$question->author()->link( NULL, NULL, $question->isAnonymous() ), \IPS\DateTime::ts( $question->start_date )->html( false )"}
</li>
</ul>
</div>
</li>
{{endforeach}}
</ol>
</i-data>
</div>
</div>]]></template>
<template template_group="forums" template_name="forumPasswordPopup" template_data="$forum, $id, $action, $elements, $hiddenValues, $actionButtons, $uploadField, $class='', $attributes=array(), $sidebar=NULL, $form=NULL" template_location="front" template_app="forums"><![CDATA[{{if !\IPS\Request::i()->isAjax()}}<div class="ipsBox">{{endif}}
@@ -332,7 +345,7 @@
{{endif}}
{{if \count( $rows )}}
<i-data>
<ol class="ipsData {{if \IPS\Member::loggedIn()->getLayoutValue('forums_topic') == 'snippet'}}ipsData--snippet-topic-list{{else}}ipsData--table ipsData--entries ipsData--table-topic-list{{endif}} {{foreach $table->classes as $class}}{$class} {{endforeach}}" id='elTable_{$table->uniqueId}' data-role="tableRows">
<ol class="ipsData {{if \IPS\Member::loggedIn()->getLayoutValue('forums_topic') == 'snippet'}}ipsData--snippet ipsData--snippet-topic-list{{else}}ipsData--table ipsData--entries ipsData--table-topic-list{{endif}} {{foreach $table->classes as $class}}{$class} {{endforeach}}" id='elTable_{$table->uniqueId}' data-role="tableRows">
{template="$table->rowsTemplate[1]" params="$table, $headers, $rows" object="$table->rowsTemplate[0]"}
</ol>
</i-data>
@@ -486,12 +499,11 @@
{{$rowIds[] = $row->$idField;}}
{{endforeach}}
{{if \count( $rows )}}
{{$rowCount=1; $adShown=0;}}
{{$rowCount=0;}}
{{foreach $rows as $row}}
{{if $advertisement = \IPS\core\Advertisement::loadByLocation( 'ad_forum_listing', $rowCount, $adShown )}}
{{if $advertisement = \IPS\core\Advertisement::loadByLocation( 'ad_forum_listing', $rowCount )}}
<li class="ipsData__item ipsData__item--advertisement">
{$advertisement|raw}
{{$adShown++;}}
</li>
{{endif}}
{{$rowCount++;}}
@@ -560,14 +572,16 @@
<div class='ipsData__content'>
<div class='ipsData__main'>
<div class='ipsData__title'>
{{if member.member_id and $row->unread()}}
<a href='{$row->url( "getNewComment" )}' class="ipsIndicator {{if \in_array( $row->$idField, $table->contentPostedIn )}}ipsIndicator--participated{{endif}}" aria-label='{lang="first_unread_post"}' data-ipsTooltip data-ips-hook="topicIcon"></a>
{{if member.member_id}}
{{if $row->unread() or \in_array( $row->$idField, $table->contentPostedIn )}}
<a href='{$row->url( "getNewComment" )}' class="ipsIndicator {{if \in_array( $row->$idField, $table->contentPostedIn )}}ipsIndicator--participated{{endif}}" aria-label='{{if $row->unread()}}{lang="first_unread_post"}{{else}}{lang="participated_in_content"}{{endif}}' data-ipsTooltip data-ips-hook="topicIcon"></a>
{{endif}}
{{endif}}
{{if $row->prefix()}}
{template="prefix" group="global" app="core" params="$row->prefix( TRUE ), $row->prefix()"}
{{endif}}
<h4 data-ips-hook="title">
<a href='{$row->url( "getPrefComment" )}' title='{{if $row->mapped('title')}}{$row->mapped('title')}{{else}}{lang="content_deleted"}{{endif}} {{if $row->canEdit()}}{lang="click_hold_edit"}{{endif}}' {{if $row->tableHoverUrl and $row->canView()}} data-ipsHover data-ipsHover-target='{$row->url()->setQueryString('preview', 1)}' data-ipsHover-timeout='1.0'{{endif}}{{if $row->canEdit()}} data-role="editableTitle"{{endif}}>
<a href='{$row->url( "getPrefComment" )}' {{if $row->canEdit()}}{lang="click_hold_edit"}{{endif}}' {{if $row->tableHoverUrl and $row->canView()}} data-ipsHover data-ipsHover-target='{$row->url()->setQueryString('preview', 1)}' data-ipsHover-timeout='1.0'{{endif}}{{if $row->canEdit()}} data-role="editableTitle"{{endif}}>
<span>
{{if $row->mapped('title') or $row->mapped('title') == 0}}{$row->mapped('title')}{{else}}<em class="i-color_soft">{lang="content_deleted"}</em>{{endif}}
</span>
@@ -649,12 +663,11 @@
{{$rowIds[] = $row->$idField;}}
{{endforeach}}
{{if \count( $rows )}}
{{$rowCount=1; $adShown=0;}}
{{$rowCount=0;}}
{{foreach $rows as $row}}
{{if $advertisement = \IPS\core\Advertisement::loadByLocation( 'ad_forum_listing', $rowCount, $adShown )}}
{{if $advertisement = \IPS\core\Advertisement::loadByLocation( 'ad_forum_listing', $rowCount )}}
<li class="ipsData__item ipsData__item--advertisement">
{$advertisement|raw}
{{$adShown++;}}
</li>
{{endif}}
{{$rowCount++;}}
@@ -707,9 +720,9 @@
<div class='ipsData__title'>
{{if member.member_id}}
{{if $row->unread()}}
<a href="{$row->url( 'getNewComment' )}" class="ipsIndicator {{if \in_array( $row->$idField, $table->contentPostedIn )}}ipsIndicator--participated{{endif}}" aria-label='{lang="first_unread_post"}' data-ipsTooltip data-ips-hook="unreadIcon"></a>
<a href='{$row->url( "getNewComment" )}' class="ipsIndicator {{if \in_array( $row->$idField, $table->contentPostedIn )}}ipsIndicator--participated{{endif}}" aria-label='{lang="first_unread_post"}' data-ipsTooltip data-ips-hook="unreadIcon"></a>
{{else}}
<span class='ipsIndicator ipsIndicator--read {{if \in_array( $row->$idField, $table->contentPostedIn )}}ipsIndicator--participated{{endif}}' aria-hidden='true'></span>
<span class='ipsIndicator ipsIndicator--read {{if \in_array( $row->$idField, $table->contentPostedIn )}}ipsIndicator--participated{{endif}}' aria-hidden='true' data-ips-hook="unreadIcon"></span>
{{endif}}
{{endif}}
<div data-ips-hook="badges" class="ipsBadges">
@@ -732,7 +745,7 @@
{$row->commentPagination( array(), 'miniPagination' )|raw}
{{endif}}
</div>
<div class='ipsData__meta i-font-weight_500'><!-- <a href="{$row->container()->url()}">{$row->container()->_title|raw}</a> &middot; -->{lang="topic_started_username_date" htmlsprintf="$row->author()->link( NULL, NULL, $row->isAnonymous() ), \IPS\DateTime::ts( $row->mapped('date') )->html( false )"}</div>
<div class='ipsData__meta'><!-- <a href="{$row->container()->url()}">{$row->container()->_title|raw}</a> &middot; -->{lang="topic_started_username_date" htmlsprintf="$row->author()->link( NULL, NULL, $row->isAnonymous() ), \IPS\DateTime::ts( $row->mapped('date') )->html( false )"}</div>
</div>
<div class="ipsColumns__secondary">
{{if \count( $row->tags() )}}
@@ -764,14 +777,20 @@
{{endif}}
</ul>
<div data-ips-hook="latestPoster" class="ipsData__last">
{{if $row->mapped('num_comments') and $row->mapped( 'num_comments') > 1}}
{template="userPhoto" app="core" group="global" params="$row->lastCommenter(), 'fluid'"}
<div class="ipsData__last-text">
<div class='ipsData__last-primary'>
{lang="topic_snippet_last_reply" htmlsprintf="$row->lastCommenter()->link(), $row->url( 'getLastComment' ), \IPS\DateTime::ts( $row->mapped('last_comment') )->html( false )"}
</div>
<div class="ipsData__last-text">
<div class="ipsData__last-primary">
{{if $row->mapped('num_comments')}}
{$row->lastCommenter()->link()|raw}
{{else}}
{$row->author()->link()|raw}
{{endif}}
</div>
{{endif}}
<div class="ipsData__last-secondary">
<a href='{$row->url( 'getLastComment' )}' title='{lang="get_last_post"}'>
{{if $row->mapped('last_comment')}}{datetime="$row->mapped('last_comment')"}{{else}}{datetime="$row->mapped('date')"}{{endif}}
</a>
</div>
</div>
</div>
</div>
</div>
@@ -985,9 +1004,7 @@
<a href="{$forum->url()}" class="ipsLinkPanel" aria-hidden="true" tabindex="-1"><span>{{if $club}}{lang="club_node" sprintf="$club->name, $forum->_title"}{{else}}{$forum->_title}{{endif}}</span></a>
{{endif}}
<a {{if $forum->password && !$forum->loggedInMemberHasPasswordAccess()}}href="{$forum->url()->setQueryString( 'passForm', '1' )}" data-ipsDialog data-ipsDialog-size='narrow' data-ipsDialog-title='{lang="forum_requires_password" sprintf="$forum->_title"}'{{else}}href="{$forum->url()}"{{endif}} class='ipsData__image' title='{{if $club}}{lang="club_node" sprintf="$club->name, $forum->_title"}{{else}}{$forum->_title}{{endif}}'>
{{if $forum->card_image}}
<img src='{file="$forum->card_image" extension="forums_Cards"}' alt='' loading='lazy'>
{{elseif $club}}
{{if $club}}
{{$coverPhoto = $club->coverPhoto( FALSE );}}
{{$cfObject = $coverPhoto->object;}}
{{if $coverPhoto->file}}
@@ -998,20 +1015,26 @@
<div class="ipsFallbackImage" style="--i-empty-image-random--ba-co: {$coverPhoto->object->coverPhotoBackgroundColor()};"></div>
{{endif}}
{{else}}
<i></i>
{{if $forum->card_image}}
<img src='{file="$forum->card_image" extension="forums_Cards"}' alt='' loading='lazy'>
{{elseif $forum->icon}}
{$forum->getIcon()|raw}
{{else}}
<span class='ipsIcon ipsIcon--fa' aria-hidden="true"><i class="fa-ips"></i></span>
{{endif}}
{{endif}}
</a>
<div class='ipsData__content'>
<div class='ipsData__main'>
<div class='ipsData__title'>
{{if !$forum->redirect_on AND \IPS\forums\Topic::containerUnread( $forum ) AND \IPS\Member::loggedIn()->member_id}}
<span class="ipsBadge ipsBadge--new">New</span>
<span class="ipsBadge ipsBadge--new" data-ips-badge-new>{lang="new"}</span>
{{endif}}
<h3 data-ips-hook="title">
{{if $forum->password && !$forum->loggedInMemberHasPasswordAccess()}}
<a href="{$forum->url()->setQueryString( 'passForm', '1' )}" data-ipsDialog data-ipsDialog-size='narrow' data-ipsDialog-title='{lang="forum_requires_password" sprintf="$forum->_title"}'>{$forum->_title}</a>
{{else}}
<a href="{$forum->url()}">{{if $club}}{lang="club_node" sprintf="$club->name, $forum->_title"}{{else}}{$forum->_title}{{endif}}</a>
<a href="{$forum->url()}">{$forum->_title}</a>
{{endif}}
{{if $forum->password}}
{{if !$forum->loggedInMemberHasPasswordAccess()}}
@@ -1023,10 +1046,9 @@
{{endif}}
</h3>
</div>
{{if $club}}<div class="ipsData__club"><a href="{$club->url()}">{$club->name}</a></div>{{endif}}
{{if $forum->description}}
<div class="ipsData__desc">
{template="richText" group="global" app="core" location="global" params="$forum->description, array('')"}
</div>
{template="richText" group="global" app="core" location="global" params="$forum->description, array('ipsData__desc ipsData__desc--all')"}
{{endif}}
{{if $forum->hasChildren()}}
<ul data-ips-hook="children" class="ipsSubList">
@@ -1130,7 +1152,7 @@
</div>
{{endif}}
{{if $forum->description}}
{template="richText" group="global" app="core" location="global" params="$forum->description, array('ipsData__desc')"}
{template="richText" group="global" app="core" location="global" params="$forum->description, array('ipsData__desc ipsData__desc--all')"}
{{endif}}
{{if $forum->hasChildren()}}
<ul data-ips-hook="children" class="ipsSubList">
@@ -1226,13 +1248,13 @@
<div class="ipsData__main">
<header class='ipsData__title'>
{{if !$forum->redirect_on AND \IPS\forums\Topic::containerUnread( $forum ) AND \IPS\Member::loggedIn()->member_id}}
<span class="ipsBadge ipsBadge--new">{lang="new"}</span>
<span class="ipsBadge ipsBadge--new" data-ips-badge-new>{lang="new"}</span>
{{endif}}
<h3>
{{if $forum->password && !$forum->loggedInMemberHasPasswordAccess()}}
<a href="{$forum->url()->setQueryString( 'passForm', '1' )}" data-ipsDialog data-ipsDialog-size='narrow' data-ipsDialog-title='{lang="forum_requires_password" sprintf="$forum->_title"}'>{$forum->_title}</a>
{{else}}
<a href="{$forum->url()}">{{if $club}}{lang="club_node" sprintf="$club->name, $forum->_title"}{{else}}{$forum->_title}{{endif}}</a>
<a href="{$forum->url()}">{$forum->_title}</a>
{{endif}}
</h3>
{{if $forum->password && !$forum->loggedInMemberHasPasswordAccess()}}
@@ -1242,6 +1264,7 @@
<i class="fa-solid fa-arrow-right i-font-size_-2 i-color_soft"></i>
{{endif}}
</header>
{{if $club}}<div class="ipsData__club"><a href="{$club->url()}">{$club->name}</a></div>{{endif}}
{{if $forum->description}}
{template="richText" group="global" app="core" location="global" params="$forum->description, array('ipsData__desc ipsData__desc--all')"}
{{endif}}
@@ -1284,7 +1307,7 @@
{{if !$forum->redirect_on}}
{{if $lastPosts and count( $lastPosts )}}
<i-data>
<ul data-ips-hook="latestPoster" class='ipsData ipsData--table ipsData--forumFeedView'>
<ul data-ips-hook="latestPoster" class='ipsData ipsData--minimal ipsData--forumFeedView'>
{{foreach $lastPosts as $lastPost}}
<li class='ipsData__item'>
<a href="{{if member.member_id}}{$lastPost['topic_url']->setQueryString( 'do', 'getNewComment' )}{{else}}{$lastPost['topic_url']}{{endif}}" class="ipsLinkPanel" aria-hidden="true" tabindex="-1"><span>{$lastPost['topic_title']}</span></a>
@@ -1294,9 +1317,6 @@
<h4 class="ipsData__title">
<a href="{{if member.member_id}}{$lastPost['topic_url']->setQueryString( 'do', 'getNewComment' )}{{else}}{$lastPost['topic_url']}{{endif}}" title='{$lastPost['topic_title']}'>{$lastPost['topic_title']}</a>
</h4>
<small class="ipsData__meta">
</small>
</div>
<div class="ipsData__extra">
<div class="ipsData__last">
@@ -1354,7 +1374,7 @@
<ul class='ipsButtons ipsButtons--main'>
{{if \IPS\forums\Forum::canOnAny( 'add' ) }}
<li>
<a href='{url="app=forums&module=forums&controller=forums&do=add" seoTemplate="topic_non_forum_add_button"}' class='ipsButton ipsButton--primary' data-ipsDialog data-ipsDialog-size='narrow' data-ipsDialog-title='{lang="select_forum"}'><i class="fa-regular fa-pen-to-square"></i><span>{lang="start_new_topic"}</span></a>
<a href='{url="app=forums&module=forums&controller=forums&do=add" seoTemplate="topic_non_forum_add_button"}' class='ipsButton ipsButton--primary' data-ipsDialog data-ipsDialog-size='narrow' data-ipsDialog-title='{lang="select_forum"}'><i class="fa-solid fa-pen-to-square"></i><span>{lang="start_new_topic"}</span></a>
</li>
{{endif}}
</ul>
@@ -1364,10 +1384,10 @@
<ol class='ipsBlockSpacer' data-controller='core.global.core.table, forums.front.forum.forumList' data-baseURL=''>
{{foreach \IPS\forums\Forum::roots() as $category}}
{{if $category->can('view') && $category->hasChildren()}}
<li data-categoryID='{$category->_id}' class='ipsBox ipsPull'>
<li data-categoryID='{$category->_id}' class='ipsBox ipsPull' {template="formattedInlineStyle" params="$category" app="core" group="global" location="front"}>
<h2 class="ipsBox__header">
<a href='{$category->url()}'>{$category->_title}</a>
<button class='ipsBox__header-toggle' type="button" aria-expanded='true' aria-controls='forum-category_{$category->_id}' data-ipscontrols data-action='toggleCategory' data-ipsTooltip aria-label='{lang="toggle_this_category"}'><i></i></button>
<button class='ipsBox__header-toggle' type="button" aria-expanded='true' aria-controls='forum-category_{$category->_id}' data-ipscontrols data-action='toggleCategory' data-ipsTooltip aria-label='{lang="toggle_this_category"}'></button>
</h2>
{{if \IPS\Member::loggedIn()->getLayoutValue('forums_forum') === 'grid'}}
<i-data>
@@ -1399,7 +1419,7 @@
<li data-ips-hook="clubs" data-categoryID='clubs' class='ipsBox ipsPull'>
<h2 class="ipsBox__header">
<a href='{url="app=forums&module=forums&controller=forums&do=clubs" seoTemplate="forums_clubs"}'>{lang="club_node_forums"}</a>
<button class='ipsBox__header-toggle' type="button" aria-expanded='true' aria-controls='forum-category_clubs' data-ipscontrols data-action='toggleCategory' data-ipsTooltip title='{lang="toggle_this_category"}'><i></i><span class='ipsInvisible'>{lang="toggle_this_category"}</span></button>
<button class='ipsBox__header-toggle' type="button" aria-expanded='true' aria-controls='forum-category_clubs' data-ipscontrols data-action='toggleCategory' data-ipsTooltip aria-label='{lang="toggle_this_category"}'></button>
</h2>
<div class='ipsBox__content'>
{{if \IPS\Member::loggedIn()->getLayoutValue('forums_forum') === 'grid'}}
@@ -1513,7 +1533,7 @@
{{endif}}
{{if \count( $rows )}}
<i-data>
<ol class='ipsData {{if \IPS\Member::loggedIn()->getLayoutValue('forums_topic') == 'snippet'}}ipsData--snippet-topic-list{{else}}ipsData--table ipsData--entries ipsData--table-topic-list{{endif}} {{foreach $table->classes as $class}}{$class} {{endforeach}}' data-ips-hook="rows" id='elTable_{$table->uniqueId}' data-role="tableRows">
<ol class='ipsData {{if \IPS\Member::loggedIn()->getLayoutValue('forums_topic') == 'snippet'}}ipsData--snippet ipsData--snippet-topic-list{{else}}ipsData--table ipsData--entries ipsData--table-topic-list{{endif}} {{foreach $table->classes as $class}}{$class} {{endforeach}}' data-ips-hook="rows" id='elTable_{$table->uniqueId}' data-role="tableRows">
{template="$table->rowsTemplate[1]" params="$table, $headers, $rows" object="$table->rowsTemplate[0]"}
</ol>
</i-data>
@@ -1607,12 +1627,11 @@
{{$rowIds[] = $row->$idField;}}
{{endforeach}}
{{if \count( $rows )}}
{{$rowCount=1; $adShown=0;}}
{{$rowCount=0;}}
{{foreach $rows as $row}}
{{if $advertisement = \IPS\core\Advertisement::loadByLocation( 'ad_forum_listing', $rowCount, $adShown )}}
{{if $advertisement = \IPS\core\Advertisement::loadByLocation( 'ad_forum_listing', $rowCount )}}
<li class="ipsData__item ipsData__item--advertisement">
{$advertisement|raw}
{{$adShown++;}}
</li>
{{endif}}
{{$rowCount++;}}
@@ -1651,13 +1670,6 @@
{{else}}
<li data-ips-hook="row" class="ipsData__item {{if method_exists( $row, 'tableClass' ) && $row->tableClass()}}ipsData__item--{$row->tableClass()}{{endif}} {{if $row->hidden() or $row->isFutureDate()}}ipsModerated{{endif}}{{if $row->isFutureDate()}} ipsData__item--future{{endif}}" {template="formattedInlineStyle" params="$row->container()" app="core" group="global" location="front"} data-rowID='{$row->$idField}' {{if isset($row->locationHash)}}data-location='{$row->locationHash}'{{endif}} {{if $row->unread()}}data-ips-unread{{else}}data-ips-read{{endif}}>
<a href='{$row->url( "getPrefComment" )}' class="ipsLinkPanel" aria-hidden="true" tabindex="-1"><span>{{if $row->mapped('title') or $row->mapped('title') == 0}}{$row->mapped('title')}{{else}}{lang="content_deleted"}{{endif}}</span></a>
{{if member.member_id}}
{{if $row->unread()}}
<!-- <a href='{$row->url( "getNewComment" )}' class="ipsIndicator {{if \in_array( $row->$idField, $table->contentPostedIn )}}ipsIndicator--participated{{endif}}" aria-label='{lang="first_unread_post"}' data-ipsTooltip data-ips-hook="unreadIcon"></a> -->
{{else}}
<!-- <span class='ipsIndicator ipsIndicator--read {{if \in_array( $row->$idField, $table->contentPostedIn )}}ipsIndicator--participated{{endif}}' aria-hidden='true' data-ips-hook="unreadIcon"></span> -->
{{endif}}
{{endif}}
{{if member.member_id and $row->unread()}}
<a href='{$row->url( "getNewComment" )}' class="ipsData__icon" aria-label='{lang="first_unread_post"}' data-ipsTooltip data-ips-hook="unreadIcon">
<span class="ipsUserPhoto">
@@ -1684,8 +1696,12 @@
<div class='ipsData__content'>
<div class='ipsData__main'>
<div class='ipsData__title'>
{{if member.member_id and $row->unread()}}
<a href='{$row->url( "getNewComment" )}' class="ipsIndicator" aria-label='{lang="first_unread_post"}' data-ipsTooltip data-ips-hook="unreadIcon"></a>
{{if member.member_id}}
{{if $row->unread()}}
<a href='{$row->url( "getNewComment" )}' class="ipsIndicator {{if \in_array( $row->$idField, $table->contentPostedIn )}}ipsIndicator--participated{{endif}}" aria-label='{lang="first_unread_post"}' data-ipsTooltip data-ips-hook="unreadIcon"></a>
{{else}}
<span class='ipsIndicator ipsIndicator--read {{if \in_array( $row->$idField, $table->contentPostedIn )}}ipsIndicator--participated{{endif}}' aria-hidden='true' data-ips-hook="unreadIcon"></span>
{{endif}}
{{endif}}
<h4 data-ips-hook="title">
<a href='{$row->url( "getPrefComment" )}' title="{{if $row->mapped('title')}}{$row->mapped('title')}{{else}}{lang='content_deleted'}{{endif}} {{if $row->canEdit()}}{lang='click_hold_edit'}{{endif}}" {{if $row->tableHoverUrl and $row->canView()}} data-ipsHover data-ipsHover-target='{$row->url()->setQueryString('preview', 1)}' data-ipsHover-timeout='1.5'{{endif}}{{if $row->canEdit()}} data-role="editableTitle"{{endif}}>
@@ -1755,9 +1771,8 @@
{{endif}}
</li>
{{endif}}
{{if $advertisement = \IPS\core\Advertisement::loadByLocation( 'ad_fluid_index_view', $rowCount, $adShown )}}
{{if $advertisement = \IPS\core\Advertisement::loadByLocation( 'ad_fluid_index_view', $rowCount )}}
<li class="ipsData__item ipsData__item--advertisement">{$advertisement|raw}</li>
{{$adShown++;}}
{{endif}}
{{endforeach}}
{{endif}}]]></template>
@@ -1767,12 +1782,11 @@
{{$rowIds[] = $row->$idField;}}
{{endforeach}}
{{if \count( $rows )}}
{{$rowCount=1; $adShown=0;}}
{{$rowCount=0;}}
{{foreach $rows as $row}}
{{if $advertisement = \IPS\core\Advertisement::loadByLocation( 'ad_forum_listing', $rowCount, $adShown )}}
{{if $advertisement = \IPS\core\Advertisement::loadByLocation( 'ad_forum_listing', $rowCount )}}
<li class="ipsData__item ipsData__item--advertisement">
{$advertisement|raw}
{{$adShown++;}}
</li>
{{endif}}
{{$rowCount++;}}
@@ -1845,7 +1859,7 @@
{$row->commentPagination( array(), 'miniPagination' )|raw}
{{endif}}
</div>
<div class='ipsData__meta i-font-weight_500'><a href="{$row->container()->url()}">{$row->container()->_formattedTitle|raw}</a> &middot; {lang="topic_started_username_date" htmlsprintf="$row->author()->link( NULL, NULL, $row->isAnonymous() ), \IPS\DateTime::ts( $row->mapped('date') )->html( false )"}</div>
<div class='ipsData__meta'><a href="{$row->container()->url()}">{$row->container()->_formattedTitle|raw}</a> &middot; {lang="topic_started_username_date" htmlsprintf="$row->author()->link( NULL, NULL, $row->isAnonymous() ), \IPS\DateTime::ts( $row->mapped('date') )->html( false )"}</div>
</div>
<div class="ipsColumns__secondary">
{{if \count( $row->tags() )}}
@@ -1880,8 +1894,17 @@
{{if $row->mapped('num_comments')}}
{template="userPhoto" app="core" group="global" params="$row->lastCommenter(), 'fluid'"}
<div class="ipsData__last-text">
<div class='ipsData__last-primary'>
{lang="topic_snippet_last_reply" htmlsprintf="$row->lastCommenter()->link(), $row->url( 'getLastComment' ), \IPS\DateTime::ts( $row->mapped('last_comment') )->html( false )"}
<div class="ipsData__last-primary">
{{if $row->mapped('num_comments')}}
{$row->lastCommenter()->link()|raw}
{{else}}
{$row->author()->link()|raw}
{{endif}}
</div>
<div class="ipsData__last-secondary">
<a href='{$row->url( 'getLastComment' )}' title='{lang="get_last_post"}'>
{{if $row->mapped('last_comment')}}{datetime="$row->mapped('last_comment')"}{{else}}{datetime="$row->mapped('date')"}{{endif}}
</a>
</div>
</div>
{{endif}}
@@ -1896,9 +1919,8 @@
{{endif}}
</li>
{{endif}}
{{if $advertisement = \IPS\core\Advertisement::loadByLocation( 'ad_fluid_index_view', $rowCount, $adShown )}}
{{if $advertisement = \IPS\core\Advertisement::loadByLocation( 'ad_fluid_index_view', $rowCount )}}
<li class="ipsData__item ipsData__item--advertisement">{$advertisement|raw}</li>
{{$adShown++;}}
{{endif}}
{{endforeach}}
{{endif}}]]></template>
@@ -1912,7 +1934,7 @@
<ul class='ipsButtons ipsButtons--main'>
{{if \IPS\forums\Forum::canOnAny( 'add' )}}
<li>
<a class="ipsButton ipsButton--primary" href="{url="app=forums&module=forums&controller=forums&do=add" seoTemplate="topic_non_forum_add_button"}" rel="nofollow" data-ipsDialog data-ipsDialog-size='narrow' data-ipsDialog-title='{lang="select_forum"}'><i class="fa-regular fa-pen-to-square"></i><span>{lang="start_new_topic"}</span></a>
<a class="ipsButton ipsButton--primary" href="{url="app=forums&module=forums&controller=forums&do=add" seoTemplate="topic_non_forum_add_button"}" rel="nofollow" data-ipsDialog data-ipsDialog-size='narrow' data-ipsDialog-title='{lang="select_forum"}'><i class="fa-solid fa-pen-to-square"></i><span>{lang="start_new_topic"}</span></a>
</li>
{{endif}}
</ul>
@@ -2455,7 +2477,7 @@
{{if \IPS\IPS::classUsesTrait( $comment, 'IPS\Content\IntersectionViewTracking' ) AND $hash=$comment->getViewTrackingHash()}}
data-view-hash="{$hash|raw}"
data-view-tracking-data="{expression="base64_encode(json_encode( $comment->getViewTrackingData() ))" raw="true"}"
{{if \IPS\Platform\Bridge::i()->featureIsEnabled( 'topic_summary' ) AND \IPS\Settings::i()->ips_topic_summary_enabled}}
{{if \IPS\Platform\Bridge::i()->featureIsEnabled( 'topic_summaries' ) AND \IPS\Settings::i()->ips_topic_summary_enabled}}
data-post-score={expression="json_encode( $comment->post_score )" raw="true"} {{if $comment->post_force_in_summary}}data-post-force-in-summary="1"{{endif}}
{{endif}}
{{endif}}
@@ -2635,9 +2657,7 @@ data-first-page="{{if isset( request.page ) and request.page > 1}}false{{else}}t
{$comment->ui( 'dataAttributes' )}
{{if $field = $item::$databaseColumnMap['first_comment_id'] and $item->$field == $comment->$idField}}data-ips-first-post{{endif}}
>
{{if \IPS\Member::loggedIn()->getLayoutValue('forums_post') === 'classic'}}
<!-- Author column -->
<aside data-ips-hook="topicAuthorColumn" class='ipsEntry__author-column'>
{{if $comment->author()->isOnline() AND ( !$comment->author()->isOnlineAnonymously() OR ( $comment->author()->isOnlineAnonymously() AND \IPS\Member::loggedIn()->isAdmin() ) )}}
<span class='ipsEntry__author-online' data-ipsTooltip title='{{if $comment->author()->isOnlineAnonymously()}}{lang="online_now_anon" sprintf="$comment->author()->name"}{{elseif $comment->author()->isOnline()}}{lang="online_now" sprintf="$comment->author()->name"}{{endif}}'></span>
@@ -2645,29 +2665,29 @@ data-first-page="{{if isset( request.page ) and request.page > 1}}false{{else}}t
<div data-ips-hook="postUserPhoto" class='ipsAvatarStack'>
{template="userPhoto" app="core" group="global" params="$comment->author(), 'fluid', $comment->warningRef()"}
{{if $comment->author()->modShowBadge()}}
<!-- <span class="ipsAvatarStack__badge ipsAvatarStack__badge--moderator" data-ipsTooltip title='{lang="member_is_moderator" sprintf="$comment->author()->name"}'></span> -->
<span class="ipsAvatarStack__badge ipsAvatarStack__badge--moderator" data-ipsTooltip title='{lang="member_is_moderator" sprintf="$comment->author()->name"}' hidden></span>
{{elseif $comment->author()->joinedRecently()}}
<span class="ipsAvatarStack__badge ipsAvatarStack__badge--new" data-ipsTooltip title='{lang="member_is_new_badge" sprintf="$comment->author()->name"}'></span>
{{endif}}
{{if !$comment->isAnonymous() and $comment->author()->canHaveAchievements() and \IPS\core\Achievements\Rank::show() and $rank = $comment->author()->rank()}}
{$rank->html( 'ipsAvatarStack__rank' )|raw}
{{endif}}
{{endif}}
</div>
<h3 data-ips-hook="postUsername" class='ipsEntry__username'>
{{if $comment->author()->isOnline() AND ( !$comment->author()->isOnlineAnonymously() OR ( $comment->author()->isOnlineAnonymously() AND \IPS\Member::loggedIn()->isAdmin() ) )}}
<span class='ipsOnline' data-ipsTooltip title='{{if $comment->author()->isOnlineAnonymously()}}{lang="online_now_anon" sprintf="$comment->author()->name"}{{elseif $comment->author()->isOnline()}}{lang="online_now" sprintf="$comment->author()->name"}{{endif}}'></span>
{{endif}}
{template="userLink" group="global" app="core" params="$comment->author(), $comment->warningRef(), FALSE, $comment->isAnonymous()"}
{{if $comment->isAnonymous() and \IPS\Member::loggedIn()->modPermission('can_view_anonymous_posters')}}
<a data-ipsHover data-ipsHover-width="370" data-ipsHover-onClick href="{{if $comment->isFirst()}}{$comment->item()->url( 'reveal' )->csrf()}{{else}}{$comment->url( 'reveal' )->csrf()}{{endif}}" rel="nofollow"><span class="ipsAnonymous" data-ipsTooltip title="{lang="post_anonymously_reveal"}"></span></a>
{{endif}}
{{if $comment->author()->modShowBadge()}}
<span class="ipsEntry__author-moderator-badge ipsBadge ipsBadge--icon ipsBadge--soft" data-ipsTooltip title='{lang="member_is_moderator" sprintf="$comment->author()->name"}'>
<i class="fa-solid fa-shield-halved"></i>
</span>
{{endif}}
</h3>
{{if !$comment->isAnonymous()}}
<div data-ips-hook="postUserGroup" class='ipsEntry__group'>
{{if $comment->author()->modShowBadge()}}
<a href='{url="app=core&module=staffdirectory&controller=directory" seoTemplate="staffdirectory"}'>{expression="\IPS\Member\Group::load( $comment->author()->member_group_id )->formattedName" raw="true"}</a>
<a href='{url="app=core&module=staffdirectory&controller=directory" seoTemplate="staffdirectory"}' class="ipsEntry__moderatorBadge" data-ipsTooltip title='{lang="member_is_moderator" sprintf="$comment->author()->name"}'>
{expression="\IPS\Member\Group::load( $comment->author()->member_group_id )->formattedName" raw="true"}
</a>
{{else}}
{expression="\IPS\Member\Group::load( $comment->author()->member_group_id )->formattedName" raw="true"}
{{endif}}
@@ -2755,7 +2775,7 @@ data-first-page="{{if isset( request.page ) and request.page > 1}}false{{else}}t
{template="postHeader" group="topics" app="forums" params="$item, $comment, $idField, $viewerIsFollowingTheseExperts"}
{template="post" group="topics" app="forums" params="$item, $comment, $item::$formLangPrefix . 'comment', $item::$application, $item::$module, $itemClassSafe, $viewerIsFollowingTheseExperts"}
</article>]]></template>
<template template_group="topics" template_name="postHeader" template_data="$item, $comment, $idField, $viewerIsFollowingTheseExperts=[]" template_location="front" template_app="forums"><![CDATA[<aside data-ips-hook="topicAuthorColumn" class='ipsEntry__header'>
<template template_group="topics" template_name="postHeader" template_data="$item, $comment, $idField, $viewerIsFollowingTheseExperts=[]" template_location="front" template_app="forums"><![CDATA[<aside data-ips-hook="topicAuthorColumn" class='ipsEntry__header' data-feedid="{$item->feedId}">
<div class='ipsEntry__header-align'>
<div class='ipsPhotoPanel'>
@@ -2766,7 +2786,7 @@ data-first-page="{{if isset( request.page ) and request.page > 1}}false{{else}}t
{$rank->html( 'ipsAvatarStack__rank' )|raw}
{{endif}}
{{if $comment->author()->isOnline() AND ( !$comment->author()->isOnlineAnonymously() OR ( $comment->author()->isOnlineAnonymously() AND \IPS\Member::loggedIn()->isAdmin() ) )}}
<span class='ipsOnlineStatus' data-ipsTooltip title='{{if $comment->author()->isOnlineAnonymously()}}{lang="online_now_anon" sprintf="$comment->author()->name"}{{elseif $comment->author()->isOnline()}}{lang="online_now" sprintf="$comment->author()->name"}{{endif}}'></span>
<span class='ipsOnline' data-ipsTooltip title='{{if $comment->author()->isOnlineAnonymously()}}{lang="online_now_anon" sprintf="$comment->author()->name"}{{elseif $comment->author()->isOnline()}}{lang="online_now" sprintf="$comment->author()->name"}{{endif}}'></span>
{{endif}}
</div>
<!-- Username -->
@@ -2774,7 +2794,15 @@ data-first-page="{{if isset( request.page ) and request.page > 1}}false{{else}}t
<h3 data-ips-hook="postUsername" class='ipsEntry__username'>
{template="userLink" group="global" app="core" params="$comment->author(), $comment->warningRef(), FALSE, $comment->isAnonymous()"}
{{if !$comment->isAnonymous()}}
<span class='ipsEntry__group'>{expression="\IPS\Member\Group::load( $comment->author()->member_group_id )->formattedName" raw="true"}</span>
<span class='ipsEntry__group'>
{{if $comment->author()->modShowBadge()}}
<a href='{url="app=core&module=staffdirectory&controller=directory" seoTemplate="staffdirectory"}' class="ipsEntry__moderatorBadge" data-ipsTooltip title='{lang="member_is_moderator" sprintf="$comment->author()->name"}'>
{expression="\IPS\Member\Group::load( $comment->author()->member_group_id )->formattedName" raw="true"}
</a>
{{else}}
{expression="\IPS\Member\Group::load( $comment->author()->member_group_id )->formattedName" raw="true"}
{{endif}}
</span>
{{endif}}
{{if $comment->isAnonymous() and \IPS\Member::loggedIn()->modPermission('can_view_anonymous_posters')}}
<a data-ipsHover data-ipsHover-width="370" data-ipsHover-onClick href="{{if $comment->isFirst()}}{$comment->item()->url( 'reveal' )->csrf()}{{else}}{$comment->url( 'reveal' )->csrf()}{{endif}}" rel="nofollow"><span class="ipsAnonymousIcon" data-ipsTooltip title="{lang="post_anonymously_reveal"}"></span></a>
@@ -2981,7 +3009,7 @@ data-first-page="{{if isset( request.page ) and request.page > 1}}false{{else}}t
</li>
{{if $topic->container()->can('add')}}
<li>
<a href="{$topic->container()->url()->setQueryString( 'do', 'add' )}" rel="nofollow" class='ipsButton ipsButton--text' title='{lang="start_new_topic_desc"}'><i class="fa-regular fa-pen-to-square"></i><span>{lang="start_new_topic"}</span></a>
<a href="{$topic->container()->url()->setQueryString( 'do', 'add' )}" rel="nofollow" class='ipsButton ipsButton--text' title='{lang="start_new_topic_desc"}'><i class="fa-solid fa-pen-to-square"></i><span>{lang="start_new_topic"}</span></a>
</li>
{{endif}}
{{if $topic->canComment()}}
@@ -3000,7 +3028,7 @@ data-first-page="{{if isset( request.page ) and request.page > 1}}false{{else}}t
{template="featuredComments" group="global" app="core" params="$topic->featuredComments(), $topic->url()->setQueryString( 'recommended', 'comments' ), 'recommended_posts', 'post_lc'"}
<div id='comments' data-controller='core.front.core.commentFeed,forums.front.topic.view, core.front.core.ignoredComments' {{if settings.auto_polling_enabled}}data-autoPoll{{endif}} data-baseURL='{$topic->url()}' {{if $topic->isLastPage()}}data-lastPage{{endif}} data-feedID='{$topic->feedId}' class='cTopic ipsBlockSpacer'>
<div id='comments' data-controller='core.front.core.commentFeed,forums.front.topic.view, core.front.core.ignoredComments' {{if settings.auto_polling_enabled}}data-autoPoll{{endif}} data-baseURL='{$topic->url()}' {{if $topic->isLastPage()}}data-lastPage{{endif}} data-feedID='{$topic->feedId}' class='cTopic ipsBlockSpacer' data-follow-area-id="topic-{$topic->tid}">
<div data-ips-hook="topicPostFeed" id="elPostFeed" class="ipsEntries ipsPull ipsEntries--topic" data-role='commentFeed' data-controller='core.front.core.moderation' {{if $topic->topic_answered_pid}} data-topicAnswerID="{$topic->topic_answered_pid}"{{endif}}>
@@ -3033,7 +3061,7 @@ data-first-page="{{if isset( request.page ) and request.page > 1}}false{{else}}t
</div>
{{endif}}
<form action="{$topic->url()->csrf()->setQueryString( 'do', 'multimodComment' )->setPage('page', (int) \IPS\Request::i()->page )}" method="post" data-ipsPageAction data-role='moderationTools'>
{{$postCount=0; $adShown=0; $timeLastRead = $topic->timeLastRead(); $lined = FALSE;}}
{{$postCount=0; $timeLastRead = $topic->timeLastRead(); $lined = FALSE;}}
{{if \count( $comments )}}
{{foreach $topic->generateCommentMetaData( $comments, \IPS\Settings::i()->forums_mod_actions_anon ) as $comment}}
@@ -3099,9 +3127,10 @@ data-first-page="{{if isset( request.page ) and request.page > 1}}false{{else}}t
</ul>
{{endif}}
{{if $advertisement = \IPS\core\Advertisement::loadByLocation( 'ad_topic_view', $postCount, $adShown )}}
{{$adShown++;}}
{$advertisement|raw}
{{if $advertisement = \IPS\core\Advertisement::loadByLocation( 'ad_topic_view', $postCount )}}
<div data-ips-ad="topic_view">
{$advertisement|raw}
</div>
{{endif}}
{{if ( !$featureFirstPost and $postCount == 1 and ( $topic->showSummaryOnDesktop() === 'post' OR $topic->showSummaryOnMobile() ) )}}
{template="activity" group="topics" app="forums" params="$topic, 'post'"}
@@ -3156,7 +3185,7 @@ data-first-page="{{if isset( request.page ) and request.page > 1}}false{{else}}t
{{if !$topic->isArchived() and !$topic->container()->password}}
<div class='ipsPageActions ipsBox i-padding_2 ipsPull ipsResponsive_showPhone'>
{{if !$topic->container()->disable_sharelinks}}
{template="shareButton" app="core" group="sharelinks" params="$topic, 'verySmall', 'light'"}
{template="shareButton" app="core" group="sharelinks" params="$topic"}
{{endif}}
{{if \IPS\Application::appIsEnabled('cloud')}}
{template="spam" app="cloud" group="spam" params="$topic"}
@@ -3553,20 +3582,15 @@ data-first-page="{{if isset( request.page ) and request.page > 1}}false{{else}}t
.ipsCategoryWithFeed__meta{
border-inline-end: 1px solid var(--i-background_4);
}
.ipsData--forumFeedViewParent{
height: 100%;
}
/* Prepare the list for the following 2 changes */
.ipsData--forumFeedView{
--i-data--padding: 1.1em;
--i-data--cell-spacing: 1em;
--i-data--icon-width: 30px;
height: 100%;
display: flex;
flex-direction: column;
/* Long dates */
.ipsCategoryWithFeed__item .ipsTime__long{
display: revert;
}
.ipsCategoryWithFeed__item .ipsTime__short{
display: none;
}
}
@@ -3861,6 +3885,7 @@ data-first-page="{{if isset( request.page ) and request.page > 1}}false{{else}}t
/* Stats */
.cTopicOverview__item--stats{
display: flex;
flex-wrap: wrap;
gap: 1em 2em;
text-align: center;
}
@@ -3961,5 +3986,10 @@ data-first-page="{{if isset( request.page ) and request.page > 1}}false{{else}}t
/* Improve alignment of assigned icon */
.ipsMessage--assigned .ipsMessage__icon{
top: calc(50% - .5em);
}
/* Advertisement spacing */
[data-ips-ad="topic_view"]{
margin-bottom: 1em;
}]]></css>
</theme>
+33 -1
View File
@@ -267,6 +267,13 @@
"107785": "4.7.19",
"107786": "4.7.19",
"107787": "4.7.19",
"107795": "4.7.20 Beta 1",
"107796": "4.7.20 Beta 2",
"107797": "4.7.20 Beta 3",
"107798": "4.7.20 Beta 4",
"107799": "4.7.20 Beta 5",
"107800": "4.7.20",
"107801": "4.7.20",
"500001": "5.0.0 Alpha 1",
"500002": "5.0.0 Alpha 2",
"5000003": "5.0.0 Alpha 3",
@@ -315,5 +322,30 @@
"5000046": "5.0.0 Beta 14",
"5000047": "5.0.0 Beta 14.1",
"5000048": "5.0.0 Beta 14.2",
"5000049": "5.0.0"
"5000049": "5.0.0",
"5000050": "5.0.0",
"5000051": "5.0.0",
"5000052": "5.0.1",
"5000053": "5.0.1",
"5000054": "5.0.2",
"5000055": "5.0.2",
"5000056": "5.0.2",
"5000057": "5.0.3",
"5000058": "5.0.3",
"5000059": "5.0.3",
"5000060": "5.0.3",
"5000061": "5.0.4 Beta 1",
"5000062": "5.0.4 Beta 1",
"5000063": "5.0.4 Beta 1",
"5000064": "5.0.4 Beta 2",
"5000065": "5.0.4 Beta 3",
"5000066": "5.0.4",
"5000067": "5.0.5 Beta 1",
"5000068": "5.0.5 Beta 2",
"5000069": "5.0.5",
"5000070": "5.0.6 Beta 1",
"5000071": "5.0.6 Beta 2",
"5000072": "5.0.6 Beta 3",
"5000073": "5.0.6 Beta 4",
"5000074": "5.0.6"
}
@@ -161,7 +161,7 @@ class AnswerMarkedBest extends AchievementActionAbstract
*/
public function awardOther( mixed $extra = NULL, ?array $filters = NULL ): array
{
return [ $extra->item()->author() ];
return [ $extra['post']->item()->author() ];
}
/**
@@ -303,6 +303,6 @@ class AnswerMarkedBest extends AchievementActionAbstract
public static function rebuildRow( array $row, array $data ) : void
{
$post = Post::load( $row['comment_id'] );
$post->author()->achievementAction( 'forums', 'AnswerMarkedBest', $post, DateTime::ts( $row[ $data['date'] ] ) );
$post->author()->achievementAction( 'forums', 'AnswerMarkedBest', [ 'post' => $post, 'type' => $data['type'] ], DateTime::ts( $row[ $data['date'] ] ) );
}
}
@@ -127,7 +127,6 @@ class RebuildSolvedStats extends QueueAbstract
[ Db::i()->in( 'approved', array( -2, -3 ), TRUE ) ],
[ 'forum_id=?', $forum->_id ],
[ 'start_date > ? AND start_date < ?', $start->getTimestamp(), $end->getTimestamp() ],
[ 'type=?', 'solved' ]
];
@@ -47,24 +47,19 @@ class PercentageSolved extends \IPS\core\Statistics\Chart
*/
public function getChart( Url $url ): Chart
{
/* Determine minimum date */
$minimumDate = NULL;
/* Determine minimum date - if there is nothing, set it to today */
$minimumDate = Db::i()->select( 'min(solved_date)', 'core_solved_index' )->first();
$minimumDate = $minimumDate ? DateTime::ts( $minimumDate ) : DateTime::create();
/* We can't retrieve any stats prior to the new tracking being implemented */
try
$oldestLog = Db::i()->select( 'MIN(time)', 'core_statistics', array( 'type=?', 'solved' ) )->first();
if( $oldestLog )
{
$oldestLog = Db::i()->select( 'MIN(time)', 'core_statistics', array( 'type=?', 'solved' ) )->first();
if( !$minimumDate OR $oldestLog < $minimumDate->getTimestamp() )
if( $oldestLog < $minimumDate->getTimestamp() )
{
$minimumDate = DateTime::ts( $oldestLog );
}
}
catch( UnderflowException $e )
{
/* We have nothing tracked, set minimum date to today */
$minimumDate = DateTime::create();
}
$chart = new Database( $url, 'core_statistics', 'time', '', array(
'isStacked' => FALSE,
@@ -50,24 +50,19 @@ class SolvedByForum extends \IPS\core\Statistics\Chart
*/
public function getChart( Url $url ): Chart
{
/* Determine minimum date */
$minimumDate = NULL;
/* Determine minimum date - if there is nothing, set it to today */
$minimumDate = Db::i()->select( 'min(solved_date)', 'core_solved_index' )->first();
$minimumDate = $minimumDate ? DateTime::ts( $minimumDate ) : DateTime::create();
/* We can't retrieve any stats prior to the new tracking being implemented */
try
$oldestLog = Db::i()->select( 'MIN(time)', 'core_statistics', array( 'type=?', 'solved' ) )->first();
if( $oldestLog )
{
$oldestLog = Db::i()->select( 'MIN(time)', 'core_statistics', array( 'type=?', 'solved' ) )->first();
if( !$minimumDate OR $oldestLog < $minimumDate->getTimestamp() )
if( $oldestLog < $minimumDate->getTimestamp() )
{
$minimumDate = DateTime::ts( $oldestLog );
}
}
catch( UnderflowException $e )
{
/* We have nothing tracked, set minimum date to today */
$minimumDate = DateTime::create();
}
$chart = new Database( $url, 'core_solved_index', 'solved_date', '', array(
'isStacked' => FALSE,
@@ -80,7 +75,7 @@ class SolvedByForum extends \IPS\core\Statistics\Chart
),
'LineChart',
'monthly',
array( 'start' => ( new DateTime )->sub( new DateInterval('P90D') ), 'end' => new DateTime ),
array( 'start' => $minimumDate, 'end' => new DateTime ),
array(),
'solved'
);
@@ -11,15 +11,14 @@
namespace IPS\forums\extensions\core\Statistics;
use IPS\core\Statistics\Chart as ParentClass;
use IPS\DateTime;
use IPS\Db;
use IPS\Helpers\Chart;
use IPS\Helpers\Chart\Database as DbChart;
use IPS\Helpers\Form\Select;
use IPS\Http\Url;
use IPS\DateTime as IPSDateTime;
use IPS\Member;
use IPS\Member\Group;
use UnderflowException;
use DateInterval;
use function defined;
@@ -52,24 +51,19 @@ class SolvedByGroup extends ParentClass
*/
public function getChart( Url $url ): Chart
{
/* Determine minimum date */
$minimumDate = NULL;
/* Determine minimum date - if there is nothing, set it to today */
$minimumDate = Db::i()->select( 'min(solved_date)', 'core_solved_index' )->first();
$minimumDate = $minimumDate ? DateTime::ts( $minimumDate ) : DateTime::create();
/* We can't retrieve any stats prior to the new tracking being implemented */
try
$oldestLog = Db::i()->select( 'MIN(time)', 'core_statistics', array( 'type=?', 'solved' ) )->first();
if( $oldestLog )
{
$oldestLog = Db::i()->select( 'MIN(time)', 'core_statistics', array( 'type=?', 'solved' ) )->first();
if( !$minimumDate OR $oldestLog < $minimumDate->getTimestamp() )
if( $oldestLog < $minimumDate->getTimestamp() )
{
$minimumDate = IPSDateTime::ts( $oldestLog );
$minimumDate = DateTime::ts( $oldestLog );
}
}
catch( UnderflowException $e )
{
/* We have nothing tracked, set minimum date to today */
$minimumDate = IPSDateTime::create();
}
$chart = new DbChart( $url, 'core_solved_index', 'solved_date', '', array(
'isStacked' => FALSE,
@@ -82,7 +76,7 @@ class SolvedByGroup extends ParentClass
),
'LineChart',
'monthly',
array( 'start' => ( new IPSDateTime )->sub( new DateInterval('P90D') ), 'end' => new IPSDateTime ),
array( 'start' => $minimumDate, 'end' => new DateTime ),
array(),
'solved'
);
@@ -47,24 +47,19 @@ class TimeSolved extends \IPS\core\Statistics\Chart
*/
public function getChart( Url $url ): Chart
{
/* Determine minimum date */
$minimumDate = NULL;
/* Determine minimum date - if there is nothing, set it to today */
$minimumDate = Db::i()->select( 'min(solved_date)', 'core_solved_index' )->first();
$minimumDate = $minimumDate ? DateTime::ts( $minimumDate ) : DateTime::create();
/* We can't retrieve any stats prior to the new tracking being implemented */
try
$oldestLog = Db::i()->select( 'MIN(time)', 'core_statistics', array( 'type=?', 'solved' ) )->first();
if( $oldestLog )
{
$oldestLog = Db::i()->select( 'MIN(time)', 'core_statistics', array( 'type=?', 'solved' ) )->first();
if( $oldestLog !== null and ( !$minimumDate OR $oldestLog < $minimumDate->getTimestamp() ) )
if( $oldestLog < $minimumDate->getTimestamp() )
{
$minimumDate = DateTime::ts( $oldestLog );
}
}
catch( UnderflowException $e )
{
/* We have nothing tracked, set minimum date to today */
$minimumDate = DateTime::create();
}
$chart = new Database( $url, 'core_statistics', 'time', '', array(
'isStacked' => FALSE,
@@ -17,6 +17,7 @@ use IPS\Dispatcher;
use IPS\forums\Forum;
use IPS\Member;
use IPS\Node\Controller;
use IPS\Node\Model;
use IPS\Output;
use IPS\Request;
use OutOfRangeException;
@@ -53,6 +54,18 @@ class forums extends Controller
Dispatcher::i()->checkAcpPermission( 'forums_manage' );
parent::execute();
}
/**
* Determines if the node can be a root-level
*
* @param Model $node
* @return bool
*/
public function _canBeRoot( Model $node ) : bool
{
/* Only allow categories to be root level */
return $node instanceof Forum and !$node->sub_can_post;
}
/**
* Permissions
@@ -120,7 +120,7 @@ class solved extends Controller
else
{
Output::i()->title = Member::loggedIn()->language()->addToStack( 'menu__forums_stats_solved' );
Output::i()->output = Theme::i()->getTemplate( 'global', 'core' )->tabs( $tabs, $activeTab, (string)$chart, Url::internal( "app=forums&module=stats&controller=solved" ), 'tab', '', 'i-padding_3' );
Output::i()->output = Theme::i()->getTemplate( 'global', 'core' )->tabs( $tabs, $activeTab, (string)$chart, Url::internal( "app=forums&module=stats&controller=solved" ), 'tab', '', '' );
}
}
@@ -318,20 +318,6 @@ class topic extends Controller
$offset = ( ( $page - 1 ) * $topic::getCommentsPerPage() ) + 1;
if ( ( ! isset( Request::i()->sortby ) or 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' ), 'pagination', $pagesCount ) : NULL;
}
else
@@ -1375,7 +1361,7 @@ class topic extends Controller
*/
public function _find( string $commentClass, Comment $comment, Item $item ) : void
{
if ( Bridge::i()->featureIsEnabled( 'topic_summary' ) )
if ( Bridge::i()->featureIsEnabled( 'topic_summaries' ) )
{
$idField = $comment::$databaseColumnId;
Bridge::i()->trackPostRankingEvent( $comment->$idField, 'linked' );
@@ -1394,7 +1380,7 @@ class topic extends Controller
*/
protected function _react( string $commentClass, Comment $comment, Item $item ): void
{
if ( Bridge::i()->featureIsEnabled( 'topic_summary' ) )
if ( Bridge::i()->featureIsEnabled( 'topic_summaries' ) )
{
try
{
@@ -0,0 +1,23 @@
{
"id": 107795,
"name": "4.7.20 Beta 1",
"steps": {
"queries": false,
"lang": false,
"theme": true,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,22 @@
{
"html": {
"added": [],
"edited": [
"front\/forums\/topicRow",
"front\/forums\/topicRowSnippet",
"front\/index\/simplifiedTopicRow",
"front\/index\/simplifiedTopicRowSnippet"
],
"removed": []
},
"css": {
"added": [],
"edited": [],
"removed": []
},
"resources": {
"added": [],
"edited": [],
"removed": []
}
}
@@ -0,0 +1,23 @@
{
"id": 107796,
"name": "4.7.20 Beta 2",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,23 @@
{
"id": 107797,
"name": "4.7.20 Beta 3",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,23 @@
{
"id": 107798,
"name": "4.7.20 Beta 4",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,23 @@
{
"id": 107799,
"name": "4.7.20 Beta 5",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,23 @@
{
"id": 107800,
"name": "4.7.20",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,23 @@
{
"id": 107801,
"name": "4.7.20",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,22 @@
{
"id": 5000050,
"name": "5.0.0",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,17 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_forums_forum",
"layout_forums_topic",
"layout_forums_post",
"layout_forum_topic_view_firstpost"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000051,
"name": "5.0.0",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,17 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_forums_forum",
"layout_forums_topic",
"layout_forums_post",
"layout_forum_topic_view_firstpost"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000052,
"name": "5.0.1",
"steps": {
"queries": false,
"lang": false,
"theme": true,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"html": {
"added": [],
"edited": [
"front\/index\/forumGridItem",
"front\/index\/forumRow",
"front\/index\/forumSummaryRow",
"front\/index\/index"
],
"removed": []
},
"css": {
"added": [],
"edited": [
"front\/topics.css"
],
"removed": []
},
"resources": {
"added": [],
"edited": [],
"removed": []
}
}
@@ -0,0 +1,17 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_forums_forum",
"layout_forums_topic",
"layout_forums_post",
"layout_forum_topic_view_firstpost"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000053,
"name": "5.0.1",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,17 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_forums_forum",
"layout_forums_topic",
"layout_forums_post",
"layout_forum_topic_view_firstpost"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000054,
"name": "5.0.2",
"steps": {
"queries": false,
"lang": false,
"theme": true,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,26 @@
{
"html": {
"added": [],
"edited": [
"front\/forums\/forumDisplay",
"front\/forums\/forumTable",
"front\/forums\/topicRow",
"front\/forums\/topicRowSnippet",
"front\/index\/simplifiedForumTable",
"front\/index\/simplifiedTopicRow",
"front\/index\/simplifiedTopicRowSnippet",
"front\/topics\/topic"
],
"removed": []
},
"css": {
"added": [],
"edited": [],
"removed": []
},
"resources": {
"added": [],
"edited": [],
"removed": []
}
}
@@ -0,0 +1,17 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_forums_forum",
"layout_forums_topic",
"layout_forums_post",
"layout_forum_topic_view_firstpost"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000055,
"name": "5.0.2",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,17 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_forums_forum",
"layout_forums_topic",
"layout_forums_post",
"layout_forum_topic_view_firstpost"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000056,
"name": "5.0.2",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,17 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_forums_forum",
"layout_forums_topic",
"layout_forums_post",
"layout_forum_topic_view_firstpost"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000057,
"name": "5.0.3",
"steps": {
"queries": false,
"lang": false,
"theme": true,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,19 @@
{
"html": {
"added": [],
"edited": [
"front\/index\/index"
],
"removed": []
},
"css": {
"added": [],
"edited": [],
"removed": []
},
"resources": {
"added": [],
"edited": [],
"removed": []
}
}
@@ -0,0 +1,17 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_forums_forum",
"layout_forums_topic",
"layout_forums_post",
"layout_forum_topic_view_firstpost"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000058,
"name": "5.0.3",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,17 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_forums_forum",
"layout_forums_topic",
"layout_forums_post",
"layout_forum_topic_view_firstpost"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000059,
"name": "5.0.3",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,17 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_forums_forum",
"layout_forums_topic",
"layout_forums_post",
"layout_forum_topic_view_firstpost"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000060,
"name": "5.0.3",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,17 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_forums_forum",
"layout_forums_topic",
"layout_forums_post",
"layout_forum_topic_view_firstpost"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000061,
"name": "5.0.4 Beta 1",
"steps": {
"queries": false,
"lang": true,
"theme": true,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": true
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,14 @@
{
"normal": {
"added": [],
"edited": [
"forum_solved_mode_desc"
],
"removed": []
},
"js": {
"added": [],
"edited": [],
"removed": []
}
}
@@ -0,0 +1,25 @@
{
"html": {
"added": [],
"edited": [
"front\/forums\/forumButtons",
"front\/index\/forumGridItem",
"front\/index\/forumSummaryRow",
"front\/index\/simplifiedView",
"front\/topics\/postContainer",
"front\/topics\/postHeader",
"front\/topics\/topic"
],
"removed": []
},
"css": {
"added": [],
"edited": [],
"removed": []
},
"resources": {
"added": [],
"edited": [],
"removed": []
}
}
@@ -0,0 +1,17 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_forums_forum",
"layout_forums_topic",
"layout_forums_post",
"layout_forum_topic_view_firstpost"
],
"removed": []
}
}
@@ -0,0 +1,50 @@
<?php
/**
* @brief 5.0.4 Beta 1 Upgrade Code
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Forums
* @since 07 Mar 2025
*/
namespace IPS\forums\setup\upg_5000061;
use IPS\Db;
use IPS\Member\Group;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* 5.0.4 Beta 1 Upgrade Code
*/
class Upgrade
{
/**
* Previous to this version, everyone could mark a post as helpful. Now, only certain groups can, so lets restore the previous permissions by giving all groups the permission to mark a post as helpful.
*
* @return bool|array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step1() : bool|array
{
/* Get all groups inc admin, exc guests */
foreach( Group::groups( true, false ) as $group )
{
$group = Group::load( $group->g_id );
$group->g_bitoptions['gbw_can_mark_helpful'] = 1;
$group->save();
}
return TRUE;
}
// You can create as many additional methods (step2, step3, etc.) as is necessary.
// Each step will be executed in a new HTTP request
}
@@ -0,0 +1,22 @@
{
"id": 5000062,
"name": "5.0.4 Beta 1",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,17 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_forums_forum",
"layout_forums_topic",
"layout_forums_post",
"layout_forum_topic_view_firstpost"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000063,
"name": "5.0.4 Beta 1",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,17 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_forums_forum",
"layout_forums_topic",
"layout_forums_post",
"layout_forum_topic_view_firstpost"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000064,
"name": "5.0.4 Beta 2",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,17 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_forums_forum",
"layout_forums_topic",
"layout_forums_post",
"layout_forum_topic_view_firstpost"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000065,
"name": "5.0.4 Beta 3",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,17 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_forums_forum",
"layout_forums_topic",
"layout_forums_post",
"layout_forum_topic_view_firstpost"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000066,
"name": "5.0.4",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,17 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_forums_forum",
"layout_forums_topic",
"layout_forums_post",
"layout_forum_topic_view_firstpost"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000067,
"name": "5.0.5 Beta 1",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,17 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_forums_forum",
"layout_forums_topic",
"layout_forums_post",
"layout_forum_topic_view_firstpost"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000068,
"name": "5.0.5 Beta 2",
"steps": {
"queries": false,
"lang": false,
"theme": true,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,20 @@
{
"html": {
"added": [],
"edited": [
"front\/topics\/post",
"front\/topics\/topic"
],
"removed": []
},
"css": {
"added": [],
"edited": [],
"removed": []
},
"resources": {
"added": [],
"edited": [],
"removed": []
}
}
@@ -0,0 +1,17 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_forums_forum",
"layout_forums_topic",
"layout_forums_post",
"layout_forum_topic_view_firstpost"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000069,
"name": "5.0.5",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,17 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_forums_forum",
"layout_forums_topic",
"layout_forums_post",
"layout_forum_topic_view_firstpost"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000070,
"name": "5.0.6 Beta 1",
"steps": {
"queries": false,
"lang": false,
"theme": true,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,24 @@
{
"html": {
"added": [],
"edited": [
"front\/forums\/forumHome",
"front\/index\/forumGridItem",
"front\/index\/forumSummaryRow",
"front\/index\/index"
],
"removed": []
},
"css": {
"added": [],
"edited": [
"front\/forums.css"
],
"removed": []
},
"resources": {
"added": [],
"edited": [],
"removed": []
}
}
@@ -0,0 +1,17 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_forums_forum",
"layout_forums_topic",
"layout_forums_post",
"layout_forum_topic_view_firstpost"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000071,
"name": "5.0.6 Beta 2",
"steps": {
"queries": false,
"lang": false,
"theme": true,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,22 @@
{
"html": {
"added": [],
"edited": [
"front\/topics\/postHeader",
"front\/topics\/topic"
],
"removed": []
},
"css": {
"added": [],
"edited": [
"front\/topics.css"
],
"removed": []
},
"resources": {
"added": [],
"edited": [],
"removed": []
}
}
@@ -0,0 +1,17 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_forums_forum",
"layout_forums_topic",
"layout_forums_post",
"layout_forum_topic_view_firstpost"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000072,
"name": "5.0.6 Beta 3",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,17 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_forums_forum",
"layout_forums_topic",
"layout_forums_post",
"layout_forum_topic_view_firstpost"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000073,
"name": "5.0.6 Beta 4",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,17 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_forums_forum",
"layout_forums_topic",
"layout_forums_post",
"layout_forum_topic_view_firstpost"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000074,
"name": "5.0.6",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,17 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_forums_forum",
"layout_forums_topic",
"layout_forums_post",
"layout_forum_topic_view_firstpost"
],
"removed": []
}
}
+30 -12
View File
@@ -569,7 +569,7 @@ class Forum extends Model implements Permissions
}
$lastPostData = [
$updatedItem->last_post . $updatedItem->tid => [
$updatedItem->last_post . '.' . $updatedItem->tid => [
'last_post' => $updatedItem->last_post,
'last_poster_id' => $updatedItem->last_poster_id,
'last_poster_name' => $updatedItem->last_poster_name,
@@ -634,8 +634,12 @@ class Forum extends Model implements Permissions
$lastPost['last_poster_name'] = $topic->last_poster_name;
}
if( $lastPost['last_poster_id'] AND !empty( $lastPost['last_poster_name'] ) )
{
$lastPost['seo_last_name'] = Friendly::seoTitle( $lastPost['last_poster_name'] );
}
$lastPost['last_post'] = ( $lastComment ? $lastComment->post_date : $topic->last_post );
$lastPost['seo_last_name'] = Friendly::seoTitle( $lastPost['last_poster_name'] );
$lastPost['last_title'] = $topic->title;
$lastPost['seo_last_title'] = Friendly::seoTitle( $topic->title );
$lastPost['last_id'] = $topic->tid;
@@ -643,7 +647,7 @@ class Forum extends Model implements Permissions
$lastPost['last_post_snippet'] = $lastComment?->truncated( true, 350 );
$lastPost['posts'] = $topic->posts - 1;
$lastPostData[ $topic->last_post . $topic->tid ] = $lastPost;
$lastPostData[ $topic->last_post . '.' . $topic->tid ] = $lastPost;
}
}
catch ( UnderflowException $e ){}
@@ -877,9 +881,10 @@ class Forum extends Model implements Permissions
}
else
{
/* Default to a guest account so we can be sure the author is never null */
$results[ $timestamp ]['author'] = new Member;
if ( $data['_author'] and is_string( $data['_author'] ) )
{
$results[ $timestamp ]['author'] = new Member;
$results[ $timestamp ]['author']->name = $data['_author'];
}
}
@@ -1268,19 +1273,32 @@ class Forum extends Model implements Permissions
'forum_permission_showtopic',
'forum_permission_custom_error',
"form_{$id}_header_permissions",
"form_{$id}_tab_forum_display",
"ipsTabs_form_{$id}_forum_display",
'forum_disable_sharelinks',
"form_{$id}_tab_posting_settings",
"ipsTabs_form_{$id}_posting_settings",
"form_{$id}_header_forum_display_topic",
"form_{$id}_tab_permissions",
"ipsTabs_form_{$id}_permissions",
'forum_preview_posts',
'forum_icon_choose',
'forum_sort_key',
'forum_feature_color'
'forum_feature_color',
'forum_skin_id',
"form_{$id}_header_forum_solved_options",
"forum_solved_mode",
"forum_enable_assignments",
"bw_fluid_view",
"form_{$id}_header_forum_display_forum",
"ipsTabs_form_{$id}_forum_rules",
"ipsTabs_form_{$id}_topic_and_post_settings",
),
'category' => array(
"form_{$id}_tab_forum_display",
'forum_feature_color'
"ipsTabs_form_{$id}_forum_display",
'forum_feature_color',
'forum_skin_id',
"bw_fluid_view",
"form_{$id}_header_forum_display_forum",
"ipsTabs_form_{$id}_forum_rules",
"ipsTabs_form_{$id}_topic_and_post_settings",
),
'redirect' => array(
'forum_password_on',
@@ -1456,7 +1474,7 @@ class Forum extends Model implements Permissions
'forum_rules_text'
),
)
) ) );
), null, null, null, "forum_show_rules" ) );
$form->add( new Translatable( 'forum_rules_title', NULL, FALSE, array( 'app' => 'forums', 'key' => ( $this->id ? "forums_forum_{$this->id}_rulestitle" : NULL ) ), NULL, NULL, NULL, 'forum_rules_title' ) );
$form->add( new Translatable( 'forum_rules_text', NULL, FALSE, array( 'app' => 'forums', 'key' => ( $this->id ? "forums_forum_{$this->id}_rules" : NULL ), 'editor' => array( 'app' => 'forums', 'key' => 'Forums', 'autoSaveKey' => ( $this->id ? "forums-rules-{$this->id}" : "forums-new-rules" ), 'attachIds' => $this->id ? array( $this->id, NULL, 'rules' ) : NULL ) ), NULL, NULL, NULL, 'forum_rules_text' ) );
@@ -2309,7 +2327,7 @@ class Forum extends Model implements Permissions
* @param Club $club
* @return void
*/
public function clubForm( Form $form, Club $club ) : void
public function _clubForm( Form $form, Club $club ) : void
{
/* @var Topic $itemClass */
$itemClass = static::$contentItemClass;
@@ -91,6 +91,13 @@ class SavedAction extends Model
* @brief [Node] Title prefix. If specified, will look for a language key with "{$key}_title" as the key
*/
public static ?string $titleLangPrefix = 'forums_mmod_';
/**
* Determines if this class can be extended via UI Extension
*
* @var bool
*/
public static bool $canBeExtended = true;
/**
* Get available saved actions for a forum
@@ -171,6 +178,8 @@ class SavedAction extends Model
$form->add( new YesNo( 'topic_reply', $this->mm_id ? $this->topic_reply : FALSE, FALSE, array( 'togglesOn' => array( 'topic_reply_content_editor', 'topic_reply_postcount' ) ) ) );
$form->add( new Editor( 'topic_reply_content', $this->mm_id ? $this->topic_reply_content : FALSE, FALSE, array( 'app' => 'core', 'key' => 'Admin', 'autoSaveKey' => ( $this->mm_id ? "forums-mmod-{$this->mm_id}" : "forums-new-mmod" ), 'attachIds' => $this->mm_id ? array( $this->mm_id, NULL, 'mmod' ) : NULL ), NULL, NULL, NULL, 'topic_reply_content_editor' ) );
$form->add( new YesNo( 'topic_reply_postcount', $this->mm_id ? $this->topic_reply_postcount : TRUE, FALSE, array(), NULL, NULL, NULL, 'topic_reply_postcount' ) );
parent::form( $form );
}
/**
+59 -21
View File
@@ -59,6 +59,7 @@ use IPS\Helpers\Form\Date;
use IPS\Helpers\Form\Password;
use IPS\Http\Url;
use IPS\Http\Url\Friendly;
use IPS\IPS;
use IPS\Member;
use IPS\Node\Model;
use IPS\Output;
@@ -75,13 +76,17 @@ use SplObserver;
use SplSubject;
use function array_reverse;
use function array_slice;
use function class_implements;
use function count;
use function defined;
use function explode;
use function func_get_args;
use function get_class;
use function in_array;
use function intval;
use function is_array;
use function is_null;
use function is_string;
use function json_decode;
use const IPS\LARGE_TOPIC_REPLIES;
@@ -356,7 +361,7 @@ class Topic extends Item implements Embeddable,
* @param array $where Where clause
* @param string|null $order MySQL ORDER BY clause (NULL to order by date)
* @param int|array|null $limit Limit clause
* @param string $permissionKey A key which has a value in the permission map (either of the container or of this class) matching a column ID in core_permission_index or NULL to ignore permissions
* @param string|null $permissionKey A key which has a value in the permission map (either of the container or of this class) matching a column ID in core_permission_index or NULL to ignore permissions
* @param int|bool|null $includeHiddenItems Include hidden items? NULL to detect if currently logged in member has permission, -1 to return public content only, TRUE to return unapproved content and FALSE to only return unapproved content the viewing member submitted
* @param int $queryFlags Select bitwise flags
* @param Member|null $member The member (NULL to use currently logged in member)
@@ -373,7 +378,7 @@ class Topic extends Item implements Embeddable,
* @param array|null $location Array of item lat and long
* @return ActiveRecordIterator|int
*/
public static function getItemsWithPermission( array $where=array(), string $order=null, int|array|null $limit=10, string $permissionKey='read', int|bool|null $includeHiddenItems= Filter::FILTER_AUTOMATIC, int $queryFlags=0, Member $member=null, bool $joinContainer=FALSE, bool $joinComments=FALSE, bool $joinReviews=FALSE, bool $countOnly=FALSE, array|null $joins=null, bool|Model $skipPermission=FALSE, bool $joinTags=TRUE, bool $joinAuthor=TRUE, bool $joinLastCommenter=TRUE, bool $showMovedLinks=FALSE, array|null $location=null ): ActiveRecordIterator|int
public static function getItemsWithPermission( array $where=array(), string $order=null, int|array|null $limit=10, ?string $permissionKey='read', int|bool|null $includeHiddenItems= Filter::FILTER_AUTOMATIC, int $queryFlags=0, Member $member=null, bool $joinContainer=FALSE, bool $joinComments=FALSE, bool $joinReviews=FALSE, bool $countOnly=FALSE, array|null $joins=null, bool|Model $skipPermission=FALSE, bool $joinTags=TRUE, bool $joinAuthor=TRUE, bool $joinLastCommenter=TRUE, bool $showMovedLinks=FALSE, array|null $location=null ): ActiveRecordIterator|int
{
$where = static::getItemsWithPermissionWhere( $where, $permissionKey, $member, $joinContainer, $skipPermission );
return parent::getItemsWithPermission( $where, $order, $limit, $permissionKey, $includeHiddenItems, $queryFlags, $member, $joinContainer, $joinComments, $joinReviews, $countOnly, $joins, $skipPermission, $joinTags, $joinAuthor, $joinLastCommenter, $showMovedLinks );
@@ -1028,7 +1033,7 @@ class Topic extends Item implements Embeddable,
{
parent::delete();
if( in_array( $this->archive_status, array( static::ARCHIVE_DONE, static::ARCHIVE_WORKING, static::ARCHIVE_RESTORE ) ) )
if( in_array( $this->topic_archive_status, array( static::ARCHIVE_DONE, static::ARCHIVE_WORKING, static::ARCHIVE_RESTORE ) ) )
{
try
{
@@ -1177,12 +1182,13 @@ class Topic extends Item implements Embeddable,
/* @var Records $class */
$class = '\IPS\cms\Records' . $database['database_id'];
$class::load( $this->tid, 'record_topicid' );
$database = Databases::constructFromData( $database );
Member::loggedIn()->language()->words['cms_delete_linked_topic'] = sprintf( Member::loggedIn()->language()->get('cms_delete_linked_topic'), $database->recordWord( 1 ) );
Output::i()->error( 'cms_delete_linked_topic', '1T281/1', 403, '' );
if( class_exists( $class ) )
{
$class::load( $this->tid, 'record_topicid' );
$database = Databases::constructFromData( $database );
Member::loggedIn()->language()->words[ 'cms_delete_linked_topic' ] = sprintf( Member::loggedIn()->language()->get( 'cms_delete_linked_topic' ), $database->recordWord( 1 ) );
Output::i()->error( 'cms_delete_linked_topic', '1T281/1', 403, '' );
}
}
catch( OutOfRangeException | Exception $ex ) { }
}
@@ -1763,6 +1769,48 @@ class Topic extends Item implements Embeddable,
if ( ! $alreadyDone )
{
/* Optimise getting just the first or last post */
if ( $this->mapped('num_comments') > LARGE_TOPIC_REPLIES and ! $cutoff and ! $this->isArchived() and $limit === 1 and $order === 'date' )
{
$minMax = ( $orderDirection === 'asc' ) ? 'MIN' : 'MAX';
$pidWhere = [
[ 'topic_id=?', $this->tid ],
];
if ( IPS::classUsesTrait( $class, 'IPS\Content\Hideable' ) )
{
if ( $includeHiddenComments === NULL )
{
$includeHiddenComments = $this->canViewHiddenComments();
}
if ( ! $includeHiddenComments )
{
/* @var \IPS\Content\Comment $class */
$pidWhere[] = [ $class::db()->in( 'queued', [0,2] ) ];
}
}
try
{
$row = $class::db()->select( "{$minMax}( CONCAT( post_date, '.', pid) ) as pid", 'forums_posts', $pidWhere )->first();
$pid = (int) explode( '.', $row )[1];
if( \is_array( $extraWhereClause ) or is_null( $extraWhereClause ) )
{
$extraWhereClause[] = [ 'pid=?', $pid ];
}
else if ( is_string( $extraWhereClause ) )
{
$extraWhereClause = [
[ $extraWhereClause ],
[ 'pid=?', $pid ]
];
}
}
catch( \UnderflowException ) { }
}
$comments[ $_hash ] = $this->_comments( $class, $originalLimit ?: static::getCommentsPerPage(), $originalOffset, ( isset( $class::$databaseColumnMap[$order] ) ? ( $class::$databasePrefix . $class::$databaseColumnMap[$order] ) : $order ) . ' ' . $orderDirection, $member, $includeHiddenComments, $cutoff, $includeWarnings, $extraWhereClause, $includeDeleted );
}
}
@@ -1973,7 +2021,7 @@ class Topic extends Item implements Embeddable,
}
/* ! Reactions */
/**
* Reaction type
*
@@ -1982,17 +2030,7 @@ class Topic extends Item implements Embeddable,
public static function reactionType(): string
{
/* Because of firstCommentRequired, the reaction on the item will always be the reaction for a comment */
return Post::reactionType();
}
/**
* Reaction class
*
* @return string
*/
public static function reactionClass(): string
{
return Post::class;
return 'tid';
}
/**