Version 4.1.2

This commit is contained in:
Neo committed 2025-12-19 05:32:19 -08:00
1 parent 3ba79295ee
commit 28bd025b35
1131 files changed
+63658 -20579

No files matched your search

+39 -34
View File
@@ -204,42 +204,46 @@ class _Post extends \IPS\Content\Comment implements \IPS\Content\ReportCenter, \
/**
* Get HTML for search result display
*
* @return callable
* @param array $indexData Data from the search index
* @param array $authorData Basic data about the author. Only includes columns returned by \IPS\Member::columnsForPhoto()
* @param array $itemData Basic data about the item. Only includes columns returned by item::basicDataColumns()
* @param array|NULL $containerData Basic data about the author. Only includes columns returned by container::basicDataColumns()
* @param array $reputationData Array of people who have given reputation and the reputation they gave
* @param int|NULL $reviewRating If this is a review, the rating
* @param bool $iPostedIn If the user has posted in the item
* @param string $view 'expanded' or 'condensed'
* @param bool $asItem Displaying results as items?
* @return string
*/
public function searchResultHtml()
{
if ( $this->item()->container()->password and !\IPS\Member::loggedIn()->inGroup( explode( ',', $this->item()->container()->password_override ) ) and !( isset( \IPS\Request::i()->cookie[ 'ipbforumpass_' . $this->item()->container()->id ] ) and md5( $this->item()->container()->password ) === \IPS\Request::i()->cookie[ 'ipbforumpass_' . $this->item()->container()->id ] ) )
public static function searchResult( array $indexData, array $authorData, array $itemData, array $containerData = NULL, array $reputationData, $reviewRating, $iPostedIn, $view, $asItem )
{
/* Password protected */
if (
$containerData['password'] // There is a password
and !\IPS\Member::loggedIn()->inGroup( explode( ',', $containerData['password_override'] ) ) // We can't bypass it
and (
!isset( \IPS\Request::i()->cookie[ 'ipbforumpass_' . $indexData['index_container_id'] ] )
or
md5( $containerData['password'] ) !== \IPS\Request::i()->cookie[ 'ipbforumpass_' . $indexData['index_container_id'] ]
) // We don't have the correct password
)
{
return \IPS\Theme::i()->getTemplate( 'global', 'forums' )->searchNoPermission( $this, \IPS\Member::loggedIn()->language()->addToStack('no_perm_post_password'), $this->item()->container()->url()->setQueryString( 'topic', $this->item()->tid ) );
return \IPS\Theme::i()->getTemplate( 'global', 'forums' )->searchNoPermission(
\IPS\Member::loggedIn()->language()->addToStack('no_perm_post_password'),
\IPS\Http\Url::internal( \IPS\forums\Forum::$urlBase . $indexData['index_container_id'], 'front', \IPS\forums\Forum::$urlTemplate, array( $containerData[ \IPS\forums\Forum::$databasePrefix . \IPS\forums\Forum::$seoTitleColumn ] ) )->setQueryString( 'topic', $indexData['index_item_id'] )
);
}
elseif ( $this->item()->container()->min_posts_view and $this->item()->container()->min_posts_view >= \IPS\Member::loggedIn()->member_posts )
/* Minimum posts */
elseif ( $containerData['min_posts_view'] and $containerData['min_posts_view'] >= \IPS\Member::loggedIn()->member_po )
{
return \IPS\Theme::i()->getTemplate( 'global', 'forums' )->searchNoPermission( $this, \IPS\Member::loggedIn()->language()->addToStack( 'no_perm_post_min_posts', FALSE, array( 'pluralize' => array( $this->item()->container()->min_posts_view ) ) ) );
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'] ) ) ) );
}
/* Normal */
else
{
return \IPS\Theme::i()->getTemplate( 'search', 'core', 'front' )->contentComment( $this );
}
}
/**
* Get HTML for search result display
*
* @return callable
*/
public function activityStreamHtml()
{
if ( $this->item()->container()->password and !\IPS\Member::loggedIn()->inGroup( explode( ',', $this->item()->container()->password_override ) ) and !( isset( \IPS\Request::i()->cookie[ 'ipbforumpass_' . $this->item()->container()->id ] ) and md5( $this->item()->container()->password ) === \IPS\Request::i()->cookie[ 'ipbforumpass_' . $this->item()->container()->id ] ) )
{
return \IPS\Theme::i()->getTemplate( 'global', 'forums' )->searchNoPermission( $this, \IPS\Member::loggedIn()->language()->addToStack('no_perm_post_password'), $this->item()->container()->url()->setQueryString( 'topic', $this->item()->tid ) );
}
elseif ( $this->item()->container()->min_posts_view and $this->item()->container()->min_posts_view >= \IPS\Member::loggedIn()->member_posts )
{
return \IPS\Theme::i()->getTemplate( 'global', 'forums' )->searchNoPermission( $this, \IPS\Member::loggedIn()->language()->addToStack( 'no_perm_post_min_posts', FALSE, array( 'pluralize' => array( $this->item()->container()->min_posts_view ) ) ) );
}
else
{
return \IPS\Theme::i()->getTemplate( 'system', 'core', 'front' )->activityStreamResult( $this );
return parent::searchResult( $indexData, $authorData, $itemData, $containerData, $reputationData, $reviewRating, $iPostedIn, $view, $asItem );
}
}
@@ -322,17 +326,18 @@ class _Post extends \IPS\Content\Comment implements \IPS\Content\ReportCenter, \
* @param \IPS\Lang|NULL $language The language to use, or NULL for the language of the currently logged in member
* @return string
*/
public function indefiniteArticle( \IPS\Lang $lang = NULL )
public static function _indefiniteArticle( array $containerData = NULL, \IPS\Lang $lang = NULL )
{
if ( $this->item()->isQuestion() )
$bitOptions = ( $containerData['forums_bitoptions'] instanceof \IPS\Patterns\Bitwise ) ? $containerData['forums_bitoptions'] : new \IPS\Patterns\Bitwise( array( 'forums_bitoptions' => $containerData['forums_bitoptions'] ), \IPS\forums\Forum::$bitOptions['forums_bitoptions'] );
if ( $bitOptions['bw_enable_answers'] )
{
$lang = $lang ?: \IPS\Member::loggedIn()->language();
return ( $this->isFirst() ) ? $lang->get( '__indefart_question', FALSE ) : $lang->get( '__indefart_answer', FALSE );
return $lang->addToStack( '__indefart_answer', FALSE );
}
else
{
return parent::indefiniteArticle( $lang );
return parent::_indefiniteArticle( $containerData, $lang );
}
}
+134 -101
View File
@@ -260,16 +260,16 @@ class _Topic extends \IPS\Content\Item implements
}
/**
* Additional WHERE clauses for New Content view
* Additional WHERE clauses for Follow view
*
* @param bool $joinContainer If true, will join container data (set to TRUE if your $where clause depends on this data)
* @param array $joins Other joins
* @return array
*/
public static function vncWhere( &$joinContainer, &$joins )
public static function followWhere( &$joinContainer, &$joins )
{
$joinContainer = FALSE;
return array_merge( parent::vncWhere( $joinContainer, $joins ), static::getItemsWithPermissionWhere( array(), 'read', NULL, $joinContainer ) );
return array_merge( parent::followWhere( $joinContainer, $joins ), static::getItemsWithPermissionWhere( array(), 'read', NULL, $joinContainer ) );
}
/**
@@ -315,7 +315,7 @@ class _Topic extends \IPS\Content\Item implements
{
$member = $member ?: \IPS\Member::loggedIn();
if ( !$member->modPermission( 'can_read_all_topics' ) or $member->modPermission( 'forums' ) !== true )
if ( !$member->modPermission( 'can_read_all_topics' ) or $member->modPermission( 'forums' ) !== -1 )
{
if ( $skipPermission instanceof \IPS\forums\Forum )
{
@@ -496,48 +496,53 @@ class _Topic extends \IPS\Content\Item implements
/* Moderator actions */
if ( isset( $values['topic_create_state'] ) )
{
if ( in_array( 'lock', $values['topic_create_state'] ) )
if ( static::modPermission( 'feature', NULL, $this->container() ) )
{
$this->state = 'closed';
$this->state = ( in_array( 'lock', $values['topic_create_state'] ) ) ? 'closed' : 'open';
}
if ( in_array( 'hide', $values['topic_create_state'] ) )
if ( static::modPermission( 'hide', NULL, $this->container() ) )
{
$this->approved = -1;
$this->approved = ( in_array( 'hide', $values['topic_create_state'] ) ) ? -1 : 1;
}
if ( in_array( 'pin', $values['topic_create_state'] ) )
if ( static::modPermission( 'pin', NULL, $this->container() ) )
{
$this->pinned = 1;
$this->pinned = ( in_array( 'pin', $values['topic_create_state'] ) ) ? 1 : 0;
}
if ( in_array( 'feature', $values['topic_create_state'] ) )
if ( static::modPermission( 'feature', NULL, $this->container() ) )
{
$this->featured = 1;
$this->featured = ( in_array( 'feature', $values['topic_create_state'] ) ) ? 1 : 0;
}
}
/* Set open/close time */
if ( isset( $values['topic_open_time'] ) and $values['topic_open_time'] )
if ( static::modPermission( 'lock', NULL, $this->container() ) )
{
$this->topic_open_time = $values['topic_open_time']->getTimestamp();
}
if ( isset( $values['topic_close_time'] ) and $values['topic_close_time'] )
{
$this->topic_close_time = $values['topic_close_time']->getTimestamp();
}
else if( isset( $values['topic_create_state'] ) and !in_array( 'lock', $values['topic_create_state'] ) )
{
$this->topic_close_time = 0;
$this->state = 'open';
}
/* If open time is before close time, close now */
if ( $this->topic_open_time and $this->topic_close_time and $this->topic_open_time < $this->topic_close_time )
{
$this->state = 'closed';
/* Set open/close time */
if ( isset( $values['topic_open_time'] ) and $values['topic_open_time'] )
{
$this->topic_open_time = $values['topic_open_time']->getTimestamp();
}
if ( isset( $values['topic_close_time'] ) and $values['topic_close_time'] )
{
$this->topic_close_time = $values['topic_close_time']->getTimestamp();
}
else if( isset( $values['topic_create_state'] ) and !in_array( 'lock', $values['topic_create_state'] ) )
{
$this->topic_close_time = 0;
$this->state = 'open';
}
/* If open time is before close time, close now */
if ( $this->topic_open_time and $this->topic_close_time and $this->topic_open_time < $this->topic_close_time )
{
$this->state = 'closed';
}
}
}
/**
@@ -574,29 +579,21 @@ class _Topic extends \IPS\Content\Item implements
* @brief Cached URLs
*/
protected $_url = array();
/**
* Get URL
*
* @param string|NULL $action Action
* @return \IPS\Http\Url
*/
public function url( $action=NULL )
{
$_key = md5( $action );
if( !isset( $this->_url[ $_key ] ) )
{
$this->_url[ $_key ] = \IPS\Http\Url::internal( "app=forums&module=forums&controller=topic&id={$this->tid}", 'front', 'forums_topic', array( $this->title_seo ) );
if ( $action )
{
$this->_url[ $_key ] = $this->_url[ $_key ]->setQueryString( 'do', $action );
}
}
return $this->_url[ $_key ];
}
/**
* @brief URL Base
*/
public static $urlBase = 'app=forums&module=forums&controller=topic&id=';
/**
* @brief URL Base
*/
public static $urlTemplate = 'forums_topic';
/**
* @brief SEO Title Column
*/
public static $seoTitleColumn = 'title_seo';
/**
* Stats for table view
@@ -695,7 +692,7 @@ class _Topic extends \IPS\Content\Item implements
if
(
(
$member->modPermission( 'forums' ) !== 0
$member->modPermission( 'forums' ) !== -1
and
(
is_array( $member->modPermission( 'forums' ) )
@@ -729,48 +726,49 @@ class _Topic extends \IPS\Content\Item implements
if ( !$this->container()->can_view_others )
{
$return = array();
if ( $this->starter_id )
/* If the search index permissions are empty, just return now because no one can see content in this forum */
if( !$return )
{
$return[] = "m{$this->starter_id}";
return $return;
}
$normal = $return;
$return = array();
$members = array();
foreach ( \IPS\Db::i()->select( '*', 'core_moderators' ) as $moderator )
{
if ( $moderator['perms'] === '*' or in_array( 'can_read_all_topics', explode( ',', $moderator['perms'] ) ) )
{
$return[] = ( $moderator['type'] === 'g' ) ? $moderator['id'] : "m{$moderator['id']}";
if( $moderator['type'] === 'g' )
{
$return[] = $moderator['id'];
}
else
{
$members[] = "m{$moderator['id']}";
}
}
}
$return = implode( ',', array_unique( $return ) );
$return = ( $normal == '*' ) ? array_unique( $return ) : array_intersect( explode( ',', $normal ), array_unique( $return ) );
if ( $this->starter_id )
{
$members[] = "m{$this->starter_id}";
}
if( count( $members ) )
{
$return = array_merge( $return, $members );
}
$return = implode( ',', $return );
}
return $return;
}
/**
* Get HTML for search result display
*
* @return callable
*/
public function searchResultHtml()
{
if ( $this->container()->password and !\IPS\Member::loggedIn()->inGroup( explode( ',', $this->container()->password_override ) ) and !( isset( \IPS\Request::i()->cookie[ 'ipbforumpass_' . $this->container()->id ] ) and md5( $this->container()->password ) === \IPS\Request::i()->cookie[ 'ipbforumpass_' . $this->container()->id ] ) )
{
return \IPS\Theme::i()->getTemplate( 'global', 'forums' )->searchNoPermission( $this, \IPS\Member::loggedIn()->language()->addToStack('no_perm_topic_password'), $this->container()->url()->setQueryString( 'topic', $this->tid ) );
}
elseif ( $this->container()->min_posts_view and $this->container()->min_posts_view >= \IPS\Member::loggedIn()->member_posts )
{
return \IPS\Theme::i()->getTemplate( 'global', 'forums' )->searchNoPermission( $this, \IPS\Member::loggedIn()->language()->addToStack( 'no_perm_topic_min_posts', FALSE, array( 'pluralize' => array( $this->container()->min_posts_view ) ) ) );
}
else
{
return \IPS\Theme::i()->getTemplate( 'search', 'core', 'front' )->contentItem( $this );
}
}
/**
* Can Rate?
*
@@ -1042,18 +1040,38 @@ class _Topic extends \IPS\Content\Item implements
*/
public function canSetBestAnswer( \IPS\Member $member = NULL )
{
/* Archived topics cannot be modified */
if ( $this->isArchived() )
{
return FALSE;
}
$member = $member ?: \IPS\Member::loggedIn();
if ( ( $member == $this->author() and $this->container()->forums_bitoptions['bw_enable_answers_member'] ) or $member->modPermission('can_set_best_answer') )
/* If we asked this question, we can set the best answer */
$member = $member ?: \IPS\Member::loggedIn();
if ( $member == $this->author() and $this->container()->forums_bitoptions['bw_enable_answers_member'] )
{
return TRUE;
}
/* Or if we're a moderator */
if
(
$member->modPermission( 'can_set_best_answer' )
and
(
$member->modPermission( \IPS\forums\Forum::$modPerm ) === -1
or
(
is_array( $member->modPermission( \IPS\forums\Forum::$modPerm ) )
and
in_array( $this->container()->_id, $member->modPermission( \IPS\forums\Forum::$modPerm ) )
)
)
) {
return TRUE;
}
/* Otherwise no */
return FALSE;
}
@@ -1115,13 +1133,7 @@ class _Topic extends \IPS\Content\Item implements
{
throw new \InvalidArgumentException;
}
/* Downvoting disabled? */
if ( $rating === -1 and !\IPS\Settings::i()->forums_questions_downvote )
{
return FALSE;
}
/* Guests can't vote */
$member = $member ?: \IPS\Member::loggedIn();
if ( !$member->member_id )
@@ -1151,6 +1163,12 @@ class _Topic extends \IPS\Content\Item implements
}
}
/* Downvoting disabled? */
if ( $rating === -1 and !\IPS\Settings::i()->forums_questions_downvote and ( !isset( $ratings[ $member->member_id ] ) or $ratings[ $member->member_id ] != 1 ) )
{
return FALSE;
}
return TRUE;
}
@@ -1184,19 +1202,21 @@ class _Topic extends \IPS\Content\Item implements
* @param \IPS\Lang|NULL $language The language to use, or NULL for the language of the currently logged in member
* @return string
*/
public function indefiniteArticle( \IPS\Lang $lang = NULL )
public static function _indefiniteArticle( array $containerData = NULL, \IPS\Lang $lang = NULL )
{
if ( $this->isQuestion() )
$bitOptions = ( $containerData['forums_bitoptions'] instanceof \IPS\Patterns\Bitwise ) ? $containerData['forums_bitoptions'] : new \IPS\Patterns\Bitwise( array( 'forums_bitoptions' => $containerData['forums_bitoptions'] ), \IPS\forums\Forum::$bitOptions['forums_bitoptions'] );
if ( $bitOptions['bw_enable_answers'] )
{
$lang = $lang ?: \IPS\Member::loggedIn()->language();
return $lang->get( '__indefart_question', FALSE );
return $lang->addToStack( '__indefart_question', FALSE );
}
else
{
return parent::indefiniteArticle( $lang );
return parent::_indefiniteArticle( $containerData, $lang );
}
}
/* !Sitemap */
/**
@@ -1508,10 +1528,17 @@ class _Topic extends \IPS\Content\Item implements
return $comments[ $_hash ];
}
$includeWarnings = NULL;
$includeWarnings = NULL;
$commentClass = NULL;
if ( $this->isArchived() )
{
$class = static::$archiveClass;
/* We need to set $commentClass to the archive class, otherwise the includeHidden checks in _comments fail, as they verify $class == static::$commentClass */
$class = static::$archiveClass;
$commentClass = static::$commentClass;
static::$commentClass = $class;
$includeWarnings = FALSE;
if( $extraWhereClause !== NULL )
@@ -1535,13 +1562,19 @@ class _Topic extends \IPS\Content\Item implements
}
$comments[ $_hash ] = $this->_comments( $class, $limit ?: static::getCommentsPerPage(), $offset, ( isset( $class::$databaseColumnMap[ $order ] ) ? ( $class::$databasePrefix . $class::$databaseColumnMap[ $order ] ) : $order ) . ' ' . $orderDirection, $member, $includeHiddenComments, $cutoff, $includeWarnings, $extraWhereClause );
/* Restore comment class now */
if( $commentClass )
{
static::$commentClass = $commentClass;
}
return $comments[ $_hash ];
}
/**
* Resync the comments/unapproved comment counts
*
* @param string $commentClass
* @param string $commentClass Override comment class to use
* @return void
*/
public function resyncCommentCounts( $commentClass=NULL )
@@ -1569,7 +1602,7 @@ class _Topic extends \IPS\Content\Item implements
$title = static::$title;
if
(
$member->modPermission( $containerClass::$modPerm ) === 0
$member->modPermission( $containerClass::$modPerm ) === -1
or
(
is_array( $member->modPermission( $containerClass::$modPerm ) )