Version 5.0.0 beta 1
This commit is contained in:
1 parent
25ddeb65d6
commit
15c7beabc5
6736 files changed
+627902
-497943
No files matched your search
@@ -11,42 +11,61 @@
|
||||
namespace IPS\core\modules\admin\support;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\DateTime;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Dispatcher\Controller;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\Interval;
|
||||
use IPS\Helpers\Form\Radio;
|
||||
use IPS\Helpers\Table\Db;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\Output;
|
||||
use IPS\Session;
|
||||
use IPS\Settings;
|
||||
use IPS\Theme;
|
||||
use function defined;
|
||||
use const IPS\Helpers\Table\SEARCH_CONTAINS_TEXT;
|
||||
use const IPS\Helpers\Table\SEARCH_DATE_RANGE;
|
||||
use const IPS\Helpers\Table\SEARCH_MEMBER;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Error Logs
|
||||
*/
|
||||
class _errorLogs extends \IPS\Dispatcher\Controller
|
||||
class errorLogs extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'system_logs_view' );
|
||||
Dispatcher::i()->checkAcpPermission( 'system_logs_view' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get table
|
||||
*
|
||||
* @param \IPS\Http\Url $url The URL where the table will be displayed
|
||||
* @return \IPS\Helpers\Table\Db
|
||||
* @param Url $url The URL where the table will be displayed
|
||||
* @return Db
|
||||
*/
|
||||
public static function table( \IPS\Http\Url $url )
|
||||
public static function table( Url $url ) : Db
|
||||
{
|
||||
$table = new \IPS\Helpers\Table\Db( 'core_error_logs', $url );
|
||||
$table = new Db( 'core_error_logs', $url );
|
||||
$table->langPrefix = 'errorlogs_';
|
||||
$table->include = array( 'log_error_code', 'log_error', 'log_ip_address', 'log_request_uri', 'log_member', 'log_date' );
|
||||
$table->mainColumn = 'log_error_code';
|
||||
@@ -55,7 +74,7 @@ class _errorLogs extends \IPS\Dispatcher\Controller
|
||||
$table->parsers = array(
|
||||
'log_member' => function( $val )
|
||||
{
|
||||
$member = \IPS\Member::load( $val );
|
||||
$member = Member::load( $val );
|
||||
|
||||
if( $member->member_id )
|
||||
{
|
||||
@@ -68,35 +87,35 @@ class _errorLogs extends \IPS\Dispatcher\Controller
|
||||
},
|
||||
'log_ip_address'=> function( $val )
|
||||
{
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'membertools_ip' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'membertools_ip' ) )
|
||||
{
|
||||
return "<a href='" . \IPS\Http\Url::internal( "app=core&module=members&controller=ip&ip={$val}" ) . "'>{$val}</a>";
|
||||
return "<a href='" . Url::internal( "app=core&module=members&controller=ip&ip={$val}" ) . "'>{$val}</a>";
|
||||
}
|
||||
return $val;
|
||||
},
|
||||
'log_date' => function( $val )
|
||||
{
|
||||
return (string) \IPS\DateTime::ts( $val );
|
||||
return (string) DateTime::ts( $val );
|
||||
},
|
||||
'log_error' => function( $val )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( $val );
|
||||
return Member::loggedIn()->language()->addToStack( $val );
|
||||
},
|
||||
'log_request_uri' => function( $val )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->truncatedUrl( $val );
|
||||
return Theme::i()->getTemplate( 'global', 'core', 'global' )->truncatedUrl( $val );
|
||||
}
|
||||
);
|
||||
$table->sortBy = $table->sortBy ?: 'log_date';
|
||||
$table->sortDirection = $table->sortDirection ?: 'desc';
|
||||
|
||||
$table->advancedSearch = array(
|
||||
'log_member' => \IPS\Helpers\Table\SEARCH_MEMBER,
|
||||
'log_ip_address' => \IPS\Helpers\Table\SEARCH_CONTAINS_TEXT,
|
||||
'log_date' => \IPS\Helpers\Table\SEARCH_DATE_RANGE,
|
||||
'log_error' => \IPS\Helpers\Table\SEARCH_CONTAINS_TEXT,
|
||||
'log_error_code' => \IPS\Helpers\Table\SEARCH_CONTAINS_TEXT,
|
||||
'log_request_uri' => \IPS\Helpers\Table\SEARCH_CONTAINS_TEXT,
|
||||
'log_member' => SEARCH_MEMBER,
|
||||
'log_ip_address' => SEARCH_CONTAINS_TEXT,
|
||||
'log_date' => SEARCH_DATE_RANGE,
|
||||
'log_error' => SEARCH_CONTAINS_TEXT,
|
||||
'log_error_code' => SEARCH_CONTAINS_TEXT,
|
||||
'log_request_uri' => SEARCH_CONTAINS_TEXT,
|
||||
);
|
||||
$table->quickSearch = 'log_error';
|
||||
|
||||
@@ -108,22 +127,22 @@ class _errorLogs extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
protected function manage() : void
|
||||
{
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'support', 'diagnostic_log_settings' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'core', 'support', 'diagnostic_log_settings' ) )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['actions'] = array(
|
||||
Output::i()->sidebar['actions'] = array(
|
||||
'settings' => array(
|
||||
'title' => 'settings',
|
||||
'icon' => 'cog',
|
||||
'link' => \IPS\Http\Url::internal( 'app=core&module=support&controller=errorLogs&do=settings' ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('settings') )
|
||||
'link' => Url::internal( 'app=core&module=support&controller=errorLogs&do=settings' ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => Member::loggedIn()->language()->addToStack('settings') )
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('errorlogs');
|
||||
\IPS\Output::i()->output = (string) static::table( \IPS\Http\Url::internal( 'app=core&module=support&controller=errorLogs' ) );
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('errorlogs');
|
||||
Output::i()->output = (string) static::table( Url::internal( 'app=core&module=support&controller=errorLogs' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,9 +150,9 @@ class _errorLogs extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function settings()
|
||||
protected function settings() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'diagnostic_log_settings' );
|
||||
Dispatcher::i()->checkAcpPermission( 'diagnostic_log_settings' );
|
||||
|
||||
$levelOptions = array(
|
||||
'0' => 'level_number_0',
|
||||
@@ -144,22 +163,22 @@ class _errorLogs extends \IPS\Dispatcher\Controller
|
||||
'5' => 'level_number_5',
|
||||
);
|
||||
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'error_log_level', \IPS\Settings::i()->error_log_level, FALSE, array( 'options' => $levelOptions ) ) );
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'staff', 'error_prune' ) )
|
||||
$form = new Form;
|
||||
$form->add( new Radio( 'error_log_level', Settings::i()->error_log_level, FALSE, array( 'options' => $levelOptions ) ) );
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'core', 'staff', 'error_prune' ) )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Interval( 'prune_log_error', \IPS\Settings::i()->prune_log_error, FALSE, array( 'valueAs' => \IPS\Helpers\Form\Interval::DAYS, 'unlimited' => 0, 'unlimitedLang' => 'never' ), NULL, \IPS\Member::loggedIn()->language()->addToStack('after'), NULL, 'prune_log_error' ) );
|
||||
$form->add( new Interval( 'prune_log_error', Settings::i()->prune_log_error, FALSE, array( 'valueAs' => Interval::DAYS, 'unlimited' => 0, 'unlimitedLang' => 'never' ), NULL, Member::loggedIn()->language()->addToStack('after'), NULL, 'prune_log_error' ) );
|
||||
}
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
$form->saveAsSettings();
|
||||
\IPS\Session::i()->log( 'acplog__errorlog_settings' );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=support&controller=errorLogs' ), 'saved' );
|
||||
Session::i()->log( 'acplog__errorlog_settings' );
|
||||
Output::i()->redirect( Url::internal( 'app=core&module=support&controller=errorLogs' ), 'saved' );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('errorlogssettings');
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('global')->block( 'errorlogssettings', $form, FALSE );
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('errorlogssettings');
|
||||
Output::i()->output = Theme::i()->getTemplate('global')->block( 'errorlogssettings', $form, FALSE );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief hookedFiles
|
||||
* @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 11 Nov 2016
|
||||
*/
|
||||
|
||||
namespace IPS\core\modules\admin\support;
|
||||
|
||||
/* 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' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* hookedFiles
|
||||
*/
|
||||
class _hookedFiles extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'app_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show all third party hooks
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
{
|
||||
$table = new \IPS\Helpers\Table\Db( 'core_hooks', \IPS\Http\Url::internal( 'app=core&module=support&controller=hookedFiles' ), array( array( "( app NOT IN( '" . implode( "','", \IPS\IPS::$ipsApps ) . "' ) OR app IS NULL )" ) ) );
|
||||
$table->langPrefix = 'hooks_';
|
||||
$table->quickSearch = array( 'class', 'hook_class' );
|
||||
$table->include = array( 'hooks_id', 'hooks_app', 'hooks_plugin', 'hooks_type', 'hooks_class', 'hooks_file' );
|
||||
|
||||
$table->parsers = array(
|
||||
'hooks_id' => function( $val, $row )
|
||||
{
|
||||
return $row['id'];
|
||||
},
|
||||
'hooks_app' => function( $val, $row )
|
||||
{
|
||||
try
|
||||
{
|
||||
return \IPS\Application::load($row['app'])->_title;
|
||||
}
|
||||
catch ( \OutOfRangeException | \UnexpectedValueException $e )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('hook_class_none');
|
||||
}
|
||||
},
|
||||
'hooks_plugin' => function( $val, $row )
|
||||
{
|
||||
try
|
||||
{
|
||||
return htmlspecialchars( \IPS\Plugin::load($row['plugin'])->name, ENT_DISALLOWED, 'UTF-8', FALSE );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('hook_class_none');
|
||||
}
|
||||
},
|
||||
'hooks_type' => function( $val, $row )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'plugin_hook_type_' . mb_strtolower( $row['type'] ) );
|
||||
},
|
||||
'hooks_class' => function( $val, $row )
|
||||
{
|
||||
return $row['class'];
|
||||
},
|
||||
'hooks_file' => function( $val, $row )
|
||||
{
|
||||
if ( $row['app'] )
|
||||
{
|
||||
return '/applications/' . $row['app'] . '/hooks/' . $row['filename'] . '.php';
|
||||
}
|
||||
else if ( $row['plugin'] )
|
||||
{
|
||||
try
|
||||
{
|
||||
$plugin = \IPS\Plugin::load($row['plugin']);
|
||||
return '/plugins' . ( $plugin->location ? '/' . $plugin->location . '/hooks/' : '/' ) . $row['filename'] . '.php';
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('hook_class_none');
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'hooked_classes' );
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'support' )->hookedClasses( $table );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,30 +11,35 @@
|
||||
namespace IPS\core\modules\admin\support;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Dispatcher\Controller;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display phpinfo
|
||||
*/
|
||||
class _phpinfo extends \IPS\Dispatcher\Controller
|
||||
class phpinfo extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'get_support' );
|
||||
Dispatcher::i()->checkAcpPermission( 'get_support' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
@@ -43,7 +48,7 @@ class _phpinfo extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
protected function manage() : void
|
||||
{
|
||||
phpinfo();
|
||||
exit;
|
||||
|
||||
@@ -12,47 +12,65 @@
|
||||
namespace IPS\core\modules\admin\support;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Application;
|
||||
use IPS\Db;
|
||||
use IPS\Dispatcher\Controller;
|
||||
use IPS\Helpers\MultipleRedirect;
|
||||
use IPS\Http\Url;
|
||||
use IPS\IPS;
|
||||
use IPS\Lang;
|
||||
use IPS\Member;
|
||||
use IPS\Output;
|
||||
use IPS\Session;
|
||||
use IPS\Theme;
|
||||
use function defined;
|
||||
use function in_array;
|
||||
use function intval;
|
||||
use const IPS\NO_WRITES;
|
||||
use const IPS\RECOVERY_MODE;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* recovery
|
||||
*/
|
||||
class _recovery extends \IPS\Dispatcher\Controller
|
||||
class recovery extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Recover
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
protected function manage() : void
|
||||
{
|
||||
/* Are we even in recovery mode? */
|
||||
if ( \IPS\RECOVERY_MODE === FALSE )
|
||||
if ( RECOVERY_MODE === FALSE )
|
||||
{
|
||||
\IPS\Output::i()->error( 'recovery_mode_disabled', '1C342/1', 403, '' );
|
||||
Output::i()->error( 'recovery_mode_disabled', '1C342/1', 403, '' );
|
||||
}
|
||||
|
||||
if ( \IPS\NO_WRITES === TRUE )
|
||||
if ( NO_WRITES )
|
||||
{
|
||||
\IPS\Output::i()->error( 'no_writes', '1C342/2', 403, '' );
|
||||
Output::i()->error( 'no_writes', '1C342/2', 403, '' );
|
||||
}
|
||||
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
Session::i()->csrfCheck();
|
||||
|
||||
/* We are, let's set up a multi-redirect to disable things. At the end of the process, we'll list everything we did. */
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'recovery_mode' );
|
||||
\IPS\Output::i()->output = new \IPS\Helpers\MultipleRedirect( \IPS\Http\Url::internal( 'app=core&module=support&controller=recovery' )->csrf(), function( $step )
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack( 'recovery_mode' );
|
||||
Output::i()->output = new MultipleRedirect( Url::internal( 'app=core&module=support&controller=recovery' )->csrf(), function( $step )
|
||||
{
|
||||
$step = \intval( $step );
|
||||
$step = intval( $step );
|
||||
|
||||
switch( $step )
|
||||
{
|
||||
@@ -60,9 +78,9 @@ class _recovery extends \IPS\Dispatcher\Controller
|
||||
$appsDisabled = array();
|
||||
|
||||
/* Disable All non-IPS Applications */
|
||||
foreach( \IPS\Application::applications() AS $app )
|
||||
foreach( Application::applications() AS $app )
|
||||
{
|
||||
if ( !\in_array( $app->directory, \IPS\IPS::$ipsApps ) )
|
||||
if ( !in_array( $app->directory, IPS::$ipsApps ) )
|
||||
{
|
||||
$app->_enabled = FALSE;
|
||||
$appDisabled[] = $app->_id;
|
||||
@@ -71,60 +89,41 @@ class _recovery extends \IPS\Dispatcher\Controller
|
||||
|
||||
$_SESSION['recoveryApps'] = $appsDisabled;
|
||||
|
||||
return array( 1, \IPS\Member::loggedIn()->language()->addToStack( 'disabled_applications' ), 25 );
|
||||
break;
|
||||
|
||||
case 1: # Plugins
|
||||
$pluginsDisabled = array();
|
||||
|
||||
/* Disable All Plugins */
|
||||
foreach( \IPS\Plugin::plugins() AS $plugin )
|
||||
{
|
||||
$plugin->_enabled = FALSE;
|
||||
$plugin->save();
|
||||
$pluginsDisabled[] = $plugin->_id;
|
||||
}
|
||||
|
||||
$_SESSION['recoveryPlugins'] = $pluginsDisabled;
|
||||
|
||||
return array( 2, \IPS\Member::loggedIn()->language()->addToStack( 'disabled_plugins' ), 50 );
|
||||
break;
|
||||
return array( 2, Member::loggedIn()->language()->addToStack( 'disabled_applications' ), 25 );
|
||||
|
||||
case 2: # Reset Theme
|
||||
$themeReset = FALSE;
|
||||
|
||||
if ( \IPS\Db::i()->select( 'COUNT(*)', 'core_theme_templates', array( "template_set_id>?", 0 ) )->first() OR \IPS\Db::i()->select( 'COUNT(*)', 'core_theme_css', array( "css_set_id>?", 0 ) )->first() )
|
||||
if ( Db::i()->select( 'COUNT(*)', 'core_theme_templates', array( "template_set_id>?", 0 ) )->first() OR Db::i()->select( 'COUNT(*)', 'core_theme_css', array( "css_set_id>?", 0 ) )->first() )
|
||||
{
|
||||
/* Create a new theme */
|
||||
$theme = new \IPS\Theme;
|
||||
$theme->permissions = \IPS\Member::loggedIn()->member_group_id;
|
||||
$theme = new Theme;
|
||||
$theme->permissions = Member::loggedIn()->member_group_id;
|
||||
$theme->save();
|
||||
$theme->installThemeSettings();
|
||||
$theme->copyResourcesFromSet();
|
||||
$theme->installThemeEditorSettings();
|
||||
|
||||
\IPS\Lang::saveCustom( 'core', "core_theme_set_title_" . $theme->id, "IPS Support" );
|
||||
Lang::saveCustom( 'core', "core_theme_set_title_" . $theme->id, "IPS Support" );
|
||||
|
||||
/* Set this account to use that theme */
|
||||
\IPS\Member::loggedIn()->skin = $theme->id;
|
||||
\IPS\Member::loggedIn()->save();
|
||||
Member::loggedIn()->skin = $theme->id;
|
||||
Member::loggedIn()->save();
|
||||
|
||||
$themeReset = TRUE;
|
||||
}
|
||||
|
||||
$_SESSION['recoveryTheme'] = $themeReset;
|
||||
|
||||
return array( 3, \IPS\Member::loggedIn()->language()->addToStack( 'reset_theme_to_default' ), 75 );
|
||||
break;
|
||||
return array( 3, Member::loggedIn()->language()->addToStack( 'reset_theme_to_default' ), 75 );
|
||||
|
||||
case 4: # Done
|
||||
default:
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
}, function()
|
||||
{
|
||||
\IPS\IPS::resyncIPSCloud('Enabled recovery mode');
|
||||
\IPS\Session::i()->log( 'acplog__enabled_recovery' );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=support&controller=recovery&do=done' ) );
|
||||
IPS::resyncIPSCloud('Enabled recovery mode');
|
||||
Session::i()->log( 'acplog__enabled_recovery' );
|
||||
Output::i()->redirect( Url::internal( 'app=core&module=support&controller=recovery&do=done' ) );
|
||||
} );
|
||||
}
|
||||
|
||||
@@ -133,26 +132,19 @@ class _recovery extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function done()
|
||||
public function done() : void
|
||||
{
|
||||
/* Did we disable any apps? */
|
||||
$apps = array();
|
||||
foreach( $_SESSION['recoveryApps'] AS $app )
|
||||
{
|
||||
$apps[] = \IPS\Application::load( $app );
|
||||
}
|
||||
|
||||
/* Did we disable any plugins? */
|
||||
$plugins = array();
|
||||
foreach( $_SESSION['recoveryPlugins'] AS $plugin )
|
||||
{
|
||||
$plugins[] = \IPS\Plugin::load( $plugin );
|
||||
$apps[] = Application::load( $app );
|
||||
}
|
||||
|
||||
/* Did we reset the theme? */
|
||||
$theme = $_SESSION['recoveryTheme'];
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'recovery_mode' );
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'support' )->recovery( $apps, $plugins, $theme );
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack( 'recovery_mode' );
|
||||
Output::i()->output = Theme::i()->getTemplate( 'support' )->recovery( $apps, $theme );
|
||||
}
|
||||
}
|
||||
@@ -11,37 +11,54 @@
|
||||
namespace IPS\core\modules\admin\support;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Dispatcher\Controller;
|
||||
use IPS\Helpers\Table\Custom;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\Output;
|
||||
use IPS\Redis as RedisClass;
|
||||
use IPS\Theme;
|
||||
use function count;
|
||||
use function defined;
|
||||
use function intval;
|
||||
use const IPS\CACHE_METHOD;
|
||||
use const IPS\CIC;
|
||||
use const IPS\REDIS_ENABLED;
|
||||
use const IPS\STORE_METHOD;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Redis info
|
||||
*/
|
||||
class _redis extends \IPS\Dispatcher\Controller
|
||||
class redis extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
/* Not accessible for CIC */
|
||||
if( \IPS\CIC )
|
||||
if( CIC )
|
||||
{
|
||||
\IPS\Output::i()->error( 'no_module_permission', '2C394/3', 403, '' );
|
||||
Output::i()->error( 'no_module_permission', '2C394/3', 403, '' );
|
||||
}
|
||||
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'redis_data' );
|
||||
\IPS\Output::i()->breadcrumb[] = array( \IPS\Http\Url::internal( 'app=core&module=support&controller=support' ), \IPS\Member::loggedIn()->language()->addToStack('support') );
|
||||
Dispatcher::i()->checkAcpPermission( 'redis_data' );
|
||||
Output::i()->breadcrumb[] = array( Url::internal( 'app=core&module=support&controller=support' ), Member::loggedIn()->language()->addToStack('support') );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
@@ -50,46 +67,46 @@ class _redis extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
protected function manage() : void
|
||||
{
|
||||
$redis = NULL;
|
||||
$info = NULL;
|
||||
$datasource = array();
|
||||
|
||||
if ( \IPS\CACHE_METHOD == 'Redis' or \IPS\STORE_METHOD == 'Redis' )
|
||||
if ( CACHE_METHOD == 'Redis' or STORE_METHOD == 'Redis' )
|
||||
{
|
||||
$info = \IPS\Redis::i()->info();
|
||||
$info = RedisClass::i()->info();
|
||||
|
||||
$data = array( 'type' => 'redis_datastore', 'count' => NULL, 'enabled' => false );
|
||||
|
||||
if ( \IPS\STORE_METHOD == 'Redis' )
|
||||
if ( STORE_METHOD == 'Redis' )
|
||||
{
|
||||
$data['enabled'] = true;
|
||||
|
||||
/* Lets ensure we have in the cache */
|
||||
$data['count'] = \count( \IPS\Redis::i()->debugGetKeys( \IPS\Redis::i()->get( 'redisKey_store' ) . '_str_*', TRUE ) );
|
||||
$data['count'] = count( RedisClass::i()->debugGetKeys( RedisClass::i()->get( 'redisKey_store' ) . '_str_*', TRUE ) );
|
||||
}
|
||||
|
||||
$datasource[] = $data;
|
||||
|
||||
$data = array( 'type' => 'redis_cache', 'count' => NULL, 'enabled' => false );
|
||||
|
||||
if ( \IPS\CACHE_METHOD == 'Redis' )
|
||||
if ( CACHE_METHOD == 'Redis' )
|
||||
{
|
||||
$data['enabled'] = true;
|
||||
|
||||
/* Lets ensure we have something */
|
||||
$data['count'] = \count( \IPS\Redis::i()->debugGetKeys( \IPS\Redis::i()->get( 'redisKey' ) . '_*', TRUE ) );
|
||||
$data['count'] = count( RedisClass::i()->debugGetKeys( RedisClass::i()->get( 'redisKey' ) . '_*', TRUE ) );
|
||||
}
|
||||
|
||||
$datasource[] = $data;
|
||||
|
||||
/* And now sessions */
|
||||
if ( \IPS\CACHE_METHOD == 'Redis' and \IPS\REDIS_ENABLED )
|
||||
if ( CACHE_METHOD == 'Redis' and REDIS_ENABLED )
|
||||
{
|
||||
$datasource[] = array( 'type' => 'redis_sessions', 'count' => \count( \IPS\Redis::i()->debugGetKeys( 'session_id_*', TRUE ) ), 'enabled' => true );
|
||||
$datasource[] = array( 'type' => 'redis_topic_views', 'count' => \IPS\Redis::i()->zCard('topic_views'), 'enabled' => true );
|
||||
$datasource[] = array( 'type' => 'redis_advert_impressions', 'count' => \IPS\Redis::i()->zCard('advert_impressions'), 'enabled' => true );
|
||||
$datasource[] = array( 'type' => 'redis_sessions', 'count' => count( RedisClass::i()->debugGetKeys( 'session_id_*', TRUE ) ), 'enabled' => true );
|
||||
$datasource[] = array( 'type' => 'redis_topic_views', 'count' => RedisClass::i()->zCard('topic_views'), 'enabled' => true );
|
||||
$datasource[] = array( 'type' => 'redis_advert_impressions', 'count' => RedisClass::i()->zCard('advert_impressions'), 'enabled' => true );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -102,35 +119,35 @@ class _redis extends \IPS\Dispatcher\Controller
|
||||
/* Not using redis then are we? */
|
||||
if ( $info === NULL )
|
||||
{
|
||||
\IPS\Output::i()->error( 'redis_not_enabled', '2C394/2', 403, '' );
|
||||
Output::i()->error( 'redis_not_enabled', '2C394/2', 403, '' );
|
||||
}
|
||||
|
||||
$table = new \IPS\Helpers\Table\Custom( $datasource, \IPS\Http\Url::internal( 'app=core&module=support&controller=redis' ) );
|
||||
$table = new Custom( $datasource, Url::internal( 'app=core&module=support&controller=redis' ) );
|
||||
$table->langPrefix = 'redis_table_';
|
||||
|
||||
/* Custom parsers */
|
||||
$table->parsers = array(
|
||||
'type' => function( $val, $row )
|
||||
'type' => function( $val )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( $val );
|
||||
return Member::loggedIn()->language()->addToStack( $val );
|
||||
},
|
||||
'count' => function( $val, $row )
|
||||
'count' => function( $val )
|
||||
{
|
||||
return \intval( $val );
|
||||
return intval( $val );
|
||||
},
|
||||
'enabled' => function( $val, $row )
|
||||
'enabled' => function( $val )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'support' )->redisEnabledBadge( $val );
|
||||
return Theme::i()->getTemplate( 'support' )->redisEnabledBadge( $val );
|
||||
}
|
||||
);
|
||||
|
||||
\IPS\Output::i()->sidebar['actions']['settings'] = array(
|
||||
Output::i()->sidebar['actions']['settings'] = array(
|
||||
'icon' => 'cog',
|
||||
'link' => \IPS\Http\Url::internal( '&app=core&module=settings&controller=advanced&tab=datastore' ),
|
||||
'link' => Url::internal( '&app=core&module=settings&controller=advanced&tab=datastore' ),
|
||||
'title' => 'redis_settings',
|
||||
);
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('redis_info');
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'support' )->redis( $info, $table );
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('redis_info');
|
||||
Output::i()->output = Theme::i()->getTemplate( 'support' )->redis( $info, $table );
|
||||
}
|
||||
}
|
||||
@@ -11,28 +11,32 @@
|
||||
namespace IPS\core\modules\admin\support;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Dispatcher\Controller;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* sql
|
||||
*/
|
||||
class _sql extends \IPS\Dispatcher\Controller
|
||||
class sql extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function manage()
|
||||
public function manage() : void
|
||||
{
|
||||
// Intentionally blank
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -11,30 +11,56 @@
|
||||
namespace IPS\core\modules\admin\support;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DirectoryIterator;
|
||||
use DomainException;
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Dispatcher\Controller;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\Interval;
|
||||
use IPS\Helpers\Table\Custom;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Log;
|
||||
use IPS\Member;
|
||||
use IPS\Output;
|
||||
use IPS\Request;
|
||||
use IPS\Session;
|
||||
use IPS\Settings;
|
||||
use IPS\Theme;
|
||||
use OutOfRangeException;
|
||||
use function defined;
|
||||
use const IPS\Helpers\Table\SEARCH_CONTAINS_TEXT;
|
||||
use const IPS\Helpers\Table\SEARCH_DATE_RANGE;
|
||||
use const IPS\Helpers\Table\SEARCH_MEMBER;
|
||||
use const IPS\Helpers\Table\SEARCH_SELECT;
|
||||
use const IPS\NO_WRITES;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Error Logs
|
||||
*/
|
||||
class _systemLogs extends \IPS\Dispatcher\Controller
|
||||
class systemLogs extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'system_logs_view' );
|
||||
Dispatcher::i()->checkAcpPermission( 'system_logs_view' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
@@ -43,27 +69,27 @@ class _systemLogs extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
protected function manage() : void
|
||||
{
|
||||
/* Button to settings */
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'support', 'diagnostic_log_settings' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'core', 'support', 'diagnostic_log_settings' ) )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['actions'] = array(
|
||||
Output::i()->sidebar['actions'] = array(
|
||||
'settings' => array(
|
||||
'title' => 'prunesettings',
|
||||
'icon' => 'cog',
|
||||
'link' => \IPS\Http\Url::internal( 'app=core&module=support&controller=systemLogs&do=logSettings' ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('prunesettings') )
|
||||
'link' => Url::internal( 'app=core&module=support&controller=systemLogs&do=logSettings' ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => Member::loggedIn()->language()->addToStack('prunesettings') )
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/* Button to view filebased logs */
|
||||
$dir = \IPS\Log::fallbackDir();
|
||||
if ( !\IPS\NO_WRITES and is_dir( $dir ) )
|
||||
$dir = Log::fallbackDir();
|
||||
if ( !NO_WRITES and is_dir( $dir ) )
|
||||
{
|
||||
$hasFiles = FALSE;
|
||||
$dir = new \DirectoryIterator( $dir );
|
||||
$dir = new DirectoryIterator( $dir );
|
||||
foreach ( $dir as $file )
|
||||
{
|
||||
if ( mb_substr( $file, 0, 1 ) !== '.' and $file != 'index.html' )
|
||||
@@ -75,17 +101,17 @@ class _systemLogs extends \IPS\Dispatcher\Controller
|
||||
|
||||
if ( $hasFiles )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['actions']['files'] = array(
|
||||
Output::i()->sidebar['actions']['files'] = array(
|
||||
'title' => 'log_view_file_logs',
|
||||
'icon' => 'search',
|
||||
'link' => \IPS\Http\Url::internal( 'app=core&module=support&controller=systemLogs&do=fileLogs' ),
|
||||
'link' => Url::internal( 'app=core&module=support&controller=systemLogs&do=fileLogs' ),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Create table */
|
||||
$table = new \IPS\Helpers\Table\Db( 'core_log', \IPS\Http\Url::internal( 'app=core&module=support&controller=systemLogs' ) );
|
||||
$table = new \IPS\Helpers\Table\Db( 'core_log', Url::internal( 'app=core&module=support&controller=systemLogs' ) );
|
||||
$table->langPrefix = 'log_';
|
||||
$table->include = array( 'time', 'category', 'message' );
|
||||
$table->parsers = array(
|
||||
@@ -100,48 +126,46 @@ class _systemLogs extends \IPS\Dispatcher\Controller
|
||||
$val = "{$row['exception_class']} ({$row['exception_code']})\n{$val}";
|
||||
}
|
||||
|
||||
$val = htmlspecialchars( $val, ENT_DISALLOWED, 'UTF-8', FALSE );
|
||||
|
||||
return $val;
|
||||
return htmlspecialchars( $val, ENT_DISALLOWED, 'UTF-8', FALSE );
|
||||
},
|
||||
'time' => function( $val )
|
||||
{
|
||||
return \IPS\DateTime::ts( $val );
|
||||
return DateTime::ts( $val );
|
||||
},
|
||||
'member_id' => function ( $val )
|
||||
{
|
||||
return htmlspecialchars( \IPS\Member::load( $val )->name, ENT_DISALLOWED, 'UTF-8', FALSE );
|
||||
return htmlspecialchars( Member::load( $val )->name, ENT_DISALLOWED, 'UTF-8', FALSE );
|
||||
}
|
||||
);
|
||||
$table->sortBy = $table->sortBy ?: 'time';
|
||||
$table->sortDirection = $table->sortDirection ?: 'desc';
|
||||
$table->quickSearch = 'message';
|
||||
$table->advancedSearch = array(
|
||||
'category' => array( \IPS\Helpers\Table\SEARCH_SELECT, array( 'options' => iterator_to_array( \IPS\Db::i()->select( 'DISTINCT(category) AS cat', 'core_log' )->setKeyField( 'cat' )->setValueField( 'cat' ) ), 'multiple' => TRUE, 'parse' => 'normal' ) ),
|
||||
'message' => \IPS\Helpers\Table\SEARCH_CONTAINS_TEXT,
|
||||
'time' => \IPS\Helpers\Table\SEARCH_DATE_RANGE,
|
||||
'member_id' => \IPS\Helpers\Table\SEARCH_MEMBER,
|
||||
'url' => \IPS\Helpers\Table\SEARCH_CONTAINS_TEXT
|
||||
'category' => array( SEARCH_SELECT, array( 'options' => iterator_to_array( Db::i()->select( 'DISTINCT(category) AS cat', 'core_log' )->setKeyField( 'cat' )->setValueField( 'cat' ) ), 'multiple' => TRUE, 'parse' => 'normal' ) ),
|
||||
'message' => SEARCH_CONTAINS_TEXT,
|
||||
'time' => SEARCH_DATE_RANGE,
|
||||
'member_id' => SEARCH_MEMBER,
|
||||
'url' => SEARCH_CONTAINS_TEXT
|
||||
);
|
||||
$table->rowButtons = function( $row ) {
|
||||
return array(
|
||||
'view' => array(
|
||||
'title' => 'view',
|
||||
'icon' => 'search',
|
||||
'link' => \IPS\Http\Url::internal( 'app=core&module=support&controller=systemLogs&do=view' )->setQueryString( 'id', $row['id'] )
|
||||
'link' => Url::internal( 'app=core&module=support&controller=systemLogs&do=view' )->setQueryString( 'id', $row['id'] )
|
||||
),
|
||||
'delete' => array(
|
||||
'title' => 'delete',
|
||||
'icon' => 'times-circle',
|
||||
'link' => \IPS\Http\Url::internal( 'app=core&module=support&controller=systemLogs&do=delete' )->setQueryString( 'id', $row['id'] )->csrf(),
|
||||
'link' => Url::internal( 'app=core&module=support&controller=systemLogs&do=delete' )->setQueryString( 'id', $row['id'] )->csrf(),
|
||||
'data' => array( 'delete' => '' )
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
/* Display */
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('r__system_logs');
|
||||
\IPS\Output::i()->output = $table;
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('r__system_logs');
|
||||
Output::i()->output = $table;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -149,43 +173,30 @@ class _systemLogs extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function view()
|
||||
protected function view() : void
|
||||
{
|
||||
/* Load */
|
||||
try
|
||||
{
|
||||
$log = \IPS\Log::load( \IPS\Request::i()->id );
|
||||
$log = Log::load( Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2C324/1', 404, '' );
|
||||
Output::i()->error( 'node_error', '2C324/1', 404, '' );
|
||||
}
|
||||
|
||||
/* Delete button */
|
||||
\IPS\Output::i()->sidebar['actions']['delete'] = array(
|
||||
Output::i()->sidebar['actions']['delete'] = array(
|
||||
'icon' => 'times-circle',
|
||||
'link' => \IPS\Http\Url::internal( 'app=core&module=support&controller=systemLogs&do=delete' )->setQueryString( 'id', $log->id )->csrf(),
|
||||
'link' => Url::internal( 'app=core&module=support&controller=systemLogs&do=delete' )->setQueryString( 'id', $log->id )->csrf(),
|
||||
'title' => 'delete',
|
||||
'data' => array( 'confirm' => '' )
|
||||
);
|
||||
|
||||
/* Display */
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('r__system_logs');
|
||||
\IPS\Output::i()->breadcrumb[] = array( \IPS\Http\Url::internal( "app=core&module=support&controller=systemLogs" ), \IPS\Member::loggedIn()->language()->addToStack('r__system_logs') );
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->systemLogView( $log );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all logs
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function deleteAll()
|
||||
{
|
||||
/* Delete */
|
||||
\IPS\Db::i()->query( "TRUNCATE " . \IPS\Settings::i()->sql_tbl_prefix . "core_log" );
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=support&controller=systemLogs' ), 'deleted' );
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('r__system_logs');
|
||||
Output::i()->breadcrumb[] = array( Url::internal( "app=core&module=support&controller=systemLogs" ), Member::loggedIn()->language()->addToStack('r__system_logs') );
|
||||
Output::i()->output = Theme::i()->getTemplate( 'system' )->systemLogView( $log );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -193,20 +204,20 @@ class _systemLogs extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function delete()
|
||||
protected function delete() : void
|
||||
{
|
||||
/* Load */
|
||||
try
|
||||
{
|
||||
$log = \IPS\Log::load( \IPS\Request::i()->id );
|
||||
$log = Log::load( Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2C324/2', 404, '' );
|
||||
Output::i()->error( 'node_error', '2C324/2', 404, '' );
|
||||
}
|
||||
|
||||
/* Make sure the user confirmed the deletion */
|
||||
\IPS\Request::i()->confirmedDelete();
|
||||
Request::i()->confirmedDelete();
|
||||
|
||||
/* Delete */
|
||||
$log->delete();
|
||||
@@ -214,13 +225,13 @@ class _systemLogs extends \IPS\Dispatcher\Controller
|
||||
/* Log and redirect */
|
||||
if ( $log->category )
|
||||
{
|
||||
\IPS\Session::i()->log( 'acplog__log_delete', array( $log->category => FALSE, ( (string) \IPS\DateTime::ts( $log->time ) ) => FALSE ) );
|
||||
Session::i()->log( 'acplog__log_delete', array( $log->category => FALSE, ( (string) DateTime::ts( $log->time ) ) => FALSE ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Session::i()->log( 'acplog__log_delete_uncategoried', array( ( (string) \IPS\DateTime::ts( $log->time ) ) => FALSE ) );
|
||||
Session::i()->log( 'acplog__log_delete_uncategoried', array( ( (string) DateTime::ts( $log->time ) ) => FALSE ) );
|
||||
}
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=support&controller=systemLogs' ), 'deleted' );
|
||||
Output::i()->redirect( Url::internal( 'app=core&module=support&controller=systemLogs' ), 'deleted' );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -228,20 +239,20 @@ class _systemLogs extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function fileLogs()
|
||||
protected function fileLogs() : void
|
||||
{
|
||||
/* NO_WRITES check */
|
||||
if ( \IPS\NO_WRITES )
|
||||
if ( NO_WRITES )
|
||||
{
|
||||
\IPS\Output::i()->error( 'no_writes', '1C324/8', 403, '' );
|
||||
Output::i()->error( 'no_writes', '1C324/8', 403, '' );
|
||||
}
|
||||
|
||||
/* Get list of files */
|
||||
$dir = \IPS\Log::fallbackDir();
|
||||
$dir = Log::fallbackDir();
|
||||
$source = array();
|
||||
if ( is_dir( $dir ) )
|
||||
{
|
||||
$directoryIterator = new \DirectoryIterator( $dir );
|
||||
$directoryIterator = new DirectoryIterator( $dir );
|
||||
foreach ( $directoryIterator as $file )
|
||||
{
|
||||
if ( mb_substr( $file, 0, 1 ) !== '.' and $file != 'index.html' )
|
||||
@@ -252,12 +263,12 @@ class _systemLogs extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
|
||||
/* Create table */
|
||||
$table = new \IPS\Helpers\Table\Custom( $source, \IPS\Http\Url::internal( 'app=core&module=support&controller=systemLogs&do=fileLogs' ) );
|
||||
$table = new Custom( $source, Url::internal( 'app=core&module=support&controller=systemLogs&do=fileLogs' ) );
|
||||
$table->langPrefix = 'log_';
|
||||
$table->parsers = array(
|
||||
'time' => function( $val )
|
||||
{
|
||||
return \IPS\DateTime::ts( $val );
|
||||
return DateTime::ts( $val );
|
||||
}
|
||||
);
|
||||
$table->sortBy = $table->sortBy ?: 'time';
|
||||
@@ -267,22 +278,22 @@ class _systemLogs extends \IPS\Dispatcher\Controller
|
||||
'view' => array(
|
||||
'title' => 'view',
|
||||
'icon' => 'search',
|
||||
'link' => \IPS\Http\Url::internal( 'app=core&module=support&controller=systemLogs&do=viewFile' )->setQueryString( 'file', $row['file'] )
|
||||
'link' => Url::internal( 'app=core&module=support&controller=systemLogs&do=viewFile' )->setQueryString( 'file', $row['file'] )
|
||||
),
|
||||
'delete' => array(
|
||||
'title' => 'delete',
|
||||
'icon' => 'times-circle',
|
||||
'link' => \IPS\Http\Url::internal( 'app=core&module=support&controller=systemLogs&do=deleteFile' )->setQueryString( 'file', $row['file'] )->csrf(),
|
||||
'link' => Url::internal( 'app=core&module=support&controller=systemLogs&do=deleteFile' )->setQueryString( 'file', $row['file'] )->csrf(),
|
||||
'data' => array( 'delete' => '' )
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
/* Display */
|
||||
\IPS\Output::i()->breadcrumb[] = array( \IPS\Http\Url::internal( "app=core&module=support&controller=systemLogs" ), \IPS\Member::loggedIn()->language()->addToStack('r__system_logs') );
|
||||
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack('file_logs') );
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('file_logs');
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'forms' )->blurb( \IPS\Member::loggedIn()->language()->addToStack('log_view_file_logs_info', FALSE, array( 'sprintf' => $dir ) ) ) . $table;
|
||||
Output::i()->breadcrumb[] = array( Url::internal( "app=core&module=support&controller=systemLogs" ), Member::loggedIn()->language()->addToStack('r__system_logs') );
|
||||
Output::i()->breadcrumb[] = array( NULL, Member::loggedIn()->language()->addToStack('file_logs') );
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('file_logs');
|
||||
Output::i()->output = Theme::i()->getTemplate( 'forms' )->blurb( Member::loggedIn()->language()->addToStack('log_view_file_logs_info', FALSE, array( 'sprintf' => $dir ) ) ) . $table;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -290,34 +301,34 @@ class _systemLogs extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function viewFile()
|
||||
protected function viewFile() : void
|
||||
{
|
||||
/* NO_WRITES check */
|
||||
if ( \IPS\NO_WRITES )
|
||||
if ( NO_WRITES )
|
||||
{
|
||||
\IPS\Output::i()->error( 'no_writes', '1C324/3', 403, '' );
|
||||
Output::i()->error( 'no_writes', '1C324/3', 403, '' );
|
||||
}
|
||||
|
||||
/* Try to find it */
|
||||
$file = \IPS\Log::fallbackDir() . DIRECTORY_SEPARATOR . preg_replace( '/[^a-z_0-9\.]/i', '', \IPS\Request::i()->file );
|
||||
$file = Log::fallbackDir() . DIRECTORY_SEPARATOR . preg_replace( '/[^a-z_0-9\.]/i', '', Request::i()->file );
|
||||
if ( !is_file( $file ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2C324/5', 404, '' );
|
||||
Output::i()->error( 'node_error', '2C324/5', 404, '' );
|
||||
}
|
||||
|
||||
/* Delete button */
|
||||
\IPS\Output::i()->sidebar['actions']['delete'] = array(
|
||||
Output::i()->sidebar['actions']['delete'] = array(
|
||||
'icon' => 'times-circle',
|
||||
'link' => \IPS\Http\Url::internal( 'app=core&module=support&controller=systemLogs&do=deleteFile' )->setQueryString( 'file', \IPS\Request::i()->file )->csrf(),
|
||||
'link' => Url::internal( 'app=core&module=support&controller=systemLogs&do=deleteFile' )->setQueryString( 'file', Request::i()->file )->csrf(),
|
||||
'title' => 'delete',
|
||||
'data' => array( 'confirm' => '' )
|
||||
);
|
||||
|
||||
/* Display */
|
||||
\IPS\Output::i()->title = basename( $file );
|
||||
\IPS\Output::i()->breadcrumb[] = array( \IPS\Http\Url::internal( "app=core&module=support&controller=systemLogs" ), \IPS\Member::loggedIn()->language()->addToStack('r__system_logs') );
|
||||
\IPS\Output::i()->breadcrumb[] = array( \IPS\Http\Url::internal( "app=core&module=support&controller=systemLogs&do=fileLogs" ), \IPS\Member::loggedIn()->language()->addToStack('log_view_file_logs') );
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->systemLogFileView( file_get_contents( $file ) );
|
||||
Output::i()->title = basename( $file );
|
||||
Output::i()->breadcrumb[] = array( Url::internal( "app=core&module=support&controller=systemLogs" ), Member::loggedIn()->language()->addToStack('r__system_logs') );
|
||||
Output::i()->breadcrumb[] = array( Url::internal( "app=core&module=support&controller=systemLogs&do=fileLogs" ), Member::loggedIn()->language()->addToStack('log_view_file_logs') );
|
||||
Output::i()->output = Theme::i()->getTemplate( 'system' )->systemLogFileView( file_get_contents( $file ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -325,32 +336,32 @@ class _systemLogs extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function deleteFile()
|
||||
protected function deleteFile() : void
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
Session::i()->csrfCheck();
|
||||
|
||||
/* NO_WRITES check */
|
||||
if ( \IPS\NO_WRITES )
|
||||
if ( NO_WRITES )
|
||||
{
|
||||
\IPS\Output::i()->error( 'no_writes', '1C324/4', 403, '' );
|
||||
Output::i()->error( 'no_writes', '1C324/4', 403, '' );
|
||||
}
|
||||
|
||||
/* Try to find it */
|
||||
$file = \IPS\Log::fallbackDir() . DIRECTORY_SEPARATOR . preg_replace( '/[^a-z_0-9\.]/i', '', \IPS\Request::i()->file );
|
||||
$file = Log::fallbackDir() . DIRECTORY_SEPARATOR . preg_replace( '/[^a-z_0-9\.]/i', '', Request::i()->file );
|
||||
if ( !is_file( $file ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2C324/6', 404, '' );
|
||||
Output::i()->error( 'node_error', '2C324/6', 404, '' );
|
||||
}
|
||||
|
||||
/* Delete it */
|
||||
if ( !@unlink( $file ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'log_file_could_not_delete', '1C324/7', 403, '' );
|
||||
Output::i()->error( 'log_file_could_not_delete', '1C324/7', 403, '' );
|
||||
}
|
||||
|
||||
/* Log and redirect */
|
||||
\IPS\Session::i()->log( 'acplog__log_delete_file', array( basename( $file ) => FALSE ) );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=support&controller=systemLogs&do=fileLogs' ), 'deleted' );
|
||||
Session::i()->log( 'acplog__log_delete_file', array( basename( $file ) => FALSE ) );
|
||||
Output::i()->redirect( Url::internal( 'app=core&module=support&controller=systemLogs&do=fileLogs' ), 'deleted' );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -358,26 +369,26 @@ class _systemLogs extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function logSettings()
|
||||
protected function logSettings() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'diagnostic_log_settings' );
|
||||
Dispatcher::i()->checkAcpPermission( 'diagnostic_log_settings' );
|
||||
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->add( new \IPS\Helpers\Form\Interval( 'prune_log_system', \IPS\Settings::i()->prune_log_system, FALSE, array( 'valueAs' => \IPS\Helpers\Form\Interval::DAYS, 'unlimited' => 0, 'unlimitedLang' => 'never' ), function( $val ) {
|
||||
$form = new Form;
|
||||
$form->add( new Interval( 'prune_log_system', Settings::i()->prune_log_system, FALSE, array( 'valueAs' => Interval::DAYS, 'unlimited' => 0, 'unlimitedLang' => 'never' ), function( $val ) {
|
||||
if( $val > 0 AND $val < 7 )
|
||||
{
|
||||
throw new \DomainException( \IPS\Member::loggedIn()->language()->addToStack( 'form_interval_min_d', FALSE, array( 'pluralize' => array( 6 ) ) ) );
|
||||
throw new DomainException( Member::loggedIn()->language()->addToStack( 'form_interval_min_d', FALSE, array( 'pluralize' => array( 6 ) ) ) );
|
||||
}
|
||||
}, \IPS\Member::loggedIn()->language()->addToStack('after'), NULL, 'prune_log_moderator' ) );
|
||||
}, Member::loggedIn()->language()->addToStack('after'), NULL, 'prune_log_moderator' ) );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
$form->saveAsSettings();
|
||||
\IPS\Session::i()->log( 'acplog__systemlog_settings' );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=support&controller=systemLogs' ), 'saved' );
|
||||
Session::i()->log( 'acplog__systemlog_settings' );
|
||||
Output::i()->redirect( Url::internal( 'app=core&module=support&controller=systemLogs' ), 'saved' );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('systemlogssettings');
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('global')->block( 'systemlogssettings', $form, FALSE );
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('systemlogssettings');
|
||||
Output::i()->output = Theme::i()->getTemplate('global')->block( 'systemlogssettings', $form, FALSE );
|
||||
}
|
||||
}
|
||||
@@ -11,64 +11,90 @@
|
||||
namespace IPS\core\modules\admin\support;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use Exception;
|
||||
use IPS\Application;
|
||||
use IPS\Content\Search\Index;
|
||||
use IPS\Db;
|
||||
use IPS\Db\Select;
|
||||
use IPS\Dispatcher\Controller;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\MultipleRedirect;
|
||||
use IPS\Helpers\Wizard;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Log;
|
||||
use IPS\Member;
|
||||
use IPS\Output;
|
||||
use IPS\Request;
|
||||
use IPS\Session;
|
||||
use IPS\Settings;
|
||||
use IPS\Theme;
|
||||
use function count;
|
||||
use function defined;
|
||||
use function in_array;
|
||||
use function is_array;
|
||||
use function mb_strtolower;
|
||||
use function strtoupper;
|
||||
use const IPS\CIC;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* utf8mb4 Converter
|
||||
*/
|
||||
class _utf8mb4 extends \IPS\Dispatcher\Controller
|
||||
class utf8mb4 extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Bootstrap
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
protected function manage() : void
|
||||
{
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('utf8mb4_converter');
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('utf8mb4_converter');
|
||||
|
||||
/* Check it isn't utf8mb4 already */
|
||||
if ( \IPS\Settings::i()->getFromConfGlobal('sql_utf8mb4') === TRUE)
|
||||
if ( Settings::i()->getFromConfGlobal('sql_utf8mb4') === TRUE)
|
||||
{
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('global', 'core')->message( 'utf8mb4_converter_finished', 'success' );
|
||||
Output::i()->output = Theme::i()->getTemplate('global', 'core')->message( 'utf8mb4_converter_finished', 'success' );
|
||||
return;
|
||||
}
|
||||
|
||||
/* Requires MySQL 5.5.3 */
|
||||
if ( !\IPS\CIC AND version_compare( \IPS\Db::i()->server_info, '5.5.3', '<' ) )
|
||||
if ( !CIC AND version_compare( Db::i()->server_info, '5.5.3', '<' ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'utf8mb4_converter_requires_553', '1C325/1', 403, '' );
|
||||
Output::i()->error( 'utf8mb4_converter_requires_553', '1C325/1', 403, '' );
|
||||
}
|
||||
|
||||
/* Display Wizard */
|
||||
$supportController = new support;
|
||||
\IPS\Output::i()->output = (string) new \IPS\Helpers\Wizard( array(
|
||||
Output::i()->output = (string) new Wizard( array(
|
||||
'utf8mb4_converter_intro' => array( $this, '_introduction' ),
|
||||
'utf8mb4_converter_convert' => array( $this, '_convert' ),
|
||||
'utf8mb4_converter_finish' => array( $this, '_finish' ),
|
||||
), \IPS\Http\Url::internal( 'app=core&module=support&controller=utf8mb4' )->csrf() );
|
||||
), Url::internal( 'app=core&module=support&controller=utf8mb4' )->csrf() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Introduction
|
||||
*
|
||||
* @param mixed $data Wizard Data
|
||||
* @return mixed
|
||||
* @param array $data Wizard Data
|
||||
* @return array|string
|
||||
*/
|
||||
public function _introduction( $data )
|
||||
public function _introduction( array $data ) : array|string
|
||||
{
|
||||
$form = new \IPS\Helpers\Form( 'utf8mb4_converter_intro', 'continue' );
|
||||
$form = new Form( 'utf8mb4_converter_intro', 'continue' );
|
||||
$form->hiddenValues['continue'] = 1;
|
||||
$form->addMessage( \IPS\CIC ? 'utf8mb4_converter_cic_explain' : 'utf8mb4_converter_explain' );
|
||||
$form->addMessage( CIC ? 'utf8mb4_converter_cic_explain' : 'utf8mb4_converter_explain' );
|
||||
|
||||
if ( $form->values() )
|
||||
{
|
||||
@@ -81,50 +107,50 @@ class _utf8mb4 extends \IPS\Dispatcher\Controller
|
||||
/**
|
||||
* Convert
|
||||
*
|
||||
* @param mixed $wizardData Wizard Data
|
||||
* @return mixed
|
||||
* @param array $wizardData Wizard Data
|
||||
* @return array|string
|
||||
*/
|
||||
public function _convert( $wizardData )
|
||||
public function _convert( array $wizardData ) : array|string
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
Session::i()->csrfCheck();
|
||||
|
||||
if ( isset( \IPS\Request::i()->finished ) )
|
||||
if ( isset( Request::i()->finished ) )
|
||||
{
|
||||
return $wizardData;
|
||||
}
|
||||
|
||||
$baseUrl = \IPS\Http\Url::internal( 'app=core&module=support&controller=utf8mb4' )->csrf();
|
||||
$baseUrl = Url::internal( 'app=core&module=support&controller=utf8mb4' )->csrf();
|
||||
|
||||
return new \IPS\Helpers\MultipleRedirect( $baseUrl,
|
||||
return new MultipleRedirect( $baseUrl,
|
||||
function( $mrData )
|
||||
{
|
||||
try
|
||||
{
|
||||
/* If this is the first run, do the database itself... */
|
||||
if ( !\is_array( $mrData ) )
|
||||
if ( !is_array( $mrData ) )
|
||||
{
|
||||
$databaseName = \IPS\Settings::i()->sql_database;
|
||||
\IPS\Db::i()->query("ALTER DATABASE `{$databaseName}` CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;");
|
||||
$databaseName = Settings::i()->sql_database;
|
||||
Db::i()->query("ALTER DATABASE `{$databaseName}` CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;");
|
||||
|
||||
return array( array( 'done' => array() ), \IPS\Member::loggedIn()->language()->addToStack('utf8mb4_converter_converting'), 0 );
|
||||
return array( array( 'done' => array() ), Member::loggedIn()->language()->addToStack('utf8mb4_converter_converting'), 0 );
|
||||
}
|
||||
|
||||
/* Set properties */
|
||||
\IPS\Db::i()->charset = 'utf8mb4';
|
||||
\IPS\Db::i()->collation = 'utf8mb4_unicode_ci';
|
||||
\IPS\Db::i()->binaryCollation = 'utf8mb4_bin';
|
||||
Db::i()->charset = 'utf8mb4';
|
||||
Db::i()->collation = 'utf8mb4_unicode_ci';
|
||||
Db::i()->binaryCollation = 'utf8mb4_bin';
|
||||
|
||||
/* Do each table */
|
||||
$select = \IPS\Settings::i()->sql_tbl_prefix ? ( new \IPS\Db\Select( "SHOW TABLES LIKE '" . \IPS\Db::i()->escape_string( \IPS\Settings::i()->sql_tbl_prefix ) . "%'", array(), \IPS\Db::i() ) ) : ( new \IPS\Db\Select( "SHOW TABLES", array(), \IPS\Db::i() ) );
|
||||
$totalCount = \count( $select );
|
||||
$select = Settings::i()->sql_tbl_prefix ? ( new Select( "SHOW TABLES LIKE '" . Db::i()->escape_string( Settings::i()->sql_tbl_prefix ) . "%'", array(), Db::i() ) ) : ( new Select( "SHOW TABLES", array(), Db::i() ) );
|
||||
$totalCount = count( $select );
|
||||
$i = 0;
|
||||
foreach ( $select as $table )
|
||||
{
|
||||
$i++;
|
||||
$table = mb_substr( $table, mb_strlen( \IPS\Settings::i()->sql_tbl_prefix ) );
|
||||
$table = mb_substr( $table, mb_strlen( Settings::i()->sql_tbl_prefix ) );
|
||||
|
||||
/* If we've already done it, skip to next */
|
||||
if ( \in_array( $table, $mrData['done'] ) )
|
||||
if ( in_array( $table, $mrData['done'] ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -133,8 +159,8 @@ class _utf8mb4 extends \IPS\Dispatcher\Controller
|
||||
$appName = mb_substr( $table, 0, mb_strpos( $table, '_' ) );
|
||||
try
|
||||
{
|
||||
$app = \IPS\Application::load( $appName );
|
||||
$schemaRoot = \in_array( $app->directory, \IPS\IPS::$ipsApps ) ? \IPS\ROOT_PATH : \IPS\SITE_FILES_PATH;
|
||||
$app = Application::load( $appName );
|
||||
$schemaRoot = in_array( $app->directory, \IPS\IPS::$ipsApps ) ? \IPS\ROOT_PATH : \IPS\SITE_FILES_PATH;
|
||||
$schema = json_decode( file_get_contents( $schemaRoot . "/applications/{$app->directory}/data/schema.json" ), TRUE );
|
||||
if ( !array_key_exists( $table, $schema ) )
|
||||
{
|
||||
@@ -145,7 +171,7 @@ class _utf8mb4 extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
}
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
catch ( Exception $e )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -154,15 +180,15 @@ class _utf8mb4 extends \IPS\Dispatcher\Controller
|
||||
table because it is large and it has a primary key and a unique index, so the table work is too intensive. */
|
||||
if( $table == 'core_search_index' )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_search_index' );
|
||||
Db::i()->delete( 'core_search_index' );
|
||||
}
|
||||
|
||||
/* Get table definition */
|
||||
$tableDefinition = \IPS\Db::i()->getTableDefinition( $table, FALSE, TRUE );
|
||||
$tableDefinition = Db::i()->getTableDefinition( $table, FALSE, TRUE );
|
||||
|
||||
/* Drop any potentially problematic indexes */
|
||||
$indexesToRecreate = array();
|
||||
$maxLen = \mb_strtolower( $tableDefinition['engine'] ) === 'innodb' ? 767 : 1000;
|
||||
$maxLen = mb_strtolower( $tableDefinition['engine'] ) === 'innodb' ? 767 : 1000;
|
||||
foreach ( $tableDefinition['indexes'] as $indexName => $indexData )
|
||||
{
|
||||
/* If this is a fulltext index, we don't need to drop it and recreate it */
|
||||
@@ -178,13 +204,13 @@ class _utf8mb4 extends \IPS\Dispatcher\Controller
|
||||
$hasText = false;
|
||||
foreach( $indexData['columns'] as $column )
|
||||
{
|
||||
if ( \in_array( mb_strtolower( $tableDefinition['columns'][ $column ]['type'] ), array( 'mediumtext', 'text' ) ) )
|
||||
if ( in_array( mb_strtolower( $tableDefinition['columns'][ $column ]['type'] ), array( 'mediumtext', 'text' ) ) )
|
||||
{
|
||||
$hasText = true;
|
||||
}
|
||||
if ( isset( $tableDefinition['columns'][ $column ]['length'] ) )
|
||||
{
|
||||
$length += $tableDefinition['columns'][ $column ]['length'];
|
||||
$length += (int) ( $tableDefinition['columns'][ $column ]['length'] );
|
||||
}
|
||||
|
||||
if( isset( $tableDefinition['columns'][ $column ]['collation'] ) AND $tableDefinition['columns'][ $column ]['collation'] !== 'utf8mb4_unicode_ci' )
|
||||
@@ -196,7 +222,7 @@ class _utf8mb4 extends \IPS\Dispatcher\Controller
|
||||
if ( $needToRecreate AND ( ( $length * 4 > $maxLen ) or $hasText ) )
|
||||
{
|
||||
$indexesToRecreate[ $indexName ] = $indexData;
|
||||
\IPS\Db::i()->dropIndex( $table, $indexName );
|
||||
Db::i()->dropIndex( $table, $indexName );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,8 +231,8 @@ class _utf8mb4 extends \IPS\Dispatcher\Controller
|
||||
|
||||
if( $tableDefinition['collation'] !== 'utf8mb4_unicode_ci' )
|
||||
{
|
||||
\IPS\Db::i()->query("ALTER TABLE `" . \IPS\Settings::i()->sql_tbl_prefix . "{$table}` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci");
|
||||
\IPS\Db::i()->query("ALTER TABLE `" . \IPS\Settings::i()->sql_tbl_prefix . "{$table}` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci");
|
||||
Db::i()->query("ALTER TABLE `" . Settings::i()->sql_tbl_prefix . "{$table}` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci");
|
||||
Db::i()->query("ALTER TABLE `" . Settings::i()->sql_tbl_prefix . "{$table}` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci");
|
||||
$repair = true;
|
||||
}
|
||||
|
||||
@@ -216,11 +242,11 @@ class _utf8mb4 extends \IPS\Dispatcher\Controller
|
||||
/* Do each column */
|
||||
foreach ( $tableDefinition['columns'] as $columnName => $columnData )
|
||||
{
|
||||
if( \in_array( \strtoupper( $columnData['type'] ), array( 'CHAR', 'VARCHAR', 'TINYTEXT', 'TEXT', 'MEDIUMTEXT', 'LONGTEXT', 'ENUM', 'SET' ) ) )
|
||||
if( in_array( strtoupper( $columnData['type'] ), array( 'CHAR', 'VARCHAR', 'TINYTEXT', 'TEXT', 'MEDIUMTEXT', 'LONGTEXT', 'ENUM', 'SET' ) ) )
|
||||
{
|
||||
if( $tableDefinition['columns'][ $columnName ]['collation'] !== 'utf8mb4_unicode_ci' )
|
||||
{
|
||||
$aggregatedChanges[] = "CHANGE COLUMN `" . \IPS\Db::i()->escape_string( $columnName ) . "` " . \IPS\Db::i()->compileColumnDefinition( $columnData );
|
||||
$aggregatedChanges[] = "CHANGE COLUMN `" . Db::i()->escape_string( $columnName ) . "` " . Db::i()->compileColumnDefinition( $columnData );
|
||||
$repair = true;
|
||||
}
|
||||
}
|
||||
@@ -229,47 +255,47 @@ class _utf8mb4 extends \IPS\Dispatcher\Controller
|
||||
/* Recreate any indexes */
|
||||
foreach ( $indexesToRecreate as $indexName => $indexData )
|
||||
{
|
||||
$aggregatedChanges[] = \IPS\Db::i()->buildIndex( $table, $indexData );
|
||||
$aggregatedChanges[] = Db::i()->buildIndex( $table, $indexData );
|
||||
$repair = true;
|
||||
}
|
||||
|
||||
/* Now if we have any changes to make....make them */
|
||||
if( \count( $aggregatedChanges ) )
|
||||
if( count( $aggregatedChanges ) )
|
||||
{
|
||||
\IPS\Db::i()->query( "ALTER TABLE " . \IPS\Db::i()->prefix . \IPS\Db::i()->escape_string( $table ) . " " . implode( ', ', $aggregatedChanges ) );
|
||||
Db::i()->query( "ALTER TABLE " . Db::i()->prefix . Db::i()->escape_string( $table ) . " " . implode( ', ', $aggregatedChanges ) );
|
||||
}
|
||||
|
||||
/* Repair and optimize */
|
||||
if( $repair === true )
|
||||
{
|
||||
\IPS\Db::i()->query("REPAIR TABLE `" . \IPS\Settings::i()->sql_tbl_prefix . "{$table}`");
|
||||
Db::i()->query("REPAIR TABLE `" . Settings::i()->sql_tbl_prefix . "{$table}`");
|
||||
//\IPS\Db::i()->query("OPTIMIZE TABLE `" . \IPS\Settings::i()->sql_tbl_prefix . "{$table}`");
|
||||
}
|
||||
|
||||
/* If this is the search index table, initiate rebuild now. */
|
||||
if( $table == 'core_search_index' and \IPS\Settings::i()->search_method == 'mysql' )
|
||||
if( $table == 'core_search_index' and Settings::i()->search_method == 'mysql' )
|
||||
{
|
||||
\IPS\Content\Search\Index::i()->rebuild();
|
||||
Index::i()->rebuild();
|
||||
}
|
||||
|
||||
/* Continue */
|
||||
$mrData['done'][] = $table;
|
||||
return array( $mrData, \IPS\Member::loggedIn()->language()->addToStack('utf8mb4_converter_converting'), floor( 100 / $totalCount * $i ) );
|
||||
return array( $mrData, Member::loggedIn()->language()->addToStack('utf8mb4_converter_converting'), floor( 100 / $totalCount * $i ) );
|
||||
}
|
||||
|
||||
/* If we get to this point, we're finished */
|
||||
return NULL;
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
catch ( Exception $e )
|
||||
{
|
||||
\IPS\Log::log( $e, 'utf8mb4' );
|
||||
\IPS\Output::i()->error( \IPS\Member::loggedIn()->language()->addToStack( 'utf8mb4_converter_error', FALSE, array( 'sprintf' => array( $e->getMessage() ) ) ), '4C171/4', 403, '' );
|
||||
Log::log( $e, 'utf8mb4' );
|
||||
Output::i()->error( Member::loggedIn()->language()->addToStack( 'utf8mb4_converter_error', FALSE, array( 'sprintf' => array( $e->getMessage() ) ) ), '4C171/4', 403, '' );
|
||||
}
|
||||
|
||||
},
|
||||
function() use ( $baseUrl )
|
||||
{
|
||||
\IPS\Output::i()->redirect( $baseUrl->setQueryString( 'finished', 1 ) );
|
||||
Output::i()->redirect( $baseUrl->setQueryString( 'finished', 1 ) );
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -277,13 +303,13 @@ class _utf8mb4 extends \IPS\Dispatcher\Controller
|
||||
/**
|
||||
* Finish
|
||||
*
|
||||
* @param mixed $data Wizard Data
|
||||
* @return mixed
|
||||
* @param array $data Wizard Data
|
||||
* @return array|string
|
||||
*/
|
||||
public function _finish( $data )
|
||||
public function _finish( array $data ) : array|string
|
||||
{
|
||||
\IPS\Session::i()->log( 'acplog__ran_utf8mb4_converter' );
|
||||
Session::i()->log( 'acplog__ran_utf8mb4_converter' );
|
||||
|
||||
return \IPS\Theme::i()->getTemplate('support')->finishUtf8Mb4Conversion();
|
||||
return Theme::i()->getTemplate('support')->finishUtf8Mb4Conversion();
|
||||
}
|
||||
}
|
||||
@@ -1,215 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief v5
|
||||
* @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 19 Sep 2024
|
||||
*/
|
||||
|
||||
namespace IPS\core\modules\admin\support;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
|
||||
use IPS\Application;
|
||||
use IPS\Db;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Login;
|
||||
use IPS\Member;
|
||||
use IPS\Output;
|
||||
use IPS\Settings;
|
||||
use IPS\Theme;
|
||||
use function count;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* v5
|
||||
*/
|
||||
class _v5 extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
public static bool $csrfProtected = true;
|
||||
|
||||
/**
|
||||
* ...
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
{
|
||||
$actions = $this->v5Actions();
|
||||
|
||||
Output::i()->cssFiles = array_merge( Output::i()->cssFiles, Theme::i()->css( 'support/dashboard.css', 'core', 'admin' ) );
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack( 'prepare_v5_title' );
|
||||
Output::i()->output = Theme::i()->getTemplate( 'support' )->v5( ...$actions );
|
||||
}
|
||||
|
||||
public function v5actions()
|
||||
{
|
||||
if( \IPS\CIC )
|
||||
{
|
||||
$phpCheck = true;
|
||||
$mySqlCheck = true;
|
||||
$innoDb = true;
|
||||
$elasticsearch = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check PHP */
|
||||
$phpCheck = ( version_compare( PHP_VERSION, "8.1.0" ) >= 0 );
|
||||
|
||||
/* Check MySQL */
|
||||
$mySqlVersion = Db::i()->server_info;
|
||||
$mySqlCheck = ( version_compare( $mySqlVersion, "8.0.13" ) >=0 );
|
||||
|
||||
/* Check InnoDb */
|
||||
$innoDb = !count( iterator_to_array( Db::i()->query( "SHOW TABLE STATUS WHERE Engine!='InnoDB'" ) ) );
|
||||
|
||||
/* Are we using elasticsearch */
|
||||
$elasticsearch = ( \IPS\Settings::i()->search_method == 'elastic' AND \IPS\Settings::i()->search_elastic_server );
|
||||
}
|
||||
|
||||
Output::i()->sidebar['actions']['deprecations'] = array(
|
||||
'icon' => 'question-circle',
|
||||
'title' => 'deprecation_tracker',
|
||||
'link' => Url::ips( 'docs/deprecation_tracker' ),
|
||||
'target' => '_blank'
|
||||
);
|
||||
|
||||
$deprecations = [];
|
||||
|
||||
$status = (bool) Db::i()->select( 'count(*)', 'core_member_status_updates' )->first();
|
||||
if( $status )
|
||||
{
|
||||
$deprecations['status'] = Member::loggedIn()->language()->addToStack( 'v5_deprecate_status' );
|
||||
}
|
||||
|
||||
$login = (bool) Db::i()->select( 'count(*)', 'core_login_methods', [
|
||||
[ 'login_enabled=?', 1 ],
|
||||
[ Db::i()->in( 'login_classname', [
|
||||
'IPS\Login\Handler\Standard',
|
||||
'IPS\Login\Handler\OAuth2\Apple',
|
||||
'IPS\Login\Handler\OAuth2\Facebook',
|
||||
'IPS\Login\Handler\OAuth2\Google',
|
||||
'IPS\Login\Handler\OAuth2\LinkedIn',
|
||||
'IPS\Login\Handler\OAuth2\Microsoft',
|
||||
'IPS\Login\Handler\OAuth1\Twitter',
|
||||
'IPS\Login\Handler\OAuth2\Invision',
|
||||
'IPS\Login\Handler\OAuth2\Wordpress',
|
||||
'IPS\Login\Handler\OAuth2\Custom',
|
||||
'IPS\Login\Handler\ExternalDatabase',
|
||||
'IPS\Login\Handler\LDAP',
|
||||
'IPS\convert\Login'
|
||||
], true ) ]
|
||||
] )->first();
|
||||
if( $login )
|
||||
{
|
||||
$deprecations['login'] = Member::loggedIn()->language()->addToStack( 'v5_deprecate_login' );
|
||||
}
|
||||
|
||||
$login = new Login;
|
||||
if( $login->authType() & Login::AUTH_TYPE_USERNAME )
|
||||
{
|
||||
$deprecations['display_names'] = Member::loggedIn()->language()->addToStack( 'v5_deprecate_display_name_login' );
|
||||
}
|
||||
|
||||
if( \IPS\CP_DIRECTORY != 'admin' )
|
||||
{
|
||||
$deprecations['cp_directory'] = Member::loggedIn()->language()->addToStack( 'v5_deprecate_cp_directory' );
|
||||
}
|
||||
|
||||
if( Settings::i()->tags_open_system )
|
||||
{
|
||||
$deprecations['open_tagging'] = Member::loggedIn()->language()->addToStack( 'v5_deprecate_open_tagging' );
|
||||
}
|
||||
|
||||
if( (bool) Db::i()->select('count(*)', 'core_social_promote_sharers', [ 'sharer_key!=? AND sharer_enabled=?', 'Internal', 1 ] )->first() )
|
||||
{
|
||||
$deprecations['social_promotes'] = Member::loggedIn()->language()->addToStack( 'v5_deprecate_social_promotes' );
|
||||
}
|
||||
|
||||
if( !\IPS\CIC )
|
||||
{
|
||||
if( !Settings::i()->use_friendly_urls )
|
||||
{
|
||||
$deprecations['core_furls'] = Member::loggedIn()->language()->addToStack( 'v5_deprecate_core_furls' );
|
||||
}
|
||||
|
||||
$dummyRequest = Url::external('https://invisioncommunity.com')->request();
|
||||
if( ( $dummyRequest instanceof \IPS\Http\Request\Sockets ) )
|
||||
{
|
||||
$deprecations['classic_sockets'] = Member::loggedIn()->language()->addToStack( 'v5_deprecate_classic_sockets' );
|
||||
}
|
||||
}
|
||||
|
||||
/* Pages Checks */
|
||||
if( Application::appIsEnabled( 'cms' ) )
|
||||
{
|
||||
$appName = Application::load('cms')->_title;
|
||||
foreach( Db::i()->select( '*', 'cms_blocks', [ 'block_type=?', 'custom'] ) as $row )
|
||||
{
|
||||
$config = json_decode( $row['block_config'], true );
|
||||
if( isset( $config['editor'] ) and $config['editor'] == 'php' )
|
||||
{
|
||||
$deprecations['php_blocks'] = Member::loggedIn()->language()->addToStack( 'v5_deprecate_php_blocks', false, [ 'sprintf' => [ $appName ] ] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Commerce checks */
|
||||
if( Application::appIsEnabled( 'nexus' ) )
|
||||
{
|
||||
$appName = Application::load('nexus')->_title;
|
||||
$physical = (bool) Db::i()->select( 'count(*)', 'nexus_packages_products', [ 'p_physical=?', 1 ] )->first();
|
||||
if( $physical )
|
||||
{
|
||||
$deprecations['physical'] = Member::loggedIn()->language()->addToStack( 'v5_deprecate_physical', false, [ 'sprintf' => [ $appName ] ] );
|
||||
}
|
||||
|
||||
$shipping = (bool) Db::i()->select( 'count(*)', 'nexus_shipping' )->first();
|
||||
$shipOrders = (bool) Db::i()->select( 'count(*)', 'nexus_ship_orders' )->first();
|
||||
if( $shipping or $shipOrders )
|
||||
{
|
||||
$deprecations['shipping'] = Member::loggedIn()->language()->addToStack( 'v5_deprecate_shipping', false, [ 'sprintf' => [ $appName ] ] );
|
||||
}
|
||||
|
||||
$requests = (bool) Db::i()->select( 'count(*)', 'nexus_support_requests' )->first();
|
||||
if( $requests )
|
||||
{
|
||||
$deprecations['support'] = Member::loggedIn()->language()->addToStack( 'v5_deprecate_support', false, [ 'sprintf' => [ $appName ] ] );
|
||||
}
|
||||
|
||||
$gateways = iterator_to_array(
|
||||
Db::i()->select( 'distinct m_gateway', 'nexus_paymethods', Db::i()->in( 'm_gateway', [ 'Braintree', 'AuthorizeNet', 'TwoCheckout' ] ) )
|
||||
);
|
||||
if( count( $gateways ) )
|
||||
{
|
||||
$deprecations['gateways'] = Member::loggedIn()->language()->addToStack( 'v5_deprecate_gateways', false, [ 'sprintf' => [ $appName, implode( ", ", $gateways ) ] ] );
|
||||
}
|
||||
|
||||
if( Settings::i()->easypost_enable )
|
||||
{
|
||||
$deprecations['easypost'] = Member::loggedIn()->language()->addToStack( 'v5_deprecate_easypost', false, [ 'sprintf' => [ $appName ] ] );
|
||||
}
|
||||
}
|
||||
|
||||
/* Forums checks */
|
||||
if( Application::appIsEnabled( 'forums' ) )
|
||||
{
|
||||
$appName = Application::load('forums')->_title;
|
||||
if( (bool) \IPS\Db::i()->select( 'COUNT(*)', 'forums_forums', \IPS\Db::i()->bitwiseWhere( \IPS\forums\Forum::$bitOptions['forums_bitoptions'], 'bw_enable_answers' ) )->first() )
|
||||
{
|
||||
$deprecations['qa'] = Member::loggedIn()->language()->addToStack( 'v5_deprecate_forums_qa', false, [ 'sprintf' => [ $appName ] ] );
|
||||
}
|
||||
}
|
||||
|
||||
return [ 'phpCheck' => $phpCheck, 'mySqlCheck' => $mySqlCheck, 'innoDb' => $innoDb, 'elasticsearch' => $elasticsearch, 'deprecations' => $deprecations ];
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user