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
File diff suppressed because it is too large.
Load diff
@@ -11,30 +11,47 @@
|
||||
namespace IPS\core\modules\admin\settings;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Application;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Dispatcher\Controller;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\CheckboxSet;
|
||||
use IPS\Helpers\Form\Radio;
|
||||
use IPS\Helpers\Form\YesNo;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\Member\Group;
|
||||
use IPS\Output;
|
||||
use IPS\Session;
|
||||
use IPS\Settings;
|
||||
use IPS\Theme;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* contactus
|
||||
*/
|
||||
class _contactus extends \IPS\Dispatcher\Controller
|
||||
class contactus 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( 'contactus_manage' );
|
||||
Dispatcher::i()->checkAcpPermission( 'contactus_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
@@ -43,11 +60,11 @@ class _contactus extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
protected function manage() : void
|
||||
{
|
||||
$form = $this->_getConfigForm();
|
||||
|
||||
if ( $values = $form->values( true ) )
|
||||
if ( $values = $form->values(true) )
|
||||
{
|
||||
/* If we unselect 'everyone' and save, an empty string is passed through, so the default value is picked up in Settings::changeValues(),
|
||||
which is the 'everyone' preference...the end result is that everyone gets rechecked when you uncheck it. To counter that, we'll store an invalid
|
||||
@@ -59,33 +76,30 @@ class _contactus extends \IPS\Dispatcher\Controller
|
||||
|
||||
$form->saveAsSettings( $values );
|
||||
|
||||
/* Clear guest page caches */
|
||||
\IPS\Data\Cache::i()->clearAll();
|
||||
|
||||
\IPS\Session::i()->log( 'acplogs__contactus_settings' );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=settings&controller=contactus' ), 'saved' );
|
||||
Session::i()->log( 'acplogs__contactus_settings' );
|
||||
Output::i()->redirect( Url::internal( 'app=core&module=settings&controller=contactus' ), 'saved' );
|
||||
|
||||
}
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'r__contactus' );
|
||||
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'global' )->block( '', $form );
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack( 'r__contactus' );
|
||||
Output::i()->output .= Theme::i()->getTemplate( 'global' )->block( '', $form );
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the configuration form
|
||||
*
|
||||
* @return \IPS\Helpers\Form
|
||||
* @return Form
|
||||
*/
|
||||
protected function _getConfigForm()
|
||||
protected function _getConfigForm() : Form
|
||||
{
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form = new Form;
|
||||
$options = array();
|
||||
$toggles = array();
|
||||
$disabled = array();
|
||||
$formFields = array();
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'contact_access', ( \IPS\Settings::i()->contact_access == '*' ) ? '*' : explode( ',', \IPS\Settings::i()->contact_access ), FALSE, array(
|
||||
'options' => array_combine( array_keys( \IPS\Member\Group::groups() ), array_map( function( $_group ) { return (string) $_group; }, \IPS\Member\Group::groups() ) ),
|
||||
$form->add( new CheckboxSet( 'contact_access', ( Settings::i()->contact_access == '*' ) ? '*' : explode( ',', Settings::i()->contact_access ), FALSE, array(
|
||||
'options' => array_combine( array_keys( Group::groups() ), array_map( function( $_group ) { return (string) $_group; }, Group::groups() ) ),
|
||||
'multiple' => true,
|
||||
'unlimited' => '*',
|
||||
'unlimitedLang' => 'everyone',
|
||||
@@ -93,14 +107,14 @@ class _contactus extends \IPS\Dispatcher\Controller
|
||||
), NULL, NULL, NULL, 'contact_access' ) );
|
||||
|
||||
/* Get extensions */
|
||||
$extensions = \IPS\Application::allExtensions( 'core', 'ContactUs', FALSE, 'core', 'InternalEmail', TRUE );
|
||||
$extensions = Application::allExtensions( 'core', 'ContactUs', FALSE, 'core', 'InternalEmail', TRUE );
|
||||
|
||||
foreach ( $extensions as $k => $class )
|
||||
{
|
||||
$class->process( $form, $formFields, $options, $toggles, $disabled );
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'contact_type', \IPS\Settings::i()->contact_type, FALSE, array(
|
||||
$form->add( new Radio( 'contact_type', Settings::i()->contact_type, FALSE, array(
|
||||
'options' => $options,
|
||||
'toggles' => $toggles,
|
||||
'disabled' => $disabled
|
||||
@@ -111,7 +125,7 @@ class _contactus extends \IPS\Dispatcher\Controller
|
||||
$form->add( $field );
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'contact_email_verify', \IPS\Settings::i()->contact_email_verify, TRUE ) );
|
||||
$form->add( new YesNo( 'contact_email_verify', Settings::i()->contact_email_verify, TRUE ) );
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
@@ -12,21 +12,55 @@
|
||||
namespace IPS\core\modules\admin\settings;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use InvalidArgumentException;
|
||||
use IPS\Application;
|
||||
use IPS\core\DataLayer as DataLayerClass;
|
||||
use IPS\core\DataLayer\Handler;
|
||||
use IPS\Data\Store;
|
||||
use IPS\Db;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Dispatcher\Controller;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\CheckboxSet;
|
||||
use IPS\Helpers\Form\Node;
|
||||
use IPS\Helpers\Form\Text;
|
||||
use IPS\Helpers\Form\TextArea;
|
||||
use IPS\Helpers\Form\YesNo;
|
||||
use IPS\Helpers\Table\Custom;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Login\Handler as HandlerClass;
|
||||
use IPS\Member;
|
||||
use IPS\Output;
|
||||
use IPS\Request;
|
||||
use IPS\Session;
|
||||
use IPS\Settings;
|
||||
use IPS\Theme;
|
||||
use OutOfRangeException;
|
||||
use function call_user_func_array;
|
||||
use function count;
|
||||
use function defined;
|
||||
use function mb_substr;
|
||||
use function strlen;
|
||||
use function strtolower;
|
||||
use function substr;
|
||||
use function trim;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* dataLayer
|
||||
*/
|
||||
class _dataLayer extends \IPS\Dispatcher\Controller
|
||||
class dataLayer extends Controller
|
||||
{
|
||||
/**
|
||||
* @breif the tabs
|
||||
*/
|
||||
protected static $tabs = array(
|
||||
protected static array $tabs = array(
|
||||
'main' => 'datalayer_main',
|
||||
'pageContext' => 'datalayer_pageContext',
|
||||
'properties' => 'datalayer_properties',
|
||||
@@ -36,22 +70,35 @@ class _dataLayer extends \IPS\Dispatcher\Controller
|
||||
/**
|
||||
* @breif Makes this controller work
|
||||
*/
|
||||
public static $csrfProtected = true;
|
||||
public static bool $csrfProtected = true;
|
||||
|
||||
/**
|
||||
* @brief used to actually handle events and properties in the browser
|
||||
*/
|
||||
public static $handlerClass = '\IPS\core\DataLayer\Handler';
|
||||
public static string $handlerClass = '\IPS\core\DataLayer\Handler';
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
if ( Application::appIsEnabled('cloud') and DataLayerClass::i() instanceof \IPS\cloud\DataLayer\Handler )
|
||||
{
|
||||
static::$handlerClass = 'IPS\cloud\DataLayer\Handler';
|
||||
}
|
||||
|
||||
return parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'dataLayer_manage' );
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'menu__core_settings_dataLayer' );
|
||||
Dispatcher::i()->checkAcpPermission( 'dataLayer_manage' );
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack( 'menu__core_settings_dataLayer' );
|
||||
|
||||
/* Can we use custom handlers? Only show the tab on sites that have full analytics */
|
||||
$class = static::$handlerClass;
|
||||
@@ -60,7 +107,7 @@ class _dataLayer extends \IPS\Dispatcher\Controller
|
||||
class_exists( 'IPS\cloud\Application' ) AND
|
||||
method_exists( $class, 'handlerForm' ) AND
|
||||
method_exists( $class, 'loadWhere' ) AND
|
||||
\IPS\Member::loggedIn()->hasAcpRestriction( 'dataLayer_handlers_view' ) AND
|
||||
Member::loggedIn()->hasAcpRestriction( 'dataLayer_handlers_view' ) AND
|
||||
\IPS\cloud\Application::featureIsEnabled('analytics_full')
|
||||
)
|
||||
{
|
||||
@@ -73,7 +120,7 @@ class _dataLayer extends \IPS\Dispatcher\Controller
|
||||
);
|
||||
}
|
||||
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'settings/general.css', 'core', 'admin' ) );
|
||||
Output::i()->cssFiles = array_merge( Output::i()->cssFiles, Theme::i()->css( 'settings/general.css', 'core', 'admin' ) );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
@@ -86,12 +133,12 @@ class _dataLayer extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
if ( method_exists( $this, $name ) )
|
||||
{
|
||||
return \call_user_func_array( $this->$name, $arguments );
|
||||
return call_user_func_array( $this->$name, $arguments );
|
||||
}
|
||||
elseif ( method_exists( \IPS\core\DataLayer::i(), $name ) )
|
||||
elseif ( method_exists( DataLayerClass::i(), $name ) )
|
||||
{
|
||||
$method = array( \IPS\core\DataLayer::i(), $name );
|
||||
return \call_user_func_array( $method, $arguments );
|
||||
$method = array( DataLayerClass::i(), $name );
|
||||
return call_user_func_array( $method, $arguments );
|
||||
}
|
||||
|
||||
return "You should Upgrade!";
|
||||
@@ -102,49 +149,49 @@ class _dataLayer extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
protected function manage() : void
|
||||
{
|
||||
$tab = \IPS\Request::i()->tab;
|
||||
$tab = Request::i()->tab;
|
||||
$tab = empty( static::$tabs[ $tab ] ) ? 'main' : $tab;
|
||||
$output = $this->$tab();
|
||||
$output = "<div id='dataLayerContent'>$output</div>" ;
|
||||
|
||||
if ( isset( static::$tabs['handlers'] ) AND \IPS\Member::loggedIn()->hasAcpRestriction( 'dataLayer_handlers_edit' ) )
|
||||
if ( isset( static::$tabs['handlers'] ) AND Member::loggedIn()->hasAcpRestriction( 'dataLayer_handlers_edit' ) )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['actions']['addHandler'] = array(
|
||||
'title' => \IPS\Member::loggedIn()->language()->addToStack( 'datalayer_handler_form' ),
|
||||
Output::i()->sidebar['actions']['addHandler'] = array(
|
||||
'title' => Member::loggedIn()->language()->addToStack( 'datalayer_handler_form' ),
|
||||
'icon' => 'plus',
|
||||
'link' => \IPS\Http\Url::internal( 'app=core&module=settings&controller=dataLayer&do=addHandler' ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack( 'datalayer_handler_form' ) )
|
||||
'link' => Url::internal( 'app=core&module=settings&controller=dataLayer&do=addHandler' ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => Member::loggedIn()->language()->addToStack( 'datalayer_handler_form' ) )
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
$addPropertyUrl = \IPS\Http\Url::internal( 'app=core&module=settings&controller=dataLayer&do=addProperty' );
|
||||
\IPS\Output::i()->sidebar['actions']['addProperty'] = array(
|
||||
'title' => \IPS\Member::loggedIn()->language()->addToStack( 'datalayer_add_property' ),
|
||||
$addPropertyUrl = Url::internal( 'app=core&module=settings&controller=dataLayer&do=addProperty' );
|
||||
Output::i()->sidebar['actions']['addProperty'] = array(
|
||||
'title' => Member::loggedIn()->language()->addToStack( 'datalayer_add_property' ),
|
||||
'icon' => 'plus',
|
||||
'link' => $addPropertyUrl,
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack( 'datalayer_add_property' ) )
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => Member::loggedIn()->language()->addToStack( 'datalayer_add_property' ) )
|
||||
);
|
||||
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
if ( Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->output = $output;
|
||||
Output::i()->output = $output;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( isset( $_SESSION['deleted_datalayer_property'] ) )
|
||||
{
|
||||
\IPS\Output::i()->inlineMessage = 'Deleted Property';
|
||||
Output::i()->inlineMessage = 'Deleted Property';
|
||||
unset( $_SESSION['deleted_datalayer_property'] );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core', 'admin' )->tabs(
|
||||
Output::i()->output = Theme::i()->getTemplate( 'global', 'core', 'admin' )->tabs(
|
||||
static::$tabs,
|
||||
$tab,
|
||||
$output,
|
||||
\IPS\Http\Url::internal( 'app=core&module=settings&controller=dataLayer', 'admin' )
|
||||
Url::internal( 'app=core&module=settings&controller=dataLayer', 'admin' )
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -155,25 +202,25 @@ class _dataLayer extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function main()
|
||||
protected function main() : string
|
||||
{
|
||||
$form = new \IPS\Helpers\Form( 'datalayer_general' );
|
||||
$form = new Form( 'datalayer_general' );
|
||||
|
||||
$form->addHeader('Settings');
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'core_datalayer_enabled', \IPS\Settings::i()->core_datalayer_enabled, false ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'core_datalayer_include_pii', \IPS\Settings::i()->core_datalayer_include_pii, false, array( 'togglesOn' => [ 'datalayer_general_core_datalayer_member_pii_choice' ] ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'core_datalayer_member_pii_choice', \IPS\Settings::i()->core_datalayer_member_pii_choice, false ) );
|
||||
$form->add( new YesNo( 'core_datalayer_enabled', Settings::i()->core_datalayer_enabled, false ) );
|
||||
$form->add( new YesNo( 'core_datalayer_include_pii', Settings::i()->core_datalayer_include_pii, false, array( 'togglesOn' => [ 'datalayer_general_core_datalayer_member_pii_choice' ] ) ) );
|
||||
$form->add( new YesNo( 'core_datalayer_member_pii_choice', Settings::i()->core_datalayer_member_pii_choice, false ) );
|
||||
|
||||
try
|
||||
{
|
||||
$default = \IPS\Login\Handler::load( \IPS\Settings::i()->core_datalayer_replace_with_sso );
|
||||
$default = HandlerClass::load( Settings::i()->core_datalayer_replace_with_sso );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
$default = 0;
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'core_datalayer_replace_with_sso', $default, false, array(
|
||||
$form->add( new Node( 'core_datalayer_replace_with_sso', $default, false, array(
|
||||
'class' => '\IPS\Login\Handler',
|
||||
'zeroVal' => 'Use internal Member ID (default)',
|
||||
'where' => array(
|
||||
@@ -185,47 +232,47 @@ class _dataLayer extends \IPS\Dispatcher\Controller
|
||||
) ) );
|
||||
|
||||
$form->addHeader('enhancements__core_GoogleTagManager');
|
||||
$form->addMessage( 'use_gtm_for_installation', 'ipsMessage ipsMessage_info ipsMargin' );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'core_datalayer_use_gtm', \IPS\Settings::i()->core_datalayer_use_gtm, false ) );
|
||||
$gtmkey = explode( '.', \IPS\Settings::i()->core_datalayer_gtmkey );
|
||||
$form->add( new \IPS\Helpers\Form\Text(
|
||||
$form->addMessage( 'use_gtm_for_installation', 'ipsMessage ipsMessage--info i-margin_3' );
|
||||
$form->add( new YesNo( 'core_datalayer_use_gtm', Settings::i()->core_datalayer_use_gtm, false ) );
|
||||
$gtmkey = explode( '.', Settings::i()->core_datalayer_gtmkey );
|
||||
$form->add( new Text(
|
||||
'core_datalayer_gtmkey',
|
||||
array_pop( $gtmkey ),
|
||||
false,
|
||||
array(),
|
||||
function( $_value ) {
|
||||
/* Check for invalid characters */
|
||||
if ( preg_match( '/[^a-z,A-Z,0-9,\_]/', $_value ) )
|
||||
if ( preg_match( '/[^a-zA-Z0-9_]/', $_value ) )
|
||||
{
|
||||
throw new \InvalidArgumentException( 'The variable name can only contain alphanumeric characters and underscores.' );
|
||||
throw new InvalidArgumentException( 'The variable name can only contain alphanumeric characters and underscores.' );
|
||||
}
|
||||
elseif ( preg_match( '/[0-9]/', \mb_substr( $_value, 0, 1 ) ) )
|
||||
elseif ( preg_match( '/[0-9]/', mb_substr( $_value, 0, 1 ) ) )
|
||||
{
|
||||
throw new \InvalidArgumentException( 'The variable name cannot start with a number.' );
|
||||
throw new InvalidArgumentException( 'The variable name cannot start with a number.' );
|
||||
}
|
||||
|
||||
/* Is a custom handler using this? Note that, in JS, window.variable and variable are nearly always the same */
|
||||
$where = [
|
||||
[ 'enabled=?', 1 ],
|
||||
[ 'use_js=?', 1 ],
|
||||
\IPS\Db::i()->in( 'datalayer_key', [ $_value, "window.$_value" ] ),
|
||||
Db::i()->in( 'datalayer_key', [ $_value, "window.$_value" ] ),
|
||||
];
|
||||
|
||||
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 ) )
|
||||
DataLayerClass::i() instanceof \IPS\cloud\DataLayer AND
|
||||
count( 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." );
|
||||
throw new InvalidArgumentException( "$_value or window.$_value is in use by a custom handler." );
|
||||
}
|
||||
},
|
||||
'<span class="ipsType_monospace">window.</span>'
|
||||
'<span class="i-font-family_monospace">window.</span>'
|
||||
));
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
Session::i()->csrfCheck();
|
||||
|
||||
if ( isset( $values['core_datalayer_replace_with_sso'] ) )
|
||||
{
|
||||
@@ -243,21 +290,21 @@ class _dataLayer extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
if ( isset( $values[$input] ) )
|
||||
{
|
||||
$key = \IPS\core\DataLayer\Handler::$handlerCacheKey;
|
||||
unset( \IPS\Data\Store::i()->$key );
|
||||
$key = Handler::$handlerCacheKey;
|
||||
unset( Store::i()->$key );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear the cached configuration since we're changing it */
|
||||
\IPS\core\DataLayer::i()->clearCachedConfiguration([ '_jsConfig', '_eventProperties', '_propertyEvents' ]);
|
||||
DataLayerClass::i()->clearCachedConfiguration([ '_jsConfig', '_eventProperties', '_propertyEvents' ]);
|
||||
|
||||
\IPS\Settings::i()->changeValues( $values );
|
||||
Settings::i()->changeValues( $values );
|
||||
|
||||
\IPS\Session::i()->log( 'acplog__datalayer_settings_edited' );
|
||||
Session::i()->log( 'acplog__datalayer_settings_edited' );
|
||||
|
||||
/* Redirect to avoid csrfKey errors */
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=settings&controller=dataLayer&tab=main' ) );
|
||||
Output::i()->redirect( Url::internal( 'app=core&module=settings&controller=dataLayer&tab=main' ) );
|
||||
}
|
||||
|
||||
return "<br>$form";
|
||||
@@ -268,10 +315,10 @@ class _dataLayer extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function pageContext()
|
||||
protected function pageContext() : string
|
||||
{
|
||||
/* Get the page level properties */
|
||||
$_properties = \IPS\core\DataLayer::i()->propertiesConfiguration;
|
||||
$_properties = DataLayerClass::i()->propertiesConfiguration;
|
||||
foreach ( $_properties as $k => $property )
|
||||
{
|
||||
if ( $property['page_level'] AND $property['enabled'] )
|
||||
@@ -286,20 +333,20 @@ class _dataLayer extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
}
|
||||
|
||||
$propertyBlock = new \IPS\Helpers\Table\Custom(
|
||||
$propertyBlock = new Custom(
|
||||
$properties,
|
||||
\IPS\Http\Url::internal( 'app=core&module=settings&controller=dataLayer&tab=pageContext' )
|
||||
Url::internal( 'app=core&module=settings&controller=dataLayer&tab=pageContext' )
|
||||
);
|
||||
$propertyBlock->classes[] = 'ipsPadding:none ipsMargin:none';
|
||||
$propertyBlock->classes[] = 'ipsPadding:none';
|
||||
$propertyBlock->exclude = array('custom', 'description');
|
||||
$propertyBlock->langPrefix = 'datalayer_';
|
||||
|
||||
if ( !\IPS\Request::i()->sortby )
|
||||
if ( !Request::i()->sortby )
|
||||
{
|
||||
$propertyBlock->sortBy = 'name';
|
||||
}
|
||||
|
||||
if ( !\IPS\Request::i()->sortdirection )
|
||||
if ( !Request::i()->sortdirection )
|
||||
{
|
||||
$propertyBlock->sortDirection = 'asc';
|
||||
}
|
||||
@@ -307,13 +354,13 @@ class _dataLayer extends \IPS\Dispatcher\Controller
|
||||
$propertyBlock->parsers = array(
|
||||
'pii' => array( $this, '_yesNo' ),
|
||||
'name' => function ( $val, $row ) {
|
||||
$url = \IPS\Http\Url::internal('app=core&module=settings&controller=dataLayer&tab=properties&property_key=' . $val);
|
||||
$url = Url::internal('app=core&module=settings&controller=dataLayer&tab=properties&property_key=' . $val);
|
||||
$title = $row['short'];
|
||||
return "<span class='ipsType_monospace ipsMargin:none'><a href='$url' data-ipstooltip title='$title'>$val</a></span>";
|
||||
return "<span class='i-font-family_monospace'><a href='$url' data-ipstooltip title='$title'>$val</a></span>";
|
||||
},
|
||||
);
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'settings', 'core', 'admin' )->dataLayerContext( $propertyBlock );
|
||||
return Theme::i()->getTemplate( 'settings', 'core', 'admin' )->dataLayerContext( $propertyBlock );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -321,21 +368,21 @@ class _dataLayer extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function properties()
|
||||
protected function properties() : string
|
||||
{
|
||||
/* Load our properties */
|
||||
$properties = \IPS\core\DataLayer::i()->propertiesConfiguration;
|
||||
$property_key = \IPS\Request::i()->property_key ?: array_keys( $properties )[0];
|
||||
$properties = DataLayerClass::i()->propertiesConfiguration;
|
||||
$property_key = Request::i()->property_key ?: array_keys( $properties )[0];
|
||||
|
||||
/* Do we know the requested property? */
|
||||
if ( !isset( $properties[$property_key] ) )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Request::i()->url()->stripQueryString([ 'property_key' ]) );
|
||||
Output::i()->redirect( Request::i()->url()->stripQueryString([ 'property_key' ]) );
|
||||
}
|
||||
$property = $properties[$property_key];
|
||||
|
||||
/* Sidebar */
|
||||
$propertySelector = \IPS\Theme::i()->getTemplate( 'settings', 'core', 'admin' )->dataLayerSelector(
|
||||
$propertySelector = Theme::i()->getTemplate( 'settings', 'core', 'admin' )->dataLayerSelector(
|
||||
$properties,
|
||||
'properties',
|
||||
'property_key',
|
||||
@@ -346,46 +393,30 @@ class _dataLayer extends \IPS\Dispatcher\Controller
|
||||
);
|
||||
|
||||
/* Form */
|
||||
$form = new \IPS\Helpers\Form( 'datalayer_properties_' . $property_key, 'save', \IPS\Http\Url::internal( 'app=core&module=settings&controller=dataLayer&tab=properties&property_key=' . $property_key ) );
|
||||
$form->class = 'ipsForm_vertical';
|
||||
$form = new Form( 'datalayer_properties_' . $property_key, 'save', Url::internal( 'app=core&module=settings&controller=dataLayer&tab=properties&property_key=' . $property_key ) );
|
||||
$form->class = 'ipsForm--vertical ipsForm--datalayer-properties';
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'datalayer_property_enabled', $property['enabled'], false ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'datalayer_property_formatted_name', $property['formatted_name'], false, array(), $this->formattedNameValid('properties', $property_key) ) );
|
||||
$form->add( new YesNo( 'datalayer_property_enabled', $property['enabled'], false ) );
|
||||
$form->add( new Text( 'datalayer_property_formatted_name', $property['formatted_name'], false, array(), $this->formattedNameValid('properties', $property_key) ) );
|
||||
|
||||
if ( $property['custom'] ?? 0 )
|
||||
{
|
||||
$defaults = [
|
||||
'pii' => false,
|
||||
'value' => null,
|
||||
'page_level' => true,
|
||||
'short' => "",
|
||||
'description' => "",
|
||||
'event_keys' => []
|
||||
];
|
||||
$form->add( new Text( 'datalayer_property_value', $property['value'], true ) );
|
||||
$form->add( new YesNo( 'datalayer_property_page_level', $property['page_level'], true ) );
|
||||
$form->add( new Text( 'datalayer_property_short', $property['short'], false, array( 'maxLength' => 50 ) ) );
|
||||
|
||||
foreach ( $defaults as $key => $value )
|
||||
{
|
||||
if ( !array_key_exists( $key, $property ) )
|
||||
{
|
||||
$property[$key] = $value;
|
||||
}
|
||||
}
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'datalayer_property_value', $property['value'], true ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'datalayer_property_page_level', $property['page_level'], true ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'datalayer_property_short', $property['short'], false, array( 'maxLength' => 50 ) ) );
|
||||
|
||||
$events = \IPS\core\DataLayer::i()->eventConfiguration;
|
||||
$events = DataLayerClass::i()->eventConfiguration;
|
||||
$options = array();
|
||||
foreach ( $events as $key => $data )
|
||||
{
|
||||
$options[$key] = $data['formatted_name'];
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'datalayer_property_event_keys', $property['event_keys'], false, array('options' => $options, 'multiple' => 1) ) );
|
||||
$form->add( new CheckboxSet( 'datalayer_property_event_keys', $property['event_keys'], false, array('options' => $options, 'multiple' => 1) ) );
|
||||
}
|
||||
|
||||
/* Update the values as long as the property_key was specified in the request */
|
||||
if ( ( $values = $form->values() ) AND \IPS\Request::i()->property_key === $property_key )
|
||||
if ( ( $values = $form->values() ) AND Request::i()->property_key === $property_key )
|
||||
{
|
||||
/* Get our submitted values */
|
||||
$_values = array();
|
||||
@@ -418,18 +449,18 @@ class _dataLayer extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\core\DataLayer::i()->savePropertyConfiguration( $property_key, $_values );
|
||||
DataLayerClass::i()->savePropertyConfiguration( $property_key, $_values );
|
||||
}
|
||||
catch ( \InvalidArgumentException $e ) {}
|
||||
catch ( InvalidArgumentException $e ) {}
|
||||
|
||||
\IPS\Session::i()->log( 'acplog__data_layer_property_edited', array( $property_key => FALSE ) );
|
||||
Session::i()->log( 'acplog__data_layer_property_edited', array( $property_key => FALSE ) );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=settings&controller=dataLayer&tab=properties&property_key=' . $property_key ) );
|
||||
Output::i()->redirect( Url::internal( 'app=core&module=settings&controller=dataLayer&tab=properties&property_key=' . $property_key ) );
|
||||
}
|
||||
|
||||
/* Load our events */
|
||||
$_events = \IPS\core\DataLayer::i()->getPropertyEvents( $property_key );
|
||||
$_events = DataLayerClass::i()->getPropertyEvents( $property_key );
|
||||
$events = array();
|
||||
foreach( $_events as $key => $event )
|
||||
{
|
||||
@@ -448,18 +479,18 @@ class _dataLayer extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
else
|
||||
{
|
||||
$eventTable = new \IPS\Helpers\Table\Custom(
|
||||
$eventTable = new Custom(
|
||||
$events,
|
||||
\IPS\Http\Url::internal( 'app=core&module=settings&controller=dataLayer&tab=properties&property_key=' . $property_key )
|
||||
Url::internal( 'app=core&module=settings&controller=dataLayer&tab=properties&property_key=' . $property_key )
|
||||
);
|
||||
|
||||
|
||||
|
||||
if ( !\IPS\Request::i()->sortby )
|
||||
if ( !Request::i()->sortby )
|
||||
{
|
||||
$eventTable->sortBy = 'name';
|
||||
}
|
||||
if ( !\IPS\Request::i()->sortdirection )
|
||||
if ( !Request::i()->sortdirection )
|
||||
{
|
||||
$eventTable->sortDirection = 'asc';
|
||||
}
|
||||
@@ -469,16 +500,16 @@ class _dataLayer extends \IPS\Dispatcher\Controller
|
||||
$eventTable->parsers = array(
|
||||
'name' => function ( $val, $row )
|
||||
{
|
||||
$url = \IPS\Http\Url::internal('app=core&module=settings&controller=dataLayer&tab=events&event_key=' . $row['key']);
|
||||
$url = Url::internal('app=core&module=settings&controller=dataLayer&tab=events&event_key=' . $row['key']);
|
||||
$title = $row['short'];
|
||||
return "<span class='ipsMargin:none ipsType_monospace'><a href='$url' data-ipstooltip title='$title'>$val</a></span>";
|
||||
return "<span class='i-font-family_monospace'><a href='$url' data-ipstooltip title='$title'>$val</a></span>";
|
||||
},
|
||||
'enabled' => array( $this, '_enabledDisabled' ),
|
||||
);
|
||||
}
|
||||
|
||||
/* Render Content */
|
||||
$content = \IPS\Theme::i()->getTemplate( 'settings', 'core', 'admin' )->dataLayerTitleContent(
|
||||
$content = Theme::i()->getTemplate( 'settings', 'core', 'admin' )->dataLayerTitleContent(
|
||||
$property,
|
||||
$property_key,
|
||||
'property',
|
||||
@@ -486,36 +517,36 @@ class _dataLayer extends \IPS\Dispatcher\Controller
|
||||
(string) $eventTable
|
||||
);
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'settings', 'core', 'admin' )->dataLayerTab( $propertySelector, $content );
|
||||
return Theme::i()->getTemplate( 'settings', 'core', 'admin' )->dataLayerTab( $propertySelector, $content );
|
||||
}
|
||||
|
||||
/**
|
||||
* Property settings and configuration
|
||||
*
|
||||
* @return string
|
||||
* @return void
|
||||
*/
|
||||
protected function addProperty()
|
||||
protected function addProperty() : void
|
||||
{
|
||||
\IPS\Output::i()->title = 'Add property';
|
||||
$form = new \IPS\Helpers\Form( 'datalayer_add_property' );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'datalayer_property_formatted_name', null, true, array(), $this->formattedNameValid() ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'datalayer_property_value', null, true ) );
|
||||
$form->add( new \IPS\Helpers\Form\TextArea( 'datalayer_property_description', null, true ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'datalayer_property_short', null, false, array( 'maxLength' => 50 ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'datalayer_property_page_level', 1, true ) );
|
||||
Output::i()->title = 'Add property';
|
||||
$form = new Form( 'datalayer_add_property' );
|
||||
$form->add( new Text( 'datalayer_property_formatted_name', null, true, array(), $this->formattedNameValid() ) );
|
||||
$form->add( new Text( 'datalayer_property_value', null, true ) );
|
||||
$form->add( new TextArea( 'datalayer_property_description', null, true ) );
|
||||
$form->add( new Text( 'datalayer_property_short', null, false, array( 'maxLength' => 50 ) ) );
|
||||
$form->add( new YesNo( 'datalayer_property_page_level', 1, true ) );
|
||||
|
||||
$events = \IPS\core\DataLayer::i()->eventConfiguration;
|
||||
$events = DataLayerClass::i()->eventConfiguration;
|
||||
$options = array();
|
||||
foreach ( $events as $key => $data )
|
||||
{
|
||||
$options[$key] = $data['formatted_name'];
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'datalayer_property_event_keys', array(), false, array('options' => $options, 'multiple' => 1) ) );
|
||||
$form->add( new CheckboxSet( 'datalayer_property_event_keys', array(), false, array('options' => $options, 'multiple' => 1) ) );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
Session::i()->csrfCheck();
|
||||
$_values = array();
|
||||
foreach ( $values as $field => $value )
|
||||
{
|
||||
@@ -527,40 +558,40 @@ class _dataLayer extends \IPS\Dispatcher\Controller
|
||||
$values['enabled'] = true;
|
||||
$key = $values['formatted_name'];
|
||||
|
||||
\IPS\core\DataLayer::i()->savePropertyConfiguration( $key, $values, true );
|
||||
DataLayerClass::i()->savePropertyConfiguration( $key, $values, true );
|
||||
|
||||
\IPS\Session::i()->log( 'acplog__data_layer_property_added', array( $key => FALSE ) );
|
||||
Session::i()->log( 'acplog__data_layer_property_added', array( $key => FALSE ) );
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=settings&controller=dataLayer&tab=properties&property_key=' . $key ) );
|
||||
Output::i()->redirect( Url::internal( 'app=core&module=settings&controller=dataLayer&tab=properties&property_key=' . $key ) );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = (string) $form;
|
||||
Output::i()->output = (string) $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a property
|
||||
*/
|
||||
protected function deleteProperty()
|
||||
protected function deleteProperty() : void
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
Session::i()->csrfCheck();
|
||||
|
||||
$key = \IPS\Request::i()->property_key;
|
||||
$propertiesUrl = \IPS\Http\Url::internal( 'app=core&module=settings&controller=dataLayer&tab=properties' );
|
||||
$key = Request::i()->property_key;
|
||||
$propertiesUrl = Url::internal( 'app=core&module=settings&controller=dataLayer&tab=properties' );
|
||||
if ( empty( $key ) )
|
||||
{
|
||||
\IPS\Output::i()->redirect( $propertiesUrl );
|
||||
Output::i()->redirect( $propertiesUrl );
|
||||
}
|
||||
|
||||
$properties = \IPS\core\DataLayer::i()->propertiesConfiguration;
|
||||
$properties = DataLayerClass::i()->propertiesConfiguration;
|
||||
if ( isset( $properties[$key] ) )
|
||||
{
|
||||
if ( $properties[$key]['custom'] ?? 0 )
|
||||
{
|
||||
$setting = json_decode( \IPS\Settings::i()->core_datalayer_properties, true ) ?: array();
|
||||
$setting = json_decode( Settings::i()->core_datalayer_properties, true ) ?: array();
|
||||
unset( $setting[$key] );
|
||||
\IPS\Settings::i()->changeValues([ 'core_datalayer_properties' => json_encode( $setting ) ]);
|
||||
\IPS\core\DataLayer::i()->clearCachedConfiguration();
|
||||
\IPS\Session::i()->log( 'acplog__data_layer_property_deleted', array( $key => FALSE ) );
|
||||
Settings::i()->changeValues([ 'core_datalayer_properties' => json_encode( $setting ) ]);
|
||||
DataLayerClass::i()->clearCachedConfiguration();
|
||||
Session::i()->log( 'acplog__data_layer_property_deleted', array( $key => FALSE ) );
|
||||
$_SESSION['deleted_datalayer_property'] = 1;
|
||||
}
|
||||
else
|
||||
@@ -568,7 +599,7 @@ class _dataLayer extends \IPS\Dispatcher\Controller
|
||||
$propertiesUrl = $propertiesUrl->setQueryString([ 'property_key' => $key ]);
|
||||
}
|
||||
}
|
||||
\IPS\Output::i()->redirect( $propertiesUrl );
|
||||
Output::i()->redirect( $propertiesUrl );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -576,16 +607,16 @@ class _dataLayer extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function events()
|
||||
protected function events() : string
|
||||
{
|
||||
/* Load our events */
|
||||
$events = \IPS\core\DataLayer::i()->eventConfiguration;
|
||||
$event_key = \IPS\Request::i()->event_key ?: 'content_create';
|
||||
$events = DataLayerClass::i()->eventConfiguration;
|
||||
$event_key = Request::i()->event_key ?: 'content_create';
|
||||
|
||||
/* Do we know the recognized one? */
|
||||
if ( !isset( $events[$event_key] ) )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Request::i()->url()->stripQueryString([ 'event_key' ]) );
|
||||
Output::i()->redirect( Request::i()->url()->stripQueryString([ 'event_key' ]) );
|
||||
}
|
||||
$event = $events[$event_key];
|
||||
|
||||
@@ -595,7 +626,7 @@ class _dataLayer extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
|
||||
/* Create our sidebar */
|
||||
$eventSelector = \IPS\Theme::i()->getTemplate( 'settings', 'core', 'admin' )->dataLayerSelector(
|
||||
$eventSelector = Theme::i()->getTemplate( 'settings', 'core', 'admin' )->dataLayerSelector(
|
||||
$events,
|
||||
'events',
|
||||
'event_key',
|
||||
@@ -606,14 +637,14 @@ class _dataLayer extends \IPS\Dispatcher\Controller
|
||||
);
|
||||
|
||||
/* Form */
|
||||
$form = new \IPS\Helpers\Form( 'datalayer_events_' . $event_key, 'save', \IPS\Http\Url::internal( 'app=core&module=settings&controller=dataLayer&tab=events&event_key=' . $event_key ) );
|
||||
$form->class = 'ipsForm_vertical';
|
||||
$form = new Form( 'datalayer_events_' . $event_key, 'save', Url::internal( 'app=core&module=settings&controller=dataLayer&tab=events&event_key=' . $event_key ) );
|
||||
$form->class = 'ipsForm--vertical ipsForm--datalayer-events';
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'datalayer_event_enabled', $event['enabled'], false ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'datalayer_event_formatted_name', $event['formatted_name'], false, array(), $this->formattedNameValid( 'events', $event_key ) ) );
|
||||
$form->add( new YesNo( 'datalayer_event_enabled', $event['enabled'], false ) );
|
||||
$form->add( new Text( 'datalayer_event_formatted_name', $event['formatted_name'], false, array(), $this->formattedNameValid( 'events', $event_key ) ) );
|
||||
|
||||
/* We only want to change values when a real event is specified in the request */
|
||||
if ( ( $values = $form->values() ) AND \IPS\Request::i()->event_key === $event_key )
|
||||
if ( ( $values = $form->values() ) AND Request::i()->event_key === $event_key )
|
||||
{
|
||||
/* Pull out the values to use */
|
||||
$_values = array();
|
||||
@@ -632,19 +663,19 @@ class _dataLayer extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\core\DataLayer::i()->saveEventConfiguration( $event_key, $_values );
|
||||
DataLayerClass::i()->saveEventConfiguration( $event_key, $_values );
|
||||
}
|
||||
catch ( \InvalidArgumentException $e ) {}
|
||||
catch ( InvalidArgumentException $e ) {}
|
||||
}
|
||||
|
||||
\IPS\Session::i()->log( 'acplog__data_layer_event_edited', array( $event_key => FALSE ) );
|
||||
Session::i()->log( 'acplog__data_layer_event_edited', array( $event_key => FALSE ) );
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=settings&controller=dataLayer&tab=events&event_key=' . $event_key ) );
|
||||
Output::i()->redirect( Url::internal( 'app=core&module=settings&controller=dataLayer&tab=events&event_key=' . $event_key ) );
|
||||
}
|
||||
|
||||
|
||||
/* Load our properties */
|
||||
$_properties = \IPS\core\DataLayer::i()->getEventProperties( $event_key );
|
||||
$_properties = DataLayerClass::i()->getEventProperties( $event_key );
|
||||
$properties = array();
|
||||
foreach( $_properties as $key => $property )
|
||||
{
|
||||
@@ -666,17 +697,17 @@ class _dataLayer extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
else
|
||||
{
|
||||
$propertyTable = new \IPS\Helpers\Table\Custom(
|
||||
$propertyTable = new Custom(
|
||||
$properties,
|
||||
\IPS\Http\Url::internal( 'app=core&module=settings&controller=dataLayer&tab=events&event_key=' . $event_key )
|
||||
Url::internal( 'app=core&module=settings&controller=dataLayer&tab=events&event_key=' . $event_key )
|
||||
);
|
||||
|
||||
if ( !\IPS\Request::i()->sortby )
|
||||
if ( !Request::i()->sortby )
|
||||
{
|
||||
$propertyTable->sortBy = 'name';
|
||||
}
|
||||
|
||||
if ( !\IPS\Request::i()->sortdirection )
|
||||
if ( !Request::i()->sortdirection )
|
||||
{
|
||||
$propertyTable->sortDirection = 'asc';
|
||||
}
|
||||
@@ -688,16 +719,16 @@ class _dataLayer extends \IPS\Dispatcher\Controller
|
||||
'pii' => array( $this, '_yesNo' ),
|
||||
'name' => function ( $val, $row )
|
||||
{
|
||||
$url = \IPS\Http\Url::internal( 'app=core&module=settings&controller=dataLayer&tab=properties&property_key=' . $row['key'] );
|
||||
$url = Url::internal( 'app=core&module=settings&controller=dataLayer&tab=properties&property_key=' . $row['key'] );
|
||||
$title = $row['short'];
|
||||
return "<pre class='ipsMargin:none'><a href='$url' data-ipstooltip title='$title' >$val</a></pre>";
|
||||
return "<pre><a href='$url' data-ipstooltip title='$title' >$val</a></pre>";
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/* Render Content */
|
||||
$event['description'] = "Fires when {$event['description']}";
|
||||
$content = \IPS\Theme::i()->getTemplate( 'settings', 'core', 'admin' )->dataLayerTitleContent(
|
||||
$content = Theme::i()->getTemplate( 'settings', 'core', 'admin' )->dataLayerTitleContent(
|
||||
$event,
|
||||
$event_key,
|
||||
'event',
|
||||
@@ -705,7 +736,7 @@ class _dataLayer extends \IPS\Dispatcher\Controller
|
||||
(string) $propertyTable
|
||||
);
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'settings', 'core', 'admin' )->dataLayerTab( $eventSelector, $content );
|
||||
return Theme::i()->getTemplate( 'settings', 'core', 'admin' )->dataLayerTab( $eventSelector, $content );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -714,23 +745,23 @@ class _dataLayer extends \IPS\Dispatcher\Controller
|
||||
* @param string $group Either properties or events; the datalayer collection to test the key against
|
||||
* @param ?string $current The key of the property/event that currently has this value set as its formatted name
|
||||
*
|
||||
* @return callback
|
||||
* @return callable
|
||||
*/
|
||||
public function formattedNameValid( string $group='properties', ?string $current=null )
|
||||
public function formattedNameValid( string $group='properties', ?string $current=null ) : callable
|
||||
{
|
||||
return function( $value ) use ( $group, $current )
|
||||
{
|
||||
if ( $group === 'properties' AND \strtolower( $value ) === 'event' )
|
||||
if ( $group === 'properties' AND strtolower( $value ) === 'event' )
|
||||
{
|
||||
throw new \InvalidArgumentException( "You cannot name a property '$value' because that key is reserved" );
|
||||
throw new InvalidArgumentException( "You cannot name a property '$value' because that key is reserved" );
|
||||
}
|
||||
|
||||
if ( preg_match( '/[^a-z,A-Z,\_]/', $value ) )
|
||||
if ( preg_match( '/[^a-zA-Z_]/', $value ) )
|
||||
{
|
||||
throw new \InvalidArgumentException( 'The name can only contain letters and underscores.' );
|
||||
throw new InvalidArgumentException( 'The name can only contain letters and underscores.' );
|
||||
}
|
||||
|
||||
$collection = ( $group === 'events' ) ? \IPS\core\DataLayer::i()->eventConfiguration : \IPS\core\DataLayer::i()->propertiesConfiguration;
|
||||
$collection = ( $group === 'events' ) ? DataLayerClass::i()->eventConfiguration : DataLayerClass::i()->propertiesConfiguration;
|
||||
foreach ( $collection as $key => $data )
|
||||
{
|
||||
if ( $key === $current )
|
||||
@@ -740,7 +771,7 @@ class _dataLayer extends \IPS\Dispatcher\Controller
|
||||
|
||||
if ( isset( $data['formatted_name'] ) AND $data['formatted_name'] === $value )
|
||||
{
|
||||
throw new \InvalidArgumentException( 'This Data Layer name is already in use' );
|
||||
throw new InvalidArgumentException( 'This Data Layer name is already in use' );
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -749,11 +780,11 @@ class _dataLayer extends \IPS\Dispatcher\Controller
|
||||
/**
|
||||
* Formatter method to make code cleaner
|
||||
*
|
||||
* @param mixed $val
|
||||
*
|
||||
* @param mixed $val
|
||||
* @param array|null $row *
|
||||
* @return string
|
||||
*/
|
||||
public function _enabledDisabled( $val, $row=null )
|
||||
public function _enabledDisabled( mixed $val, ?array $row=null ) : string
|
||||
{
|
||||
return $val ? 'Enabled' : 'Disabled';
|
||||
}
|
||||
@@ -762,10 +793,10 @@ class _dataLayer extends \IPS\Dispatcher\Controller
|
||||
* Formatter method to make code cleaner
|
||||
*
|
||||
* @param mixed $val
|
||||
*
|
||||
* @param array|null $row
|
||||
* @return string
|
||||
*/
|
||||
public function _yesNo( $val, $row=null )
|
||||
public function _yesNo( mixed $val, ?array $row=null ) : string
|
||||
{
|
||||
return $val ? 'Yes' : 'No';
|
||||
}
|
||||
@@ -778,15 +809,15 @@ class _dataLayer extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function _truncate( $_string, $length=100 )
|
||||
public function _truncate( string $_string, int $length=100 ) : string
|
||||
{
|
||||
$_string = strip_tags( $_string );
|
||||
$string = \substr( $_string, 0, $length );
|
||||
$changedLength = ( \strlen( $_string ) !== \strlen( $string ) );
|
||||
$string = substr( $_string, 0, $length );
|
||||
$changedLength = ( strlen( $_string ) !== strlen( $string ) );
|
||||
$string = trim( $string, ". \n\r\t\v\x00" );
|
||||
if ( $changedLength )
|
||||
{
|
||||
$string = \trim( \substr( $string, 0, $length - 3 ), ". \n\r\t\v\x00" ) . '...';
|
||||
$string = trim( substr( $string, 0, $length - 3 ), ". \n\r\t\v\x00" ) . '...';
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
|
||||
@@ -10,21 +10,30 @@
|
||||
|
||||
namespace IPS\core\modules\admin\settings;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
|
||||
use DateInterval;
|
||||
use Exception;
|
||||
use IPS\core\AdminNotification;
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Email;
|
||||
use IPS\Dispatcher\Controller;
|
||||
use IPS\Email as EmailClass;
|
||||
use IPS\File;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\Color;
|
||||
use IPS\Helpers\Form\Email as FormEmail;
|
||||
use IPS\Helpers\Form\Interval;
|
||||
use IPS\Helpers\Form\Number;
|
||||
use IPS\Helpers\Form\Password;
|
||||
use IPS\Helpers\Form\Radio;
|
||||
use IPS\Helpers\Form\Select;
|
||||
use IPS\Helpers\Form\Text;
|
||||
use IPS\Helpers\Form\TextArea;
|
||||
use IPS\Helpers\Form\Upload;
|
||||
use IPS\Helpers\Form\YesNo;
|
||||
use IPS\Helpers\Table\Db as TableDb;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\Output;
|
||||
@@ -32,31 +41,35 @@ use IPS\Request;
|
||||
use IPS\Session;
|
||||
use IPS\Settings;
|
||||
use IPS\Theme;
|
||||
use function defined;
|
||||
use function get_class;
|
||||
use function is_string;
|
||||
use const IPS\CIC;
|
||||
use const IPS\DEMO_MODE;
|
||||
use const IPS\Helpers\Table\SEARCH_CONTAINS_TEXT;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* email
|
||||
*/
|
||||
class _email extends \IPS\Dispatcher\Controller
|
||||
class email 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
|
||||
{
|
||||
Dispatcher::i()->checkAcpPermission( 'email_manage' );
|
||||
parent::execute();
|
||||
@@ -67,33 +80,30 @@ class _email extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
protected function manage() : void
|
||||
{
|
||||
/* Build the settings form */
|
||||
$messageHtml = '';
|
||||
|
||||
$settingsForm = new Form( 'settings_form' );
|
||||
$settingsForm->addHeader( 'basic_settings' );
|
||||
$settingsForm->add( new FormEmail( 'email_out', Settings::i()->email_out, TRUE, [], NULL, NULL, NULL, 'email_out' ) );
|
||||
$settingsForm->add( new FormEmail( 'email_out', Settings::i()->email_out, TRUE, array(), NULL, NULL, NULL, 'email_out' ) );
|
||||
$settingsForm->add( new FormEmail( 'email_in', Settings::i()->email_in, TRUE ) );
|
||||
$settingsForm->add( new Color( 'email_color', Settings::i()->email_color, TRUE ) );
|
||||
$settingsForm->add( new Upload( 'email_logo', Settings::i()->email_logo ? File::get( 'core_Theme', Settings::i()->email_logo ) : NULL, FALSE, [ 'image' => TRUE, 'storageExtension' => 'core_Theme' ] ) );
|
||||
$settingsForm->add( new YesNo( 'social_links_in_email', Settings::i()->social_links_in_email, FALSE, [], NULL, NULL, NULL, 'social_links_in_email' ) );
|
||||
$settingsForm->add( new Upload( 'email_logo', Settings::i()->email_logo ? File::get( 'core_Theme', Settings::i()->email_logo ) : NULL, FALSE, array( 'image' => TRUE, 'storageExtension' => 'core_Theme' ) ) );
|
||||
$settingsForm->add( new YesNo( 'social_links_in_email', Settings::i()->social_links_in_email, FALSE, array(), NULL, NULL, NULL, 'social_links_in_email' ) );
|
||||
$settingsForm->add( new YesNo( 'our_picks_in_email', Settings::i()->our_picks_in_email, FALSE, array(), NULL, NULL, NULL, 'our_picks_in_email' ) );
|
||||
|
||||
if ( Settings::i()->promote_community_enabled )
|
||||
{
|
||||
$settingsForm->add( new YesNo( 'our_picks_in_email', Settings::i()->our_picks_in_email, FALSE, [], NULL, NULL, NULL, 'our_picks_in_email' ) );
|
||||
}
|
||||
|
||||
$settingsForm->add( new YesNo( 'email_truncate', ( Settings::i()->email_truncate ), FALSE, [], NULL, NULL, NULL, 'email_truncate' ) );
|
||||
$settingsForm->add( new YesNo( 'email_log_do', ( Settings::i()->prune_log_emailstats != 0 ), FALSE, [ 'togglesOn' => [ 'prune_log_emailstats' ] ], NULL, NULL, NULL, 'email_log_do' ) );
|
||||
$settingsForm->add( new Interval( 'prune_log_emailstats', Settings::i()->prune_log_emailstats ?: 60, FALSE, [ 'valueAs' => 'd', 'unlimited' => '-1', 'unlimitedLang' => 'never' ], NULL, NULL, NULL, 'prune_log_emailstats' ) );
|
||||
$settingsForm->add( new YesNo( 'email_truncate', ( Settings::i()->email_truncate ), FALSE, array(), NULL, NULL, NULL, 'email_truncate' ) );
|
||||
$settingsForm->add( new YesNo( 'email_log_do', ( Settings::i()->prune_log_emailstats != 0 ), FALSE, array( 'togglesOn' => array( 'prune_log_emailstats' ) ), NULL, NULL, NULL, 'email_log_do' ) );
|
||||
$settingsForm->add( new Interval( 'prune_log_emailstats', Settings::i()->prune_log_emailstats ?: 60, FALSE, array( 'valueAs' => 'd', 'unlimited' => '-1', 'unlimitedLang' => 'never' ), NULL, NULL, NULL, 'prune_log_emailstats' ) );
|
||||
if ( !DEMO_MODE )
|
||||
{
|
||||
$settingsForm->addHeader( 'advanced_settings' );
|
||||
|
||||
$method = Settings::i()->mail_method;
|
||||
$disabled = [];
|
||||
$disabled = array();
|
||||
|
||||
if ( Settings::i()->sendgrid_api_key AND Settings::i()->sendgrid_use_for > 0 )
|
||||
{
|
||||
@@ -113,49 +123,23 @@ class _email extends \IPS\Dispatcher\Controller
|
||||
$method = 'php';
|
||||
}
|
||||
|
||||
$debug = FALSE;
|
||||
if( Email::classToUse( Email::TYPE_TRANSACTIONAL ) == 'IPS\\Email\\Outgoing\\Debug' )
|
||||
$settingsForm->add( new Radio( 'mail_method', $method, TRUE, array(
|
||||
'options' => array( 'php' => ( CIC ? 'mail_method_cic' : 'mail_method_php' ), 'smtp' => 'mail_method_smtp', 'sendgrid' => 'mail_method_sendgrid' ),
|
||||
'disabled' => $disabled,
|
||||
'toggles' => array(
|
||||
'php' => array( 'php_mail_extra' ),
|
||||
'smtp' => array( 'smtp_host', 'smtp_port', 'smtp_user', 'smtp_pass', 'smtp_helo', 'smtp_protocol' ),
|
||||
)
|
||||
) ) );
|
||||
$options = array( 'plain' => 'smtp_plaintext', 'ssl' => 'smtp_ssl', 'tls' => 'smtp_tls' );
|
||||
$settingsForm->add( new Text( 'smtp_host', Settings::i()->smtp_host, FALSE, array(), NULL, NULL, NULL, 'smtp_host' ) );
|
||||
$settingsForm->add( new Select( 'smtp_protocol', Settings::i()->smtp_protocol, FALSE, array( 'options' => $options ), NULL, NULL, NULL, 'smtp_protocol' ) );
|
||||
$settingsForm->add( new Number( 'smtp_port', Settings::i()->smtp_port, FALSE, array(), NULL, NULL, NULL, 'smtp_port' ) );
|
||||
$settingsForm->add( new Text( 'smtp_user', Settings::i()->smtp_user, FALSE, array(), NULL, NULL, NULL, 'smtp_user' ) );
|
||||
$settingsForm->add( new Password( 'smtp_pass', Settings::i()->smtp_pass, FALSE, array( 'enforceMaxLimit' => FALSE ), NULL, NULL, NULL, 'smtp_pass' ) );
|
||||
if ( !CIC )
|
||||
{
|
||||
$debug = true;
|
||||
$method = 'debug';
|
||||
}
|
||||
|
||||
$mailOptions = $toggles = $fields = [];
|
||||
foreach( Email::outgoingHandlers() as $key => $handler )
|
||||
{
|
||||
if( ! $handler::isUsable( Email::TYPE_TRANSACTIONAL ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
$mailOptions[ $key ] = 'mail_method_' . $key;
|
||||
|
||||
$formFields = $handler::form();
|
||||
$toggles[ $key ] = array_keys( $formFields );
|
||||
$fields = $fields + $formFields;
|
||||
}
|
||||
|
||||
/* Change value back to default for platform */
|
||||
if( !\in_array( $method, array_keys( $mailOptions ) ) )
|
||||
{
|
||||
$method = \IPS\CIC ? 'cloud' : 'php';
|
||||
}
|
||||
|
||||
if( !$debug )
|
||||
{
|
||||
$settingsForm->add( new Radio( 'mail_method', $method, TRUE, [
|
||||
'options' => $mailOptions,
|
||||
'disabled' => $disabled,
|
||||
'toggles' => $toggles
|
||||
] ) );
|
||||
|
||||
foreach( $fields as $f )
|
||||
{
|
||||
$settingsForm->add( $f );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$settingsForm->addDummy( 'mail_method', Member::loggedIn()->language()->addToStack('mail_method_debug', false, [ 'sprintf' => [ \IPS\EMAIL_DEBUG_PATH ] ] ) );
|
||||
$settingsForm->add( new Text( 'php_mail_extra', Settings::i()->php_mail_extra, FALSE, array(), NULL, NULL, NULL, 'php_mail_extra' ) );
|
||||
}
|
||||
}
|
||||
if ( $values = $settingsForm->values() )
|
||||
@@ -176,11 +160,14 @@ class _email extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
|
||||
unset( $values['email_log_do'] );
|
||||
|
||||
/* Allow individual handlers to save settings */
|
||||
foreach( Email::outgoingHandlers() as $key => $handler )
|
||||
|
||||
if ( $values['mail_method'] != 'sendgrid' and Settings::i()->sendgrid_use_for == 2 )
|
||||
{
|
||||
$values = $handler::processSettings( $values );
|
||||
$values['sendgrid_use_for'] = 1;
|
||||
}
|
||||
elseif ( $values['mail_method'] == 'sendgrid' )
|
||||
{
|
||||
$values['sendgrid_use_for'] = 2;
|
||||
}
|
||||
|
||||
if ( $values['email_logo'] )
|
||||
@@ -193,27 +180,31 @@ class _email extends \IPS\Dispatcher\Controller
|
||||
|
||||
if( $sendTestEmail )
|
||||
{
|
||||
$email = Email::buildFromContent( Member::loggedIn()->language()->get('email_test_subject'), Member::loggedIn()->language()->addToStack('email_test_message'), Member::loggedIn()->language()->addToStack('email_test_message'), Email::TYPE_BULK );
|
||||
$email = EmailClass::buildFromContent( Member::loggedIn()->language()->get('email_test_subject'), Member::loggedIn()->language()->addToStack('email_test_message'), Member::loggedIn()->language()->addToStack('email_test_message'), EmailClass::TYPE_BULK );
|
||||
|
||||
try
|
||||
{
|
||||
$email->_send( Member::loggedIn(), fromEmail: Settings::i()->email_out );
|
||||
$messageHtml = Theme::i()->getTemplate( 'global', 'core', 'global' )->message( 'email_test_okay_auto', 'success' );
|
||||
$result = $email->send( to: Member::loggedIn(), fromEmail: Settings::i()->email_out, returnException: TRUE );
|
||||
if( $result )
|
||||
{
|
||||
$messageHtml = Theme::i()->getTemplate( 'global', 'core', 'global' )->message( 'email_test_okay_auto', 'success' );
|
||||
}
|
||||
|
||||
/* Sent successfully, remove notification */
|
||||
AdminNotification::remove( 'core', 'ConfigurationError', 'failedMail' );
|
||||
Db::i()->update( 'core_mail_error_logs', [ 'mlog_notification_sent' => TRUE ] );
|
||||
Db::i()->update( 'core_mail_error_logs', array( 'mlog_notification_sent' => TRUE ) );
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
catch ( Exception $e )
|
||||
{
|
||||
$messageHtml = Theme::i()->getTemplate( 'global', 'core', 'global' )->message( 'email_test_error_auto', 'error', $e->getMessage() );
|
||||
$messageHtml = Theme::i()->getTemplate( 'global', 'core', 'global' )->message( $e->getMessage() ?: 'email_test_error_auto', 'error', $e->getMessage() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Build the test form */
|
||||
$testFormHtml = '';
|
||||
if ( !DEMO_MODE AND Member::loggedIn()->hasAcpRestriction( 'core', 'settings', 'email_test' ) )
|
||||
if ( !DEMO_MODE AND Member::loggedIn()->hasAcpRestriction( 'core', 'settings', 'email_test' ) )
|
||||
{
|
||||
Output::i()->sidebar['actions']['test'] = array(
|
||||
'title' => 'email_test',
|
||||
@@ -231,23 +222,26 @@ class _email extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
try
|
||||
{
|
||||
$email = Email::buildFromContent( $values['subject'], $values['message'], $values['message'], Email::TYPE_BULK );
|
||||
$email->_send( $values['to'], fromEmail: $values['from'] );
|
||||
|
||||
$email = EmailClass::buildFromContent( $values['subject'], $values['message'], $values['message'], EmailClass::TYPE_BULK );
|
||||
$result = $email->send( to: $values['to'], fromEmail: $values['from'], returnException: TRUE );
|
||||
|
||||
/* Sent successfully, remove notification */
|
||||
AdminNotification::remove( 'core', 'ConfigurationError', 'failedMail' );
|
||||
Db::i()->update( 'core_mail_error_logs', array( 'mlog_notification_sent' => TRUE ) );
|
||||
if( $result )
|
||||
{
|
||||
$messageHtml = Theme::i()->getTemplate( 'global', 'core', 'global' )->message( 'email_test_okay', 'success' );
|
||||
}
|
||||
|
||||
$messageHtml = Theme::i()->getTemplate( 'global', 'core', 'global' )->message( 'email_test_okay', 'success' );
|
||||
}
|
||||
catch ( \Exception $exception )
|
||||
catch ( Exception $exception )
|
||||
{
|
||||
$content = $exception->getMessage();
|
||||
if ( !( $exception instanceof \IPS\Email\Outgoing\Exception ) )
|
||||
{
|
||||
$content = \get_class( $exception ) . ": " . $exception->getMessage() . " (" . $exception->getCode() . ")";
|
||||
$content = get_class( $exception ) . ": " . $exception->getMessage() . " (" . $exception->getCode() . ")";
|
||||
}
|
||||
$messageHtml = Theme::i()->getTemplate( 'global', 'core', 'global' )->message( $content ?: 'email_test_error_auto', 'error' );
|
||||
$messageHtml = Theme::i()->getTemplate( 'global', 'core', 'global' )->message( $content, 'error' );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -265,7 +259,7 @@ class _email extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
|
||||
/* Display */
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('email_settings');
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('email_settings');
|
||||
Output::i()->output = $messageHtml;
|
||||
Output::i()->output .= Theme::i()->getTemplate( 'global' )->block( 'email_settings', $settingsForm );
|
||||
Output::i()->output .= $testFormHtml;
|
||||
@@ -276,7 +270,7 @@ class _email extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function errorLog()
|
||||
protected function errorLog() : void
|
||||
{
|
||||
Dispatcher::i()->checkAcpPermission( 'email_errorlog' );
|
||||
|
||||
@@ -303,12 +297,12 @@ class _email extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @param Url $url Base URL for table
|
||||
* @param array $where Where Array
|
||||
* @return \IPS\Helpers\Table\Db
|
||||
* @return TableDb
|
||||
*/
|
||||
public static function emailErrorLogTable( Url $url, array $where=array() ): \IPS\Helpers\Table\Db
|
||||
public static function emailErrorLogTable( Url $url, array $where=array() ): TableDb
|
||||
{
|
||||
/* Create the table */
|
||||
$table = new \IPS\Helpers\Table\Db( 'core_mail_error_logs', $url, $where );
|
||||
$table = new TableDb( 'core_mail_error_logs', $url, $where );
|
||||
$table->langPrefix = 'emailerrorlogs_';
|
||||
|
||||
/* Columns we need */
|
||||
@@ -322,16 +316,16 @@ class _email extends \IPS\Dispatcher\Controller
|
||||
/* Search */
|
||||
$table->quickSearch = 'mlog_to';
|
||||
$table->advancedSearch = array(
|
||||
'mlog_to' => \IPS\Helpers\Table\SEARCH_CONTAINS_TEXT,
|
||||
'mlog_from' => \IPS\Helpers\Table\SEARCH_CONTAINS_TEXT,
|
||||
'mlog_subject' => \IPS\Helpers\Table\SEARCH_CONTAINS_TEXT,
|
||||
'mlog_msg' => \IPS\Helpers\Table\SEARCH_CONTAINS_TEXT,
|
||||
'mlog_content' => \IPS\Helpers\Table\SEARCH_CONTAINS_TEXT,
|
||||
'mlog_to' => SEARCH_CONTAINS_TEXT,
|
||||
'mlog_from' => SEARCH_CONTAINS_TEXT,
|
||||
'mlog_subject' => SEARCH_CONTAINS_TEXT,
|
||||
'mlog_msg' => SEARCH_CONTAINS_TEXT,
|
||||
'mlog_content' => SEARCH_CONTAINS_TEXT,
|
||||
);
|
||||
|
||||
/* Custom parsers */
|
||||
$table->parsers = array(
|
||||
'mlog_date' => function( $val, $row )
|
||||
'mlog_date' => function( $val )
|
||||
{
|
||||
return DateTime::ts( $val );
|
||||
},
|
||||
@@ -348,7 +342,7 @@ class _email extends \IPS\Dispatcher\Controller
|
||||
/* We may not have a 'message' key if this is an older SendGrid log entry */
|
||||
if( isset( $data['message'] ) )
|
||||
{
|
||||
$val = \is_string( $data['message'] ) ?
|
||||
$val = is_string( $data['message'] ) ?
|
||||
( ( isset( $data['details'] ) AND $data['details'] ) ? Member::loggedIn()->language()->addToStack( $data['message'], FALSE, array( 'sprintf' => $data['details'] ) ) : Member::loggedIn()->language()->addToStack( $data['message'] ) ) :
|
||||
$val;
|
||||
}
|
||||
@@ -394,7 +388,7 @@ class _email extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function errorLogResend()
|
||||
public function errorLogResend() : void
|
||||
{
|
||||
Dispatcher::i()->checkAcpPermission( 'email_errorlog' );
|
||||
Session::i()->csrfCheck();
|
||||
@@ -416,7 +410,7 @@ class _email extends \IPS\Dispatcher\Controller
|
||||
unset( $emailData['headers']['Content-Type'] );
|
||||
unset( $emailData['headers']['Content-Transfer-Encoding'] );
|
||||
|
||||
$email = Email::buildFromContent( $log['mlog_subject'], $emailData['body']['html'], $emailData['body']['plain'], isset( $emailData['type'] ) ? $emailData['type'] : Email::TYPE_TRANSACTIONAL );
|
||||
$email = EmailClass::buildFromContent( $log['mlog_subject'], $emailData['body']['html'], $emailData['body']['plain'], $emailData['type'] ?? EmailClass::TYPE_TRANSACTIONAL );
|
||||
$email->_send(
|
||||
array_map( 'trim', explode( ',', $log['mlog_to'] ) ),
|
||||
isset( $emailData['headers']['Cc'] ) ? array_map( 'trim', explode( ',', $emailData['headers']['Cc'] ) ) : array(),
|
||||
@@ -426,7 +420,7 @@ class _email extends \IPS\Dispatcher\Controller
|
||||
$emailData['headers']
|
||||
);
|
||||
}
|
||||
catch( \Exception $e )
|
||||
catch( Exception $e )
|
||||
{
|
||||
Output::i()->error( $e->getMessage(), '4C143/1', 500, '' );
|
||||
}
|
||||
@@ -434,7 +428,7 @@ class _email extends \IPS\Dispatcher\Controller
|
||||
Db::i()->delete( 'core_mail_error_logs', array( 'mlog_id=?', $id ) );
|
||||
|
||||
/* Remove notification since this was re-sent with success and it is below the recent threshold */
|
||||
if( Email::countFailedMail( DateTime::create()->sub( new \DateInterval( 'P3D' ) ), FALSE, TRUE ) <= 3 )
|
||||
if( EmailClass::countFailedMail( DateTime::create()->sub( new DateInterval( 'P3D' ) ), FALSE, TRUE ) <= 3 )
|
||||
{
|
||||
AdminNotification::remove( 'core', 'ConfigurationError', 'failedMail' );
|
||||
Db::i()->update( 'core_mail_error_logs', array( 'mlog_notification_sent' => TRUE ), array( 'mlog_id=?', $id ) );
|
||||
@@ -448,7 +442,7 @@ class _email extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function errorLogView()
|
||||
public function errorLogView() : void
|
||||
{
|
||||
Dispatcher::i()->checkAcpPermission( 'email_errorlog' );
|
||||
|
||||
@@ -463,7 +457,7 @@ class _email extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function errorLogSettings()
|
||||
protected function errorLogSettings() : void
|
||||
{
|
||||
Dispatcher::i()->checkAcpPermission( 'email_errorlog_prune' );
|
||||
|
||||
|
||||
@@ -11,30 +11,57 @@
|
||||
namespace IPS\core\modules\admin\settings;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\core\AdminNotification;
|
||||
use IPS\Data\Store;
|
||||
use IPS\Db;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Dispatcher\Controller;
|
||||
use IPS\GeoLocation;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\Address;
|
||||
use IPS\Helpers\Form\CheckboxSet;
|
||||
use IPS\Helpers\Form\Editor;
|
||||
use IPS\Helpers\Form\Stack;
|
||||
use IPS\Helpers\Form\Text;
|
||||
use IPS\Helpers\Form\Translatable;
|
||||
use IPS\Helpers\Form\Url as FormUrl;
|
||||
use IPS\Helpers\Form\YesNo;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Lang;
|
||||
use IPS\Member;
|
||||
use IPS\Output;
|
||||
use IPS\Session;
|
||||
use IPS\Settings;
|
||||
use IPS\Theme;
|
||||
use function defined;
|
||||
use function in_array;
|
||||
use function intval;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* general
|
||||
*/
|
||||
class _general extends \IPS\Dispatcher\Controller
|
||||
class general 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( 'general_manage' );
|
||||
Dispatcher::i()->checkAcpPermission( 'general_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
@@ -43,27 +70,31 @@ class _general extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
protected function manage() : void
|
||||
{
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'board_name', \IPS\Settings::i()->board_name, TRUE ) );
|
||||
$form = new Form;
|
||||
$form->add( new Text( 'board_name', Settings::i()->board_name, TRUE ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'site_online', \IPS\Settings::i()->site_online, FALSE, array(
|
||||
$form->add( new YesNo( 'site_online', Settings::i()->site_online, FALSE, array(
|
||||
'togglesOff' => array( 'site_offline_message_id' ),
|
||||
) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Editor( 'site_offline_message', \IPS\Settings::i()->site_offline_message, FALSE, array( 'app' => 'core', 'key' => 'Admin', 'autoSaveKey' => 'onlineoffline', 'attachIds' => array( NULL, NULL, 'site_offline_message' ) ), NULL, NULL, NULL, 'site_offline_message_id' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Address( 'site_address', \IPS\GeoLocation::buildFromJson( \IPS\Settings::i()->site_address ), FALSE ) );
|
||||
$form->add( new \IPS\Helpers\Form\Stack( 'site_social_profiles', \IPS\Settings::i()->site_social_profiles ? json_decode( \IPS\Settings::i()->site_social_profiles, true ) : array(), FALSE, array( 'stackFieldType' => '\IPS\core\Form\SocialProfiles', 'maxItems' => 50, 'key' => array( 'placeholder' => 'http://example.com', 'size' => 20 ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'site_twitter_id', \IPS\Settings::i()->site_twitter_id, FALSE, array( 'placeholder' => \IPS\Member::loggedIn()->language()->addToStack('site_twitter_id_placeholder'), 'size' => 20 ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Translatable( 'copyright_line', NULL, FALSE, array( 'app' => 'core', 'key' => 'copyright_line_value', 'placeholder' => \IPS\Member::loggedIn()->language()->addToStack('copyright_line_placeholder') ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'relative_dates_enable', \IPS\Settings::i()->relative_dates_enable, FALSE ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'site_site_elsewhere', \IPS\Settings::i()->site_site_elsewhere, FALSE, [ 'togglesOn' => [ 'site_main_url', 'site_main_title' ] ] ) );
|
||||
$form->add( new \IPS\Helpers\Form\Url( 'site_main_url', \IPS\Settings::i()->site_main_url, FALSE, [], NULL, NULL, NULL, 'site_main_url' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'site_main_title', \IPS\Settings::i()->site_main_title, FALSE, [], NULL, NULL, NULL, 'site_main_title' ) );
|
||||
|
||||
$form->add( new Editor( 'site_offline_message', Settings::i()->site_offline_message, FALSE, array( 'app' => 'core', 'key' => 'Admin', 'autoSaveKey' => 'onlineoffline', 'attachIds' => array( NULL, NULL, 'site_offline_message' ) ), NULL, NULL, NULL, 'site_offline_message_id' ) );
|
||||
$form->add( new Address( 'site_address', GeoLocation::buildFromJson( Settings::i()->site_address ), FALSE ) );
|
||||
$form->add( new Stack( 'site_social_profiles', Settings::i()->site_social_profiles ? json_decode( Settings::i()->site_social_profiles, true ) : array(), FALSE, array( 'stackFieldType' => '\IPS\core\Form\SocialProfiles', 'maxItems' => 50, 'key' => array( 'placeholder' => 'https://example.com', 'size' => 20 ) ) ) );
|
||||
$form->add( new Text( 'site_twitter_id', Settings::i()->site_twitter_id, FALSE, array( 'placeholder' => Member::loggedIn()->language()->addToStack('site_twitter_id_placeholder'), 'size' => 20 ) ) );
|
||||
$form->add( new Translatable( 'copyright_line', NULL, FALSE, array( 'app' => 'core', 'key' => 'copyright_line_value', 'placeholder' => Member::loggedIn()->language()->addToStack('copyright_line_placeholder') ) ) );
|
||||
$form->add( new YesNo( 'relative_dates_enable', Settings::i()->relative_dates_enable, FALSE ) );
|
||||
$form->add( new YesNo( 'site_site_elsewhere', Settings::i()->site_site_elsewhere, FALSE, [ 'togglesOn' => [ 'site_main_url', 'site_main_title' ] ] ) );
|
||||
$form->add( new FormUrl( 'site_main_url', Settings::i()->site_main_url, FALSE, [], NULL, NULL, NULL, 'site_main_url' ) );
|
||||
$form->add( new Text( 'site_main_title', Settings::i()->site_main_title, FALSE, [], NULL, NULL, NULL, 'site_main_title' ) );
|
||||
$form->add( new CheckboxSet( 'diagnostics_reporting', array( 'usage' => ( (bool) Settings::i()->usage_reporting ), 'diagnostics' => ( (bool) Settings::i()->diagnostics_reporting ) ), FALSE, array( 'options' => array(
|
||||
'usage' => 'diagnostics_reporting_usage',
|
||||
'diagnostics' => 'diagnostics_reporting_diagnostics',
|
||||
) ) ) );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
\IPS\Lang::saveCustom( 'core', "copyright_line_value", $values['copyright_line'] );
|
||||
Lang::saveCustom( 'core', "copyright_line_value", $values['copyright_line'] );
|
||||
unset( $values['copyright_line'] );
|
||||
|
||||
array_walk( $values['site_social_profiles'], function( &$value ){
|
||||
@@ -74,30 +105,31 @@ class _general extends \IPS\Dispatcher\Controller
|
||||
} ) );
|
||||
|
||||
$values['site_address'] = json_encode( $values['site_address'] );
|
||||
|
||||
|
||||
$values['usage_reporting'] = in_array( 'usage', $values['diagnostics_reporting'] );
|
||||
$values['diagnostics_reporting'] = in_array( 'diagnostics', $values['diagnostics_reporting'] );
|
||||
Db::i()->update( 'core_tasks', array( 'enabled' => intval( $values['usage_reporting'] ) ), array( '`key`=?', 'usagereporting' ) );
|
||||
|
||||
$form->saveAsSettings( $values );
|
||||
|
||||
if ( $values['site_online'] )
|
||||
{
|
||||
\IPS\core\AdminNotification::remove( 'core', 'ConfigurationError', 'siteOffline' );
|
||||
AdminNotification::remove( 'core', 'ConfigurationError', 'siteOffline' );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\core\AdminNotification::send( 'core', 'ConfigurationError', 'siteOffline', FALSE, NULL, \IPS\Member::loggedIn() );
|
||||
AdminNotification::send( 'core', 'ConfigurationError', 'siteOffline', FALSE, NULL, Member::loggedIn() );
|
||||
}
|
||||
|
||||
/* Clear guest page caches */
|
||||
\IPS\Data\Cache::i()->clearAll();
|
||||
|
||||
/* Clear manifest and ie browser data stores */
|
||||
unset( \IPS\Data\Store::i()->manifest, \IPS\Data\Store::i()->iebrowserconfig );
|
||||
unset( Store::i()->manifest, Store::i()->iebrowserconfig );
|
||||
|
||||
\IPS\Session::i()->log( 'acplogs__general_settings' );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=settings&controller=general' ), 'saved' );
|
||||
Session::i()->log( 'acplogs__general_settings' );
|
||||
Output::i()->redirect( Url::internal( 'app=core&module=settings&controller=general' ), 'saved' );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__core_settings_general');
|
||||
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'global' )->block( 'menu__core_settings_general', $form );
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'settings/general.css', 'core', 'admin' ) );
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('menu__core_settings_general');
|
||||
Output::i()->output .= Theme::i()->getTemplate( 'global' )->block( 'menu__core_settings_general', $form );
|
||||
Output::i()->cssFiles = array_merge( Output::i()->cssFiles, Theme::i()->css( 'settings/general.css', 'core', 'admin' ) );
|
||||
}
|
||||
}
|
||||
@@ -11,35 +11,53 @@
|
||||
namespace IPS\core\modules\admin\settings;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Application;
|
||||
use IPS\core\AdminNotification;
|
||||
use IPS\Data\Store;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Dispatcher\Controller;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\Text;
|
||||
use IPS\Http\Url;
|
||||
use IPS\IPS;
|
||||
use IPS\Member;
|
||||
use IPS\Output;
|
||||
use IPS\Request;
|
||||
use IPS\Session;
|
||||
use IPS\Settings;
|
||||
use IPS\Theme;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* licensekey
|
||||
*/
|
||||
class _licensekey extends \IPS\Dispatcher\Controller
|
||||
class licensekey extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* @brief Data about the license key from the store
|
||||
*/
|
||||
protected $licenseData = array();
|
||||
protected array $licenseData = array();
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'licensekey_manage' );
|
||||
Dispatcher::i()->checkAcpPermission( 'licensekey_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
@@ -48,42 +66,43 @@ class _licensekey extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
protected function manage() : void
|
||||
{
|
||||
/* Get license info. If license info is empty, refresh it. */
|
||||
$licenseData = \IPS\IPS::licenseKey();
|
||||
$licenseData = IPS::licenseKey();
|
||||
|
||||
/* If no license key has been supplied yet just show the form */
|
||||
if( !\IPS\Settings::i()->ipb_reg_number )
|
||||
if( !Settings::i()->ipb_reg_number )
|
||||
{
|
||||
return $this->settings();
|
||||
$this->settings();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Init */
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('license_settings');
|
||||
\IPS\Output::i()->sidebar['actions'] = array(
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('license_settings');
|
||||
Output::i()->sidebar['actions'] = array(
|
||||
'refresh' => array(
|
||||
'icon' => 'refresh',
|
||||
'link' => \IPS\Http\Url::internal( 'app=core&module=settings&controller=licensekey&do=refresh' )->csrf(),
|
||||
'link' => Url::internal( 'app=core&module=settings&controller=licensekey&do=refresh' )->csrf(),
|
||||
'title' => 'license_refresh',
|
||||
),
|
||||
'remove' => array(
|
||||
'icon' => 'pencil',
|
||||
'link' => \IPS\Http\Url::internal( 'app=core&module=settings&controller=licensekey&do=settings' ),
|
||||
'link' => Url::internal( 'app=core&module=settings&controller=licensekey&do=settings' ),
|
||||
'title' => 'license_change',
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('license_change') )
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => Member::loggedIn()->language()->addToStack('license_change') )
|
||||
),
|
||||
);
|
||||
|
||||
/* If we have a license key, but the server doesn't recognise it, show an error */
|
||||
if ( !$licenseData )
|
||||
{
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->message( 'license_not_recognised', 'error' );
|
||||
Output::i()->output = Theme::i()->getTemplate( 'global', 'core' )->message( 'license_not_recognised', 'error' );
|
||||
}
|
||||
/* Otherwise show the normal info */
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'licensekey', 'core' )->overview( $licenseData );
|
||||
Output::i()->output = Theme::i()->getTemplate( 'licensekey', 'core' )->overview( $licenseData );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,22 +111,22 @@ class _licensekey extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function refresh()
|
||||
protected function refresh() : void
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
Session::i()->csrfCheck();
|
||||
|
||||
/* Fetch the license key data and update our local storage */
|
||||
\IPS\IPS::licenseKey( TRUE );
|
||||
IPS::licenseKey( TRUE );
|
||||
|
||||
/* Return the overview screen afterwards */
|
||||
if ( isset( \IPS\Request::i()->return ) and \IPS\Request::i()->return === 'cloud' and \IPS\Application::appIsEnabled('cloud') )
|
||||
if ( isset( Request::i()->return ) and Request::i()->return === 'cloud' and Application::appIsEnabled('cloud') )
|
||||
{
|
||||
\IPS\cloud\Application::toggleDisabledApps();
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=cloud&module=smartcommunity&controller=smartcommunity' ), 'cloud_license_refreshed' );
|
||||
Output::i()->redirect( Url::internal( 'app=cloud&module=smartcommunity&controller=smartcommunity' ), 'cloud_license_refreshed' );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=settings&controller=licensekey' ), 'license_key_refreshed' );
|
||||
Output::i()->redirect( Url::internal( 'app=core&module=settings&controller=licensekey' ), 'license_key_refreshed' );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,32 +135,12 @@ class _licensekey extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function settings()
|
||||
protected function settings() : void
|
||||
{
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->addHeader('ipb_license_edit_main');
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'ipb_reg_number', \IPS\Settings::i()->ipb_reg_number, TRUE ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'ipb_license_active', \IPS\Settings::i()->ipb_license_active ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'ipb_license_expires', \IPS\Settings::i()->ipb_license_expires ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'ipb_license_cloud', \IPS\Settings::i()->ipb_license_cloud ) );
|
||||
|
||||
$form->addHeader('ipb_license_urls');
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'ipb_license_url', \IPS\Settings::i()->ipb_license_url ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'ipb_license_test_url', \IPS\Settings::i()->ipb_license_test_url ) );
|
||||
|
||||
$form->addHeader('ipb_license_components');
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'ipb_license_product_forums', \IPS\Settings::i()->ipb_license_product_forums ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'ipb_license_product_calendar', \IPS\Settings::i()->ipb_license_product_calendar ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'ipb_license_product_blog', \IPS\Settings::i()->ipb_license_product_blog ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'ipb_license_product_gallery', \IPS\Settings::i()->ipb_license_product_gallery ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'ipb_license_product_downloads', \IPS\Settings::i()->ipb_license_product_downloads ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'ipb_license_product_cms', \IPS\Settings::i()->ipb_license_product_cms ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'ipb_license_product_nexus', \IPS\Settings::i()->ipb_license_product_nexus ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'ipb_license_product_copyright', \IPS\Settings::i()->ipb_license_product_copyright ) );
|
||||
|
||||
$form->addHeader('ipb_license_services');
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'ipb_license_chat_limit', \IPS\Settings::i()->ipb_license_chat_limit ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'ipb_license_support', \IPS\Settings::i()->ipb_license_support ) );
|
||||
$form = new Form;
|
||||
$form->add( new Text( 'ipb_reg_number', NULL, TRUE, array(), function( $val ){
|
||||
IPS::checkLicenseKey( $val, Settings::i()->base_url );
|
||||
} ) );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
@@ -153,17 +152,17 @@ class _licensekey extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
|
||||
$form->saveAsSettings( $values );
|
||||
\IPS\Session::i()->log( 'acplogs__license_settings' );
|
||||
Session::i()->log( 'acplogs__license_settings' );
|
||||
|
||||
/* Refresh the locally stored license info */
|
||||
unset( \IPS\Data\Store::i()->license_data );
|
||||
unset( Store::i()->license_data );
|
||||
|
||||
\IPS\core\AdminNotification::remove( 'core', 'License', 'missing' );
|
||||
AdminNotification::remove( 'core', 'License', 'missing' );
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=settings&controller=licensekey' ), 'saved' );
|
||||
Output::i()->redirect( Url::internal( 'app=core&module=settings&controller=licensekey' ), 'saved' );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('license_settings');
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global' )->block( 'menu__core_settings_licensekey', $form );
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('license_settings');
|
||||
Output::i()->output = Theme::i()->getTemplate( 'global' )->block( 'menu__core_settings_licensekey', $form );
|
||||
}
|
||||
}
|
||||
@@ -11,41 +11,76 @@
|
||||
namespace IPS\core\modules\admin\settings;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DomainException;
|
||||
use IPS\Application;
|
||||
use IPS\Data\Cache;
|
||||
use IPS\Data\Store;
|
||||
use IPS\Db;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Extensions\SSOAbstract;
|
||||
use IPS\GeoLocation;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\Address;
|
||||
use IPS\Helpers\Form\Interval;
|
||||
use IPS\Helpers\Form\Number;
|
||||
use IPS\Helpers\Form\Radio;
|
||||
use IPS\Helpers\Form\Stack;
|
||||
use IPS\Helpers\Form\Tel;
|
||||
use IPS\Helpers\Form\Url as FormUrl;
|
||||
use IPS\Helpers\Form\YesNo;
|
||||
use IPS\Helpers\Wizard;
|
||||
use IPS\Http\Request\Exception;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Login as LoginClass;
|
||||
use IPS\Login\Handler;
|
||||
use IPS\Member;
|
||||
use IPS\Member\Group;
|
||||
use IPS\Node\Controller;
|
||||
use IPS\Output;
|
||||
use IPS\Request;
|
||||
use IPS\Session;
|
||||
use IPS\Settings;
|
||||
use IPS\Theme;
|
||||
use LogicException;
|
||||
use function defined;
|
||||
use function is_array;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Login Methods
|
||||
*/
|
||||
class _login extends \IPS\Node\Controller
|
||||
class login extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Node Class
|
||||
*/
|
||||
protected $nodeClass = 'IPS\Login\Handler';
|
||||
protected string $nodeClass = 'IPS\Login\Handler';
|
||||
|
||||
/**
|
||||
* Show the "add" button in the page root rather than the table root
|
||||
*/
|
||||
protected $_addButtonInRoot = FALSE;
|
||||
protected bool $_addButtonInRoot = FALSE;
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'login_access' );
|
||||
return parent::execute();
|
||||
Dispatcher::i()->checkAcpPermission( 'login_access' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -53,7 +88,7 @@ class _login extends \IPS\Node\Controller
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function _getRootButtons()
|
||||
public function _getRootButtons(): array
|
||||
{
|
||||
$buttons = parent::_getRootButtons();
|
||||
|
||||
@@ -70,31 +105,31 @@ class _login extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
protected function manage() : void
|
||||
{
|
||||
/* Work out tabs */
|
||||
$tabs = array();
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'settings', 'login_manage' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'core', 'settings', 'login_manage' ) )
|
||||
{
|
||||
$tabs['handlers'] = 'login_handlers';
|
||||
}
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'settings', 'login_settings' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'core', 'settings', 'login_settings' ) )
|
||||
{
|
||||
$tabs['settings'] = 'login_settings';
|
||||
}
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'settings', 'registration_settings' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'core', 'settings', 'registration_settings' ) )
|
||||
{
|
||||
$tabs['registration'] = 'registration_settings';
|
||||
}
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'settings', 'login_account_management' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'core', 'settings', 'login_account_management' ) )
|
||||
{
|
||||
$tabs['accountsettings'] = 'account_management_settings';
|
||||
}
|
||||
|
||||
/* Get active tab */
|
||||
if ( isset( \IPS\Request::i()->tab ) and isset( $tabs[ \IPS\Request::i()->tab ] ) )
|
||||
if ( isset( Request::i()->tab ) and isset( $tabs[ Request::i()->tab ] ) )
|
||||
{
|
||||
$activeTab = \IPS\Request::i()->tab;
|
||||
$activeTab = Request::i()->tab;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -107,9 +142,9 @@ class _login extends \IPS\Node\Controller
|
||||
switch ( $activeTab )
|
||||
{
|
||||
case 'handlers':
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'login_manage' );
|
||||
Dispatcher::i()->checkAcpPermission( 'login_manage' );
|
||||
parent::manage();
|
||||
$output = \IPS\Output::i()->output;
|
||||
$output = Output::i()->output;
|
||||
break;
|
||||
case 'settings':
|
||||
$output = $this->_settings();
|
||||
@@ -123,22 +158,22 @@ class _login extends \IPS\Node\Controller
|
||||
}
|
||||
|
||||
/* Output */
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__core_settings_login');
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('menu__core_settings_login');
|
||||
if ( Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->output = $output;
|
||||
Output::i()->output = $output;
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->sidebar['actions'] = array(
|
||||
Output::i()->sidebar['actions'] = array(
|
||||
'forcelogout' => array(
|
||||
'title' => 'force_all_logout',
|
||||
'icon' => 'lock',
|
||||
'link' => \IPS\Http\Url::internal( 'app=core&module=settings&controller=login&do=forceLogout' )->csrf(),
|
||||
'link' => Url::internal( 'app=core&module=settings&controller=login&do=forceLogout' )->csrf(),
|
||||
'data' => array( 'confirm' => '' ),
|
||||
),
|
||||
);
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->tabs( $tabs, $activeTab, $output, \IPS\Http\Url::internal( "app=core&module=settings&controller=login" ) );
|
||||
Output::i()->output = Theme::i()->getTemplate( 'global', 'core' )->tabs( $tabs, $activeTab, $output, Url::internal( "app=core&module=settings&controller=login" ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,23 +182,24 @@ class _login extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function form()
|
||||
protected function form() : void
|
||||
{
|
||||
if ( \IPS\Request::i()->id )
|
||||
if ( Request::i()->id )
|
||||
{
|
||||
return parent::form();
|
||||
parent::form();
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->output = (string) new \IPS\Helpers\Wizard( array(
|
||||
Output::i()->output = (string) new Wizard( array(
|
||||
'login_handler' => function( $data )
|
||||
{
|
||||
$options = array();
|
||||
foreach ( \IPS\Login\Handler::handlerClasses() as $class )
|
||||
foreach ( Handler::handlerClasses() as $class )
|
||||
{
|
||||
/* @var Handler $class */
|
||||
if ( !$class::$allowMultiple )
|
||||
{
|
||||
foreach ( \IPS\Login\Handler::roots() as $handler )
|
||||
foreach ( Handler::roots() as $handler )
|
||||
{
|
||||
if ( $handler instanceof $class )
|
||||
{
|
||||
@@ -174,8 +210,8 @@ class _login extends \IPS\Node\Controller
|
||||
$options[ $class ] = $class::getTitle();
|
||||
}
|
||||
|
||||
$form = new \IPS\Helpers\Form( 'login_handler_1', 'continue' );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'login_handler', TRUE, NULL, array( 'options' => $options ), function( $val )
|
||||
$form = new Form( 'login_handler_1', 'continue' );
|
||||
$form->add( new Radio( 'login_handler', TRUE, NULL, array( 'options' => $options ), function( $val )
|
||||
{
|
||||
$val::testCompatibility();
|
||||
} ) );
|
||||
@@ -195,21 +231,21 @@ class _login extends \IPS\Node\Controller
|
||||
try
|
||||
{
|
||||
$node->settings = array();
|
||||
$node->order = \IPS\Db::i()->select( 'MAX(login_order)', $node::$databaseTable )->first() + 1;
|
||||
$node->order = Db::i()->select( 'MAX(login_order)', $node::$databaseTable )->first() + 1;
|
||||
$node->saveForm( $node->formatFormValues( $values ) );
|
||||
|
||||
\IPS\Session::i()->log( 'acplog__node_created', array( $this->title => TRUE, $node->titleForLog() => FALSE ) );
|
||||
Session::i()->log( 'acplog__node_created', array( $this->title => TRUE, $node->titleForLog() => FALSE ) );
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=core&module=settings&controller=login') );
|
||||
Output::i()->redirect( Url::internal('app=core&module=settings&controller=login') );
|
||||
}
|
||||
catch ( \LogicException $e )
|
||||
catch ( LogicException $e )
|
||||
{
|
||||
$form->error = $e->getMessage();
|
||||
}
|
||||
}
|
||||
return $form;
|
||||
}
|
||||
), \IPS\Http\Url::internal('app=core&module=settings&controller=login&do=form') );
|
||||
), Url::internal('app=core&module=settings&controller=login&do=form') );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,13 +255,13 @@ class _login extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function enableToggle()
|
||||
protected function enableToggle() : void
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
Session::i()->csrfCheck();
|
||||
|
||||
$loginMethod = \IPS\Login\Handler::load( \IPS\Request::i()->id );
|
||||
$loginMethod = Handler::load( Request::i()->id );
|
||||
|
||||
if ( \IPS\Request::i()->status )
|
||||
if ( Request::i()->status )
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -233,7 +269,7 @@ class _login extends \IPS\Node\Controller
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=core&module=settings&controller=login&do=form&id={$loginMethod->id}" ) );
|
||||
Output::i()->redirect( Url::internal( "app=core&module=settings&controller=login&do=form&id={$loginMethod->id}" ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -242,11 +278,11 @@ class _login extends \IPS\Node\Controller
|
||||
}
|
||||
|
||||
/* Clear caches */
|
||||
unset( \IPS\Data\Store::i()->loginMethods, \IPS\Data\Store::i()->essentialCookieNames );
|
||||
\IPS\Data\Cache::i()->clearAll();
|
||||
unset( Store::i()->loginMethods, Store::i()->essentialCookieNames );
|
||||
Cache::i()->clearAll();
|
||||
|
||||
/* Toggle */
|
||||
return parent::enableToggle();
|
||||
parent::enableToggle();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -254,36 +290,36 @@ class _login extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function delete()
|
||||
protected function delete() : void
|
||||
{
|
||||
/* Check it's okay */
|
||||
$loginMethod = \IPS\Login\Handler::load( \IPS\Request::i()->id );
|
||||
$loginMethod = Handler::load( Request::i()->id );
|
||||
$this->_disableCheck( $loginMethod );
|
||||
|
||||
/* Do it */
|
||||
parent::delete();
|
||||
|
||||
/* Clear caches */
|
||||
unset( \IPS\Data\Store::i()->loginMethods );
|
||||
\IPS\Data\Cache::i()->clearAll();
|
||||
unset( Store::i()->loginMethods, Store::i()->essentialCookieNames );
|
||||
Cache::i()->clearAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* If a particular method is disabled/deleted - will we still be able to log in?
|
||||
*
|
||||
* @param \IPS\Login\Handler $methodToRemove Handler to be disabled/deleted
|
||||
* @return void
|
||||
* @param Handler $methodToRemove Handler to be disabled/deleted
|
||||
* @return bool
|
||||
*/
|
||||
protected function _disableCheck( \IPS\Login\Handler $methodToRemove )
|
||||
protected function _disableCheck( Handler $methodToRemove ) : bool
|
||||
{
|
||||
foreach ( \IPS\Login::methods() as $method )
|
||||
foreach ( LoginClass::methods() as $method )
|
||||
{
|
||||
if ( $method != $methodToRemove and $method->canProcess( \IPS\Member::loggedIn() ) and $method->acp )
|
||||
if ( $method != $methodToRemove and $method->canProcess( Member::loggedIn() ) and $method->acp )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
\IPS\Output::i()->error( 'login_handler_cannot_disable', '1C166/5', 403, '' );
|
||||
Output::i()->error( 'login_handler_cannot_disable', '1C166/5', 403, '' );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -291,50 +327,47 @@ class _login extends \IPS\Node\Controller
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function _settings()
|
||||
protected function _settings() : string
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'login_settings' );
|
||||
Dispatcher::i()->checkAcpPermission( 'login_settings' );
|
||||
|
||||
/* Build Form */
|
||||
$form = new \IPS\Helpers\Form();
|
||||
$form = new Form();
|
||||
$form->addHeader( 'ipb_bruteforce_attempts_title' );
|
||||
$form->addMessage( 'ipb_bruteforce_attempts_block_desc', 'ipsMessage ipsMessage_info' );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'ipb_bruteforce_attempts', \IPS\Settings::i()->ipb_bruteforce_attempts, FALSE, array( 'min' => 0, 'unlimited' => 0, 'unlimitedLang' => 'never' ), NULL, \IPS\Member::loggedIn()->language()->addToStack('after'), \IPS\Member::loggedIn()->language()->addToStack('failed_logins'), 'ipb_bruteforce_attempts' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Interval( 'ipb_bruteforce_period', \IPS\Settings::i()->ipb_bruteforce_period, FALSE, array( 'valueAs' => \IPS\Helpers\Form\Interval::MINUTES, 'min' => 0, 'max' => 10000, 'unlimited' => 0, 'unlimitedLang' => 'never' ), NULL, \IPS\Member::loggedIn()->language()->addToStack('after'), NULL, 'ipb_bruteforce_period' ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'ipb_bruteforce_unlock', \IPS\Settings::i()->ipb_bruteforce_unlock, FALSE, array(), NULL, NULL, NULL, 'ipb_bruteforce_unlock' ) );
|
||||
$form->addHtml( Theme::i()->getTemplate( 'forms' )->blurb( 'ipb_bruteforce_attempts_block_desc', true, true ) );
|
||||
$form->add( new Number( 'ipb_bruteforce_attempts', Settings::i()->ipb_bruteforce_attempts, FALSE, array( 'min' => 0, 'unlimited' => 0, 'unlimitedLang' => 'never' ), NULL, Member::loggedIn()->language()->addToStack('after'), Member::loggedIn()->language()->addToStack('failed_logins'), 'ipb_bruteforce_attempts' ) );
|
||||
$form->add( new Interval( 'ipb_bruteforce_period', Settings::i()->ipb_bruteforce_period, FALSE, array( 'valueAs' => Interval::MINUTES, 'min' => 0, 'max' => 10000, 'unlimited' => 0, 'unlimitedLang' => 'never' ), NULL, Member::loggedIn()->language()->addToStack('after'), NULL, 'ipb_bruteforce_period' ) );
|
||||
$form->add( new YesNo( 'ipb_bruteforce_unlock', Settings::i()->ipb_bruteforce_unlock, FALSE, array(), NULL, NULL, NULL, 'ipb_bruteforce_unlock' ) );
|
||||
$form->addHeader( 'bruteforce_global_attempts_title' );
|
||||
$form->addMessage( 'bruteforce_global_attempts_block_desc', 'ipsMessage ipsMessage_info' );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'bruteforce_global_attempts', \IPS\Settings::i()->bruteforce_global_attempts, FALSE, array( 'min' => 5 ), NULL, \IPS\Member::loggedIn()->language()->addToStack('after'), \IPS\Member::loggedIn()->language()->addToStack('failed_logins'), 'bruteforce_global_attempts' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Interval( 'bruteforce_global_period', \IPS\Settings::i()->bruteforce_global_period, FALSE, array( 'valueAs' => \IPS\Helpers\Form\Interval::MINUTES, 'min' => 0, 'max' => 10000 ), NULL, \IPS\Member::loggedIn()->language()->addToStack('after'), NULL, 'bruteforce_global_period' ) );
|
||||
$form->addHtml( Theme::i()->getTemplate( 'forms' )->blurb( 'bruteforce_global_attempts_block_desc', true, true ) );
|
||||
$form->add( new Number( 'bruteforce_global_attempts', Settings::i()->bruteforce_global_attempts, FALSE, array( 'min' => 5 ), NULL, Member::loggedIn()->language()->addToStack('after'), Member::loggedIn()->language()->addToStack('failed_logins'), 'bruteforce_global_attempts' ) );
|
||||
$form->add( new Interval( 'bruteforce_global_period', Settings::i()->bruteforce_global_period, FALSE, array( 'valueAs' => Interval::MINUTES, 'min' => 0, 'max' => 10000 ), NULL, Member::loggedIn()->language()->addToStack('after'), NULL, 'bruteforce_global_period' ) );
|
||||
|
||||
$form->addHeader( 'login_settings' );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'new_device_email', \IPS\Settings::i()->new_device_email, FALSE ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'login_after_inactivity_notification', \IPS\Settings::i()->login_after_inactivity_notification, FALSE ) );
|
||||
$form->add( new YesNo( 'new_device_email', Settings::i()->new_device_email, FALSE ) );
|
||||
|
||||
/* Save */
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
/* unlock all locked members if we have disabled the locking */
|
||||
if ( \IPS\Settings::i()->ipb_bruteforce_attempts > 0 AND $values['ipb_bruteforce_attempts'] == 0 )
|
||||
if ( Settings::i()->ipb_bruteforce_attempts > 0 AND $values['ipb_bruteforce_attempts'] == 0 )
|
||||
{
|
||||
\IPS\Member::updateAllMembers( array( 'failed_login_count' => 0 ) );
|
||||
\IPS\Db::i()->delete( 'core_login_failures', [ 'login_member_id IS NOT NULL' ] );
|
||||
Member::updateAllMembers( array( 'failed_login_count' => 0 ) );
|
||||
Db::i()->delete( 'core_login_failures', [ 'login_member_id IS NOT NULL' ] );
|
||||
|
||||
/* disable task */
|
||||
\IPS\Db::i()->update( 'core_tasks', array( 'enabled' => 0 ), "`key`='unlockmembers'" );
|
||||
Db::i()->update( 'core_tasks', array( 'enabled' => 0 ), "`key`='unlockmembers'" );
|
||||
}
|
||||
else if ( $values['ipb_bruteforce_attempts'] > 0 )
|
||||
{
|
||||
/* enable task */
|
||||
\IPS\Db::i()->update( 'core_tasks', array( 'enabled' => 1 ), "`key`='unlockmembers'" );
|
||||
Db::i()->update( 'core_tasks', array( 'enabled' => 1 ), "`key`='unlockmembers'" );
|
||||
}
|
||||
|
||||
$form->saveAsSettings( $values );
|
||||
|
||||
/* Clear guest page caches */
|
||||
\IPS\Data\Cache::i()->clearAll();
|
||||
|
||||
\IPS\Session::i()->log( 'acplogs__login_settings' );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=settings&controller=login&tab=settings' ), 'saved' );
|
||||
Session::i()->log( 'acplogs__login_settings' );
|
||||
Output::i()->redirect( Url::internal( 'app=core&module=settings&controller=login&tab=settings' ), 'saved' );
|
||||
}
|
||||
|
||||
/* Display */
|
||||
@@ -344,18 +377,18 @@ class _login extends \IPS\Node\Controller
|
||||
/**
|
||||
* HTTPS check
|
||||
*
|
||||
* @return null
|
||||
* @return void
|
||||
*/
|
||||
protected function httpsCheck()
|
||||
protected function httpsCheck() : void
|
||||
{
|
||||
try
|
||||
{
|
||||
$response = \IPS\Http\Url::external( 'https://' . mb_substr( \IPS\Settings::i()->base_url, 7 ) )->request()->get();
|
||||
\IPS\Output::i()->output = $response;
|
||||
$response = Url::external( 'https://' . mb_substr( Settings::i()->base_url, 7 ) )->request()->get();
|
||||
Output::i()->output = $response;
|
||||
}
|
||||
catch ( \IPS\Http\Request\Exception $e )
|
||||
catch ( Exception $e )
|
||||
{
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global' )->message( $e->getMessage() ?: '500_error_title', 'error' );
|
||||
Output::i()->output = Theme::i()->getTemplate( 'global' )->message( $e->getMessage() ?: '500_error_title', 'error' );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -364,60 +397,81 @@ class _login extends \IPS\Node\Controller
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function _registration()
|
||||
protected function _registration() : string
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'registration_settings' );
|
||||
Dispatcher::i()->checkAcpPermission( 'registration_settings' );
|
||||
|
||||
/* Check SSO Extensions for overloads */
|
||||
$disabledSettings = $appBlocks = [];
|
||||
$ssoSettings = [ 'allow_reg', 'allow_reg_target' ];
|
||||
foreach( Application::allExtensions( 'core', 'SSO', FALSE ) as $app => $ext )
|
||||
{
|
||||
/* @var SSOAbstract $ext */
|
||||
if( $ext->isEnabled() )
|
||||
{
|
||||
foreach( array_keys( $ext->overrideSettings() ) as $settingKey )
|
||||
{
|
||||
if( !in_array( $settingKey, $ssoSettings ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
$appBlocks[ $app ] = Member::loggedIn()->language()->addToStack( '__app_' . explode( '_', $app )[0], FALSE );
|
||||
$disabledSettings[ $settingKey ] = $settingKey;
|
||||
Member::loggedIn()->language()->words[ $settingKey . '_desc'] = Member::loggedIn()->language()->addToStack( 'sso_setting_override', FALSE, [ 'pluralize' => [ count( $appBlocks ) ],'htmlsprintf' => [ Member::loggedIn()->language()->formatList( $appBlocks ) ] ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Build Form */
|
||||
$form = new \IPS\Helpers\Form();
|
||||
$form = new Form();
|
||||
$form->addHeader('registration_standard_settings');
|
||||
$form->addMessage('registration_standard_settings_blurb');
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'allow_reg', \IPS\Login::registrationType(), FALSE, array(
|
||||
'options' => array(
|
||||
$form->addHtml( Theme::i()->getTemplate( 'forms' )->blurb( 'registration_standard_settings_blurb', true, true ) );
|
||||
$form->add( new Radio( 'allow_reg', LoginClass::registrationType(), FALSE, [
|
||||
'options' => [
|
||||
'normal' => 'allow_reg_normal',
|
||||
'full' => 'allow_reg_full',
|
||||
'redirect' => 'allow_reg_redirect',
|
||||
'disabled' => 'allow_reg_disabled'
|
||||
),
|
||||
'toggles' => array(
|
||||
'normal' => array( 'allow_reg_normal_warning' ),
|
||||
'full' => array( 'minimum_age', 'use_coppa' ),
|
||||
'redirect' => array( 'allow_reg_target' )
|
||||
),
|
||||
'disabled' => \IPS\Login\Handler::findMethod( 'IPS\Login\Handler\Standard' ) ? array() : array( 'normal', 'full' )
|
||||
) ) );
|
||||
],
|
||||
'toggles' => [
|
||||
'normal' => [ 'allow_reg_normal_warning' ],
|
||||
'full' => [ 'minimum_age', 'use_coppa' ],
|
||||
'redirect' => [ 'allow_reg_target' ]
|
||||
],
|
||||
'disabled' => isset( $disabledSettings['allow_reg'] ) ? TRUE : ( Handler::findMethod( 'IPS\Login\Handler\Standard' ) ? [] : [ 'normal', 'full' ] )
|
||||
] ) );
|
||||
|
||||
/* Do we have required custom fields? */
|
||||
if ( \IPS\Db::i()->select( 'COUNT(*)', 'core_pfields_data', array( 'pf_not_null != 0 and pf_show_on_reg=1' ) )->first() )
|
||||
if ( Db::i()->select( 'COUNT(*)', 'core_pfields_data', array( 'pf_not_null != 0 and pf_show_on_reg=1' ) )->first() )
|
||||
{
|
||||
\IPS\Member::loggedIn()->language()->words['allow_reg_normal_warning'] = \IPS\Member::loggedIn()->language()->addToStack( 'allow_reg_normal_desc_required_warning' );
|
||||
Member::loggedIn()->language()->words['allow_reg_normal_warning'] = Member::loggedIn()->language()->addToStack( 'allow_reg_normal_desc_required_warning' );
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Url( 'allow_reg_target', \IPS\Settings::i()->allow_reg_target, NULL, array(), function( $val )
|
||||
|
||||
$form->add( new FormUrl( 'allow_reg_target', Settings::i()->allow_reg_target, NULL, [ 'disabled' => isset( $disabledSettings['allow_reg_target'] ) ], function( $val )
|
||||
{
|
||||
if ( !$val and \IPS\Request::i()->allow_red === 'redirect' )
|
||||
if ( !$val and Request::i()->allow_red === 'redirect' )
|
||||
{
|
||||
throw new \DomainException('form_required');
|
||||
throw new DomainException('form_required');
|
||||
}
|
||||
}, NULL, NULL, 'allow_reg_target' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'minimum_age', \IPS\Settings::i()->minimum_age, FALSE, array( 'unlimited' => 0, 'unlimitedLang' => 'any_age' ), NULL, NULL, NULL, 'minimum_age' ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'use_coppa', \IPS\Settings::i()->use_coppa, FALSE, array( 'togglesOn' => array( 'coppa_fax', 'coppa_address' ) ), NULL, NULL, NULL, 'use_coppa' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Tel( 'coppa_fax', \IPS\Settings::i()->coppa_fax, FALSE, array(), NULL, NULL, NULL, 'coppa_fax' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Address( 'coppa_address', \IPS\GeoLocation::buildFromJson( \IPS\Settings::i()->coppa_address ), FALSE, array(), NULL, NULL, NULL, 'coppa_address' ) );
|
||||
$form->add( new Number( 'minimum_age', Settings::i()->minimum_age, FALSE, array( 'unlimited' => 0, 'unlimitedLang' => 'any_age' ), NULL, NULL, NULL, 'minimum_age' ) );
|
||||
$form->add( new YesNo( 'use_coppa', Settings::i()->use_coppa, FALSE, array( 'togglesOn' => array( 'coppa_fax', 'coppa_address' ) ), NULL, NULL, NULL, 'use_coppa' ) );
|
||||
$form->add( new Tel( 'coppa_fax', Settings::i()->coppa_fax, FALSE, array(), NULL, NULL, NULL, 'coppa_fax' ) );
|
||||
$form->add( new Address( 'coppa_address', Settings::i()->coppa_address ? GeoLocation::buildFromJson( Settings::i()->coppa_address ) : null, FALSE, array(), NULL, NULL, NULL, 'coppa_address' ) );
|
||||
$form->addHeader('registration_global_settings');
|
||||
$form->addMessage('registration_global_settings_blurb');
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'reg_auth_type', \IPS\Settings::i()->reg_auth_type, FALSE, array(
|
||||
$form->addHtml( Theme::i()->getTemplate( 'forms' )->blurb( 'registration_global_settings_blurb', true, true ) );
|
||||
$form->add( new Radio( 'reg_auth_type', Settings::i()->reg_auth_type, FALSE, array(
|
||||
'options' => array( 'user' => 'reg_auth_type_user', 'admin' => 'reg_auth_type_admin', 'admin_user' => 'reg_auth_type_admin_user', 'none' => 'reg_auth_type_none' ),
|
||||
'toggles' => array( 'user' => array( 'validate_day_prune' ), 'admin_user' => array( 'validate_day_prune' ) )
|
||||
), NULL, NULL, NULL, 'reg_auth_type' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Interval( 'validate_day_prune', \IPS\Settings::i()->validate_day_prune, FALSE, array( 'valueAs' => \IPS\Helpers\Form\Interval::DAYS, 'unlimited' => 0, 'unlimitedLang' => 'never' ), NULL, \IPS\Member::loggedIn()->language()->addToStack('after'), NULL, 'validate_day_prune' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Stack( 'allowed_reg_email', explode( ',', \IPS\Settings::i()->allowed_reg_email ), FALSE, array( 'placeholder' => 'mycompany.com' ), function( $value ) {
|
||||
$form->add( new Interval( 'validate_day_prune', Settings::i()->validate_day_prune, FALSE, array( 'valueAs' => Interval::DAYS, 'unlimited' => 0, 'unlimitedLang' => 'never' ), NULL, Member::loggedIn()->language()->addToStack('after'), NULL, 'validate_day_prune' ) );
|
||||
$form->add( new Stack( 'allowed_reg_email', explode( ',', Settings::i()->allowed_reg_email ), FALSE, array( 'placeholder' => 'mycompany.com' ), function( $value ) {
|
||||
if( isset( $value[0] ) AND mb_stripos( $value[0], '@' ) )
|
||||
{
|
||||
throw new \DomainException( 'allowed_reg_email_email_detected' );
|
||||
throw new DomainException( 'allowed_reg_email_email_detected' );
|
||||
}
|
||||
}, NULL, NULL ) );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'force_reg_terms', \IPS\Settings::i()->force_reg_terms, FALSE, array( 'options' => array(
|
||||
$form->add( new Radio( 'force_reg_terms', Settings::i()->force_reg_terms, FALSE, array( 'options' => array(
|
||||
'0' => 'force_reg_terms_0',
|
||||
'1' => 'force_reg_terms_1',
|
||||
) ) ) );
|
||||
@@ -426,29 +480,26 @@ class _login extends \IPS\Node\Controller
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
/* Save */
|
||||
if ( isset( $values['allowed_reg_email'] ) and \is_array( $values['allowed_reg_email'] ) )
|
||||
if ( isset( $values['allowed_reg_email'] ) and is_array( $values['allowed_reg_email'] ) )
|
||||
{
|
||||
$values['allowed_reg_email'] = implode( ',', $values['allowed_reg_email'] );
|
||||
}
|
||||
|
||||
if ( isset( $values['coppa_address'] ) AND ( $values['coppa_address'] instanceof \IPS\GeoLocation ) )
|
||||
if ( isset( $values['coppa_address'] ) AND ( $values['coppa_address'] instanceof GeoLocation ) )
|
||||
{
|
||||
$values['coppa_address'] = json_encode( $values['coppa_address'] );
|
||||
}
|
||||
|
||||
$form->saveAsSettings( $values );
|
||||
\IPS\Session::i()->log( 'acplogs__registration_settings' );
|
||||
|
||||
/* Clear guest page caches */
|
||||
\IPS\Data\Cache::i()->clearAll();
|
||||
Session::i()->log( 'acplogs__registration_settings' );
|
||||
|
||||
/* Redirect */
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=settings&controller=login&tab=registration' ), 'saved' );
|
||||
Output::i()->redirect( Url::internal( 'app=core&module=settings&controller=login&tab=registration' ), 'saved' );
|
||||
}
|
||||
$desc = \IPS\Theme::i()->getTemplate( 'global', 'core' )->message( \IPS\Member::loggedIn()->language()->addToStack('registration_default_group_info', NULL, [ 'sprintf' => [\IPS\Member\Group::load( \IPS\Settings::i()->member_group )->formattedName ] ] ), 'info' );
|
||||
$desc = Theme::i()->getTemplate( 'global', 'core' )->message( Member::loggedIn()->language()->addToStack('registration_default_group_info', NULL, [ 'sprintf' => [Group::load( Settings::i()->member_group )->formattedName ] ] ), 'none i-border-radius_0' );
|
||||
|
||||
/* Display */
|
||||
return (string) $desc . $form;
|
||||
return $desc . $form;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -456,74 +507,103 @@ class _login extends \IPS\Node\Controller
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function _accountsettings()
|
||||
protected function _accountsettings() : string
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'login_account_management' );
|
||||
|
||||
Dispatcher::i()->checkAcpPermission( 'login_account_management' );
|
||||
|
||||
/* Check SSO Extensions for overloads */
|
||||
$disabledSettings = $appBlocks = [];
|
||||
$ssoSettings = [ 'allow_email_changes', 'allow_email_changes_target', 'allow_password_changes', 'allow_password_changes_target', 'allow_forgot_password', 'allow_forgot_password_target' ];
|
||||
|
||||
foreach( Application::allExtensions( 'core', 'SSO', FALSE ) as $app => $ext )
|
||||
{
|
||||
/* @var SSOAbstract $ext */
|
||||
if( $ext->isEnabled() )
|
||||
{
|
||||
foreach( array_keys( $ext->overrideSettings() ) as $settingKey )
|
||||
{
|
||||
if( !in_array( $settingKey, $ssoSettings ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
$appBlocks[ $settingKey ][] = Member::loggedIn()->language()->addToStack( '__app_' . explode( '_', $app )[0], FALSE );
|
||||
$disabledSettings[ $settingKey ] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach( $appBlocks as $sKey => $apps )
|
||||
{
|
||||
Member::loggedIn()->language()->words[ $sKey . '_desc'] = Member::loggedIn()->language()->addToStack( 'sso_setting_override', FALSE, [ 'pluralize' => [ count( $apps ) ],'htmlsprintf' => [ Member::loggedIn()->language()->formatList( $apps ) ] ] );
|
||||
}
|
||||
|
||||
/* Build Form */
|
||||
$form = new \IPS\Helpers\Form();
|
||||
$form = new Form();
|
||||
$form->addHeader( 'security_header_accounts' );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'password_strength_meter', \IPS\Settings::i()->password_strength_meter, FALSE, array( 'togglesOn' => array( 'password_strength_meter_enforce' ) ), NULL, NULL, NULL, 'password_strength_meter' ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'password_strength_meter_enforce', \IPS\Settings::i()->password_strength_meter_enforce, FALSE, array( 'togglesOn' => array( 'password_strength_option' ) ), NULL, NULL, NULL, 'password_strength_meter_enforce' ) );
|
||||
$form->add( new YesNo( 'password_strength_meter', Settings::i()->password_strength_meter, FALSE, array( 'togglesOn' => array( 'password_strength_meter_enforce' ) ), NULL, NULL, NULL, 'password_strength_meter' ) );
|
||||
$form->add( new YesNo( 'password_strength_meter_enforce', Settings::i()->password_strength_meter_enforce, FALSE, array( 'togglesOn' => array( 'password_strength_option' ) ), NULL, NULL, NULL, 'password_strength_meter_enforce' ) );
|
||||
$strengthOptions = array(
|
||||
'3' => 'strength_3',
|
||||
'4' => 'strength_4',
|
||||
'5' => 'strength_5',
|
||||
);
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'password_strength_option', \IPS\Settings::i()->password_strength_option, FALSE, array( 'options' => $strengthOptions ), NULL, NULL, NULL, 'password_strength_option' ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'device_management', \IPS\Settings::i()->device_management, FALSE ) );
|
||||
$form->add( new Radio( 'password_strength_option', Settings::i()->password_strength_option, FALSE, array( 'options' => $strengthOptions ), NULL, NULL, NULL, 'password_strength_option' ) );
|
||||
$form->add( new YesNo( 'device_management', Settings::i()->device_management, FALSE ) );
|
||||
$form->addHeader('account_management_email_pass');
|
||||
$form->addMessage('account_management_email_pass_blurb');
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'allow_email_changes', \IPS\Settings::i()->allow_email_changes, FALSE, array(
|
||||
'options' => array(
|
||||
$form->addHtml( Theme::i()->getTemplate( 'forms' )->blurb( 'account_management_email_pass_blurb', true, true ) );
|
||||
$form->add( new Radio( 'allow_email_changes', Settings::i()->allow_email_changes, FALSE, [
|
||||
'options' => [
|
||||
'normal' => 'allow_email_changes_normal',
|
||||
'redirect' => 'allow_email_changes_redirect',
|
||||
'disabled' => 'allow_email_changes_disabled',
|
||||
),
|
||||
'toggles' => array(
|
||||
'redirect' => array( 'allow_email_changes_target' )
|
||||
)
|
||||
) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Url( 'allow_email_changes_target', \IPS\Settings::i()->allow_email_changes_target, NULL, array(), function( $val )
|
||||
],
|
||||
'toggles' => [
|
||||
'redirect' => [ 'allow_email_changes_target' ]
|
||||
],
|
||||
'disabled' => isset( $disabledSettings['allow_email_changes'] )
|
||||
] ) );
|
||||
$form->add( new FormUrl( 'allow_email_changes_target', Settings::i()->allow_email_changes_target, NULL, [ 'disabled' => isset( $disabledSettings['allow_email_changes_target'] ) ], function( $val )
|
||||
{
|
||||
if ( !$val and \IPS\Request::i()->allow_email_changes === 'redirect' )
|
||||
if ( !$val and Request::i()->allow_email_changes === 'redirect' )
|
||||
{
|
||||
throw new \DomainException('form_required');
|
||||
throw new DomainException('form_required');
|
||||
}
|
||||
}, NULL, NULL, 'allow_email_changes_target' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'allow_password_changes', \IPS\Settings::i()->allow_password_changes, FALSE, array(
|
||||
'options' => array(
|
||||
$form->add( new Radio( 'allow_password_changes', Settings::i()->allow_password_changes, FALSE, [
|
||||
'options' => [
|
||||
'normal' => 'allow_password_changes_normal',
|
||||
'redirect' => 'allow_password_changes_redirect',
|
||||
'disabled' => 'allow_password_changes_disabled',
|
||||
),
|
||||
'toggles' => array(
|
||||
'redirect' => array( 'allow_password_changes_target' )
|
||||
)
|
||||
) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Url( 'allow_password_changes_target', \IPS\Settings::i()->allow_password_changes_target, NULL, array(), function( $val )
|
||||
],
|
||||
'toggles' => [
|
||||
'redirect' => [ 'allow_password_changes_target' ]
|
||||
],
|
||||
'disabled' => isset( $disabledSettings['allow_password_changes'] )
|
||||
] ) );
|
||||
$form->add( new FormUrl( 'allow_password_changes_target', Settings::i()->allow_password_changes_target, NULL, [ 'disabled' => isset( $disabledSettings['allow_password_changes_target'] ) ], function( $val )
|
||||
{
|
||||
if ( !$val and \IPS\Request::i()->allow_password_changes === 'redirect' )
|
||||
if ( !$val and Request::i()->allow_password_changes === 'redirect' )
|
||||
{
|
||||
throw new \DomainException('form_required');
|
||||
throw new DomainException('form_required');
|
||||
}
|
||||
}, NULL, NULL, 'allow_password_changes_target' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'allow_forgot_password', \IPS\Settings::i()->allow_forgot_password, FALSE, array(
|
||||
'options' => array(
|
||||
$form->add( new Radio( 'allow_forgot_password', Settings::i()->allow_forgot_password, FALSE, [
|
||||
'options' => [
|
||||
'normal' => 'allow_forgot_password_normal',
|
||||
'handler' => 'allow_forgot_password_handler',
|
||||
'redirect' => 'allow_forgot_password_redirect',
|
||||
'disabled' => 'allow_forgot_password_disabled',
|
||||
),
|
||||
'toggles' => array(
|
||||
'redirect' => array( 'allow_forgot_password_target' )
|
||||
)
|
||||
) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Url( 'allow_forgot_password_target', \IPS\Settings::i()->allow_forgot_password_target, NULL, array(), function( $val )
|
||||
],
|
||||
'toggles' => [
|
||||
'redirect' => [ 'allow_forgot_password_target' ]
|
||||
],
|
||||
'disabled' => isset( $disabledSettings['allow_forgot_password'] )
|
||||
] ) );
|
||||
$form->add( new FormUrl( 'allow_forgot_password_target', Settings::i()->allow_forgot_password_target, FALSE, [ 'disabled' => isset( $disabledSettings['allow_forgot_password_target'] ) ], function( $val )
|
||||
{
|
||||
if ( !$val and \IPS\Request::i()->allow_forgot_password === 'redirect' )
|
||||
if ( !$val and Request::i()->allow_forgot_password === 'redirect' )
|
||||
{
|
||||
throw new \DomainException('form_required');
|
||||
throw new DomainException('form_required');
|
||||
}
|
||||
}, NULL, NULL, 'allow_forgot_password_target' ) );
|
||||
|
||||
@@ -534,8 +614,8 @@ class _login extends \IPS\Node\Controller
|
||||
|
||||
$form->saveAsSettings( $values );
|
||||
|
||||
\IPS\Session::i()->log( 'acplogs__account_management_settings' );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=settings&controller=login&tab=accountsettings' ), 'saved' );
|
||||
Session::i()->log( 'acplogs__account_management_settings' );
|
||||
Output::i()->redirect( Url::internal( 'app=core&module=settings&controller=login&tab=accountsettings' ), 'saved' );
|
||||
}
|
||||
|
||||
/* Display */
|
||||
@@ -547,14 +627,14 @@ class _login extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function forceLogout()
|
||||
protected function forceLogout() : void
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
Session::i()->csrfCheck();
|
||||
|
||||
\IPS\Db::i()->update( 'core_members_known_devices', array( 'login_key' => NULL ) );
|
||||
\IPS\Db::i()->delete( 'core_sessions' );
|
||||
Db::i()->update( 'core_members_known_devices', array( 'login_key' => NULL ) );
|
||||
Db::i()->delete( 'core_sessions' );
|
||||
|
||||
\IPS\Session::i()->log( 'acplogs__logout_force' );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=settings&controller=login' ), 'logged_out_force' );
|
||||
Session::i()->log( 'acplogs__logout_force' );
|
||||
Output::i()->redirect( Url::internal( 'app=core&module=settings&controller=login' ), 'logged_out_force' );
|
||||
}
|
||||
}
|
||||
@@ -11,30 +11,54 @@
|
||||
namespace IPS\core\modules\admin\settings;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use Exception;
|
||||
use IPS\Db;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Dispatcher\Controller;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\CheckboxSet;
|
||||
use IPS\Helpers\Form\Interval;
|
||||
use IPS\Helpers\Form\Number;
|
||||
use IPS\Helpers\Form\Radio;
|
||||
use IPS\Helpers\Form\Translatable;
|
||||
use IPS\Helpers\Tree\Tree;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Lang;
|
||||
use IPS\Member;
|
||||
use IPS\Member\Group;
|
||||
use IPS\MFA\MFAHandler;
|
||||
use IPS\Output;
|
||||
use IPS\Request;
|
||||
use IPS\Session;
|
||||
use IPS\Settings;
|
||||
use IPS\Theme;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Multi-Factor Authentication
|
||||
*/
|
||||
class _mfa extends \IPS\Dispatcher\Controller
|
||||
class mfa 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( 'mfa_manage' );
|
||||
Dispatcher::i()->checkAcpPermission( 'mfa_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
@@ -43,14 +67,14 @@ class _mfa extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
protected function manage() : void
|
||||
{
|
||||
$activeTabContents = '';
|
||||
$tabs = array(
|
||||
'handlers' => 'mfa_handlers',
|
||||
'settings' => 'mfa_settings'
|
||||
);
|
||||
$activeTab = ( isset( \IPS\Request::i()->tab ) and array_key_exists( \IPS\Request::i()->tab, $tabs ) ) ? \IPS\Request::i()->tab : 'handlers';
|
||||
$activeTab = ( isset( Request::i()->tab ) and array_key_exists( Request::i()->tab, $tabs ) ) ? Request::i()->tab : 'handlers';
|
||||
|
||||
if ( $activeTab === 'handlers' )
|
||||
{
|
||||
@@ -61,14 +85,14 @@ class _mfa extends \IPS\Dispatcher\Controller
|
||||
$activeTabContents = $this->_manageSettings();
|
||||
}
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__core_settings_mfa');
|
||||
if( \IPS\Request::i()->isAjax() )
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('menu__core_settings_mfa');
|
||||
if( Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->output = $activeTabContents;
|
||||
Output::i()->output = $activeTabContents;
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global' )->tabs( $tabs, $activeTab, $activeTabContents, \IPS\Http\Url::internal( "app=core&module=settings&controller=mfa" ) );
|
||||
Output::i()->output = Theme::i()->getTemplate( 'forms' )->blurb( 'mfa_blurb' ) . Theme::i()->getTemplate( 'global' )->tabs( $tabs, $activeTab, $activeTabContents, Url::internal( "app=core&module=settings&controller=mfa" ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,22 +101,22 @@ class _mfa extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function _manageHandlers()
|
||||
protected function _manageHandlers() : string
|
||||
{
|
||||
/* Create the tree */
|
||||
$url = \IPS\Http\Url::internal( "app=core&module=settings&controller=mfa&tab=handlers" );
|
||||
$tree = new \IPS\Helpers\Tree\Tree(
|
||||
$url = Url::internal( "app=core&module=settings&controller=mfa&tab=handlers" );
|
||||
$tree = new Tree(
|
||||
$url,
|
||||
NULL,
|
||||
function() use( $url ) {
|
||||
$return = array();
|
||||
|
||||
foreach ( \IPS\MFA\MFAHandler::handlers() as $key => $handler )
|
||||
foreach ( MFAHandler::handlers() as $key => $handler )
|
||||
{
|
||||
$return[] = \IPS\Theme::i()->getTemplate( 'trees', 'core' )->row(
|
||||
$return[] = Theme::i()->getTemplate( 'trees', 'core' )->row(
|
||||
$url,
|
||||
$key,
|
||||
\IPS\Member::loggedIn()->language()->addToStack("mfa_{$key}_title"),
|
||||
Member::loggedIn()->language()->addToStack("mfa_{$key}_title"),
|
||||
FALSE,
|
||||
array(
|
||||
'settings' => array(
|
||||
@@ -101,7 +125,7 @@ class _mfa extends \IPS\Dispatcher\Controller
|
||||
'link' => $url->setQueryString( array( 'do' => 'settings', 'key' => $key ) ),
|
||||
)
|
||||
),
|
||||
\IPS\Member::loggedIn()->language()->addToStack("mfa_{$key}_desc"),
|
||||
Member::loggedIn()->language()->addToStack("mfa_{$key}_desc"),
|
||||
NULL,
|
||||
NULL,
|
||||
FALSE,
|
||||
@@ -117,7 +141,7 @@ class _mfa extends \IPS\Dispatcher\Controller
|
||||
);
|
||||
|
||||
/* Return */
|
||||
return \IPS\Theme::i()->getTemplate( 'forms' )->blurb( 'mfa_blurb', TRUE, TRUE ) . $tree;
|
||||
return $tree;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -125,42 +149,42 @@ class _mfa extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function enableToggle()
|
||||
protected function enableToggle() : void
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
Session::i()->csrfCheck();
|
||||
|
||||
$key = \IPS\Request::i()->id;
|
||||
$handlers = \IPS\MFA\MFAHandler::handlers();
|
||||
$key = Request::i()->id;
|
||||
$handlers = MFAHandler::handlers();
|
||||
if ( !isset( $handlers[ $key ] ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2C345/1', 404, '' );
|
||||
Output::i()->error( 'node_error', '2C345/1', 404, '' );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$handlers[ $key ]->toggle( \IPS\Request::i()->status );
|
||||
$handlers[ $key ]->toggle( Request::i()->status );
|
||||
|
||||
if ( \IPS\Request::i()->status )
|
||||
if ( Request::i()->status )
|
||||
{
|
||||
\IPS\Session::i()->log( 'acplogs__mfa_handler_enabled', array( "mfa_{$key}_title" => TRUE ) );
|
||||
Session::i()->log( 'acplogs__mfa_handler_enabled', array( "mfa_{$key}_title" => TRUE ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Session::i()->log( 'acplogs__mfa_handler_disabled', array( "mfa_{$key}_title" => TRUE ) );
|
||||
Session::i()->log( 'acplogs__mfa_handler_disabled', array( "mfa_{$key}_title" => TRUE ) );
|
||||
}
|
||||
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
if ( Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->json('OK');
|
||||
Output::i()->json('OK');
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=core&module=settings&controller=mfa" ) );
|
||||
Output::i()->redirect( Url::internal( "app=core&module=settings&controller=mfa" ) );
|
||||
}
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
catch ( Exception $e )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=core&module=settings&controller=mfa&tab=handlers&do=settings&key=" . $key ) );
|
||||
Output::i()->redirect( Url::internal( "app=core&module=settings&controller=mfa&tab=handlers&do=settings&key=" . $key ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,21 +193,21 @@ class _mfa extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function settings()
|
||||
protected function settings() : void
|
||||
{
|
||||
$key = \IPS\Request::i()->key;
|
||||
$handlers = \IPS\MFA\MFAHandler::handlers();
|
||||
$key = Request::i()->key;
|
||||
$handlers = MFAHandler::handlers();
|
||||
if ( !isset( $handlers[ $key ] ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2C345/2', 404, '' );
|
||||
Output::i()->error( 'node_error', '2C345/2', 404, '' );
|
||||
}
|
||||
|
||||
$output = $handlers[ $key ]->acpSettings();
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack("mfa_{$key}_title");
|
||||
\IPS\Output::i()->output = $output;
|
||||
\IPS\Output::i()->breadcrumb[] = array( \IPS\Http\Url::internal('app=core&module=settings&controller=mfa&tab=handlers'), \IPS\Member::loggedIn()->language()->addToStack('menu__core_settings_mfa') );
|
||||
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack("mfa_{$key}_title") );
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack("mfa_{$key}_title");
|
||||
Output::i()->output = $output;
|
||||
Output::i()->breadcrumb[] = array( Url::internal('app=core&module=settings&controller=mfa&tab=handlers'), Member::loggedIn()->language()->addToStack('menu__core_settings_mfa') );
|
||||
Output::i()->breadcrumb[] = array( NULL, Member::loggedIn()->language()->addToStack("mfa_{$key}_title") );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -191,26 +215,26 @@ class _mfa extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function _manageSettings()
|
||||
protected function _manageSettings() : string
|
||||
{
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form = new Form;
|
||||
|
||||
$form->addHeader('mfa_header_setup');
|
||||
$groups = array_combine( array_keys( \IPS\Member\Group::groups() ), array_map( function( $_group ) { return (string) $_group; }, \IPS\Member\Group::groups() ) );
|
||||
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'mfa_required_groups', \IPS\Settings::i()->mfa_required_groups == '*' ? '*' : explode( ',', \IPS\Settings::i()->mfa_required_groups ), FALSE, array(
|
||||
$groups = array_combine( array_keys( Group::groups() ), array_map( function( $_group ) { return (string) $_group; }, Group::groups() ) );
|
||||
$form->add( new CheckboxSet( 'mfa_required_groups', Settings::i()->mfa_required_groups == '*' ? '*' : explode( ',', Settings::i()->mfa_required_groups ), FALSE, array(
|
||||
'multiple' => TRUE,
|
||||
'options' => $groups,
|
||||
'unlimited' => '*',
|
||||
'unlimitedLang' => 'everyone',
|
||||
'impliedUnlimited' => TRUE
|
||||
) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'mfa_required_prompt', \IPS\Settings::i()->mfa_required_prompt, FALSE, array(
|
||||
$form->add( new Radio( 'mfa_required_prompt', Settings::i()->mfa_required_prompt, FALSE, array(
|
||||
'options' => array(
|
||||
'immediate' => 'mfa_prompt_immediate',
|
||||
'access' => 'mfa_prompt_access',
|
||||
)
|
||||
), NULL, NULL, NULL, 'mfa_required_prompt' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'mfa_optional_prompt', \IPS\Settings::i()->mfa_optional_prompt, FALSE, array(
|
||||
$form->add( new Radio( 'mfa_optional_prompt', Settings::i()->mfa_optional_prompt, FALSE, array(
|
||||
'options' => array(
|
||||
'immediate' => 'mfa_prompt_immediate',
|
||||
'access' => 'mfa_prompt_access',
|
||||
@@ -221,15 +245,15 @@ class _mfa extends \IPS\Dispatcher\Controller
|
||||
'access' => array( 'security_questions_opt_out_warning' ),
|
||||
)
|
||||
), NULL, NULL, NULL, 'mfa_optional_prompt' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Translatable( 'security_questions_opt_out_warning', NULL, FALSE, array( 'app' => 'core', 'key' => 'security_questions_opt_out_warning_value' ), NULL, NULL, NULL, 'security_questions_opt_out_warning' ) );
|
||||
$form->add( new Translatable( 'security_questions_opt_out_warning', NULL, FALSE, array( 'app' => 'core', 'key' => 'security_questions_opt_out_warning_value' ), NULL, NULL, NULL, 'security_questions_opt_out_warning' ) );
|
||||
|
||||
$form->addHeader('mfa_header_authentication');
|
||||
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'security_questions_areas', \IPS\Settings::i()->security_questions_areas ? explode( ',', \IPS\Settings::i()->security_questions_areas ) : array_keys( \IPS\MFA\MFAHandler::areas() ), FALSE, array( 'options' => \IPS\MFA\MFAHandler::areas() ), NULL, NULL, NULL, 'security_questions_areas' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Interval( 'security_questions_timer', \IPS\Settings::i()->security_questions_timer, FALSE, array( 'valueAs' => \IPS\Helpers\Form\Interval::MINUTES, 'unlimited' => 0, 'unlimitedLang' => 'security_questions_timer_session' ) ) );
|
||||
$form->add( new CheckboxSet( 'security_questions_areas', Settings::i()->security_questions_areas ? explode( ',', Settings::i()->security_questions_areas ) : array_keys( MFAHandler::areas() ), FALSE, array( 'options' => MFAHandler::areas() ), NULL, NULL, NULL, 'security_questions_areas' ) );
|
||||
$form->add( new Interval( 'security_questions_timer', Settings::i()->security_questions_timer, FALSE, array( 'valueAs' => Interval::MINUTES, 'unlimited' => 0, 'unlimitedLang' => 'security_questions_timer_session' ) ) );
|
||||
|
||||
$form->addHeader('mfa_header_recovery');
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'security_questions_tries', \IPS\Settings::i()->security_questions_tries, FALSE, array( 'min' => 1 ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'mfa_lockout_behaviour', \IPS\Settings::i()->mfa_lockout_behaviour, FALSE, array(
|
||||
$form->add( new Number( 'security_questions_tries', Settings::i()->security_questions_tries, FALSE, array( 'min' => 1 ) ) );
|
||||
$form->add( new Radio( 'mfa_lockout_behaviour', Settings::i()->mfa_lockout_behaviour, FALSE, array(
|
||||
'options' => array(
|
||||
'lock' => 'mfa_lockout_behaviour_lock',
|
||||
'email' => 'mfa_lockout_behaviour_email',
|
||||
@@ -239,8 +263,8 @@ class _mfa extends \IPS\Dispatcher\Controller
|
||||
'lock' => array( 'mfa_lockout_time' )
|
||||
)
|
||||
) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Interval( 'mfa_lockout_time', \IPS\Settings::i()->mfa_lockout_time, FALSE, array( 'valueAs' => \IPS\Helpers\Form\Interval::MINUTES, 'min' => 1 ), NULL, NULL, NULL, 'mfa_lockout_time' ) );
|
||||
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'mfa_forgot_behaviour', explode( ',', \IPS\Settings::i()->mfa_forgot_behaviour ), FALSE, array(
|
||||
$form->add( new Interval( 'mfa_lockout_time', Settings::i()->mfa_lockout_time, FALSE, array( 'valueAs' => Interval::MINUTES, 'min' => 1 ), NULL, NULL, NULL, 'mfa_lockout_time' ) );
|
||||
$form->add( new CheckboxSet( 'mfa_forgot_behaviour', explode( ',', Settings::i()->mfa_forgot_behaviour ), FALSE, array(
|
||||
'options' => array(
|
||||
'email' => 'mfa_forgot_behaviour_email',
|
||||
'contact' => 'mfa_forgot_behaviour_contact',
|
||||
@@ -250,7 +274,7 @@ class _mfa extends \IPS\Dispatcher\Controller
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
\IPS\Lang::saveCustom( 'core', 'security_questions_opt_out_warning_value', $values['security_questions_opt_out_warning'] );
|
||||
Lang::saveCustom( 'core', 'security_questions_opt_out_warning_value', $values['security_questions_opt_out_warning'] );
|
||||
unset( $values['security_questions_opt_out_warning'] );
|
||||
|
||||
$values['mfa_required_groups'] = ( $values['mfa_required_groups'] == '*' ) ? '*' : implode( ',', $values['mfa_required_groups'] );
|
||||
@@ -259,8 +283,8 @@ class _mfa extends \IPS\Dispatcher\Controller
|
||||
|
||||
$form->saveAsSettings( $values );
|
||||
|
||||
\IPS\Session::i()->log( 'acplogs__mfa_settings_updated' );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=settings&controller=mfa&tab=settings' ), 'saved' );
|
||||
Session::i()->log( 'acplogs__mfa_settings_updated' );
|
||||
Output::i()->redirect( Url::internal( 'app=core&module=settings&controller=mfa&tab=settings' ), 'saved' );
|
||||
}
|
||||
|
||||
return (string) $form;
|
||||
@@ -271,16 +295,16 @@ class _mfa extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function resetSecurityAnswers()
|
||||
public function resetSecurityAnswers() : void
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
Session::i()->csrfCheck();
|
||||
|
||||
\IPS\Db::i()->delete( 'core_security_answers' );
|
||||
\IPS\Db::i()->update( 'core_members', "members_bitoptions2=members_bitoptions2 &~ 512" );
|
||||
Db::i()->delete( 'core_security_answers' );
|
||||
Db::i()->update( 'core_members', "members_bitoptions2=members_bitoptions2 &~ 512" );
|
||||
|
||||
/* Log MFA reset */
|
||||
\IPS\Session::i()->log( 'acplogs__mfa_questions_reset' );
|
||||
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' );
|
||||
Output::i()->redirect( Url::internal( "app=core&module=settings&controller=mfa&tab=handlers&do=settings&key=questions" ), 'acplogs__mfa_questions_reset' );
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -11,41 +11,50 @@
|
||||
namespace IPS\core\modules\admin\settings;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\Node\Controller;
|
||||
use IPS\Node\Model;
|
||||
use IPS\Output;
|
||||
use IPS\Request;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Security Questions
|
||||
*/
|
||||
class _securityquestions extends \IPS\Node\Controller
|
||||
class securityquestions extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Node Class
|
||||
*/
|
||||
protected $nodeClass = '\IPS\MFA\SecurityQuestions\Question';
|
||||
protected string $nodeClass = '\IPS\MFA\SecurityQuestions\Question';
|
||||
|
||||
/**
|
||||
* Show the "add" button in the page root rather than the table root
|
||||
*/
|
||||
protected $_addButtonInRoot = FALSE;
|
||||
protected bool $_addButtonInRoot = FALSE;
|
||||
|
||||
/**
|
||||
* Form
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function form()
|
||||
public function form() : void
|
||||
{
|
||||
\IPS\Output::i()->breadcrumb[] = array( \IPS\Http\Url::internal('app=core&module=settings&controller=mfa&tab=handlers'), \IPS\Member::loggedIn()->language()->addToStack('menu__core_settings_mfa') );
|
||||
\IPS\Output::i()->breadcrumb[] = array( \IPS\Http\Url::internal('app=core&module=settings&controller=mfa&tab=questions&do=settings&key=questions'), \IPS\Member::loggedIn()->language()->addToStack("mfa_questions_title") );
|
||||
Output::i()->breadcrumb[] = array( Url::internal('app=core&module=settings&controller=mfa&tab=handlers'), Member::loggedIn()->language()->addToStack('menu__core_settings_mfa') );
|
||||
Output::i()->breadcrumb[] = array( Url::internal('app=core&module=settings&controller=mfa&tab=questions&do=settings&key=questions'), Member::loggedIn()->language()->addToStack("mfa_questions_title") );
|
||||
parent::form();
|
||||
}
|
||||
|
||||
@@ -54,28 +63,28 @@ class _securityquestions extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function settings()
|
||||
protected function settings() : void
|
||||
{
|
||||
return $this->manage();
|
||||
$this->manage();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Redirect after save
|
||||
*
|
||||
* @param \IPS\Node\Model $old A clone of the node as it was before or NULL if this is a creation
|
||||
* @param \IPS\Node\Model $new The node now
|
||||
* @param string $lastUsedTab The tab last used in the form
|
||||
* @return void
|
||||
* @param Model|null $old A clone of the node as it was before or NULL if this is a creation
|
||||
* @param Model $new The node now
|
||||
* @param string $lastUsedTab The tab last used in the form
|
||||
* @return void
|
||||
*/
|
||||
protected function _afterSave( ?\IPS\Node\Model $old, \IPS\Node\Model $new, $lastUsedTab = FALSE )
|
||||
protected function _afterSave( ?Model $old, Model $new, mixed $lastUsedTab = FALSE ): void
|
||||
{
|
||||
if( \IPS\Request::i()->isAjax() )
|
||||
if( Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->json( array() );
|
||||
Output::i()->json( array() );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=core&module=settings&controller=mfa&tab=handlers&do=settings&key=questions&tab=questions'), 'saved' );
|
||||
Output::i()->redirect( Url::internal('app=core&module=settings&controller=mfa&tab=handlers&do=settings&key=questions&tab=questions'), 'saved' );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,30 +11,51 @@
|
||||
namespace IPS\core\modules\admin\settings;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Data\Store;
|
||||
use IPS\Db;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Dispatcher\Controller;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\Radio;
|
||||
use IPS\Helpers\Form\Translatable;
|
||||
use IPS\Helpers\Form\YesNo;
|
||||
use IPS\Helpers\Form\Url as FormUrl;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Lang;
|
||||
use IPS\Member;
|
||||
use IPS\Output;
|
||||
use IPS\Request;
|
||||
use IPS\Session;
|
||||
use IPS\Settings;
|
||||
use IPS\Theme;
|
||||
use function defined;
|
||||
use function intval;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* terms
|
||||
*/
|
||||
class _terms extends \IPS\Dispatcher\Controller
|
||||
class terms 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( 'terms_manage' );
|
||||
Dispatcher::i()->checkAcpPermission( 'terms_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
@@ -43,43 +64,40 @@ class _terms extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
protected function manage() : void
|
||||
{
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form = new Form;
|
||||
|
||||
static::buildForm( $form );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
/* What were our previous values? */
|
||||
$existingPrivacyPolicy = iterator_to_array( \IPS\Db::i()->select( 'word_custom', 'core_sys_lang_words', array( 'word_key=?', 'privacy_text_value' ) ) );
|
||||
$existingRegistrationTerms = iterator_to_array( \IPS\Db::i()->select( 'word_custom', 'core_sys_lang_words', array( 'word_key=?', 'reg_rules_value' ) ) );
|
||||
$existingPrivacyPolicy = iterator_to_array( Db::i()->select( 'word_custom', 'core_sys_lang_words', array( 'word_key=?', 'privacy_text_value' ) ) );
|
||||
$existingRegistrationTerms = iterator_to_array( Db::i()->select( 'word_custom', 'core_sys_lang_words', array( 'word_key=?', 'reg_rules_value' ) ) );
|
||||
|
||||
/* Save */
|
||||
$values = static::processForm( $values );
|
||||
|
||||
$form->saveAsSettings( $values );
|
||||
|
||||
/* Clear guest page caches */
|
||||
\IPS\Data\Cache::i()->clearAll();
|
||||
|
||||
/* Log */
|
||||
\IPS\Session::i()->log( 'acplogs__terms_edited' );
|
||||
Session::i()->log( 'acplogs__terms_edited' );
|
||||
|
||||
/* Do we need to ask the admin if they want to ask members to reconfirm? */
|
||||
$changedPrivacyPolicy = $existingPrivacyPolicy != iterator_to_array( \IPS\Db::i()->select( 'word_custom', 'core_sys_lang_words', array( 'word_key=?', 'privacy_text_value' ) ) );
|
||||
$changedRegistrationTerms = $existingRegistrationTerms != iterator_to_array( \IPS\Db::i()->select( 'word_custom', 'core_sys_lang_words', array( 'word_key=?', 'reg_rules_value' ) ) );
|
||||
$changedPrivacyPolicy = $existingPrivacyPolicy != iterator_to_array( Db::i()->select( 'word_custom', 'core_sys_lang_words', array( 'word_key=?', 'privacy_text_value' ) ) );
|
||||
$changedRegistrationTerms = $existingRegistrationTerms != iterator_to_array( Db::i()->select( 'word_custom', 'core_sys_lang_words', array( 'word_key=?', 'reg_rules_value' ) ) );
|
||||
if ( $changedPrivacyPolicy or $changedRegistrationTerms )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=core&module=settings&controller=terms&do=reconfirm')->setQueryString( array(
|
||||
'privacy' => \intval( $changedPrivacyPolicy ),
|
||||
'reg' => \intval( $changedRegistrationTerms )
|
||||
Output::i()->redirect( Url::internal('app=core&module=settings&controller=terms&do=reconfirm')->setQueryString( array(
|
||||
'privacy' => intval( $changedPrivacyPolicy ),
|
||||
'reg' => intval( $changedRegistrationTerms )
|
||||
) ) );
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__core_settings_terms');
|
||||
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'global' )->block( 'menu__core_settings_terms', $form );
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('menu__core_settings_terms');
|
||||
Output::i()->output .= Theme::i()->getTemplate( 'global' )->block( 'menu__core_settings_terms', $form );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,7 +106,7 @@ class _terms extends \IPS\Dispatcher\Controller
|
||||
* @param array $values Values from form
|
||||
* @return array
|
||||
*/
|
||||
public static function processForm( $values )
|
||||
public static function processForm( array $values ) : array
|
||||
{
|
||||
foreach ( array( 'gl_guidelines' => 'guidelines_value', 'privacy_text' => 'privacy_text_value', 'reg_rules' => 'reg_rules_value', 'guest_terms_bar_text' => 'guest_terms_bar_text_value', 'cookie_3rdpartynotice' => 'cookie_3rdpartynotice_value' ) as $k => $v )
|
||||
{
|
||||
@@ -101,12 +119,12 @@ class _terms extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Lang::saveCustom( 'core', $v, $values[ $k ] );
|
||||
Lang::saveCustom( 'core', $v, $values[ $k ] );
|
||||
unset( $values[ $k ] );
|
||||
}
|
||||
|
||||
/* Update the essential cookie name list */
|
||||
unset( \IPS\Data\Store::i()->essentialCookieNames );
|
||||
unset( Store::i()->essentialCookieNames );
|
||||
|
||||
return $values;
|
||||
}
|
||||
@@ -114,13 +132,13 @@ class _terms extends \IPS\Dispatcher\Controller
|
||||
/**
|
||||
* Build the form
|
||||
*
|
||||
* @param \IPS\Form $form Form to add settings to
|
||||
* @param Form $form Form to add settings to
|
||||
* @return void
|
||||
*/
|
||||
public static function buildForm( $form )
|
||||
public static function buildForm( Form $form ) : void
|
||||
{
|
||||
$form->addHeader( 'terms_guidelines' );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'gl_type', \IPS\Settings::i()->gl_type, FALSE, array(
|
||||
$form->add( new Radio( 'gl_type', Settings::i()->gl_type, FALSE, array(
|
||||
'options' => array(
|
||||
'internal' => 'gl_internal',
|
||||
'external' => 'gl_external',
|
||||
@@ -132,10 +150,10 @@ class _terms extends \IPS\Dispatcher\Controller
|
||||
)
|
||||
) ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Translatable( 'gl_guidelines', NULL, FALSE, array( 'app' => 'core', 'key' => 'guidelines_value', 'editor' => array( 'app' => 'core', 'key' => 'Admin', 'autoSaveKey' => 'Guidelines', 'attachIds' => array( NULL, NULL, 'gl_guidelines' ) ) ), NULL, NULL, NULL, 'gl_guidelines_id' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Url( 'gl_link', \IPS\Settings::i()->gl_link, FALSE, array(), NULL, NULL, NULL, 'gl_link' ) );
|
||||
$form->add( new Translatable( 'gl_guidelines', NULL, FALSE, array( 'app' => 'core', 'key' => 'guidelines_value', 'editor' => array( 'app' => 'core', 'key' => 'Admin', 'autoSaveKey' => 'Guidelines', 'attachIds' => array( NULL, NULL, 'gl_guidelines' ) ) ), NULL, NULL, NULL, 'gl_guidelines_id' ) );
|
||||
$form->add( new FormUrl( 'gl_link', Settings::i()->gl_link, FALSE, array(), NULL, NULL, NULL, 'gl_link' ) );
|
||||
$form->addHeader( 'terms_privacy');
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'privacy_type', \IPS\Settings::i()->privacy_type, FALSE, array(
|
||||
$form->add( new Radio( 'privacy_type', Settings::i()->privacy_type, FALSE, array(
|
||||
'options' => array(
|
||||
'internal' => 'privacy_internal',
|
||||
'external' => 'privacy_external',
|
||||
@@ -147,22 +165,20 @@ class _terms extends \IPS\Dispatcher\Controller
|
||||
)
|
||||
) ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Translatable( 'privacy_text', NULL, FALSE, array( 'app' => 'core', 'key' => 'privacy_text_value', 'editor' => array( 'app' => 'core', 'key' => 'Admin', 'autoSaveKey' => 'Privacy', 'attachIds' => array( NULL, NULL, 'privacy_text' ) ) ), NULL, NULL, NULL, 'privacy_text_id' ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'privacy_show_processors', \IPS\Settings::i()->privacy_show_processors, FALSE, array(), NULL, NULL, NULL, 'privacy_show_processors' ) );
|
||||
$form->add( new Translatable( 'privacy_text', NULL, FALSE, array( 'app' => 'core', 'key' => 'privacy_text_value', 'editor' => array( 'app' => 'core', 'key' => 'Admin', 'autoSaveKey' => 'Privacy', 'attachIds' => array( NULL, NULL, 'privacy_text' ) ) ), NULL, NULL, NULL, 'privacy_text_id' ) );
|
||||
$form->add( new YesNo( 'privacy_show_processors', Settings::i()->privacy_show_processors, FALSE, array(), NULL, NULL, NULL, 'privacy_show_processors' ) );
|
||||
|
||||
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Url( 'privacy_link', \IPS\Settings::i()->privacy_link, FALSE, array(), NULL, NULL, NULL, 'privacy_link' ) );
|
||||
$form->add( new FormUrl( 'privacy_link', Settings::i()->privacy_link, FALSE, array(), NULL, NULL, NULL, 'privacy_link' ) );
|
||||
|
||||
$form->addHeader( 'terms_registration' );
|
||||
$form->add( new \IPS\Helpers\Form\Translatable( 'reg_rules', NULL, FALSE, array( 'app' => 'core', 'key' => 'reg_rules_value', 'editor' => array( 'app' => 'core', 'key' => 'Admin', 'autoSaveKey' => 'RegistrationRules', 'attachIds' => array( NULL, NULL, 'reg_rules' ) ) ), NULL, NULL, NULL, 'reg_rules_id' ) );
|
||||
$form->add( new Translatable( 'reg_rules', NULL, FALSE, array( 'app' => 'core', 'key' => 'reg_rules_value', 'editor' => array( 'app' => 'core', 'key' => 'Admin', 'autoSaveKey' => 'RegistrationRules', 'attachIds' => array( NULL, NULL, 'reg_rules' ) ) ), NULL, NULL, NULL, 'reg_rules_id' ) );
|
||||
|
||||
$form->addHeader( 'guest_terms_options' );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'guest_terms_bar', \IPS\Settings::i()->guest_terms_bar, FALSE, array( 'togglesOn' => array( 'guest_terms_bar_text' ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Translatable( 'guest_terms_bar_text', NULL, FALSE, array( 'app' => 'core', 'key' => 'guest_terms_bar_text_value', 'sprintf' => array( '{terms}', '{privacy}', '{guidelines}', '{cookies}' ) ), NULL, NULL, NULL, 'guest_terms_bar_text' ) );
|
||||
$form->add( new YesNo( 'guest_terms_bar', Settings::i()->guest_terms_bar, FALSE, array( 'togglesOn' => array( 'guest_terms_bar_text' ) ) ) );
|
||||
$form->add( new Translatable( 'guest_terms_bar_text', NULL, FALSE, array( 'app' => 'core', 'key' => 'guest_terms_bar_text_value', 'sprintf' => array( '{terms}', '{privacy}', '{guidelines}', '{cookies}' ) ), NULL, NULL, NULL, 'guest_terms_bar_text' ) );
|
||||
|
||||
$form->addHeader( 'terms_cookies' );
|
||||
$form->add( new \IPS\Helpers\Form\Translatable( 'cookie_3rdpartynotice', NULL, FALSE, array( 'app' => 'core', 'key' => 'cookie_3rdpartynotice_value', 'editor' => array( 'app' => 'core', 'key' => 'Admin', 'autoSaveKey' => '3rdPartyCookies', 'attachIds' => array( NULL, NULL, 'privacy_text' ) ) ) ));
|
||||
$form->add( new Translatable( 'cookie_3rdpartynotice', NULL, FALSE, array( 'app' => 'core', 'key' => 'cookie_3rdpartynotice_value', 'editor' => array( 'app' => 'core', 'key' => 'Admin', 'autoSaveKey' => '3rdPartyCookies', 'attachIds' => array( NULL, NULL, 'privacy_text' ) ) ) ));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -170,37 +186,37 @@ class _terms extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function reconfirm()
|
||||
protected function reconfirm() : void
|
||||
{
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form = new Form;
|
||||
|
||||
$form->addMessage( 'admin_reconfirm_blurb' );
|
||||
|
||||
if ( \IPS\Request::i()->reg )
|
||||
if ( Request::i()->reg )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'admin_reconfirm_reg_terms', FALSE ) );
|
||||
$form->add( new YesNo( 'admin_reconfirm_reg_terms', FALSE ) );
|
||||
}
|
||||
|
||||
if ( \IPS\Request::i()->privacy )
|
||||
if ( Request::i()->privacy )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'admin_reconfirm_privacy', FALSE ) );
|
||||
$form->add( new YesNo( 'admin_reconfirm_privacy', FALSE ) );
|
||||
}
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
if ( isset( $values['admin_reconfirm_reg_terms'] ) and $values['admin_reconfirm_reg_terms'] )
|
||||
{
|
||||
\IPS\Member::updateAllMembers( array( "members_bitoptions2 = members_bitoptions2 | " . \IPS\Member::$bitOptions['members_bitoptions']['members_bitoptions2']['must_reaccept_terms'] ) );
|
||||
Member::updateAllMembers( array( "members_bitoptions2 = members_bitoptions2 | " . Member::$bitOptions['members_bitoptions']['members_bitoptions2']['must_reaccept_terms'] ) );
|
||||
}
|
||||
if ( isset( $values['admin_reconfirm_privacy'] ) and $values['admin_reconfirm_privacy'] )
|
||||
{
|
||||
\IPS\Member::updateAllMembers( array( "members_bitoptions2 = members_bitoptions2 | " . \IPS\Member::$bitOptions['members_bitoptions']['members_bitoptions2']['must_reaccept_privacy'] ) );
|
||||
Member::updateAllMembers( array( "members_bitoptions2 = members_bitoptions2 | " . Member::$bitOptions['members_bitoptions']['members_bitoptions2']['must_reaccept_privacy'] ) );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=core&module=settings&controller=terms') );
|
||||
Output::i()->redirect( Url::internal('app=core&module=settings&controller=terms') );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__core_settings_terms');
|
||||
\IPS\Output::i()->output = $form;
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('menu__core_settings_terms');
|
||||
Output::i()->output = $form;
|
||||
}
|
||||
}
|
||||
@@ -12,30 +12,61 @@
|
||||
namespace IPS\core\modules\admin\settings;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use Exception;
|
||||
use IPS\Data\Store;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Dispatcher\Controller;
|
||||
use IPS\File;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\Color;
|
||||
use IPS\Helpers\Form\Radio;
|
||||
use IPS\Helpers\Form\Text;
|
||||
use IPS\Helpers\Form\TextArea;
|
||||
use IPS\Helpers\Form\Upload;
|
||||
use IPS\Helpers\Form\YesNo;
|
||||
use IPS\Helpers\MultipleRedirect;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Http\Url\Friendly;
|
||||
use IPS\Image;
|
||||
use IPS\Log;
|
||||
use IPS\Member;
|
||||
use IPS\Output;
|
||||
use IPS\Request;
|
||||
use IPS\Session;
|
||||
use IPS\Settings;
|
||||
use IPS\Theme;
|
||||
use LogicException;
|
||||
use function count;
|
||||
use function defined;
|
||||
use function mb_strstr;
|
||||
use function strlen;
|
||||
use function substr;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* webapp
|
||||
*/
|
||||
class _webapp extends \IPS\Dispatcher\Controller
|
||||
class webapp 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( 'webapp_manage' );
|
||||
Dispatcher::i()->checkAcpPermission( 'webapp_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
@@ -44,74 +75,78 @@ class _webapp extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
protected function manage() : void
|
||||
{
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form = new Form;
|
||||
|
||||
$form->addTab( 'webapp_tab_icons' );
|
||||
|
||||
/* 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' ) ) );
|
||||
$homeScreen = json_decode( Settings::i()->icons_homescreen, TRUE ) ?? array();
|
||||
$form->add( new Upload( 'icons_homescreen', ( isset( $homeScreen['original'] ) ) ? File::get( 'core_Icons', $homeScreen['original'] ) : NULL, FALSE, array( 'image' => true, 'storageExtension' => 'core_Icons' ) ) );
|
||||
|
||||
$homeScreenMaskable = json_decode( \IPS\Settings::i()->icons_homescreen_maskable, TRUE ) ?? array();
|
||||
$form->add( new \IPS\Helpers\Form\Upload( 'icons_homescreen_maskable', ( isset( $homeScreenMaskable['original'] ) ) ? \IPS\File::get( 'core_Icons', $homeScreenMaskable['original'] ) : NULL, FALSE, array( 'image' => true, 'storageExtension' => 'core_Icons', 'allowedFileTypes' => ['png', 'webp' ] ) ) );
|
||||
$homeScreenMaskable = json_decode( Settings::i()->icons_homescreen_maskable, TRUE ) ?? array();
|
||||
$form->add( new Upload( 'icons_homescreen_maskable', ( isset( $homeScreenMaskable['original'] ) ) ? File::get( 'core_Icons', $homeScreenMaskable['original'] ) : NULL, FALSE, array( 'image' => true, 'storageExtension' => 'core_Icons', 'allowedFileTypes' => ['png', 'webp' ] ) ) );
|
||||
|
||||
/* Apple startup screen logo - we accept one upload and create the images we need */
|
||||
$apple = json_decode( \IPS\Settings::i()->icons_apple_startup, TRUE ) ?? array();
|
||||
$form->add( new \IPS\Helpers\Form\Upload( 'icons_apple_startup', ( isset( $apple['original'] ) ) ? \IPS\File::get( 'core_Icons', $apple['original'] ) : NULL, FALSE, array( 'image' => true, 'storageExtension' => 'core_Icons' ) ) );
|
||||
$apple = json_decode( Settings::i()->icons_apple_startup, TRUE ) ?? array();
|
||||
$form->add( new Upload( 'icons_apple_startup', ( isset( $apple['original'] ) ) ? File::get( 'core_Icons', $apple['original'] ) : NULL, FALSE, array( 'image' => true, 'storageExtension' => 'core_Icons' ) ) );
|
||||
|
||||
/* Safari pinned tabs icon and highlight color */
|
||||
$form->add( new \IPS\Helpers\Form\Upload( 'icons_mask_icon', \IPS\Settings::i()->icons_mask_icon ? \IPS\File::get( 'core_Icons', \IPS\Settings::i()->icons_mask_icon ) : NULL, FALSE, array( 'allowedFileTypes' => array( 'svg' ), 'storageExtension' => 'core_Icons', 'obscure' => FALSE ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Color( 'icons_mask_color', \IPS\Settings::i()->icons_mask_color, FALSE ) );
|
||||
$form->add( new Upload( 'icons_mask_icon', Settings::i()->icons_mask_icon ? File::get( 'core_Icons', Settings::i()->icons_mask_icon ) : NULL, FALSE, array( 'allowedFileTypes' => array( 'svg' ), 'storageExtension' => 'core_Icons', 'obscure' => FALSE ) ) );
|
||||
$form->add( new Color( 'icons_mask_color', Settings::i()->icons_mask_color, FALSE ) );
|
||||
|
||||
$form->addTab( 'webapp_tab_manifest' );
|
||||
|
||||
/* And finally, additional manifest and livetile details */
|
||||
$manifestDetails = json_decode( \IPS\Settings::i()->manifest_details, TRUE );
|
||||
$manifestDetails = json_decode( Settings::i()->manifest_details, TRUE );
|
||||
if ( isset( $manifestDetails['cache_key'] ) )
|
||||
{
|
||||
unset( $manifestDetails['cache_key'] );
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'configure_manifest', \count( $manifestDetails ) > 0, FALSE, array(
|
||||
$form->add( new YesNo( 'configure_manifest', count( $manifestDetails ) > 0, FALSE, array(
|
||||
'togglesOn' => array( 'manifest_shortname', 'manifest_fullname', 'manifest_description', 'manifest_defaultapp', 'manifest_themecolor', 'manifest_bgcolor', 'manifest_display', 'manifest_custom_url_toggle' ),
|
||||
) ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'manifest_shortname', ( isset( $manifestDetails['short_name'] ) ) ? $manifestDetails['short_name'] : '', FALSE, array(), NULL, NULL, NULL, 'manifest_shortname' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'manifest_fullname', ( isset( $manifestDetails['name'] ) ) ? $manifestDetails['name'] : '', FALSE, array(), NULL, NULL, NULL, 'manifest_fullname' ) );
|
||||
$form->add( new \IPS\Helpers\Form\TextArea( 'manifest_description', ( isset( $manifestDetails['description'] ) ) ? $manifestDetails['description'] : '', FALSE, array(), NULL, NULL, NULL, 'manifest_description' ) );
|
||||
$form->add( new Text( 'manifest_shortname', ( isset( $manifestDetails['short_name'] ) ) ? $manifestDetails['short_name'] : '', FALSE, array(), NULL, NULL, NULL, 'manifest_shortname' ) );
|
||||
$form->add( new Text( 'manifest_fullname', ( isset( $manifestDetails['name'] ) ) ? $manifestDetails['name'] : '', FALSE, array(), NULL, NULL, NULL, 'manifest_fullname' ) );
|
||||
$form->add( new TextArea( 'manifest_description', ( isset( $manifestDetails['description'] ) ) ? $manifestDetails['description'] : '', FALSE, array(), NULL, NULL, NULL, 'manifest_description' ) );
|
||||
|
||||
$formStartUrl = '';
|
||||
if( isset( $manifestDetails['start_url'] ) )
|
||||
{
|
||||
$formStartUrl = str_replace( 'index.php?/', '', \IPS\Http\Url\Friendly::fixComponentPath( $manifestDetails['start_url'] ) );
|
||||
$formStartUrl = str_replace( 'index.php?/', '', Friendly::fixComponentPath( $manifestDetails['start_url'] ) );
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'manifest_custom_url_toggle', ( isset( $manifestDetails['start_url'] ) and empty( $formStartUrl ) ? FALSE : TRUE ), FALSE, array(
|
||||
$form->add( new YesNo( 'manifest_custom_url_toggle', ( isset( $manifestDetails['start_url'] ) and !empty( $formStartUrl ) ), FALSE, array(
|
||||
'togglesOn' => array( 'manifest_short_url' ),
|
||||
), NULL, NULL, NULL, 'manifest_custom_url_toggle' ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'manifest_short_url', $formStartUrl, FALSE, array(), function( $val )
|
||||
$form->add( new Text( 'manifest_short_url', $formStartUrl, FALSE, array(), function( $val )
|
||||
{
|
||||
if ( $val and \IPS\Request::i()->manifest_custom_url_toggle_checkbox )
|
||||
if ( $val and Request::i()->manifest_custom_url_toggle_checkbox )
|
||||
{
|
||||
if ( mb_substr( $val, -1 ) !== '/' )
|
||||
{
|
||||
$val .= '/';
|
||||
}
|
||||
|
||||
$response = \IPS\Http\Url::external( \IPS\Http\Url::baseUrl() . ( \IPS\Settings::i()->htaccess_mod_rewrite ? $val : 'index.php?/' . $val ) )->request( NULL, NULL, FALSE )->get();
|
||||
if ( $response->httpResponseCode != 200 and $response->httpResponseCode != 303 and ( \IPS\Settings::i()->site_online OR $response->httpResponseCode != 503 ) )
|
||||
$response = Url::external( Url::baseUrl() . ( Settings::i()->htaccess_mod_rewrite ? $val : 'index.php?/' . $val ) )->request( NULL, NULL, FALSE )->get();
|
||||
if ( $response->httpResponseCode != 200 and $response->httpResponseCode != 303 and ( Settings::i()->site_online OR $response->httpResponseCode != 503 ) )
|
||||
{
|
||||
throw new \LogicException( 'pwa_start_url_incorrect' );
|
||||
throw new LogicException( 'pwa_start_url_incorrect' );
|
||||
}
|
||||
}
|
||||
}, \IPS\Http\Url::baseUrl() . ( !\IPS\Settings::i()->htaccess_mod_rewrite ? 'index.php?/' : '' ), NULL, 'manifest_short_url' ) );
|
||||
}, Url::baseUrl() . ( !Settings::i()->htaccess_mod_rewrite ? 'index.php?/' : '' ), NULL, 'manifest_short_url' ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Color( 'manifest_themecolor', ( isset( $manifestDetails['theme_color'] ) ) ? $manifestDetails['theme_color'] : NULL, FALSE, array(), NULL, NULL, NULL, 'manifest_themecolor' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Color( 'manifest_bgcolor', ( isset( $manifestDetails['background_color'] ) ) ? $manifestDetails['background_color'] : NULL, FALSE, array(), NULL, NULL, NULL, 'manifest_bgcolor' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'manifest_display', ( isset( $manifestDetails['display'] ) ) ? $manifestDetails['display'] : 'standalone', FALSE, array( 'options' => array( 'fullscreen' => 'manifest_fullscreen', 'standalone' => 'manifest_standalone', 'minimal-ui' => 'manifest_minimalui', 'browser' => 'manifest_browser' ) ), NULL, NULL, NULL, 'manifest_display' ) );
|
||||
$form->add( new Color( 'manifest_themecolor', ( isset( $manifestDetails['theme_color'] ) ) ? $manifestDetails['theme_color'] : NULL, FALSE, array( 'allowNoneLanguage' => 'manifest_themecolor_none', 'allowNone' => true ), NULL, NULL, NULL, 'manifest_themecolor' ) );
|
||||
$form->add( new Color( 'manifest_bgcolor', ( isset( $manifestDetails['background_color'] ) ) ? $manifestDetails['background_color'] : NULL, FALSE, array(), NULL, NULL, NULL, 'manifest_bgcolor' ) );
|
||||
$form->add( new Radio( 'manifest_display', ( isset( $manifestDetails['display'] ) ) ? $manifestDetails['display'] : 'standalone', FALSE, array( 'options' => array( 'fullscreen' => 'manifest_fullscreen', 'standalone' => 'manifest_standalone', 'minimal-ui' => 'manifest_minimalui', 'browser' => 'manifest_browser' ) ), NULL, NULL, NULL, 'manifest_display' ) );
|
||||
|
||||
if( $values = $form->values() )
|
||||
{
|
||||
$path = \IPS\Http\Url::createFromString( \IPS\Http\Url::baseUrl() )->data[ \IPS\Http\Url::COMPONENT_PATH ];
|
||||
$path = Url::createFromString( Url::baseUrl() )->data[ Url::COMPONENT_PATH ];
|
||||
$startUrl = $path ?? '';
|
||||
|
||||
if ( $values['manifest_custom_url_toggle'] !== FALSE and ! empty( $values['manifest_short_url'] ) )
|
||||
@@ -120,7 +155,7 @@ class _webapp extends \IPS\Dispatcher\Controller
|
||||
|
||||
if( !empty( $path ) )
|
||||
{
|
||||
$startUrl = '/' . trim( $path . ( !\IPS\Settings::i()->htaccess_mod_rewrite ? 'index.php?/' : '' ) . ltrim( $values['manifest_short_url'], '/' ), '/' ) . '/';
|
||||
$startUrl = '/' . trim( $path . ( !Settings::i()->htaccess_mod_rewrite ? 'index.php?/' : '' ) . ltrim( $values['manifest_short_url'], '/' ), '/' ) . '/';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,28 +204,25 @@ class _webapp extends \IPS\Dispatcher\Controller
|
||||
/* Save the settings */
|
||||
$form->saveAsSettings( $values );
|
||||
|
||||
/* Clear guest page caches */
|
||||
\IPS\Data\Cache::i()->clearAll();
|
||||
|
||||
/* Clear manifest and ie browser data stores */
|
||||
unset( \IPS\Data\Store::i()->manifest, \IPS\Data\Store::i()->iebrowserconfig );
|
||||
unset( Store::i()->manifest, Store::i()->iebrowserconfig );
|
||||
|
||||
/* And log */
|
||||
\IPS\Session::i()->log( 'acplogs__webapp' );
|
||||
Session::i()->log( 'acplogs__webapp' );
|
||||
|
||||
/* And Redirect */
|
||||
if( $rebuildStartScreen === TRUE )
|
||||
{
|
||||
\IPS\Output::i()->redirect( $this->url->setQueryString( 'do', 'buildStartupScreenImages' ), 'saved' );
|
||||
Output::i()->redirect( $this->url->setQueryString( 'do', 'buildStartupScreenImages' ), 'saved' );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->redirect( $this->url, 'saved' );
|
||||
Output::i()->redirect( $this->url, 'saved' );
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__core_settings_webapp');
|
||||
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'global' )->block( 'menu__core_settings_webapp', $form );
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('menu__core_settings_webapp');
|
||||
Output::i()->output .= Theme::i()->getTemplate( 'global' )->block( 'menu__core_settings_webapp', $form );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -201,7 +233,7 @@ class _webapp extends \IPS\Dispatcher\Controller
|
||||
* @param array $homeScreenMaskable Existing values, if any
|
||||
* @return array
|
||||
*/
|
||||
public static function processApplicationIcon( $values, $homeScreen = array(), $homeScreenMaskable = array() )
|
||||
public static function processApplicationIcon( array $values, array $homeScreen = array(), array $homeScreenMaskable = array() ) : array
|
||||
{
|
||||
if( ( isset( $values['icons_homescreen'] ) AND $values['icons_homescreen'] ) or ( isset( $values['icons_homescreen_maskable' ] ) AND $values['icons_homescreen_maskable'] ) )
|
||||
{
|
||||
@@ -244,14 +276,14 @@ class _webapp extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
$filename .= "-masked";
|
||||
|
||||
if ( ! \mb_strstr( $filename, 'android-chrome' ) )
|
||||
if ( ! mb_strstr( $filename, 'android-chrome' ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
$image = \IPS\Image::create( $values[ $type ]->contents() );
|
||||
$image = Image::create( $values[ $type ]->contents() );
|
||||
|
||||
if ( $image::exifSupported() )
|
||||
{
|
||||
@@ -261,12 +293,12 @@ class _webapp extends \IPS\Dispatcher\Controller
|
||||
$image->crop( $_sizes[0], $_sizes[1] );
|
||||
|
||||
$setting[$filename] = array(
|
||||
'url' => (string)\IPS\File::create( 'core_Icons', $filename . '.png', (string)$image, NULL, TRUE, NULL, FALSE ),
|
||||
'url' => (string)File::create( 'core_Icons', $filename . '.png', (string)$image, NULL, TRUE, NULL, FALSE ),
|
||||
'width' => $image->width,
|
||||
'height' => $image->height
|
||||
);
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
catch ( Exception $e )
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -283,18 +315,18 @@ class _webapp extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\File::get( 'core_Icons', ( $key == 'original' ) ? $image : $image['url'] )->delete();
|
||||
File::get( 'core_Icons', ( $key == 'original' ) ? $image : $image['url'] )->delete();
|
||||
}
|
||||
catch( \Exception $e ){}
|
||||
catch( Exception $e ){}
|
||||
}
|
||||
|
||||
foreach( $homeScreenMaskable as $key => $image )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\File::get( 'core_Icons', ( $key == 'original' ) ? $image : $image['url'] )->delete();
|
||||
File::get( 'core_Icons', ( $key == 'original' ) ? $image : $image['url'] )->delete();
|
||||
}
|
||||
catch( \Exception $e ){}
|
||||
catch( Exception $e ){}
|
||||
}
|
||||
|
||||
$values['icons_homescreen'] = '';
|
||||
@@ -315,7 +347,7 @@ class _webapp extends \IPS\Dispatcher\Controller
|
||||
* @param array $apple Existing values, if any
|
||||
* @return array
|
||||
*/
|
||||
public static function processAppleStartupScreen( $values, $apple = array() )
|
||||
public static function processAppleStartupScreen( array $values, array $apple = array() ) : array
|
||||
{
|
||||
if( $values['icons_apple_startup'] )
|
||||
{
|
||||
@@ -328,9 +360,9 @@ class _webapp extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\File::get( 'core_Icons', ( $key == 'original' ) ? $image : $image['url'] )->delete();
|
||||
File::get( 'core_Icons', ( $key == 'original' ) ? $image : $image['url'] )->delete();
|
||||
}
|
||||
catch( \Exception $e ){}
|
||||
catch( Exception $e ){}
|
||||
}
|
||||
|
||||
$values['icons_apple_startup'] = '';
|
||||
@@ -342,21 +374,19 @@ class _webapp extends \IPS\Dispatcher\Controller
|
||||
/**
|
||||
* Process Apple startup screen images
|
||||
*
|
||||
* @param array $values Values from form submission
|
||||
* @param array $apple Existing values, if any
|
||||
* @return array
|
||||
* @return array|null
|
||||
*/
|
||||
public function buildStartupScreenImages()
|
||||
public function buildStartupScreenImages() : ?array
|
||||
{
|
||||
$self = $this;
|
||||
|
||||
$multiRedirect = new \IPS\Helpers\MultipleRedirect(
|
||||
$multiRedirect = new MultipleRedirect(
|
||||
$this->url->setQueryString('do', 'buildStartupScreenImages'),
|
||||
function( $data )
|
||||
{
|
||||
/* Get the necessary data */
|
||||
$manifestDetails = json_decode( \IPS\Settings::i()->manifest_details, TRUE );
|
||||
$setting = json_decode( \IPS\Settings::i()->icons_apple_startup, TRUE ) ?? array();
|
||||
$manifestDetails = json_decode( Settings::i()->manifest_details, TRUE );
|
||||
$setting = json_decode( Settings::i()->icons_apple_startup, TRUE ) ?? array();
|
||||
|
||||
if( isset( $setting['original'] ) )
|
||||
{
|
||||
@@ -393,24 +423,24 @@ class _webapp extends \IPS\Dispatcher\Controller
|
||||
'apple-startup-1080x2340' => array( 360, 780, 3, 'portrait' ),
|
||||
);
|
||||
|
||||
$file = \IPS\File::get( 'core_Icons', $setting['original'] );
|
||||
$file = File::get( 'core_Icons', $setting['original'] );
|
||||
$originalContents = $file->contents();
|
||||
|
||||
$backgroundColor = ( isset( $manifestDetails['background_color'] ) ) ? str_replace( '#', '', $manifestDetails['background_color'] ) : 'FFFFFF';
|
||||
|
||||
$rgb = array();
|
||||
|
||||
if ( \strlen( $backgroundColor ) == 3 )
|
||||
if ( strlen( $backgroundColor ) == 3 )
|
||||
{
|
||||
$rgb[] = hexdec( \substr( $backgroundColor, 0, 1 ) . \substr( $backgroundColor, 0, 1 ) ); // R
|
||||
$rgb[] = hexdec( \substr( $backgroundColor, 1, 1 ) . \substr( $backgroundColor, 1, 1 ) ); // G
|
||||
$rgb[] = hexdec( \substr( $backgroundColor, 2, 1 ) . \substr( $backgroundColor, 2, 1 ) ); // B
|
||||
$rgb[] = hexdec( substr( $backgroundColor, 0, 1 ) . substr( $backgroundColor, 0, 1 ) ); // R
|
||||
$rgb[] = hexdec( substr( $backgroundColor, 1, 1 ) . substr( $backgroundColor, 1, 1 ) ); // G
|
||||
$rgb[] = hexdec( substr( $backgroundColor, 2, 1 ) . substr( $backgroundColor, 2, 1 ) ); // B
|
||||
}
|
||||
else
|
||||
{
|
||||
$rgb[] = hexdec( \substr( $backgroundColor, 0, 2 ) ); // R
|
||||
$rgb[] = hexdec( \substr( $backgroundColor, 2, 2 ) ); // G
|
||||
$rgb[] = hexdec( \substr( $backgroundColor, 4, 2 ) ); // B
|
||||
$rgb[] = hexdec( substr( $backgroundColor, 0, 2 ) ); // R
|
||||
$rgb[] = hexdec( substr( $backgroundColor, 2, 2 ) ); // G
|
||||
$rgb[] = hexdec( substr( $backgroundColor, 4, 2 ) ); // B
|
||||
}
|
||||
|
||||
$did = 0;
|
||||
@@ -429,8 +459,8 @@ class _webapp extends \IPS\Dispatcher\Controller
|
||||
$width = ( $_sizes[3] == 'landscape' ) ? $_sizes[1] * $_sizes[2] : $_sizes[0] * $_sizes[2];
|
||||
$height = ( $_sizes[3] == 'portrait' ) ? $_sizes[1] * $_sizes[2] : $_sizes[0] * $_sizes[2];
|
||||
|
||||
$logoImage = \IPS\Image::create( $originalContents );
|
||||
$canvas = \IPS\Image::newImageCanvas( $width, $height, $rgb );
|
||||
$logoImage = Image::create( $originalContents );
|
||||
$canvas = Image::newImageCanvas( $width, $height, $rgb );
|
||||
|
||||
$logoImage->resizeToMax( $width - static::MINIMUM_STARTUP_IMAGE_PADDING, $height - static::MINIMUM_STARTUP_IMAGE_PADDING );
|
||||
|
||||
@@ -445,43 +475,44 @@ class _webapp extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
|
||||
$setting[ $filename ] = array(
|
||||
'url' => (string) \IPS\File::create( 'core_Icons', $filename . '.png', (string) $canvas, NULL, TRUE, NULL, FALSE ),
|
||||
'url' => (string) File::create( 'core_Icons', $filename . '.png', (string) $canvas, NULL, TRUE, NULL, FALSE ),
|
||||
'width' => $canvas->width,
|
||||
'height' => $canvas->height,
|
||||
'density' => $_sizes[2],
|
||||
'orientation' => $_sizes[3],
|
||||
);
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
catch ( Exception $e )
|
||||
{
|
||||
\IPS\Log::log( $e, 'apple-startup-image' );
|
||||
Log::log( $e, 'apple-startup-image' );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Are we done? */
|
||||
if( $did == \count( $sizes ) )
|
||||
if( $did == count( $sizes ) )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
\IPS\Settings::i()->changeValues( array( 'icons_apple_startup' => json_encode( $setting ) ) );
|
||||
Settings::i()->changeValues( array( 'icons_apple_startup' => json_encode( $setting ) ) );
|
||||
}
|
||||
|
||||
return array( $data, \IPS\Member::loggedIn()->language()->addToStack('build_start_images_title'), ( $did ) ? round( ( 100 / \count( $sizes ) * $did ), 2 ) : 0 );
|
||||
return array( $data, Member::loggedIn()->language()->addToStack('build_start_images_title'), ( $did ) ? round( ( 100 / count( $sizes ) * $did ), 2 ) : 0 );
|
||||
},
|
||||
function() use( $self )
|
||||
{
|
||||
$manifest = json_decode( \IPS\Settings::i()->manifest_details, TRUE );
|
||||
$manifest = json_decode( Settings::i()->manifest_details, TRUE );
|
||||
$manifest['cache_key'] = time();
|
||||
|
||||
\IPS\Settings::i()->changeValues( [ 'manifest_details' => json_encode( $manifest ) ] );
|
||||
\IPS\Output::i()->redirect( $self->url, 'completed' );
|
||||
Settings::i()->changeValues( [ 'manifest_details' => json_encode( $manifest ) ] );
|
||||
Output::i()->redirect( $self->url, 'completed' );
|
||||
}
|
||||
);
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('build_start_images_title');
|
||||
\IPS\Output::i()->output = $multiRedirect;
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('build_start_images_title');
|
||||
Output::i()->output = $multiRedirect;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user