Version 5.0.0 beta 1

This commit is contained in:
Neo committed 2025-12-19 16:27:35 -08:00
1 parent 25ddeb65d6
commit 15c7beabc5
6736 files changed
+627902 -497943

No files matched your search

@@ -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;
}