Version 4.2.0

This commit is contained in:
Neo committed 2025-12-19 05:44:59 -08:00
1 parent 0dc2aee5ed
commit 96997ddd8e
2074 files changed
+125454 -55780

No files matched your search

+179 -18
View File
@@ -1,12 +1,11 @@
<?php
/**
* @brief Content Discovery Stream
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @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
* @since 1 Jul 2015
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core;
@@ -339,7 +338,7 @@ class _Stream extends \IPS\Node\Model
*
* @param \IPS\Helpers\Form $form The form
* @param string $titleType 'Text' or 'Translatable
* @pram bool $titleRequired Is the title field required?
* @param bool $titleRequired Is the title field required?
* @return void
*/
public function form( &$form, $titleType='Translatable', $titleRequired=TRUE )
@@ -360,12 +359,13 @@ class _Stream extends \IPS\Node\Model
/* All content or specific content? */
$form->add( new \IPS\Helpers\Form\Radio( 'stream_classes_type', $this->classes ? 1 : 0, TRUE, array(
'options' => array( 0 => 'stream_classes_type_all', 1 => 'stream_classes_type_custom' ),
'toggles' => array( 1 => array( 'stream_classes' ) )
'toggles' => array( 0 => array( 'stream_club_select' ), 1 => array( 'stream_classes' ) )
) ) );
/* Work out all the different classes */
$classes = array();
$classToggles = array();
foreach ( \IPS\Content::routedClasses( TRUE, FALSE, TRUE ) as $class )
{
$classes[ $class ] = $class::$title . '_pl';
@@ -374,10 +374,65 @@ class _Stream extends \IPS\Node\Model
$classToggles[ $class ][] = 'stream_containers_' . $class::$title;
}
}
$containers = json_decode( $this->containers );
/* Add the fields for them */
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'stream_classes', $this->classes ? explode( ',', $this->classes ) : array(), NULL, array( 'options' => $classes, 'toggles' => $classToggles ), NULL, NULL, NULL, 'stream_classes' ) );
if ( \IPS\Dispatcher::i()->controllerLocation === 'admin' )
{
/* Nodes */
foreach ( $classToggles as $class => $id )
{
if ( isset( $class::$containerNodeClass ) )
{
$nodeClass = $class::$containerNodeClass;
$value = isset( $containers->$class ) ? $containers->$class : 0;
$field = new \IPS\Helpers\Form\Node( 'stream_containers_' . $class::$title, $value, FALSE, array( 'class' => $nodeClass, 'multiple' => TRUE, 'zeroVal' => 'all', 'permissionCheck' => $nodeClass::searchableNodesPermission(), 'forceOwner' => FALSE ), NULL, NULL, NULL, 'stream_containers_' . $class::$title );
$field->label = \IPS\Member::loggedIn()->language()->addToStack( $nodeClass::$nodeTitle );
$form->add( $field );
}
}
}
/* Clubs */
$clubs = \IPS\Member\Club::clubs( NULL, NULL, 'name', FALSE, array(), \IPS\Settings::i()->clubs_require_approval ? array( 'approved=1' ) : NULL );
if ( count( $clubs ) )
{
$clubOptions = array();
foreach ( $clubs as $club )
{
$clubOptions[ "c{$club->id}" ] = $club->name;
}
switch ( $this->clubs )
{
case NULL:
$clubSelect = 'all';
break;
case '0':
$clubSelect = 'none';
break;
default:
$clubSelect = 'select';
break;
}
$form->add( new \IPS\Helpers\Form\Radio( 'stream_club_select', $clubSelect, TRUE, array(
'options' => array(
'all' => 'stream_club_select_all',
'none' => 'stream_club_select_none',
'select' => 'stream_club_select_select',
),
'toggles' => array(
'select' => array( 'stream_club_filter' )
)
), NULL, NULL, NULL, 'stream_club_select' ) );
$form->add( new \IPS\Helpers\Form\Select( 'stream_club_filter', explode( ',', $this->clubs ), FALSE, array( 'options' => $clubOptions, 'parse' => 'none', 'multiple' => TRUE, 'noDefault' => TRUE ), NULL, NULL, NULL, 'stream_club_filter' ) );
}
/* Tags */
if ( \IPS\Settings::i()->tags_enabled )
{
@@ -531,6 +586,39 @@ class _Stream extends \IPS\Node\Model
}
unset( $values['stream_classes_type'] );
/* Clubs */
if ( isset( $values['stream_club_select'] ) and ( !isset( $values['stream_classes_type'] ) or $values['stream_classes_type'] == 0 ) )
{
switch ( $values['stream_club_select'] )
{
case 'all':
$values['stream_clubs'] = NULL;
break;
case 'none':
$values['stream_clubs'] = 0;
break;
case 'select':
if ( $values['stream_club_filter'] )
{
$values['stream_clubs'] = is_array( $values['stream_club_filter'] ) ? implode( ',', $values['stream_club_filter'] ) : $values['stream_club_filter'];
}
else
{
$values['stream_clubs'] = 0;
}
break;
}
}
else
{
$values['stream_clubs'] = NULL;
}
unset( $values['stream_club_select'] );
unset( $values['stream_club_filter'] );
/* And tags */
if ( isset( $values['stream_tags'] ) )
{
@@ -697,6 +785,35 @@ class _Stream extends \IPS\Node\Model
$terms = array();
if ( $this->clubs === '0' )
{
$terms[] = \IPS\Member::loggedIn()->language()->addToStack('stream_blurb_no_clubs');
}
elseif ( $this->clubs )
{
$clubs = array();
foreach ( explode( ',', $this->clubs ) as $clubId )
{
try
{
$club = \IPS\Member\Club::load( ltrim( $clubId, 'c' ) );
if ( $club->canRead( \IPS\Member::loggedIn() ) )
{
$clubs[] = $club->name;
}
}
catch ( \Exception $e ) { }
}
if ( count( $clubs ) )
{
$terms[] = \IPS\Member::loggedIn()->language()->addToStack( 'stream_blurb_in_clubs', FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->formatList( $clubs ) ) ) );
}
else
{
$terms[] = \IPS\Member::loggedIn()->language()->addToStack('stream_blurb_no_clubs');
}
}
if ( $this->tags )
{
$terms[] = \IPS\Member::loggedIn()->language()->addToStack( 'stream_includes_tags', FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->formatList( array_map( function( $val ){
@@ -818,9 +935,26 @@ class _Stream extends \IPS\Node\Model
'stream_date_type' => $this->date_type,
'stream_classes' => NULL,
'stream_unread_links' => $this->unread_links,
'containers' => static::containersToUrl( $this->containers )
'containers' => static::containersToUrl( $this->containers ),
);
/* Clubs */
switch ( $this->clubs )
{
case NULL:
$config['stream_club_select'] = 'all';
$config['stream_club_filter'] = '';
break;
case '0':
$config['stream_club_select'] = 'none';
$config['stream_club_filter'] = '0';
break;
default:
$config['stream_club_select'] = 'select';
$config['stream_club_filter'] = $this->clubs;
break;
}
/* Follows */
$followedTypes = explode( ',', $this->followed_types );
$config['stream_followed_types'] = array();
@@ -929,8 +1063,10 @@ class _Stream extends \IPS\Node\Model
$query = \IPS\Content\Search\Query::init( $member );
/* Content Filters */
$filters = array();
$allowedContainers = $this->containers ? json_decode( $this->containers, TRUE ) : array();
$filters = array();
$allowedContainers = $this->containers ? json_decode( $this->containers, TRUE ) : array();
$classesChecked = array();
if ( $this->classes )
{
/* Translate how we store this into the format needed for filterByContent */
@@ -958,7 +1094,7 @@ class _Stream extends \IPS\Node\Model
if ( ! $this->include_comments or ( isset( $options['items'] ) and !isset( $options['comments'] ) and in_array( 'IPS\Content\Item', class_parents( $class ) ) and $class::$firstCommentRequired ) )
{
/* items with no comments are flagged as being the last comment */
$filter = \IPS\Content\Search\ContentFilter::init( $class, TRUE, TRUE, isset( $options['reviews'] ) )->onlyLastComment();
$filter = \IPS\Content\Search\ContentFilter::init( $class, TRUE, TRUE, TRUE )->onlyLastComment();
}
else
{
@@ -973,9 +1109,10 @@ class _Stream extends \IPS\Node\Model
/* Add to the array */
$filters[] = $filter;
$classesChecked[] = $class;
}
}
elseif ( !$this->include_comments )
else
{
foreach ( \IPS\Application::allExtensions( 'core', 'ContentRouter', FALSE ) as $object )
{
@@ -983,17 +1120,38 @@ class _Stream extends \IPS\Node\Model
{
if ( in_array( 'IPS\Content\Item', class_parents( $class ) ) )
{
$filters[] = \IPS\Content\Search\ContentFilter::init( $class, TRUE, TRUE, FALSE )->onlyLastComment();
if( !$this->include_comments )
{
$filters[] = \IPS\Content\Search\ContentFilter::init( $class, TRUE, TRUE, TRUE )->onlyLastComment();
}
$classesChecked[] = $class;
}
}
}
}
/* Give content item classes a chance to inspect and manipulate filters */
foreach( $classesChecked as $itemClass )
{
$itemClass::searchEngineFiltering( $filters, $query );
}
if ( count( $filters ) )
{
$query->filterByContent( $filters );
}
/* Clubs */
if ( $this->clubs === '0' )
{
$query->filterByClub( NULL );
}
elseif ( $this->clubs )
{
$query->filterByClub( array_map( function( $val ) { return ltrim( $val, 'c' ); }, explode( ',', $this->clubs ) ) );
}
/* Ownership */
switch ( $this->ownership )
{
@@ -1023,16 +1181,19 @@ class _Stream extends \IPS\Node\Model
$query->filterByFollowed( in_array( 'containers', $followTypes ), in_array( 'items', $followTypes ), in_array( 'members', $followTypes ) );
}
/* If we are showing all items (not grouping on last comment, then we need to filter by creation date */
$filterDateMethod = ( $this->include_comments ) ? 'filterByCreateDate' : 'filterByLastUpdatedDate';
/* Date */
switch ( $this->date_type )
{
case 'last_visit':
$query->filterByLastUpdatedDate( \IPS\DateTime::ts( \IPS\Member::loggedIn()->last_visit ) );
$query->$filterDateMethod( \IPS\DateTime::ts( \IPS\Member::loggedIn()->last_visit ) );
break;
case 'relative':
$query->filterByLastUpdatedDate( \IPS\DateTime::create()->sub( new \DateInterval( 'P' . intval( $this->date_relative_days ) . 'D' ) ) );
$query->$filterDateMethod( \IPS\DateTime::create()->sub( new \DateInterval( 'P' . intval( $this->date_relative_days ) . 'D' ) ) );
case 'custom':
$query->filterByLastUpdatedDate( $this->date_start ? \IPS\DateTime::ts( $this->date_start ) : NULL, $this->date_end ? \IPS\DateTime::ts( $this->date_end ) : NULL );
$query->$filterDateMethod( $this->date_start ? \IPS\DateTime::ts( $this->date_start ) : NULL, $this->date_end ? \IPS\DateTime::ts( $this->date_end ) : NULL );
break;
}