Version 4.5.0

This commit is contained in:
Neo committed 2025-12-19 05:51:58 -08:00
1 parent 1a0c7fd3c2
commit f79dcf067a
3791 files changed
+248032 -76372

No files matched your search

+69 -52
View File
@@ -12,7 +12,7 @@
namespace IPS\forums\Topic;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -125,7 +125,7 @@ class _Post extends \IPS\Content\Comment implements \IPS\Content\EditHistory, \I
*/
public static function create( $item, $comment, $first=FALSE, $guestName=NULL, $incrementPostCount=NULL, $member=NULL, \IPS\DateTime $time=NULL, $ipAddress=NULL, $hiddenStatus=NULL )
{
$comment = call_user_func_array( 'parent::create', func_get_args() );
$comment = parent::create( $item, $comment, $first, $guestName, $incrementPostCount, $member, $time, $ipAddress, $hiddenStatus );
if ( !$comment->hidden() )
{
@@ -165,7 +165,7 @@ class _Post extends \IPS\Content\Comment implements \IPS\Content\EditHistory, \I
*
* @param \IPS\Node\Model|NULL $container Container
* @return void
* @see \IPS\forums\Topic\Post::incrementPostCount()
* @see incrementPostCount
*/
public static function incrementPostCount( \IPS\Node\Model $container = NULL )
{
@@ -186,6 +186,18 @@ class _Post extends \IPS\Content\Comment implements \IPS\Content\EditHistory, \I
\IPS\Db::i()->select( 'id', 'forums_forums', 'inc_postcount=1' )
) )->join( 'forums_topics', 'tid=topic_id' )->first() ;
}
/**
* Post count for member
*
* @param \IPS\Member $member The memner
* @return int
*/
public static function rawMemberPostCount( \IPS\Member $member )
{
/* Explicitly calling to the parent so we don't filter by forum ID */
return parent::memberPostCount( $member );
}
/**
* Get items with permission check
@@ -200,7 +212,9 @@ class _Post extends \IPS\Content\Comment implements \IPS\Content\EditHistory, \I
* @param bool $joinContainer If true, will join container data (set to TRUE if your $where clause depends on this data)
* @param bool $joinComments If true, will join comment data (set to TRUE if your $where clause depends on this data)
* @param bool $joinReviews If true, will join review data (set to TRUE if your $where clause depends on this data)
* @return \IPS\Patterns\ActiveRecordIterator|int
* @param bool $countOnly If true will return the count
* @param array|null $joins Additional arbitrary joins for the query
* @return array|NULL|\IPS\Content\Comment If $limit is 1, will return \IPS\Content\Comment or NULL for no results. For any other number, will return an array.
*/
public static function getItemsWithPermission( $where=array(), $order=NULL, $limit=10, $permissionKey='read', $includeHiddenItems=\IPS\Content\Hideable::FILTER_AUTOMATIC, $queryFlags=0, \IPS\Member $member=NULL, $joinContainer=FALSE, $joinComments=FALSE, $joinReviews=FALSE, $countOnly=FALSE, $joins=NULL )
{
@@ -246,7 +260,7 @@ class _Post extends \IPS\Content\Comment implements \IPS\Content\EditHistory, \I
}
/* Minimum posts */
elseif ( $containerData['min_posts_view'] and $containerData['min_posts_view'] >= \IPS\Member::loggedIn()->member_posts )
elseif ( $containerData['min_posts_view'] and $containerData['min_posts_view'] > \IPS\Member::loggedIn()->member_posts )
{
return \IPS\Theme::i()->getTemplate( 'global', 'forums' )->searchNoPermission( \IPS\Member::loggedIn()->language()->addToStack( 'no_perm_post_min_posts', FALSE, array( 'pluralize' => array( $containerData['min_posts_view'] ) ) ) );
}
@@ -282,7 +296,7 @@ class _Post extends \IPS\Content\Comment implements \IPS\Content\EditHistory, \I
public function canVote( $rating=0, $member=NULL )
{
/* Is $rating valid */
if ( !in_array( $rating, array( -1, 0, 1 ) ) )
if ( !\in_array( $rating, array( -1, 0, 1 ) ) )
{
throw new \InvalidArgumentException;
}
@@ -311,17 +325,7 @@ class _Post extends \IPS\Content\Comment implements \IPS\Content\EditHistory, \I
{
return FALSE;
}
/* Have we already voted? */
if ( $rating !== 0 or !\IPS\Settings::i()->forums_answers_downvote )
{
$ratings = $this->item()->answerVotes( $member );
if ( isset( $ratings[ $this->pid ] ) and $ratings[ $this->pid ] === $rating )
{
return FALSE;
}
}
return TRUE;
}
@@ -353,13 +357,6 @@ class _Post extends \IPS\Content\Comment implements \IPS\Content\EditHistory, \I
$item = NULL;
}
/* Reset best answer if relevant */
if ( $item !== NULL AND $item->topic_answered_pid == $this->pid )
{
$item->topic_answered_pid = FALSE;
$item->save();
}
parent::delete();
/* Deleting a post may make the item no longer popular */
@@ -369,10 +366,23 @@ class _Post extends \IPS\Content\Comment implements \IPS\Content\EditHistory, \I
}
}
/**
* Get the snippet (stripped of HTML)
*
* @param int $length The length of the snippet to return
* @return string
*/
public function snippet( $length=300 )
{
$contentField = static::$databaseColumnMap['content'];
$content = trim( str_replace( \chr(0xC2) . \chr(0xA0), ' ', strip_tags( preg_replace( "/(<br(?: \/)?>|<\/p>)/i", ' ', preg_replace( "#<blockquote(?:[^>]+?)>.+?(?<!<blockquote)</blockquote>#s", " ", preg_replace( "#<script(.*?)>(.*)</script>#uis", "", ' ' . $this->$contentField . ' ' ) ) ) ) ) );
return mb_substr( $content, 0, $length ) . ( mb_strlen( $content ) > $length ? '&hellip;' : '' );
}
/**
* Indefinite Article
*
* @param \IPS\Lang|NULL $language The language to use, or NULL for the language of the currently logged in member
* @param \IPS\Lang|NULL $lang The language to use, or NULL for the language of the currently logged in member
* @return string
*/
public function indefiniteArticle( \IPS\Lang $lang = NULL )
@@ -411,8 +421,8 @@ class _Post extends \IPS\Content\Comment implements \IPS\Content\EditHistory, \I
/**
* Definite Article
*
* @param array $containerData Basic data about the container. Only includes columns returned by container::basicDataColumns()
* @param \IPS\Lang|NULL $language The language to use, or NULL for the language of the currently logged in member
* @param array|NULL $containerData Basic data about the container. Only includes columns returned by container::basicDataColumns()
* @param \IPS\Lang|NULL $lang The language to use, or NULL for the language of the currently logged in member
* @param array $options Options to pass to \IPS\Lang::addToStack
* @return string
*/
@@ -468,6 +478,17 @@ class _Post extends \IPS\Content\Comment implements \IPS\Content\EditHistory, \I
return 'pid';
}
/**
* Set this comment as solved
*
* @param boolean $value TRUE/FALSE value
* @return void
*/
public function setSolved( $value )
{
$this->post_bwoptions['best_answer'] = (bool) $value;
}
/**
* Get content for embed
*
@@ -481,34 +502,30 @@ class _Post extends \IPS\Content\Comment implements \IPS\Content\EditHistory, \I
}
/**
* Check Moderator Permission
* Create a query to fetch the "top members"
*
* @param string $type 'edit', 'hide', 'unhide', 'delete', etc.
* @param \IPS\Member|NULL $member The member to check for or NULL for the currently logged in member
* @param \IPS\Node\Model|NULL $container The container
* @return bool
* @note The intention is to formulate a query that will fetch the members with the most contributions
* @note The group by confuses MySQL and it ends up using the 'queued' index, when the 'author_id' index is far better
* @param int $limit The number of members to return
* @return \IPS\Db\Select
*/
public static function modPermission( $type, \IPS\Member $member = NULL, \IPS\Node\Model $container = NULL )
public static function topMembersQuery( $limit )
{
/* If this is called from a gateway script, i.e. email piping, just return false as we are a "guest" */
if( $member === NULL AND !\IPS\Dispatcher::hasInstance() )
{
return FALSE;
}
if ( \in_array( $type, array( 'edit', 'hide', 'unhide', 'delete' ) ) )
{
/* Load Member */
$member = $member ?: \IPS\Member::loggedIn();
/* Post related permission */
if ( $member->modPermission( "can_{$type}_post" ) )
{
return TRUE;
}
}
return parent::modPermission($type, $member, $container );
$query = parent::topMembersQuery( $limit );
return $query->forceIndex( 'author_id' );
}
/**
* Webhook filters
*
* @return array
*/
public function webhookFilters()
{
$return = parent::webhookFilters();
$return['forums'] = $this->item()->container()->_id;
$return['hasBestAnswer'] = (bool) $this->item()->topic_answered_pid;
return $return;
}
}