Version 4.3.0

This commit is contained in:
Neo committed 2025-12-19 05:47:12 -08:00
1 parent 96997ddd8e
commit fe1acf984a
1349 files changed
+116159 -67711

No files matched your search

@@ -39,7 +39,8 @@ class _streams extends \IPS\Dispatcher\Controller
/* Necessary CSS/JS */
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js('front_streams.js', 'core' ) );
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'styles/streams.css' ) );
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'front_statuses.js', 'core' ) );
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'styles/streams.css' ) );
if ( \IPS\Theme::i()->settings['responsive'] )
{
@@ -121,7 +122,7 @@ class _streams extends \IPS\Dispatcher\Controller
{
\IPS\Output::i()->json( array(
'url' => $defaultStream->url(),
'title' => htmlspecialchars( $defaultStream->_title, ENT_QUOTES | \IPS\HTMLENTITIES, 'UTF-8', FALSE ),
'title' => htmlspecialchars( $defaultStream->_title, ENT_QUOTES | ENT_DISALLOWED, 'UTF-8', FALSE ),
'tooltip' => $defaultStream->_title, // We need to pass this individually for the tooltip that shows, but the JS itself will escape any entities
'id' => $defaultStream->_id
) );
@@ -166,7 +167,7 @@ class _streams extends \IPS\Dispatcher\Controller
{
\IPS\Output::i()->json( array(
'url' => \IPS\Http\Url::internal( "app=core&module=discover&controller=streams", 'front', 'discover_all' ),
'title' => htmlspecialchars( $defaultStream->_title, ENT_QUOTES | \IPS\HTMLENTITIES, 'UTF-8', FALSE ),
'title' => htmlspecialchars( $defaultStream->_title, ENT_QUOTES | ENT_DISALLOWED, 'UTF-8', FALSE ),
'id' => $defaultStream->_id
) );
}
@@ -187,7 +188,13 @@ class _streams extends \IPS\Dispatcher\Controller
/* but only if we haven't submitted the form on this request */
if( !\IPS\Request::i()->stream_submitted )
{
$streamFields = array( 'include_comments', 'classes', 'clubs', 'ownership', 'custom_members', 'read', 'follow', 'followed_types', 'date_type', 'date_start', 'date_end', 'date_relative_days', 'sort', 'tags', 'unread_links' );
$streamFields = array( 'include_comments', 'classes', 'ownership', 'custom_members', 'read', 'follow', 'followed_types', 'date_type', 'date_start', 'date_end', 'date_relative_days', 'sort', 'tags', 'unread_links' );
/* Clubs enabled? */
if( \IPS\Settings::i()->clubs )
{
$streamFields[] = 'clubs';
}
/* Build and format field values */
$_values = array();
@@ -379,7 +386,7 @@ class _streams extends \IPS\Dispatcher\Controller
$output = \IPS\Theme::i()->getTemplate('streams')->streamItems( $results, TRUE, ( $stream->id and !$stream->include_comments ) ? 'last_comment' : 'date', $view );
$return = array(
'title' => htmlspecialchars( $stream->_title, \IPS\HTMLENTITIES | ENT_QUOTES, 'UTF-8', FALSE ),
'title' => htmlspecialchars( $stream->_title, ENT_DISALLOWED | ENT_QUOTES, 'UTF-8', FALSE ),
'blurb' => $stream->blurb(),
'config' => json_encode( $stream->config() ),
'count' => count( $results ),
@@ -484,7 +491,7 @@ class _streams extends \IPS\Dispatcher\Controller
if ( $stream->member != \IPS\Member::loggedIn()->member_id )
{
\IPS\Output::i()->error( 'no_permission', '2C280/8', 403, '' );
\IPS\Output::i()->error( 'no_module_permission', '2C280/8', 403, '' );
}
$form = new \IPS\Helpers\Form;
@@ -599,7 +606,7 @@ class _streams extends \IPS\Dispatcher\Controller
{
$url = $stream ? $stream->baseUrl->setQueryString( 'className', $class ) : \IPS\Request::i()->url()->setQueryString( 'className', $class );
$containerClass = $class::$containerNodeClass;
$field = new \IPS\Helpers\Form\Node( 'stream_containers_' . $class::$title, isset( $currentContainers[ $class ] ) ? $currentContainers[ $class ] : array(), NULL, array( 'url' => $url, 'class' => $class::$containerNodeClass, 'multiple' => TRUE, 'permissionCheck' => $containerClass::searchableNodesPermission(), 'clubs' => \IPS\IPS::classUsesTrait( $containerClass, 'IPS\Content\ClubContainer' ) ), NULL, NULL, NULL, 'stream_containers_' . $class::$title );
$field = new \IPS\Helpers\Form\Node( 'stream_containers_' . $class::$title, isset( $currentContainers[ $class ] ) ? $currentContainers[ $class ] : array(), NULL, array( 'url' => $url, 'class' => $class::$containerNodeClass, 'multiple' => TRUE, 'permissionCheck' => $containerClass::searchableNodesPermission(), 'clubs' => ( \IPS\Settings::i()->clubs AND \IPS\IPS::classUsesTrait( $containerClass, 'IPS\Content\ClubContainer' ) ) ), NULL, NULL, NULL, 'stream_containers_' . $class::$title );
$field->label = \IPS\Member::loggedIn()->language()->addToStack( 'stream_narrow_by_container_label', NULL, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->addToStack( $containerClass::$nodeTitle ) ) ) );
return \IPS\Output::i()->json( array( 'node' => \IPS\Theme::i()->getTemplate('streams')->filterFormContentTypeContent( $field, $class, \IPS\Request::i()->key ) ) );
@@ -616,6 +623,11 @@ class _streams extends \IPS\Dispatcher\Controller
*/
protected function getClubElement()
{
if( !\IPS\Settings::i()->clubs )
{
return \IPS\Output::i()->json( array( 'field' => '' ) );
}
$clubOptions = array();
foreach ( \IPS\Member\Club::clubs( \IPS\Member::loggedIn(), NULL, 'name', TRUE ) as $club )
{
@@ -681,25 +693,48 @@ class _streams extends \IPS\Dispatcher\Controller
/* Handle submissions */
if ( $values = $form->values() )
{
/* As the node container form elements are not in the actual form, we need to work some magic. And by magic, I do mean a sort of hacky thing. */
foreach ( \IPS\Request::i() as $k => $v )
/* As the node container form elements are not in the actual form, we need to work some magic.
And by magic, I do mean a sort of hacky thing. First, if we are editing a stream, we need to get our existing stream filters
and put these into an array. Then we loop over the input and overwrite the existing filters with what was submitted. If the user
never loaded the container filters we'll retain what we had (expected) but if they did and adjusted or removed container filters
then we'll update with what they submitted (expected).
*/
if( $stream->id )
{
if ( mb_substr( $k, 0, 18 ) == 'stream_containers_' and $v )
$currentContainers = $stream->containers ? json_decode( $stream->containers, TRUE ) : array();
foreach( $currentContainers as $class => $containers )
{
$vals = explode( ',', $v );
$values[ $k ] = array_combine( $vals, $vals );
$values['stream_containers_' . $class::$title ] = array_combine( $containers, $containers );
}
}
foreach ( \IPS\Request::i() as $k => $v )
{
if ( mb_substr( $k, 0, 18 ) == 'stream_containers_' )
{
if( $v )
{
$vals = explode( ',', $v );
$values[ $k ] = array_combine( $vals, $vals );
}
elseif( isset( $values[ $k ] ) )
{
$values[ $k ] = NULL;
}
}
}
/* Update only */
if ( isset( \IPS\Request::i()->updateOnly ) )
{
$formattedValues = $stream->formatFormValues( $values );
foreach ( array( 'include_comments', 'classes', 'containers', 'clubs', 'ownership', 'custom_members', 'read', 'follow', 'followed_types', 'date_type', 'date_start', 'date_end', 'date_relative_days', 'sort', 'tags', 'unread_links' ) as $k )
{
$requestKey = 'stream_' . $k;
if ( isset( $formattedValues[ $k ] ) AND $stream->$k != $formattedValues[ $k ] )
if ( array_key_exists( $k, $formattedValues ) AND $stream->$k != $formattedValues[ $k ] )
{
$stream->$k = $formattedValues[ $k ];
$stream->baseUrl = $stream->baseUrl->setQueryString( 'stream_' . $k, \IPS\Request::i()->$requestKey );