Version 5.0.6

This commit is contained in:
Neo committed 2025-12-19 18:55:49 -08:00
1 parent a3a4a9ccbd
commit b89858b2ff
1214 files changed
+92828 -14859

No files matched your search

@@ -23,6 +23,7 @@ use IPS\GeoLocation;
use IPS\Helpers\Form;
use IPS\Helpers\Form\CheckboxSet;
use IPS\Helpers\Form\Radio;
use IPS\Helpers\Form\Text;
use IPS\Http\Url;
use IPS\Member;
use IPS\Member\Club;
@@ -127,7 +128,12 @@ class directory extends Controller
/* All Clubs: Filters */
$filters = array();
$mineOnly = FALSE;
$extraWhere = NULL;
$extraWhere = [];
if ( ! empty( Request::i()->name ) )
{
$baseUrl = $baseUrl->setQueryString( 'name', Request::i()->name );
$extraWhere[] = Db::i()->like( 'name', Request::i()->name, true, true, true );
}
if ( isset( Request::i()->filter ) and Request::i()->filter === 'mine' AND Member::loggedIn()->member_id )
{
$mineOnly = TRUE;
@@ -289,7 +295,9 @@ class directory extends Controller
$fields = CustomField::roots();
$form = new Form('filter', 'filter');
$form->add( new Text( 'club_filter_name', isset( Request::i()->name ) ? Request::i()->name : '' ) );
if ( Member::loggedIn()->member_id )
{
$form->add( new Radio( 'club_filter_type', isset( Request::i()->filter ) ? Request::i()->filter : 'all', TRUE, array( 'options' => array(
@@ -339,7 +347,12 @@ class directory extends Controller
if ( $values = $form->values() )
{
$url = Url::internal( 'app=core&module=clubs&controller=directory', 'front', 'clubs_list' );
if ( ! empty ( $values['club_filter_name'] ) )
{
$url = $url->setQueryString( 'name', $values['club_filter_name'] );
}
if ( Member::loggedIn()->member_id and $values['club_filter_type'] === 'mine' )
{
$url = $url->setQueryString( 'filter', 'mine' );
@@ -243,7 +243,6 @@ class tag extends Controller
$table = new TableContent( $class, $this->tag->url()->setQueryString( 'tab', $type ), $this->_getWhereClause( $class ) );
$table->classes[] = 'ipsData--grid ipsData--tags-data ipsData--tags-' . $type;
$table->limit = 20;
$table->title = sprintf( Member::loggedIn()->language()->get( 'tag_content_tagged' ), Member::loggedIn()->language()->get( $type . '_pl' ), $this->tag->text );
$table->rowsTemplate = [ Theme::i()->getTemplate( 'tags', 'core' ), 'contentTableRows' ];
$table->noModerate = true;
return (string) $table;
@@ -215,11 +215,13 @@ class profile extends Controller
/* Work out the main content to display */
/* What tabs are available? */
$tabs = array( 'activity' => 'users_activity_feed' );
$tabs = array( 'activity' => [ 'url' => Url::internal( "app=core&module=members&controller=profile&id=" . $this->member->member_id . "&tab=activity", "front",
"profile_tab", $this->member->members_seo_name ), 'title' => 'users_activity_feed' ] );
if ( Member::loggedIn()->canAccessModule( Module::get( 'core', 'clubs', 'front' ) ) and Settings::i()->clubs and Club::clubs( Member::loggedIn(), NULL, 'created', $this->member, array(), NULL, TRUE ) )
{
$tabs['clubs'] = 'users_clubs';
$tabs['clubs'] = [ 'url' => Url::internal( "app=core&module=members&controller=profile&id=" . $this->member->member_id . "&tab=clubs", "front",
"profile_tab", $this->member->members_seo_name ), 'title' => 'users_clubs' ];
}
foreach( $mainFields as $group => $fields )
@@ -228,7 +230,8 @@ class profile extends Controller
{
if ( $value )
{
$tabs["field_{$field}"] = $field;
$tabs[ "field_{$field}" ] = [ 'url' => Url::internal( "app=core&module=members&controller=profile&id=" . $this->member->member_id . "&tab=field_" . $field, "front",
"profile_tab", $this->member->members_seo_name ), 'title' => $field ];
}
}
}
@@ -240,18 +243,29 @@ class profile extends Controller
{
preg_match( '/^IPS\\\(.+?)\\\extensions\\\core\\\Profile\\\(.+?)$/', $extension, $matches );
$nodes[ "{$matches[1]}_{$matches[2]}" ] = $profileExtension;
$tabs[ "node_{$matches[1]}_{$matches[2]}" ] = "profile_{$matches[1]}_{$matches[2]}";
$tabs[ "node_{$matches[1]}_{$matches[2]}" ] = [ 'url' => $profileExtension->url(), 'title' => "profile_{$matches[1]}_{$matches[2]}" ];
}
}
/* What tab are we on? */
if ( !isset( Request::i()->tab ) or !array_key_exists( Request::i()->tab, $tabs ) )
$tab = 'activity';
if ( isset( Request::i()->tab ) )
{
$tab = 'activity';
}
else
{
$tab = Request::i()->tab;
$currentUrl = (string) Request::i()->url()->stripQueryString();
foreach( $tabs as $k => $v )
{
if( $k == Request::i()->tab )
{
$tab = $k;
break;
}
if( $currentUrl === (string) $v['url'] )
{
$tab = $k;
break;
}
}
}
/* Work out the content */
@@ -1448,9 +1462,9 @@ class profile extends Controller
}
$limit = array( ( $page - 1 ) * 50, 50 );
$followers = $this->member->followers( ( Member::loggedIn()->isAdmin() OR Member::loggedIn()->member_id === $this->member->member_id ) ? \IPS\Content::FOLLOW_PUBLIC + \IPS\Content::FOLLOW_ANONYMOUS : \IPS\Content::FOLLOW_PUBLIC, array( 'immediate', 'daily', 'weekly', 'none' ), NULL, $limit, 'name' );
$followers = iterator_to_array( $this->member->followers( ( Member::loggedIn()->isAdmin() OR Member::loggedIn()->member_id === $this->member->member_id ) ? \IPS\Content::FOLLOW_PUBLIC + \IPS\Content::FOLLOW_ANONYMOUS : \IPS\Content::FOLLOW_PUBLIC, array( 'immediate', 'daily', 'weekly', 'none' ), NULL, $limit, 'name' ) );
$followersCount = $this->member->followersCount( ( Member::loggedIn()->isAdmin() OR Member::loggedIn()->member_id === $this->member->member_id ) ? \IPS\Content::FOLLOW_PUBLIC + \IPS\Content::FOLLOW_ANONYMOUS : \IPS\Content::FOLLOW_PUBLIC, array( 'immediate', 'daily', 'weekly', 'none' ) );
if ( Request::i()->isAjax() )
{
Output::i()->sendOutput( Theme::i()->getTemplate( 'profile' )->followers( $this->member, $followers ) );
@@ -15,6 +15,7 @@ namespace IPS\core\modules\front\modcp;
use IPS\Application;
use IPS\core\DataLayer;
use IPS\Dispatcher\Controller;
use IPS\Extensions\ModCpAbstract;
use IPS\Http\Url;
use IPS\Lang;
use IPS\Member;
@@ -24,6 +25,7 @@ use IPS\Settings;
use IPS\Theme;
use function defined;
use function method_exists;
use function ucfirst;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
@@ -98,12 +100,14 @@ class modcp extends Controller
$activeTab = Request::i()->tab ?: 'overview';
$tabs = array( 'reports' => array(), 'approval' => array() );
$content = '';
$approvalQueueCount = 0;
$counters = [];
foreach ( Application::allExtensions( 'core', 'ModCp' ) as $key => $extension )
{
/* We use this to group the sidebar for the ModCP */
$tabType = 'other';
/* @var ModCpAbstract $extension */
if ( $extension->manageType() )
{
$tabType = in_array( $extension->manageType(), array( 'content', 'members' ) ) ? $extension->manageType() : 'other';
@@ -116,10 +120,15 @@ class modcp extends Controller
$tabs[ $tabType ][ $tab ][] = $key;
}
/* Get the count for the approval queue from the extension */
if( $tab == 'approval' )
/* Get any counts that should show at the top */
foreach( $extension->getCounters() as $index => $counter )
{
$approvalQueueCount = $extension->getApprovalQueueCount( false );
if( empty( $counter['id'] ) )
{
$counter['id'] = "elModCP" . ucfirst( $tab ) . $index . "Counter";
}
$counters[] = $counter;
}
if( mb_strtolower( (string) $extension->getTab() ) == mb_strtolower( (string) $activeTab ) )
@@ -161,7 +170,7 @@ class modcp extends Controller
}
else
{
Output::i()->output = Theme::i()->getTemplate( 'modcp' )->template( $content, $tabs, $activeTab, $approvalQueueCount );
Output::i()->output = Theme::i()->getTemplate( 'modcp' )->template( $content, $tabs, $activeTab, $counters );
}
}
}
@@ -60,7 +60,7 @@ class online extends Controller
/* Create the table */
$table = new Table( Url::internal( 'app=core&module=online&controller=online', 'front', 'online' ) );
$table->tableTemplate = array( Theme::i()->getTemplate( 'online', 'core', 'front' ), 'onlineUsersTable' );
$table->rowsTemplate = array( Theme::i()->getTemplate( 'online', 'core', 'front' ), 'onlineUsersRow' );
$table->rowsTemplate = array( Theme::i()->getTemplate( 'online', 'core', 'front' ), 'onlineUsersRows' );
$table->langPrefix = 'online_users_';
$table->include = array( 'photo', 'member_name', 'location_lang', 'running_time', 'ip_address', 'login_type' );
$table->limit = 30;
@@ -58,7 +58,7 @@ class alerts extends Controller
{
$alert = Alert::load( Request::i()->id );
if( $alert->reply == Alert::REPLY_REQUIRED and Member::loggedIn()->member_id and Member::loggedIn()->canUseMessenger() )
if( $alert->reply == Alert::REPLY_REQUIRED and Member::loggedIn()->member_id and Member::loggedIn()->canUseMessenger() and Member::load( $alert->member_id )->member_id )
{
Output::i()->error( 'alert_cant_dismiss', '3C428/1', 403, '' );
}
@@ -23,6 +23,7 @@ use IPS\Output;
use IPS\Request;
use IPS\Session;
use IPS\Theme;
use LogicException;
use OutOfRangeException;
use UnderflowException;
use function defined;
@@ -110,13 +111,13 @@ class attachments extends Controller
$attachmentItem = $extensions[ $exploded[1] ]->attachmentLookup( $attachment[ 'id1' ], $attachment[ 'id2' ], $attachment[ 'id3' ] );
}
}
catch ( OutOfRangeException $e )
catch ( OutOfRangeException | LogicException $e )
{
Output::i()->json( array( 'error' => 'no_permission' ) );
}
/* If we have permission to edit the post, we're going to save the rotation angle */
if( $attachmentItem->author()->member_id == Member::loggedIn()->member_id OR $attachmentItem->canEdit() )
if( $attachmentItem instanceof \IPS\Content and ( $attachmentItem->author()->member_id == Member::loggedIn()->member_id OR $attachmentItem->canEdit() ) )
{
$baseRotation = $attachment['attach_img_rotate'];
$temp = false;
@@ -387,7 +387,7 @@ class editor extends Controller
}
}
/* Work out what tab we're on */
if ( !Request::i()->tab )
if ( !Request::i()->tab or !in_array( Request::i()->tab, $mediaSources ) )
{
if( !count( $mediaSources ) )
{
@@ -400,7 +400,8 @@ class editor extends Controller
}
$exploded = explode( '_', Request::i()->tab );
$classname = "IPS\\{$exploded[0]}\\extensions\\core\\EditorMedia\\{$exploded[1]}";
$classname = Application::getExtensionClass( $exploded[0], 'EditorMedia', $exploded[1] );
$extension = new $classname;
$url = Url::internal( "app=core&module=system&controller=editor&do=myMedia&tab=" . Request::i()->tab . "&key=" . Request::i()->key . "&postKey=" . Request::i()->postKey . "&existing=1" );
@@ -212,7 +212,11 @@ class metatags extends Controller
foreach( $manifest as $k => $v )
{
if( $v )
if ( $k == 'start_url' AND empty( $v ) )
{
$output[ $k ] = '/';
}
else if ( $v )
{
$output[ $k ] = $v;
}
@@ -258,17 +258,24 @@ class register extends Controller
$steps[ $key ] = $form;
}
}
/* This happens when the user has already completed the step.
We need to use a dummy function, or the wizard gets thrown out of whack. */
if( !array_key_exists( $step->key, $steps ) )
{
$steps[ $step->key ] = function( $data )
{
return $data;
};
}
}
}
/* If we have more than one step, add a redirect step at the end */
if( count( $steps ) > 1 )
/* The redirect is always the last step */
$steps['profile_done'] = function( $data ) use( $postBeforeRegister )
{
$steps['profile_done'] = function( $data ) use( $postBeforeRegister )
{
$this->_performRedirect( $postBeforeRegister );
};
}
$this->_performRedirect( $postBeforeRegister );
};
/* Output */
Output::i()->title = Member::loggedIn()->language()->addToStack('registration');
@@ -191,7 +191,8 @@ class settings extends Controller
{
$tabs['email'] = [
'icon' => 'envelope',
'title' => 'email_address'
'title' => 'email_address',
'url' => Url::internal( "app=core&module=system&controller=settings&area=email", "front", "settings_email" )
];
if( Member::loggedIn()->members_bitoptions['email_messages_bounce'] )
{
@@ -215,7 +216,10 @@ class settings extends Controller
if( $canChangePassword )
{
$tabs['password'] = [ 'icon' => 'key' ];
$tabs['password'] = [
'icon' => 'key',
'url' => Url::internal( "app=core&module=system&controller=settings&area=password", "front", "settings_password" )
];
}
/* MFA */
@@ -233,7 +237,8 @@ class settings extends Controller
{
$tabs['mfa'] = [
'icon' => 'lock',
'title' => 'ucp_mfa'
'title' => 'ucp_mfa',
'url' => Url::internal( "app=core&module=system&controller=settings&area=mfa", "front", "settings_mfa" )
];
}
@@ -242,20 +247,25 @@ class settings extends Controller
{
$tabs['devices'] = [
'icon' => 'laptop',
'title' => 'ucp_devices'
'title' => 'ucp_devices',
'url' => Url::internal( "app=core&module=system&controller=settings&area=devices", "front", "settings_devices" )
];
}
/* Can change username? */
if( Member::loggedIn()->group['g_dname_changes'] )
{
$tabs['username'] = [ 'icon' => 'user' ];
$tabs['username'] = [
'icon' => 'user',
'url' => Url::internal( "app=core&module=system&controller=settings&area=username", "front", "settings_username" )
];
}
/* Content Preferences */
$tabs['links'] = [
'icon' => 'file-pen',
'title' => 'profile_settings_cvb'
'title' => 'profile_settings_cvb',
'url' => Url::internal( "app=core&module=system&controller=settings&area=links", "front", "settings_links" )
];
/* Signature */
@@ -292,7 +302,8 @@ class settings extends Controller
{
$tabs['apps'] = [
'icon' => 'cubes',
'title' => 'oauth_apps'
'title' => 'oauth_apps',
'url' => Url::internal( "app=core&module=system&controller=settings&area=apps", "front", "settings_apps" )
];
}
@@ -56,6 +56,13 @@ class themeeditor extends Controller
*/
public function manage(): void
{
/* If we are coming from a login, redirect to the homepage. At this point, the
editor cookie will already be enabled, so the theme editor will open automatically. */
if( isset( Request::i()->_fromLogin ) and Request::i()->_fromLogin )
{
Output::i()->redirect( Url::internal( "" ) );
}
if( !Member::loggedIn()->modPermission( 'can_use_theme_editor' ) )
{
Output::i()->error( 'no_permission', '2S164/1', 403, '' );
@@ -364,14 +371,7 @@ class themeeditor extends Controller
*/
protected function customCss() : void
{
$functionName = "css_" . uniqid();
Theme::makeProcessFunction( Theme::fixResourceTags( (string) Request::i()->content, 'front' ), $functionName, '', FALSE, TRUE );
$fqFunc = 'IPS\\Theme\\'. $functionName;
$content = Theme::minifyCss( $fqFunc() );
/* Replace any <fileStore.xxx> tags in the CSS */
Output::i()->parseFileObjectUrls( $content );
$content = Theme::compileCustomCss( Request::i()->content );
Output::i()->json( [ 'content' => $content ] );
}
}
@@ -78,6 +78,7 @@ class widgets extends Controller
$this->pageApp = 'global';
$this->pageModule = 'global';
$this->pageController = 'global';
$this->widgetClass = Widget::class;
}
parent::execute();
@@ -90,10 +91,16 @@ class widgets extends Controller
*/
protected function getBlockList() : void
{
/* Initialize with Pages as the first in the list */
$availableBlocks = array(
'cms' => []
);
if( Application::appIsEnabled( 'cms' ) )
{
/* Initialize with Pages as the first in the list */
$availableBlocks = [
'cms' => []
];
}else
{
$availableBlocks = [];
}
$favoriteIds = json_decode( Settings::i()->favorite_blocks, true );
$favorites = [];
@@ -228,6 +235,10 @@ class widgets extends Controller
$output = (string) $widget;
Output::i()->output = ( $output ) ?: Theme::i()->getTemplate( 'widgets', 'core', 'front' )->blankWidget( $widget );
if( Request::i()->isAjax() )
{
Output::i()->sendOutput( Output::i()->output );
}
}
/**