Version 4.7.0

This commit is contained in:
Neo committed 2025-12-19 16:00:35 -08:00
1 parent 517a5e1f70
commit 8ba7d43898
1933 files changed
+65613 -11332

No files matched your search

@@ -11,6 +11,9 @@
namespace IPS\core;
/* To prevent PHP errors (extending class does not exist) revealing path */
use IPS\Text\DOMParser;
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
@@ -55,7 +58,7 @@ class _Profanity extends \IPS\Patterns\ActiveRecord implements \JsonSerializable
/**
* @brief Action Type
*/
public static $actionTypes = array( 'swap', 'moderate' );
public static $actionTypes = array( 'swap', 'moderate', 'block' );
/**
* Table
@@ -78,6 +81,7 @@ class _Profanity extends \IPS\Patterns\ActiveRecord implements \JsonSerializable
/* Filters */
$table->filters = array(
'profanity_require_approval' => "action='moderate'",
'profanity_block' => "action='block'",
'profanity_replace_text' => "action='swap'",
);
@@ -92,11 +96,15 @@ class _Profanity extends \IPS\Patterns\ActiveRecord implements \JsonSerializable
{
return \IPS\Member::loggedIn()->language()->addToStack( 'profanity_replace_with_x', FALSE, array( 'sprintf' => array( $row['swop'] ) ) );
}
else if ( $val == 'block' )
{
return \IPS\Member::loggedIn()->language()->addToStack( 'profanity_block' );
}
else
{
if ( $row['min_posts'] )
{
return \IPS\Member::loggedIn()->language()->addToStack( 'profanity_filter_action_moderate_min_posts', NULL, array( 'pluralize' => array( $row['min_posts'] ) ) );
return \IPS\Member::loggedIn()->language()->addToStack( 'profanity_filter_action_moderate_min_posts', FALSE, array( 'pluralize' => array( $row['min_posts'] ) ) );
}
return \IPS\Member::loggedIn()->language()->addToStack('profanity_filter_action_moderate');
@@ -164,10 +172,29 @@ class _Profanity extends \IPS\Patterns\ActiveRecord implements \JsonSerializable
$form->addTab('add');
}
$form->add( new \IPS\Helpers\Form\Text( 'profanity_type', ( $current ) ? $current->type : NULL, NULL, array() ) );
$form->add( new \IPS\Helpers\Form\Text( 'profanity_type', ( $current ) ? $current->type : NULL, NULL, array(), function( $val )
{
if ( $val )
{
try
{
$word = static::load( $val, 'type' );
if ( ! isset( \IPS\Request::i()->id ) or ( isset( \IPS\Request::i()->id ) and \IPS\Request::i()->id != $word->wid ) )
{
throw new \LogicException( 'profanity_already_exists' );
}
}
catch( \OutOfRangeException $e )
{
/* Nothing exists, so we are good */
}
}
} ) );
$form->add( new \IPS\Helpers\Form\Radio( 'profanity_action', ( $current ) ? $current->action : 'swap', FALSE, array(
'options' => array(
'swap' => 'profanity_filter_action_swap',
'block' => 'profanity_filter_action_block',
'moderate' => 'profanity_filter_action_moderate'
),
'toggles' => array(
@@ -296,6 +323,11 @@ class _Profanity extends \IPS\Patterns\ActiveRecord implements \JsonSerializable
{
$return = static::_checkUrlFilters( $content );
}
if ( $return == FALSE )
{
$return = static::_checkEmailFilters( $content );
}
return $return;
}
@@ -487,12 +519,72 @@ class _Profanity extends \IPS\Patterns\ActiveRecord implements \JsonSerializable
return TRUE;
}
}
catch( \Exception $e ) { }
catch( \Exception $e ) {}
catch( \ValueError $e ) {}
}
return FALSE;
}
/**
* Check Email Filters
*
* @param string $content The content to check
* @return bool
*/
protected static function _checkEmailFilters( $content )
{
/* If we are allowing ANY URL's and not doing anything, then do that */
if ( \IPS\Settings::i()->email_filter_action == 'moderate')
{
/* Ensure that image and file names don't trip up the email filter */
$source = new \IPS\Xml\DOMDocument( '1.0', 'UTF-8' );
$source->loadHTML( \IPS\Xml\DOMDocument::wrapHtml( $content ) );
$contentImages = $source->getElementsByTagName( 'img' );
foreach( $contentImages as $element )
{
foreach( [ 'data-src', 'src', 'srcset', 'alt', 'title' ] as $attr )
{
if ( $element->hasAttribute( $attr ) )
{
/* Remove any filenames, alts or titles so they don't trigger the moderation filter */
$element->setAttribute( $attr, '' );
}
}
}
/* Get document URLs */
$contentUrls = $source->getElementsByTagName( 'a' );
foreach( $contentUrls as $element )
{
foreach( [ 'href', 'title' ] as $attr )
{
if ( $element->hasAttribute( $attr ) )
{
if ( $attr === 'href' and ! mb_stristr( $element->getAttribute( $attr ), 'mailto:' ) )
{
/* Remove any hrefs or titles so they don't trigger the moderation filter */
$element->setAttribute( $attr, '' );
}
}
}
}
/* Get DOMDocument output */
$content = \IPS\Text\DOMParser::getDocumentBodyContents( $source );
if( preg_match( '/' . \IPS\Text\Parser::EMAIL_REGEX . '/u', $content, $matches ) )
{
return TRUE;
}
}
return FALSE;
}
/**
* @brief [ActiveRecord] Caches
* @note Defined cache keys will be cleared automatically as needed