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

+65 -59
View File
@@ -46,29 +46,40 @@ class _admin extends \IPS\Dispatcher\Controller
$table = new \IPS\Helpers\Table\Db( 'core_admin_permission_rows', \IPS\Http\Url::internal( 'app=core&module=staff&controller=admin' ) );
/* Columns */
$table->selects = array( 'row_perm_cache', 'row_updated', 'row_id', 'row_id_type' );
$table->langPrefix = 'acprestrictions_';
$table->joins = array(
array( 'select' => "IF(core_admin_permission_rows.row_id_type= 'group', w.word_custom, m.name) as name", 'from' => array( 'core_members', 'm' ), 'where' => "m.member_id=core_admin_permission_rows.row_id AND core_admin_permission_rows.row_id_type='member'" ),
array( 'from' => array( 'core_sys_lang_words', 'w' ), 'where' => "w.word_key=CONCAT( 'core_group_', core_admin_permission_rows.row_id ) AND core_admin_permission_rows.row_id_type='group' AND w.lang_id=" . \IPS\Member::loggedIn()->language()->id )
);
$table->include = array( 'row_id_type', 'row_id', 'row_updated' );
$table->include = array( 'name', 'row_updated', 'row_perm_cache' );
$table->parsers = array(
'row_id_type' => function( $val, $row )
'name' => function( $val, $row )
{
return \IPS\Theme::i()->getTemplate( 'global' )->shortMessage( $val, array( 'ipsBadge', 'ipsBadge_neutral' ) );
},
'row_id' => function( $val, $row )
{
return $row['row_id_type'] === 'group' ? \IPS\Member\Group::load( $row['row_id'] )->formattedName : htmlentities( $row['name'], \IPS\HTMLENTITIES, 'UTF-8', FALSE );
$return = \IPS\Theme::i()->getTemplate( 'global' )->shortMessage( $row['row_id_type'], array( 'ipsBadge', 'ipsBadge_neutral', 'ipsBadge_label' ) );
try
{
$name = empty( $row['name'] ) ? \IPS\Member::loggedIn()->language()->addToStack('deleted_member') : htmlentities( $row['name'], ENT_DISALLOWED, 'UTF-8', FALSE );
$return .= ( $row['row_id_type'] === 'group' ) ? \IPS\Member\Group::load( $row['row_id'] )->formattedName : $name;
}
catch( \OutOfRangeException $e )
{
$return .= \IPS\Member::loggedIn()->language()->addToStack('deleted_group');
}
return $return;
},
'row_updated' => function( $val )
{
return ( $val ) ? \IPS\DateTime::ts( $val )->localeDate() : \IPS\Member::loggedIn()->language()->addToStack('never');
},
'row_perm_cache' => function( $val )
{
return \IPS\Theme::i()->getTemplate( 'members' )->restrictionsLabel( $val );
}
);
$table->mainColumn = 'name';
$table->quickSearch = array( array( 'name', 'word_custom' ), 'row_id' );
$table->classes = array( 'row_id_type' => 'icon' );
$table->quickSearch = array( array( 'name', 'word_custom' ), 'name' );
$table->noSort = array( 'row_perm_cache' );
/* Sorting */
$table->sortBy = $table->sortBy ?: 'row_updated';
@@ -160,11 +171,20 @@ class _admin extends \IPS\Dispatcher\Controller
{
\IPS\Output::i()->sidebar['actions']['loginLogs'] = array(
'title' => 'adminloginlogs',
'icon' => 'key',
'icon' => 'search',
'link' => \IPS\Http\Url::internal( 'app=core&module=staff&controller=admin&do=loginLogs' ),
);
}
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members' ) )
{
\IPS\Output::i()->sidebar['actions']['list_admins'] = array(
'icon' => 'search',
'link' => \IPS\Http\Url::internal( 'app=core&module=members&controller=members&filter=members_filter_administrators' ),
'title' => 'security_list_admins',
);
}
/* Display */
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('acprestrictions');
\IPS\Output::i()->output = (string) $table;
@@ -243,7 +263,7 @@ class _admin extends \IPS\Dispatcher\Controller
unset( \IPS\Data\Store::i()->administrators );
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=core&module=staff&controller=admin&do=edit&id={$current['row_id']}&type={$current['row_id_type']}" ) );
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=core&module=staff&controller=admin" ) );
}
}
@@ -258,7 +278,8 @@ class _admin extends \IPS\Dispatcher\Controller
*/
protected function edit()
{
try {
try
{
/* Get record */
$current = \IPS\Db::i()->select( '*', 'core_admin_permission_rows', array( "row_id=? AND row_id_type=?", intval( \IPS\Request::i()->id ), \IPS\Request::i()->type ) )->first();
}
@@ -311,24 +332,7 @@ class _admin extends \IPS\Dispatcher\Controller
}
}
}
/* Warning if they have all permissions */
if ( $current['row_perm_cache'] === '*' )
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->message( 'admin_allperm_warning', 'warning' );
}
/* Or a button to give all */
else
{
\IPS\Output::i()->sidebar['actions'] = array(
'all' => array(
'title' => 'moderators_allperm',
'icon' => 'check-circle',
'link' => \IPS\Http\Url::internal( 'app=core&module=staff&controller=admin&do=allperms&id=' ) . $current['row_id'] . '&type=' . $current['row_id_type'],
),
);
}
/* Display */
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'admin_members.js', 'core', 'admin' ) );
\IPS\Output::i()->title = $current['row_id_type'] === 'group' ? \IPS\Member\Group::load( $current['row_id'] )->name : \IPS\Member::load( $current['row_id'] )->name;
@@ -349,8 +353,10 @@ class _admin extends \IPS\Dispatcher\Controller
\IPS\Output::i()->error( 'node_error', '2C113/2', 404, '' );
}
$permissions = ( \IPS\Request::i()->admin_use_restrictions == 'no' ) ? '*' : json_encode( ( is_array( \IPS\Request::i()->r ) ) ? \IPS\Request::i()->r : array() );
/* Save */
\IPS\Db::i()->update( 'core_admin_permission_rows', array( 'row_perm_cache' => json_encode( ( is_array( \IPS\Request::i()->r ) ) ? \IPS\Request::i()->r : array() ), 'row_updated' => time() ), array( "row_id=? AND row_id_type=?", intval( \IPS\Request::i()->id ), \IPS\Request::i()->type ) );
\IPS\Db::i()->update( 'core_admin_permission_rows', array( 'row_perm_cache' => $permissions, 'row_updated' => time() ), array( "row_id=? AND row_id_type=?", intval( \IPS\Request::i()->id ), \IPS\Request::i()->type ) );
unset( \IPS\Data\Store::i()->administrators );
@@ -360,32 +366,7 @@ class _admin extends \IPS\Dispatcher\Controller
/* Boink */
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=staff&controller=admin' ), 'saved' );
}
/**
* Give All Permissions
*
* @return void
*/
protected function allperms()
{
/* Load */
$current = \IPS\Db::i()->select( '*', 'core_admin_permission_rows', array( "row_id=? AND row_id_type=?", intval( \IPS\Request::i()->id ), \IPS\Request::i()->type ) )->first();
if ( !$current )
{
\IPS\Output::i()->error( 'node_error', '2C113/5', 404, '' );
}
/* Set */
\IPS\Db::i()->update( 'core_admin_permission_rows', array( 'row_perm_cache' => '*', 'row_updated' => time() ), array( array( "row_id=? AND row_id_type=?", $current['row_id'], $current['row_id_type'] ) ) );
unset( \IPS\Data\Store::i()->administrators );
\IPS\Session::i()->log( 'acplog__acpr_edited', array( ( $current['row_id_type'] == 'group' ? \IPS\Member\Group::load( $current['row_id'] )->name : \IPS\Member::load( $current['row_id'] )->name ) => FALSE ) );
/* Redirect */
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=staff&controller=admin&do=edit&id=' . $current['row_id'] . '&type=' . $current['row_id_type'] ) );
}
/**
* Delete
*
@@ -407,7 +388,32 @@ class _admin extends \IPS\Dispatcher\Controller
/* Make sure the user confirmed the deletion */
\IPS\Request::i()->confirmedDelete();
\IPS\Session::i()->log( 'acplog__acpr_deleted', array( ( $current['row_id_type'] == 'group' ? \IPS\Member\Group::load( $current['row_id'] )->name : \IPS\Member::load( $current['row_id'] )->name ) => FALSE ) );
if( $current['row_id_type'] == 'group' )
{
try
{
$name = \IPS\Member\Group::load( $current['row_id'] )->name;
}
catch( \OutOfRangeException $e )
{
$name = \IPS\Member::loggedIn()->language()->get('deleted_group');
}
}
else
{
$member = \IPS\Member::load( $current['row_id'] );
if( $member->member_id )
{
$name = $member->name;
}
else
{
$name = \IPS\Member::loggedIn()->language()->get('deleted_member');
}
}
\IPS\Session::i()->log( 'acplog__acpr_deleted', array( $name => FALSE ) );
\IPS\Db::i()->delete( 'core_admin_permission_rows', array( 'row_id=? AND row_id_type=?', intval( \IPS\Request::i()->id ), \IPS\Request::i()->type ) );
unset ( \IPS\Data\Store::i()->administrators );
@@ -434,11 +440,11 @@ class _admin extends \IPS\Dispatcher\Controller
$member = \IPS\Member::load( $val );
if ( $member->member_id )
{
return htmlentities( \IPS\Member::load( $val )->name, \IPS\HTMLENTITIES, 'UTF-8', FALSE );
return htmlentities( \IPS\Member::load( $val )->name, ENT_DISALLOWED, 'UTF-8', FALSE );
}
else if ( $row['member_name'] != '' )
{
return htmlentities( $row['member_name'], \IPS\HTMLENTITIES, 'UTF-8', FALSE );
return htmlentities( $row['member_name'], ENT_DISALLOWED, 'UTF-8', FALSE );
}
else
{
@@ -30,7 +30,9 @@ class _moderators extends \IPS\Dispatcher\Controller
public function execute()
{
\IPS\Dispatcher::i()->checkAcpPermission( 'moderators_manage' );
parent::execute();
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'members/restrictions.css', 'core', 'admin' ) );
return parent::execute();
}
/**
@@ -42,31 +44,42 @@ class _moderators extends \IPS\Dispatcher\Controller
{
/* Create the table */
$table = new \IPS\Helpers\Table\Db( 'core_moderators', \IPS\Http\Url::internal( 'app=core&module=staff&controller=moderators' ) );
/* Columns */
$table->langPrefix = 'moderators_';
$table->langPrefix = 'moderators_';
$table->selects = array( 'perms', 'id', 'type', 'updated' );
$table->joins = array(
array( 'select' => "IF(core_moderators.type= 'g', w.word_custom, m.name) as name", 'from' => array( 'core_members', 'm' ), 'where' => "m.member_id=core_moderators.id AND core_moderators.type='m'" ),
array( 'from' => array( 'core_sys_lang_words', 'w' ), 'where' => "w.word_key=CONCAT( 'core_group_', core_moderators.id ) AND core_moderators.type='g' AND w.lang_id=" . \IPS\Member::loggedIn()->language()->id )
);
$table->include = array( 'type', 'id', 'updated' );
$table->include = array( 'name', 'updated', 'perms' );
$table->parsers = array(
'type' => function( $val, $row )
'name' => function( $val, $row )
{
return "<i class='fa fa-" . ( ( $val === 'm' ) ? 'user' : 'group' ) . "' data-ipstooltip _title=' " . ( ( $val === 'm' ) ? \IPS\Member::loggedIn()->language()->addToStack('acprestrictions_member') : \IPS\Member::loggedIn()->language()->addToStack('acprestrictions_group') ) . "'></i>";
},
'id' => function( $val, $row )
{
return $row['type'] === 'g' ? \IPS\Member\Group::load( $row['id'] )->formattedName : htmlentities( $row['name'], \IPS\HTMLENTITIES, 'UTF-8', FALSE );
$return = \IPS\Theme::i()->getTemplate( 'global' )->shortMessage( $row['type'] === 'g' ? 'group' : 'member', array( 'ipsBadge', 'ipsBadge_neutral', 'ipsBadge_label' ) );
try
{
$name = empty( $row['name'] ) ? \IPS\Member::loggedIn()->language()->addToStack('deleted_member') : htmlentities( $row['name'], ENT_DISALLOWED, 'UTF-8', FALSE );
$return .= ( $row['type'] === 'g' ) ? \IPS\Member\Group::load( $row['id'] )->formattedName : $name;
}
catch( \OutOfRangeException $e )
{
$return .= \IPS\Member::loggedIn()->language()->addToStack('deleted_group');
}
return $return;
},
'updated' => function( $val )
{
return ( $val ) ? \IPS\DateTime::ts( $val )->localeDate() : \IPS\Member::loggedIn()->language()->addToStack('never');
},
'perms' => function( $val )
{
return \IPS\Theme::i()->getTemplate( 'members' )->restrictionsLabel( $val );
}
);
$table->mainColumn = 'name';
$table->quickSearch = array( array( 'name', 'word_custom' ), 'id' );
$table->classes = array( 'type' => 'icon' );
$table->quickSearch = array( array( 'name', 'word_custom' ), 'name' );
$table->noSort = array( 'perms' );
/* Sorting */
$table->sortBy = $table->sortBy ?: 'updated';
@@ -212,7 +225,7 @@ class _moderators extends \IPS\Dispatcher\Controller
unset (\IPS\Data\Store::i()->moderators);
}
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=core&module=staff&controller=moderators&do=edit&id={$current['id']}&type={$current['type']}" ) );
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=core&module=staff&controller=moderators" ) );
}
}
@@ -285,6 +298,12 @@ class _moderators extends \IPS\Dispatcher\Controller
/* Build */
$form = new \IPS\Helpers\Form;
/* Add the restricted/unrestricted option first */
$form->add(
new \IPS\Helpers\Form\Radio( 'mod_use_restrictions', ( $currentPermissions === '*' ) ? 'no' : 'yes', TRUE, array( 'options' => array( 'no' => 'mod_all_permissions', 'yes' => 'mod_restricted' ), 'toggles' => array( 'yes' => array( 'permission_form_wrapper' ) ) ), NULL, NULL, NULL, 'use_restrictions_id' )
);
$extensions = array();
foreach ( \IPS\Application::allExtensions( 'core', 'ModeratorPermissions', FALSE, 'core' ) as $k => $ext )
{
@@ -373,115 +392,84 @@ class _moderators extends \IPS\Dispatcher\Controller
/* Handle submissions */
if ( $values = $form->values() )
{
foreach ( $values as $k => $v )
if( $values['mod_use_restrictions'] == 'no' )
{
/* For node fields, if the value is 0 translate it to -1 so mod permissions can merge properly */
if( in_array( $k, $nodeFields ) )
{
/* If nothing is checked we have '', but if 'all' is checked then the value is 0 */
if( $v === 0 )
{
$v = -1;
$values[ $k ] = $v;
}
}
$permissions = '*';
if ( is_array( $v ) )
{
foreach ( $v as $l => $w )
{
if ( $w instanceof \IPS\Node\Model )
{
$values[ $k ][ $l ] = $w->_id;
}
}
}
}
if ( $currentPermissions == '*' )
{
$changed = $values;
$changed = '*';
}
else
{
$changed = array();
unset( $values['mod_use_restrictions'] );
foreach ( $values as $k => $v )
{
if ( !isset( $currentPermissions[ $k ] ) or $currentPermissions[ $k ] != $v )
/* For node fields, if the value is 0 translate it to -1 so mod permissions can merge properly */
if( in_array( $k, $nodeFields ) )
{
$changed[ $k ] = $v;
/* If nothing is checked we have '', but if 'all' is checked then the value is 0 */
if( $v === 0 )
{
$v = -1;
$values[ $k ] = $v;
}
}
if ( is_array( $v ) )
{
foreach ( $v as $l => $w )
{
if ( $w instanceof \IPS\Node\Model )
{
$values[ $k ][ $l ] = $w->_id;
}
}
}
}
if ( $currentPermissions == '*' )
{
$changed = $values;
}
else
{
$changed = array();
foreach ( $values as $k => $v )
{
if ( !isset( $currentPermissions[ $k ] ) or $currentPermissions[ $k ] != $v )
{
$changed[ $k ] = $v;
}
}
}
$permissions = json_encode( $values );
}
\IPS\Db::i()->update( 'core_moderators', array( 'perms' => json_encode( $values ), 'updated' => time() ), array( array( "id=? AND type=?", $current['id'], $current['type'] ) ) );
foreach ( \IPS\Application::allExtensions( 'core', 'ModeratorPermissions', FALSE ) as $k => $ext )
\IPS\Db::i()->update( 'core_moderators', array( 'perms' => $permissions, 'updated' => time() ), array( array( "id=? AND type=?", $current['id'], $current['type'] ) ) );
if( !( $currentPermissions == '*' AND $changed == '*' ) )
{
$ext->onChange( $current, $changed );
foreach ( \IPS\Application::allExtensions( 'core', 'ModeratorPermissions', FALSE ) as $k => $ext )
{
$ext->onChange( $current, $changed );
}
}
\IPS\Session::i()->log( 'acplog__moderator_edited', array( ( $current['type'] == 'g' ? \IPS\Member::loggedIn()->language()->get( "core_group_{$current['id']}" ) : \IPS\Member::load( $current['id'] )->name ) => FALSE ) );
$currentPermissions = $values;
unset (\IPS\Data\Store::i()->moderators);
unset( \IPS\Data\Store::i()->moderators );
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=staff&controller=moderators' ), 'saved' );
}
/* Warning if they have all permissions */
if ( $currentPermissions === '*' )
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->message( 'moderators_allperm_warning', 'warning' );
}
/* Or a button to give all */
else
{
\IPS\Output::i()->sidebar['actions'] = array(
'all' => array(
'title' => 'moderators_allperm',
'icon' => 'asterisk',
'link' => \IPS\Http\Url::internal( 'app=core&module=staff&controller=moderators&do=allperms&id=' ) . $current['id'] . '&type=' . $current['type'],
'data' => array( 'confirm' => '' )
),
);
}
/* Display */
\IPS\Output::i()->title = $_name;
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'admin_members.js', 'core', 'admin' ) );
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'members' )->moderatorPermissions( $_name, $form );
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'admin_members.js', 'core', 'admin' ) );
\IPS\Output::i()->output .= $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'members' ) ), 'moderatorPermissions' ) );
}
/**
* Give All Permissions
*
* @return void
*/
protected function allperms()
{
/* Load */
$current = \IPS\Db::i()->select( '*', 'core_moderators', array( "id=? AND type=?", intval( \IPS\Request::i()->id ), \IPS\Request::i()->type ) )->first();
if ( !$current )
{
\IPS\Output::i()->error( 'node_error', '2C118/3', 404, '' );
}
/* Set */
\IPS\Db::i()->update( 'core_moderators', array( 'perms' => '*', 'updated' => time() ), array( array( "id=? AND type=?", $current['id'], $current['type'] ) ) );
foreach ( \IPS\Application::allExtensions( 'core', 'ModeratorPermissions', FALSE ) as $k => $ext )
{
$ext->onChange( $current, '*' );
}
unset ( \IPS\Data\Store::i()->moderators );
/* Log and redirect */
\IPS\Session::i()->log( 'acplog__moderator_edited', array( ( $current['type'] == 'g' ? \IPS\Member::loggedIn()->language()->get( "core_group_{$current['id']}" ) : \IPS\Member::load( $current['id'] )->name ) => FALSE ) );
/* Redirect */
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=staff&controller=moderators&do=edit&id=' . $current['id'] . '&type=' . $current['type'] ) );
}
/**
* Delete
*
@@ -546,11 +534,11 @@ class _moderators extends \IPS\Dispatcher\Controller
$member = \IPS\Member::load( $val );
if ( $member->member_id )
{
return htmlentities( \IPS\Member::load( $val )->name, \IPS\HTMLENTITIES, 'UTF-8', FALSE );
return htmlentities( \IPS\Member::load( $val )->name, ENT_DISALLOWED, 'UTF-8', FALSE );
}
else if ( $row['member_name'] != '' )
{
return htmlentities( $row['member_name'], \IPS\HTMLENTITIES, 'UTF-8', FALSE );
return htmlentities( $row['member_name'], ENT_DISALLOWED, 'UTF-8', FALSE );
}
else
{