Version 4.7.8
This commit is contained in:
1 parent
7b7404e741
commit
fd22d99e69
688 files changed
+19814
-10890
No files matched your search
@@ -106,12 +106,12 @@ class _apiLogs extends \IPS\Dispatcher\Controller
|
||||
);
|
||||
|
||||
/* Search */
|
||||
$endpoints = array();
|
||||
$endpoints = array( '' => 'any' );
|
||||
foreach ( \IPS\Api\Controller::getAllEndpoints() as $k => $data )
|
||||
{
|
||||
$endpoints[ $data['title'] ] = $data['title'];
|
||||
}
|
||||
$statuses = array();
|
||||
$statuses = array( '' => 'any' );
|
||||
foreach ( \IPS\Output::$httpStatuses as $code => $name )
|
||||
{
|
||||
$statuses[ $code ] = "{$code} {$name}";
|
||||
|
||||
@@ -731,7 +731,7 @@ class _applications extends \IPS\Node\Controller
|
||||
/* Don't allow downloads of Marketplace resources */
|
||||
if( $application->marketplace_id )
|
||||
{
|
||||
// \IPS\Output::i()->error( 'application_cannot_build_marketplace', '2C133/Y', 403, '' );
|
||||
// \IPS\Output::i()->error( 'application_cannot_build_marketplace', '2C133/Y', 403, '' );
|
||||
}
|
||||
|
||||
$form = $this->_buildForm( $application->directory, TRUE );
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
namespace IPS\core\modules\admin\applications;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
@@ -756,27 +757,34 @@ class _developer extends \IPS\Dispatcher\Controller
|
||||
if ( \IPS\Request::i()->do === 'reorder' )
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
/* Init */
|
||||
$id = explode( '-', mb_substr( \IPS\Request::i()->root, 1 ) );
|
||||
if( isset( \IPS\Request::i()->ajax_order ) )
|
||||
|
||||
/* Figure out the items we are reordering, we would only be reordering a single group */
|
||||
$newOrder = array();
|
||||
$position = 1;
|
||||
foreach( \IPS\Request::i()->ajax_order as $i => $parent )
|
||||
{
|
||||
$order = array();
|
||||
$position = 1;
|
||||
foreach( \IPS\Request::i()->ajax_order as $i )
|
||||
if( \strpos( $i, '~' ) !== FALSE )
|
||||
{
|
||||
$order[ $i ] = $position++;
|
||||
if( !isset( $newOrder[ $parent ] ) )
|
||||
{
|
||||
$newOrder[ $parent ] = array();
|
||||
}
|
||||
$newOrder[ $parent ][ $i ] = $position++;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
foreach( $newOrder as $groupKey => $order )
|
||||
{
|
||||
$order = \IPS\Request::i()->order;
|
||||
if( isset( \IPS\Request::i()->ajax_order[ $groupKey ] ) )
|
||||
{
|
||||
$moduleKey = \IPS\Request::i()->ajax_order[ $groupKey ];
|
||||
|
||||
/* Sort */
|
||||
uasort( $this->restrictions[ $moduleKey ][ $groupKey ], function( $a, $b ) use ( $order ) {
|
||||
return ( isset( $order[ str_replace( '_', '~', $a ) ] ) ? $order[ str_replace( '_', '~', $a ) ] : 0 ) - ( isset( $order[ str_replace( '_', '~', $b ) ] ) ? $order[ str_replace( '_', '~', $b ) ] : 0 );
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/* Sort */
|
||||
uasort( $this->restrictions[ $id[0] ][ $id[1] ], function( $a, $b ) use ( $order ) {
|
||||
return ( isset( $order[ str_replace( '_', '~', $a ) ] ) ? $order[ str_replace( '_', '~', $a ) ] : 0 ) - ( isset( $order[ str_replace( '_', '~', $b ) ] ) ? $order[ str_replace( '_', '~', $b ) ] : 0 );
|
||||
});
|
||||
|
||||
/* Write */
|
||||
$this->_writeJson( \IPS\ROOT_PATH . "/applications/{$this->application->directory}/data/acprestrictions.json", $this->restrictions );
|
||||
@@ -823,7 +831,7 @@ class _developer extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
if ( empty( $module['protected'] ) )
|
||||
{
|
||||
$rows[] = $this->_restrictionsModuleRow( $this->url, $k, $this->restrictions, FALSE );
|
||||
$rows[ $k ] = $this->_restrictionsModuleRow( $this->url, $k, $this->restrictions, FALSE );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -866,7 +874,7 @@ class _developer extends \IPS\Dispatcher\Controller
|
||||
$k = mb_substr( $k, 1 );
|
||||
foreach ( $this->restrictions[ $k ] as $groupKey => $r )
|
||||
{
|
||||
$rows[] = $this->_restrictionsGroupRow( $this->url, $groupKey, $k, $r, FALSE );
|
||||
$rows[ $groupKey ] = $this->_restrictionsGroupRow( $this->url, $groupKey, $k, $r, FALSE );
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -305,7 +305,7 @@ class _clubs extends \IPS\Dispatcher\Controller
|
||||
$club->approved = TRUE;
|
||||
$club->save();
|
||||
|
||||
$club->owner->achievementAction( 'core', 'NewClub', $club );
|
||||
$club->onApprove();
|
||||
|
||||
/* Redirect */
|
||||
$target = \IPS\Http\Url::internal("app=core&module=clubs&controller=clubs");
|
||||
|
||||
@@ -745,16 +745,16 @@ class _languages extends \IPS\Node\Controller
|
||||
$form = new \IPS\Helpers\Form( 'form', 'langauge_export_button' );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'language_export_author_name', $lang->author_name, false ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'language_export_author_url', $lang->author_url, false ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'language_export_update_check', $lang->update_url, false ) );
|
||||
$form->add( new \IPS\Helpers\Form\Url( 'language_export_author_url', $lang->author_url, false ) );
|
||||
$form->add( new \IPS\Helpers\Form\Url( 'language_export_update_check', $lang->update_url, false ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'language_export_version', $lang->version, true, array( 'placeholder' => '1.0.0' ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'language_export_long_version', $lang->version_long ?: 10000, true ) );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
$lang->author_name = $values['language_export_author_name'];
|
||||
$lang->author_url = $values['language_export_author_url'];
|
||||
$lang->update_url = $values['language_export_update_check'];
|
||||
$lang->author_url = (string) $values['language_export_author_url'];
|
||||
$lang->update_url = (string) $values['language_export_update_check'];
|
||||
$lang->version = $values['language_export_version'];
|
||||
$lang->version_long = (int) $values['language_export_long_version'];
|
||||
$lang->save();
|
||||
|
||||
@@ -611,7 +611,7 @@ class _members extends \IPS\Helpers\CoverPhoto\Controller
|
||||
|
||||
if ( $member->member_id )
|
||||
{
|
||||
$member->datalayer_collect_pii = (bool) !$member->datalayer_collect_pii;
|
||||
$member->members_bitoptions['datalayer_pii_optout'] = (bool) !$member->members_bitoptions['datalayer_pii_optout'];
|
||||
$member->save();
|
||||
}
|
||||
$_SESSION['member_datalayer_changed'] = 1;
|
||||
@@ -2829,7 +2829,7 @@ class _members extends \IPS\Helpers\CoverPhoto\Controller
|
||||
else
|
||||
{
|
||||
/* Get existing banned IPs */
|
||||
$bannedIps = iterator_to_array( \IPS\Db::i()->select( 'ban_content', 'core_banfilters', array( 'ban_type=?', 'ip' ) )->setKeyField( 'ban_content' ) );
|
||||
$bannedIps = iterator_to_array( \IPS\Db::i()->select( 'ban_content', 'core_banfilters', array( 'ban_type=?', 'ip' ) ) );
|
||||
|
||||
/* Build form */
|
||||
$form = new \IPS\Helpers\Form;
|
||||
@@ -2842,7 +2842,12 @@ class _members extends \IPS\Helpers\CoverPhoto\Controller
|
||||
if ( $member->temp_ban === 0 )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'member_ban_group', $member->member_group_id, FALSE, array( 'options' => \IPS\Member\Group::groups( FALSE, FALSE ), 'parse' => 'normal' ), NULL, NULL, NULL, 'member_ban_group' ) );
|
||||
$memberIps = array_keys( $member->ipAddresses() );
|
||||
|
||||
$memberIps = array();
|
||||
foreach( $member->ipAddresses() as $k => $v )
|
||||
{
|
||||
$memberIps[ $k ] = $k;
|
||||
}
|
||||
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'member_ban_ips', array_intersect( $memberIps, $bannedIps ), FALSE, array( 'options' => $memberIps, 'multiple' => TRUE ), NULL, NULL, NULL, 'member_ban_ips' ) );
|
||||
}
|
||||
|
||||
@@ -2868,8 +2873,8 @@ class _members extends \IPS\Helpers\CoverPhoto\Controller
|
||||
{
|
||||
$member->logHistory( 'core', 'warning', array( 'restrictions' => array( 'ban' => array( 'old' => $_existingValue, 'new' => $member->temp_ban ) ) ) );
|
||||
}
|
||||
|
||||
if ( isset( $values['member_ban_group'] ) )
|
||||
|
||||
if ( isset( $values['member_ban_group'] ) AND $values['member_ban_group'] != $member->member_group_id )
|
||||
{
|
||||
$member->logHistory( 'core', 'group', array( 'type' => 'primary', 'by' => 'manual', 'old' => $member->member_group_id, 'new' => $values['member_ban_group'] ) );
|
||||
$member->member_group_id = $values['member_ban_group'];
|
||||
|
||||
@@ -81,11 +81,77 @@ class _onboard extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a form allowing the admin to configure some common settings after an initial installation
|
||||
* Save the form values
|
||||
*
|
||||
* @return void
|
||||
* @param $values
|
||||
* @param \IPS\Helpers\Form $form
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
public function handleForm( $values, \IPS\Helpers\Form $form )
|
||||
{
|
||||
/* If we dismissed, do that but also send an email */
|
||||
if( isset( \IPS\Request::i()->dismiss ) and \IPS\Request::i()->dismiss == 1 )
|
||||
{
|
||||
\IPS\Email::buildFromTemplate( 'core', 'onboard_reminder', array(), \IPS\Email::TYPE_TRANSACTIONAL )->send( \IPS\Member::loggedIn() );
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=overview&controller=dashboard' ) );
|
||||
}
|
||||
|
||||
/* If we said to remind us later, set the flag and redirect */
|
||||
if( isset( \IPS\Request::i()->remind ) and \IPS\Request::i()->remind == 1 )
|
||||
{
|
||||
\IPS\Settings::i()->changeValues( array( 'onboard_complete'=>\IPS\DateTime::ts( time() )->add( new \DateInterval( 'PT20M' ) )->getTimestamp() ) );
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=overview&controller=dashboard' ), 'onboard_will_remind' );
|
||||
}
|
||||
|
||||
array_walk( $values[ 'site_social_profiles' ], function( &$value ){
|
||||
$value[ 'key' ]= (string) $value[ 'key' ];
|
||||
} );
|
||||
$values[ 'site_social_profiles' ]=json_encode( array_filter( $values[ 'site_social_profiles' ], function( $value ){
|
||||
return (bool)$value[ 'key' ];
|
||||
} ) );
|
||||
|
||||
$values[ 'site_address' ] = json_encode( $values[ 'site_address' ] );
|
||||
$values[ 'icons_favicon' ] = (string) $values[ 'icons_favicon' ];
|
||||
|
||||
$values=\IPS\core\modules\admin\customization\icons::processApplicationIcon( $values );
|
||||
$values=\IPS\core\modules\admin\settings\terms::processForm( $values );
|
||||
|
||||
/* If a logo was uploaded, do stuff with it... */
|
||||
if( isset( $values[ 'initial_logo' ] ) )
|
||||
{
|
||||
$values[ 'email_logo' ]=(string)$values[ 'initial_logo' ];
|
||||
|
||||
/* Do this once for efficiency */
|
||||
$image=\IPS\Image::create( $values[ 'initial_logo' ]->contents() );
|
||||
$width=$image->width;
|
||||
$height=$image->height;
|
||||
unset( $image );
|
||||
|
||||
foreach( \IPS\Theme::themes() as $theme )
|
||||
{
|
||||
$logoUrl=(string)\IPS\File::create( 'core_Theme', $values[ 'initial_logo' ]->originalFilename, $values[ 'initial_logo' ]->contents(), NULL, TRUE );
|
||||
|
||||
$theme->saveSet( array( 'logo'=>array( 'front'=>array( 'url'=>$logoUrl, 'width'=>$width, 'height'=>$height ) ) ) );
|
||||
}
|
||||
|
||||
unset( $values[ 'initial_logo' ] );
|
||||
}
|
||||
elseif( array_key_exists( 'initial_logo', $values ) )
|
||||
{
|
||||
unset( $values[ 'initial_logo' ] );
|
||||
}
|
||||
|
||||
$form->saveAsSettings( $values );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the onboarding form
|
||||
*
|
||||
* @return \IPS\Helpers\Form
|
||||
*/
|
||||
public function getForm(): \IPS\Helpers\Form
|
||||
{
|
||||
/* Create the form and add our message to it */
|
||||
$form = new \IPS\Helpers\Form;
|
||||
@@ -115,7 +181,7 @@ class _onboard extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
}
|
||||
|
||||
if( !\IPS\Settings::i()->email_logo AND !$hasCustomLogo )
|
||||
if( !\IPS\Settings::i()->email_logo and !$hasCustomLogo )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Upload( 'initial_logo', NULL, FALSE, array( 'image' => true, 'storageExtension' => 'core_Theme' ) ) );
|
||||
}
|
||||
@@ -125,7 +191,7 @@ class _onboard extends \IPS\Dispatcher\Controller
|
||||
|
||||
/* Homescreen icons - we accept one upload and create the images we need */
|
||||
$homeScreen = json_decode( \IPS\Settings::i()->icons_homescreen, TRUE ) ?? array();
|
||||
$form->add( new \IPS\Helpers\Form\Upload( 'icons_homescreen', ( isset( $homeScreen['original'] ) ) ? \IPS\File::get( 'core_Icons', $homeScreen['original'] ) : NULL, FALSE, array( 'image' => true, 'storageExtension' => 'core_Icons' ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Upload( 'icons_homescreen', ( isset( $homeScreen[ 'original' ] ) ) ? \IPS\File::get( 'core_Icons', $homeScreen[ 'original' ] ) : NULL, FALSE, array( 'image' => true, 'storageExtension' => 'core_Icons' ) ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Color( 'email_color', \IPS\Settings::i()->email_color, TRUE ) );
|
||||
|
||||
@@ -151,64 +217,21 @@ class _onboard extends \IPS\Dispatcher\Controller
|
||||
$form->addButton( 'onboard_remind_later', 'submit', NULL, 'ipsButton ipsButton_secondary', array( 'name' => 'remind', 'value' => 1, 'csrfKey' => \IPS\Session::i()->csrfKey ) );
|
||||
$form->addButton( 'dismiss', 'submit', NULL, 'ipsButton ipsButton_secondary', array( 'name' => 'dismiss', 'value' => 1, 'csrfKey' => \IPS\Session::i()->csrfKey ) );
|
||||
}
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a form allowing the admin to configure some common settings after an initial installation
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
{
|
||||
$form = $this->getForm();
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
/* If we dismissed, do that but also send an email */
|
||||
if( isset( \IPS\Request::i()->dismiss ) AND \IPS\Request::i()->dismiss == 1 )
|
||||
{
|
||||
\IPS\Email::buildFromTemplate( 'core', 'onboard_reminder', array(), \IPS\Email::TYPE_TRANSACTIONAL )->send( \IPS\Member::loggedIn() );
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=overview&controller=dashboard' ) );
|
||||
}
|
||||
|
||||
/* If we said to remind us later, set the flag and redirect */
|
||||
if( isset( \IPS\Request::i()->remind ) AND \IPS\Request::i()->remind == 1 )
|
||||
{
|
||||
\IPS\Settings::i()->changeValues( array( 'onboard_complete' => \IPS\DateTime::ts( time() )->add( new \DateInterval( 'PT20M' ) )->getTimestamp() ) );
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=overview&controller=dashboard' ), 'onboard_will_remind' );
|
||||
}
|
||||
|
||||
array_walk( $values['site_social_profiles'], function( &$value ){
|
||||
$value['key'] = (string) $value['key'];
|
||||
});
|
||||
$values['site_social_profiles'] = json_encode( array_filter( $values['site_social_profiles'], function( $value ) {
|
||||
return (bool) $value['key'];
|
||||
} ) );
|
||||
|
||||
$values['site_address'] = json_encode( $values['site_address'] );
|
||||
$values['icons_favicon'] = (string) $values['icons_favicon'];
|
||||
|
||||
$values = \IPS\core\modules\admin\customization\icons::processApplicationIcon( $values );
|
||||
$values = \IPS\core\modules\admin\settings\terms::processForm( $values );
|
||||
|
||||
/* If a logo was uploaded, do stuff with it... */
|
||||
if( isset( $values['initial_logo'] ) )
|
||||
{
|
||||
$values['email_logo'] = (string) $values['initial_logo'];
|
||||
|
||||
/* Do this once for efficiency */
|
||||
$image = \IPS\Image::create( $values['initial_logo']->contents() );
|
||||
$width = $image->width;
|
||||
$height = $image->height;
|
||||
unset( $image );
|
||||
|
||||
foreach( \IPS\Theme::themes() as $theme )
|
||||
{
|
||||
$logoUrl = (string) \IPS\File::create( 'core_Theme', $values['initial_logo']->originalFilename, $values['initial_logo']->contents(), NULL, TRUE );
|
||||
|
||||
$theme->saveSet( array( 'logo' => array( 'front' => array( 'url' => $logoUrl, 'width' => $width, 'height' => $height ) ) ) );
|
||||
}
|
||||
|
||||
unset( $values['initial_logo'] );
|
||||
}
|
||||
elseif( array_key_exists( 'initial_logo', $values ) )
|
||||
{
|
||||
unset( $values['initial_logo'] );
|
||||
}
|
||||
|
||||
$form->saveAsSettings( $values );
|
||||
$this->handleForm( $values, $form );
|
||||
|
||||
/* Clear create menu caches */
|
||||
\IPS\Member::clearCreateMenu();
|
||||
@@ -217,10 +240,10 @@ class _onboard extends \IPS\Dispatcher\Controller
|
||||
\IPS\Data\Cache::i()->clearAll();
|
||||
|
||||
/* Clear data stores */
|
||||
unset(
|
||||
\IPS\Data\Store::i()->manifest,
|
||||
\IPS\Data\Store::i()->iebrowserconfig,
|
||||
\IPS\Data\Store::i()->frontNavigation
|
||||
unset(
|
||||
\IPS\Data\Store::i()->manifest,
|
||||
\IPS\Data\Store::i()->iebrowserconfig,
|
||||
\IPS\Data\Store::i()->frontNavigation
|
||||
);
|
||||
|
||||
\IPS\Session::i()->log( 'acplogs__onboard_settings' );
|
||||
@@ -231,7 +254,7 @@ class _onboard extends \IPS\Dispatcher\Controller
|
||||
\IPS\Output::i()->output .= $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'dashboard' ), 'onboardForm' ) );
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'settings/general.css', 'core', 'admin' ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Show a confirmation screen with "next steps"
|
||||
*
|
||||
|
||||
@@ -212,9 +212,9 @@ class _dataLayer extends \IPS\Dispatcher\Controller
|
||||
];
|
||||
|
||||
if (
|
||||
class_exists( 'IPS\cloud\DataLayer' ) AND
|
||||
\IPS\core\DataLayer::i() instanceof \IPS\cloud\DataLayer AND
|
||||
\count( \IPS\Db::i()->select( 'datalayer_key', \IPS\cloud\DataLayer\Handler::$databaseTable, $where, null, 1 ) )
|
||||
class_exists( 'IPS\cloud\DataLayer' ) AND
|
||||
\IPS\core\DataLayer::i() instanceof \IPS\cloud\DataLayer AND
|
||||
\count( \IPS\Db::i()->select( 'datalayer_key', \IPS\cloud\DataLayer\Handler::$databaseTable, $where, null, 1 ) )
|
||||
)
|
||||
{
|
||||
throw new \InvalidArgumentException( "$_value or window.$_value is in use by a custom handler." );
|
||||
|
||||
@@ -265,4 +265,22 @@ class _mfa extends \IPS\Dispatcher\Controller
|
||||
|
||||
return (string) $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset security answers
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function resetSecurityAnswers()
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
\IPS\Db::i()->delete( 'core_security_answers' );
|
||||
\IPS\Db::i()->update( 'core_members', "members_bitoptions2=members_bitoptions2 &~ 512" );
|
||||
|
||||
/* Log MFA reset */
|
||||
\IPS\Session::i()->log( 'acplogs__mfa_questions_reset' );
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=core&module=settings&controller=mfa&tab=handlers&do=settings&key=questions" ), 'acplogs__mfa_questions_reset' );
|
||||
}
|
||||
}
|
||||
@@ -609,6 +609,7 @@ class _admin extends \IPS\Dispatcher\Controller
|
||||
|
||||
/* Create the table */
|
||||
$table = new \IPS\Helpers\Table\Db( 'core_admin_login_logs', \IPS\Http\Url::internal( 'app=core&module=staff&controller=admin&do=loginLogs' ) );
|
||||
$table->joins[] = array( 'from' => 'core_members', 'where' => 'core_admin_login_logs.admin_username=core_members.email' );
|
||||
$table->langPrefix = 'adminloginlogs_';
|
||||
$table->sortBy = $table->sortBy ?: 'admin_time';
|
||||
$table->sortDirection = $table->sortDirection ?: 'DESC';
|
||||
@@ -617,8 +618,18 @@ class _admin extends \IPS\Dispatcher\Controller
|
||||
/* Search */
|
||||
$table->quickSearch = 'admin_username';
|
||||
$table->advancedSearch = array(
|
||||
'admin_username' => \IPS\Helpers\Table\SEARCH_MEMBER,
|
||||
'admin_username' => array(
|
||||
\IPS\Helpers\Table\SEARCH_CONTAINS_TEXT,
|
||||
array(),
|
||||
function( $val ){
|
||||
if( !empty( $val ) )
|
||||
{
|
||||
return array( "(core_members.name LIKE CONCAT(?, '%') OR admin_username LIKE CONCAT(?,'%'))", $val, $val );
|
||||
}
|
||||
}
|
||||
),
|
||||
'admin_ip_address' => \IPS\Helpers\Table\SEARCH_CONTAINS_TEXT,
|
||||
'admin_time' => \IPS\Helpers\Table\SEARCH_DATE_RANGE
|
||||
);
|
||||
|
||||
/* Filters */
|
||||
@@ -629,6 +640,15 @@ class _admin extends \IPS\Dispatcher\Controller
|
||||
|
||||
/* Custom parsers */
|
||||
$table->parsers = array(
|
||||
'admin_username' => function( $val, $row )
|
||||
{
|
||||
$member = \IPS\Member::constructFromData( $row );
|
||||
if( $member->member_id )
|
||||
{
|
||||
return "<a href='{$member->acpUrl()}'>" . htmlentities( $member->name, ENT_DISALLOWED, 'UTF-8', FALSE ) . "</a>";
|
||||
}
|
||||
return $val;
|
||||
},
|
||||
'admin_time' => function( $val, $row )
|
||||
{
|
||||
return \IPS\DateTime::ts( $val );
|
||||
|
||||
@@ -35,7 +35,7 @@ class _moderators extends \IPS\Dispatcher\Controller
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'moderators_manage' );
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'moderatorstats_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
|
||||
@@ -1020,7 +1020,23 @@ class _support extends \IPS\Dispatcher\Controller
|
||||
'recommendedIssues' => $requirements['advice']
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return all IPS log tables which can become quite large
|
||||
*
|
||||
* @return array<string, \IPS\Http\Url>
|
||||
*/
|
||||
public function getLogTables(): array
|
||||
{
|
||||
return [
|
||||
'core_log' => \IPS\Http\Url::internal( 'app=core&module=support&controller=systemLogs&do=logSettings' ),
|
||||
'core_error_logs' => \IPS\Http\Url::internal( 'app=core&module=support&controller=errorLogs&do=settings&searchResult=prune_log_error' ),
|
||||
'core_mail_error_logs' => \IPS\Http\Url::internal( 'app=core&module=settings&controller=email&do=errorLogSettings' ),
|
||||
'core_edit_history' => \IPS\Http\Url::internal( 'app=core&module=settings&controller=posting&tab=general&searchResult=edit_log_prune' ),
|
||||
'core_api_logs' => \IPS\Http\Url::internal( 'app=core&module=applications&controller=apiLogs&do=settings' ),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get block: Logs
|
||||
*
|
||||
@@ -1029,15 +1045,8 @@ class _support extends \IPS\Dispatcher\Controller
|
||||
protected function _showBlockLogs()
|
||||
{
|
||||
$requirements = array( 'advice' => 0, 'failures' => 0, 'list' => array() );
|
||||
|
||||
$logTables = array(
|
||||
'core_log' => \IPS\Http\Url::internal( 'app=core&module=support&controller=systemLogs&do=logSettings' ),
|
||||
'core_error_logs' => \IPS\Http\Url::internal( 'app=core&module=support&controller=errorLogs&do=settings&searchResult=prune_log_error' ),
|
||||
'core_mail_error_logs' => \IPS\Http\Url::internal( 'app=core&module=settings&controller=email&do=errorLogSettings' ),
|
||||
'core_edit_history' => \IPS\Http\Url::internal( 'app=core&module=settings&controller=posting&tab=general&searchResult=edit_log_prune' ),
|
||||
);
|
||||
|
||||
foreach( $logTables as $table => $url )
|
||||
|
||||
foreach( $this->getLogTables() as $table => $url )
|
||||
{
|
||||
$size = $this->_getLogTableSize( $table );
|
||||
|
||||
|
||||
@@ -65,14 +65,19 @@ class _page extends \IPS\Dispatcher\Controller
|
||||
\IPS\Output::i()->sidebar['contextual'] .= \IPS\Theme::i()->getTemplate( 'clubs', 'core' )->clubLocationBox( $this->page->club, $location );
|
||||
}
|
||||
|
||||
if( $this->page->club->type != \IPS\Member\Club::TYPE_PUBLIC )
|
||||
if( $this->page->club->type != \IPS\Member\Club::TYPE_PUBLIC AND $this->page->club->canViewMembers() )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['contextual'] .= \IPS\Theme::i()->getTemplate( 'clubs', 'core' )->clubMemberBox( $this->page->club );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->breadcrumb[] = array( $this->page->club->url(), $this->page->club->name );
|
||||
\IPS\Output::i()->breadcrumb[] = array( NULL, $this->page->title );
|
||||
|
||||
|
||||
if( !$this->page->meta_index )
|
||||
{
|
||||
\IPS\Output::i()->metaTags['robots'] = 'noindex';
|
||||
}
|
||||
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
|
||||
@@ -1496,8 +1496,7 @@ class _view extends \IPS\Helpers\CoverPhoto\Controller
|
||||
{
|
||||
$this->club->approved = TRUE;
|
||||
$this->club->save();
|
||||
|
||||
$this->club->owner->achievementAction( 'core', 'NewClub', $this->club );
|
||||
$this->club->onApprove();
|
||||
|
||||
\IPS\Output::i()->redirect( $this->club->url() );
|
||||
}
|
||||
|
||||
@@ -1143,7 +1143,8 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
|
||||
/* Moderator stuff */
|
||||
if ( ( \IPS\Member::loggedIn()->modPermission('can_modify_profiles') OR \IPS\Member::loggedIn()->modPermission('can_unban') ) AND \IPS\Member::loggedIn()->member_id != $this->member->member_id )
|
||||
{
|
||||
if( \IPS\Settings::i()->signatures_enabled )
|
||||
$sigLimits = explode( ":", $this->member->group['g_signature_limits'] );
|
||||
if( \IPS\Settings::i()->signatures_enabled AND !$sigLimits[0] AND $sigLimits[5] != 0 )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Editor( 'signature', $this->member->signature, FALSE, array( 'app' => 'core', 'key' => 'Signatures', 'autoSaveKey' => "frontsig-" . $this->member->member_id, 'attachIds' => array( $this->member->member_id ) ) ) );
|
||||
}
|
||||
|
||||
@@ -974,9 +974,15 @@ class _search extends \IPS\Dispatcher\Controller
|
||||
|
||||
/* Dates */
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'startDate', ( isset( \IPS\Request::i()->start_before ) or ( isset( \IPS\Request::i()->start_after ) and \is_numeric( \IPS\Request::i()->start_after ) ) ) ? 'custom' : \IPS\Request::i()->start_after, FALSE, array( 'options' => $dateOptions, 'toggles' => array( 'custom' => array( 'elCustomDate_startDate' ) ) ), NULL, NULL, NULL, 'startDate' ), NULL, 'search_tab_content' );
|
||||
$form->add( new \IPS\Helpers\Form\DateRange( 'startDateCustom', array( 'start' => ( isset( \IPS\Request::i()->start_after ) and \is_numeric( \IPS\Request::i()->start_after ) ) ? \IPS\DateTime::ts( \IPS\Request::i()->start_after ) : NULL, 'end' => isset( \IPS\Request::i()->start_before ) ? \IPS\DateTime::ts( \IPS\Request::i()->start_before ) : NULL ) ), NULL, 'search_tab_content' );
|
||||
$form->add( new \IPS\Helpers\Form\DateRange( 'startDateCustom', array( 'start' => ( isset( \IPS\Request::i()->start_after ) and \is_numeric( \IPS\Request::i()->start_after ) ) ? \IPS\DateTime::ts( \IPS\Request::i()->start_after, TRUE ) : NULL, 'end' => isset( \IPS\Request::i()->start_before ) ? \IPS\DateTime::ts( \IPS\Request::i()->start_before, TRUE ) : NULL ), false, array(
|
||||
'start' => array( 'timezone' => new \DateTimeZone( 'UTC' ), 'time' => FALSE ),
|
||||
'end' => array( 'timezone' => new \DateTimeZone( 'UTC' ), 'time' => FALSE )
|
||||
) ), NULL, 'search_tab_content' );
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'updatedDate', ( isset( \IPS\Request::i()->updated_before ) or ( isset( \IPS\Request::i()->updated_after ) and \is_numeric( \IPS\Request::i()->updated_after ) ) ) ? 'custom' : \IPS\Request::i()->updated_after, FALSE, array( 'options' => $dateOptions, 'toggles' => array( 'custom' => array( 'elCustomDate_updatedDate' ) ) ), NULL, NULL, NULL, 'updatedDate' ), NULL, 'search_tab_content' );
|
||||
$form->add( new \IPS\Helpers\Form\DateRange( 'updatedDateCustom', array( 'start' => ( isset( \IPS\Request::i()->updated_after ) and \is_numeric( \IPS\Request::i()->updated_after ) ) ? \IPS\DateTime::ts( \IPS\Request::i()->updated_after ) : NULL, 'end' => isset( \IPS\Request::i()->updated_before ) ? \IPS\DateTime::ts( \IPS\Request::i()->updated_before ) : NULL ) ), NULL, 'search_tab_content' );
|
||||
$form->add( new \IPS\Helpers\Form\DateRange( 'updatedDateCustom', array( 'start' => ( isset( \IPS\Request::i()->updated_after ) and \is_numeric( \IPS\Request::i()->updated_after ) ) ? \IPS\DateTime::ts( \IPS\Request::i()->updated_after, TRUE ) : NULL, 'end' => isset( \IPS\Request::i()->updated_before ) ? \IPS\DateTime::ts( \IPS\Request::i()->updated_before, TRUE ) : NULL ), false, array(
|
||||
'start' => array( 'timezone' => new \DateTimeZone( 'UTC' ), 'time' => FALSE ),
|
||||
'end' => array( 'timezone' => new \DateTimeZone( 'UTC' ), 'time' => FALSE )
|
||||
) ), NULL, 'search_tab_content' );
|
||||
|
||||
/* Other filters */
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'search_in', \IPS\Request::i()->search_in, FALSE, array( 'options' => array( 'all' => 'titles_and_body', 'titles' => 'titles_only' ) ), NULL, NULL, NULL, 'searchIn' ), NULL, 'search_tab_content' );
|
||||
@@ -1035,7 +1041,7 @@ class _search extends \IPS\Dispatcher\Controller
|
||||
|
||||
$form->add(new \IPS\Helpers\Form\CheckboxSet('group', ( isset( \IPS\Request::i()->group ) ) ? \is_array( \IPS\Request::i()->group) ? array_keys( \IPS\Request::i()->group) : array( \IPS\Request::i()->group ) : array_keys( $groups ), FALSE, array('options' => $groups, 'parse' => 'normal'), NULL, NULL, NULL, 'core_members_group'), NULL, 'search_tab_member' );
|
||||
$form->add(new \IPS\Helpers\Form\Select('joinedDate', (isset(\IPS\Request::i()->start_before) or (isset(\IPS\Request::i()->start_after) and \is_numeric(\IPS\Request::i()->start_after))) ? 'custom' : \IPS\Request::i()->start_after, FALSE, array('options' => $dateOptions, 'toggles' => array('custom' => array('elCustomDate_joinedDate'))), NULL, NULL, NULL, 'joinedDate'), NULL, 'search_tab_member' );
|
||||
$form->add(new \IPS\Helpers\Form\DateRange('joinedDateCustom', array('start' => (isset(\IPS\Request::i()->start_after) and \is_numeric(\IPS\Request::i()->start_after)) ? \IPS\DateTime::ts(\IPS\Request::i()->start_after) : NULL, 'end' => isset(\IPS\Request::i()->start_before) ? \IPS\DateTime::ts(\IPS\Request::i()->start_before) : NULL)), NULL, 'search_tab_member' );
|
||||
$form->add(new \IPS\Helpers\Form\DateRange('joinedDateCustom', array('start' => (isset(\IPS\Request::i()->start_after) and \is_numeric(\IPS\Request::i()->start_after)) ? \IPS\DateTime::ts(\IPS\Request::i()->start_after, TRUE) : NULL, 'end' => isset(\IPS\Request::i()->start_before) ? \IPS\DateTime::ts(\IPS\Request::i()->start_before, TRUE) : NULL)), NULL, 'search_tab_member' );
|
||||
|
||||
/* Profile fields for member searches */
|
||||
$memberFields = array();
|
||||
|
||||
@@ -211,10 +211,19 @@ class _ajax extends \IPS\Dispatcher\Controller
|
||||
/* Permission check */
|
||||
if ( $permission )
|
||||
{
|
||||
$toReturn[ $attachment['attach_id'] ] = array(
|
||||
'size' => \IPS\Output\Plugin\Filesize::humanReadableFilesize( $attachment['attach_filesize'], FALSE, TRUE ),
|
||||
'downloads' => \IPS\Member::loggedIn()->language()->formatNumber( $attachment['attach_hits'] )
|
||||
);
|
||||
if( $attachment['attach_is_image'] )
|
||||
{
|
||||
$toReturn[ $attachment['attach_id'] ] = array(
|
||||
'rotate' => $attachment['attach_img_rotate'] <> 0 ? (int)$attachment['attach_img_rotate'] : null
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$toReturn[ $attachment['attach_id'] ] = array(
|
||||
'size' => \IPS\Output\Plugin\Filesize::humanReadableFilesize( $attachment['attach_filesize'], FALSE, TRUE ),
|
||||
'downloads' => \IPS\Member::loggedIn()->language()->formatNumber( $attachment['attach_hits'] )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,4 +62,86 @@ class _attachments extends \IPS\Dispatcher\Controller
|
||||
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack('my_attachments') );
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('myAttachments')->template( (string) $table, \IPS\Db::i()->select( 'SUM(attach_filesize)', 'core_attachments', array( 'attach_member_id=?', \IPS\Member::loggedIn()->member_id ) )->first(), \IPS\Db::i()->select( 'COUNT(*)', 'core_attachments', array( 'attach_member_id=?', \IPS\Member::loggedIn()->member_id ) )->first() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotate imate
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function rotate()
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
/* Get attachment to make sure it's valid */
|
||||
try
|
||||
{
|
||||
$attachment = \IPS\Db::i()->select( '*', 'core_attachments', [ 'attach_id=? and attach_is_image=?', \IPS\Request::i()->id, 1 ] )
|
||||
->join( 'core_attachments_map', 'core_attachments.attach_id=core_attachments_map.attachment_id' )
|
||||
->first();
|
||||
}
|
||||
catch( \UnderflowException $e )
|
||||
{
|
||||
\IPS\Output::i()->json( array( 'error' => 'node_error' ) );
|
||||
}
|
||||
|
||||
/* Check Permission */
|
||||
$exploded = explode( '_', $attachment['location_key'] );
|
||||
try
|
||||
{
|
||||
$extensions = \IPS\Application::load( $exploded[0] )->extensions( 'core', 'EditorLocations' );
|
||||
if ( isset( $extensions[ $exploded[1] ] ) )
|
||||
{
|
||||
$attachmentItem = $extensions[ $exploded[1] ]->attachmentLookup( $attachment[ 'id1' ], $attachment[ 'id2' ], $attachment[ 'id3' ] );
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
\IPS\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 == \IPS\Member::loggedIn()->member_id OR $attachmentItem->canEdit() )
|
||||
{
|
||||
$baseRotation = $attachment['attach_img_rotate'];
|
||||
$temp = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$baseRotation = \IPS\Request::i()->current ?? 0;
|
||||
$temp = true;
|
||||
}
|
||||
|
||||
$angle = \IPS\Request::i()->direction == 'right' ? 90 : -90;
|
||||
$rotation = $baseRotation + $angle;
|
||||
|
||||
/* Make sure we don't rotate to some stupid number */
|
||||
if( $rotation >= 360 )
|
||||
{
|
||||
$rotation -= 360;
|
||||
}
|
||||
elseif( $rotation <= -360 )
|
||||
{
|
||||
$rotation += 360;
|
||||
}
|
||||
|
||||
/* Store the angle for the future */
|
||||
if( !$temp )
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_attachments', [ 'attach_img_rotate' => $rotation ], [ 'attach_id=?', $attachment[ 'attach_id' ] ] );
|
||||
}
|
||||
|
||||
if( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->json( [
|
||||
'rotate' => $rotation,
|
||||
'message' => \IPS\Member::loggedIn()->language()->addToStack('gallery_image_rotated'),
|
||||
'fileId' => \IPS\Request::i()->id,
|
||||
'saved' => $temp ? 0 : 1
|
||||
] );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->redirect( $attachmentItem->url() );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -271,7 +271,10 @@ class _notifications extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
\IPS\Member::loggedIn()->clearPwaAuths();
|
||||
}
|
||||
|
||||
|
||||
/* Digests */
|
||||
\IPS\Db::i()->update( 'core_follow', array( 'follow_notify_freq' => 'none'), array( 'follow_member_id=? AND follow_notify_freq IN(?,?)', \IPS\Member::loggedIn()->member_id, "daily", "weekly" ) );
|
||||
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->json( 'ok' );
|
||||
|
||||
@@ -29,6 +29,7 @@ class _poll extends \IPS\Dispatcher\Controller
|
||||
*/
|
||||
protected function voters()
|
||||
{
|
||||
\IPS\Output::i()->metaTags['robots'] = 'noindex';
|
||||
try
|
||||
{
|
||||
$poll = \IPS\Poll::load( \IPS\Request::i()->id );
|
||||
|
||||
@@ -131,8 +131,7 @@ class _settings extends \IPS\Dispatcher\Controller
|
||||
$canConfigureMfa = TRUE;
|
||||
}
|
||||
|
||||
$sigLimits = explode( ":", \IPS\Member::loggedIn()->group['g_signature_limits'] );
|
||||
$canChangeSignature = (bool) ( \IPS\Settings::i()->signatures_enabled && !$sigLimits[0] );
|
||||
$canChangeSignature = (bool) \IPS\Member::loggedIn()->canEditSignature();
|
||||
|
||||
/* Add login handlers */
|
||||
$loginMethods = \IPS\Login::methods();
|
||||
@@ -413,7 +412,7 @@ class _settings extends \IPS\Dispatcher\Controller
|
||||
/* Delete any pending validation emails */
|
||||
\IPS\Db::i()->delete( 'core_validating', array( 'member_id=? AND lost_pass=1', \IPS\Member::loggedIn()->member_id ) );
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=settings&area=password', 'front', 'settings' ), 'password_changed' );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=settings&area=password&success=1', 'front', 'settings' ) );
|
||||
}
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'system' )->settingsPassword( $form );
|
||||
@@ -1101,7 +1100,7 @@ class _settings extends \IPS\Dispatcher\Controller
|
||||
/* Check they have permission to change their signature */
|
||||
$sigLimits = explode( ":", \IPS\Member::loggedIn()->group['g_signature_limits']);
|
||||
|
||||
if( !\IPS\Settings::i()->signatures_enabled OR $sigLimits[0] )
|
||||
if( !\IPS\Member::loggedIn()->canEditSignature() )
|
||||
{
|
||||
\IPS\Output::i()->error( 'signatures_disabled', '2C122/C', 403, '' );
|
||||
}
|
||||
@@ -1772,7 +1771,7 @@ class _settings extends \IPS\Dispatcher\Controller
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
/* Update the bitwise flag */
|
||||
\IPS\Member::loggedIn()->datalayer_collect_pii = (bool) ! \IPS\Member::loggedIn()->datalayer_collect_pii;
|
||||
\IPS\Member::loggedIn()->members_bitoptions['datalayer_pii_optout'] = (bool) ! \IPS\Member::loggedIn()->members_bitoptions['datalayer_pii_optout'];
|
||||
\IPS\Member::loggedIn()->save();
|
||||
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
|
||||
@@ -275,6 +275,10 @@ class _widgets extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
$currentConfig = \IPS\Db::i()->select( '*', 'core_widget_areas', array( 'app=? AND module=? AND controller=? AND area=?', \IPS\Request::i()->pageApp, \IPS\Request::i()->pageModule, \IPS\Request::i()->pageController, \IPS\Request::i()->area ) )->first();
|
||||
$widgets = json_decode( $currentConfig['widgets'], TRUE );
|
||||
if( !is_countable( $widgets ) )
|
||||
{
|
||||
throw new \UnderflowException;
|
||||
}
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
{
|
||||
|
||||
@@ -113,6 +113,12 @@ class _applications extends \IPS\Dispatcher\Controller
|
||||
|
||||
if( \count( $apps ) )
|
||||
{
|
||||
/* Make sure the core app is the first index */
|
||||
if( isset( $apps['core'] ) )
|
||||
{
|
||||
$apps = [ 'core' => $apps['core'] ] + $apps;
|
||||
}
|
||||
|
||||
$_SESSION['apps'] = $apps;
|
||||
|
||||
$warnings = array();
|
||||
|
||||
Reference in new issue
Block a user