Version 4.7.0
This commit is contained in:
1 parent
517a5e1f70
commit
8ba7d43898
1933 files changed
+65613
-11332
No files matched your search
@@ -76,6 +76,7 @@ class _advanced extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
$tabs['datastore'] = 'data_store';
|
||||
}
|
||||
$tabs['pageoutput'] = 'page_output';
|
||||
|
||||
/* Display */
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__core_settings_advanced');
|
||||
@@ -546,6 +547,28 @@ class _advanced extends \IPS\Dispatcher\Controller
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Settings
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function _managePageoutput()
|
||||
{
|
||||
/* Build and show form */
|
||||
$form = new \IPS\Helpers\Form;
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Codemirror( 'custom_body_code', \IPS\Settings::i()->custom_body_code, FALSE, array('height' => 150, 'mode' => 'javascript'), NULL, NULL, NULL, 'custom_body_code' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Codemirror( 'custom_page_view_js', \IPS\Settings::i()->custom_page_view_js, FALSE, array('height' => 150, 'mode' => 'javascript'), NULL, NULL, NULL, 'custom_page_view_js' ) );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
$form->saveAsSettings( $values );
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=settings&controller=advanced&tab=pageoutput' ), 'saved' );
|
||||
}
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tasks
|
||||
*
|
||||
@@ -570,6 +593,8 @@ class _advanced extends \IPS\Dispatcher\Controller
|
||||
|
||||
$table->sortBy = $table->sortBy ?: 'next_run';
|
||||
$table->sortDirection = $table->sortDirection ?: 'asc';
|
||||
$table->noSort = array( 'frequency' );
|
||||
|
||||
$table->quickSearch = function( $val )
|
||||
{
|
||||
$matches = \IPS\Member::loggedIn()->language()->searchCustom( 'task__', $val, TRUE );
|
||||
|
||||
@@ -0,0 +1,769 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief dataLayer
|
||||
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) Invision Power Services, Inc.
|
||||
* @license https://www.invisioncommunity.com/legal/standards/
|
||||
* @package Invision Community
|
||||
|
||||
* @since 08 Feb 2022
|
||||
*/
|
||||
|
||||
namespace IPS\core\modules\admin\settings;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* dataLayer
|
||||
*/
|
||||
class _dataLayer extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
/**
|
||||
* @breif the tabs
|
||||
*/
|
||||
protected static $tabs = array(
|
||||
'main' => 'datalayer_main',
|
||||
'pageContext' => 'datalayer_pageContext',
|
||||
'properties' => 'datalayer_properties',
|
||||
'events' => 'datalayer_events',
|
||||
);
|
||||
|
||||
/**
|
||||
* @breif Makes this controller work
|
||||
*/
|
||||
public static $csrfProtected = true;
|
||||
|
||||
/**
|
||||
* @brief used to actually handle events and properties in the browser
|
||||
*/
|
||||
public static $handlerClass = '\IPS\core\DataLayer\Handler';
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'dataLayer_manage' );
|
||||
\IPS\Output::i()->title = \IPS\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;
|
||||
if (
|
||||
class_exists( $class ) AND
|
||||
class_exists( 'IPS\cloud\Application' ) AND
|
||||
method_exists( $class, 'handlerForm' ) AND
|
||||
method_exists( $class, 'loadWhere' ) AND
|
||||
\IPS\Member::loggedIn()->hasAcpRestriction( 'dataLayer_handlers_view' ) AND
|
||||
\IPS\cloud\Application::featureIsEnabled('analytics_full')
|
||||
)
|
||||
{
|
||||
static::$tabs = array(
|
||||
'main' => 'datalayer_main',
|
||||
'pageContext' => 'datalayer_pageContext',
|
||||
'handlers' => 'datalayer_handlers',
|
||||
'properties' => 'datalayer_properties',
|
||||
'events' => 'datalayer_events',
|
||||
);
|
||||
}
|
||||
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'settings/general.css', 'core', 'admin' ) );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Call Magic Method, seamless way to integrate cloud features if there are any
|
||||
*
|
||||
* @return string|void
|
||||
*/
|
||||
public function __call( $name, $arguments )
|
||||
{
|
||||
if ( method_exists( $this, $name ) )
|
||||
{
|
||||
return \call_user_func_array( $this->$name, $arguments );
|
||||
}
|
||||
elseif ( method_exists( \IPS\core\DataLayer::i(), $name ) )
|
||||
{
|
||||
$method = array( \IPS\core\DataLayer::i(), $name );
|
||||
return \call_user_func_array( $method, $arguments );
|
||||
}
|
||||
|
||||
return "You should Upgrade!";
|
||||
}
|
||||
|
||||
/**
|
||||
* ...
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
{
|
||||
$tab = \IPS\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' ) )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['actions']['addHandler'] = array(
|
||||
'title' => \IPS\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' ) )
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
$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' ),
|
||||
'icon' => 'plus',
|
||||
'link' => $addPropertyUrl,
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack( 'datalayer_add_property' ) )
|
||||
);
|
||||
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->output = $output;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( isset( $_SESSION['deleted_datalayer_property'] ) )
|
||||
{
|
||||
\IPS\Output::i()->inlineMessage = 'Deleted Property';
|
||||
unset( $_SESSION['deleted_datalayer_property'] );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core', 'admin' )->tabs(
|
||||
static::$tabs,
|
||||
$tab,
|
||||
$output,
|
||||
\IPS\Http\Url::internal( 'app=core&module=settings&controller=dataLayer', 'admin' )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the general settings form
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function main()
|
||||
{
|
||||
$form = new \IPS\Helpers\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 ) );
|
||||
|
||||
try
|
||||
{
|
||||
$default = \IPS\Login\Handler::load( \IPS\Settings::i()->core_datalayer_replace_with_sso );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
$default = 0;
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'core_datalayer_replace_with_sso', $default, false, array(
|
||||
'class' => '\IPS\Login\Handler',
|
||||
'zeroVal' => 'Use internal Member ID (default)',
|
||||
'where' => array(
|
||||
['login_enabled=?', 1],
|
||||
['login_classname LIKE ?', '%Login_Handler%'],
|
||||
['login_classname NOT LIKE ?', '%Login_Handler_Standard']
|
||||
),
|
||||
|
||||
) ) );
|
||||
|
||||
$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(
|
||||
'core_datalayer_gtmkey',
|
||||
array_pop( $gtmkey ),
|
||||
false,
|
||||
array(),
|
||||
function( $_value ) {
|
||||
/* Check for invalid characters */
|
||||
if ( preg_match( '/[^a-z,A-Z,0-9,\_]/', $_value ) )
|
||||
{
|
||||
throw new \InvalidArgumentException( 'The variable name can only contain alphanumeric characters and underscores.' );
|
||||
}
|
||||
elseif ( preg_match( '/[0-9]/', \mb_substr( $_value, 0, 1 ) ) )
|
||||
{
|
||||
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" ] ),
|
||||
];
|
||||
|
||||
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 ) )
|
||||
)
|
||||
{
|
||||
throw new \InvalidArgumentException( "$_value or window.$_value is in use by a custom handler." );
|
||||
}
|
||||
},
|
||||
'<span class="ipsType_monospace">window.</span>'
|
||||
));
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
if ( isset( $values['core_datalayer_replace_with_sso'] ) )
|
||||
{
|
||||
$values['core_datalayer_replace_with_sso'] = $values['core_datalayer_replace_with_sso'] ? $values['core_datalayer_replace_with_sso']->_id : 0;
|
||||
}
|
||||
|
||||
/* Prefix the gtmkey with window. */
|
||||
if ( isset( $values['core_datalayer_gtmkey'] ) )
|
||||
{
|
||||
$values['core_datalayer_gtmkey'] = "window.{$values['core_datalayer_gtmkey']}";
|
||||
}
|
||||
|
||||
/* Since GTM is a handler, cachebust the handler for template if it was updated */
|
||||
foreach( ['core_datalayer_use_gtm', 'core_datalayer_gtmkey', 'googletag_head_code', 'googletag_noscript_code'] as $input )
|
||||
{
|
||||
if ( isset( $values[$input] ) )
|
||||
{
|
||||
$key = \IPS\core\DataLayer\Handler::$handlerCacheKey;
|
||||
unset( \IPS\Data\Store::i()->$key );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear the cached configuration since we're changing it */
|
||||
\IPS\core\DataLayer::i()->clearCachedConfiguration([ '_jsConfig', '_eventProperties', '_propertyEvents' ]);
|
||||
|
||||
\IPS\Settings::i()->changeValues( $values );
|
||||
|
||||
/* Redirect to avoid csrfKey errors */
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=settings&controller=dataLayer&tab=main' ) );
|
||||
}
|
||||
|
||||
return "<br>$form";
|
||||
}
|
||||
|
||||
/**
|
||||
* Property settings and configuration
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function pageContext()
|
||||
{
|
||||
/* Get the page level properties */
|
||||
$_properties = \IPS\core\DataLayer::i()->propertiesConfiguration;
|
||||
foreach ( $_properties as $k => $property )
|
||||
{
|
||||
if ( $property['page_level'] AND $property['enabled'] )
|
||||
{
|
||||
$properties[$k] = array(
|
||||
'name' => $property['formatted_name'],
|
||||
'type' => $property['type'],
|
||||
'pii' => $property['pii'],
|
||||
'custom' => $property['custom'] ?? 0,
|
||||
'short' => $property['short'],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$propertyBlock = new \IPS\Helpers\Table\Custom(
|
||||
$properties,
|
||||
\IPS\Http\Url::internal( 'app=core&module=settings&controller=dataLayer&tab=pageContext' )
|
||||
);
|
||||
$propertyBlock->classes[] = 'ipsPadding:none ipsMargin:none';
|
||||
$propertyBlock->exclude = array('custom', 'description');
|
||||
$propertyBlock->langPrefix = 'datalayer_';
|
||||
|
||||
if ( !\IPS\Request::i()->sortby )
|
||||
{
|
||||
$propertyBlock->sortBy = 'name';
|
||||
}
|
||||
|
||||
if ( !\IPS\Request::i()->sortdirection )
|
||||
{
|
||||
$propertyBlock->sortDirection = 'asc';
|
||||
}
|
||||
|
||||
$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);
|
||||
$title = $row['short'];
|
||||
return "<span class='ipsType_monospace ipsMargin:none'><a href='$url' data-ipstooltip title='$title'>$val</a></span>";
|
||||
},
|
||||
);
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'settings', 'core', 'admin' )->dataLayerContext( $propertyBlock );
|
||||
}
|
||||
|
||||
/**
|
||||
* Property settings and configuration
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function properties()
|
||||
{
|
||||
/* Load our properties */
|
||||
$properties = \IPS\core\DataLayer::i()->propertiesConfiguration;
|
||||
$property_key = \IPS\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' ]) );
|
||||
}
|
||||
$property = $properties[$property_key];
|
||||
|
||||
/* Sidebar */
|
||||
$propertySelector = \IPS\Theme::i()->getTemplate( 'settings', 'core', 'admin' )->dataLayerSelector(
|
||||
$properties,
|
||||
'properties',
|
||||
'property_key',
|
||||
'Data Layer Properties',
|
||||
$property_key,
|
||||
true,
|
||||
array( $this, '_truncate' )
|
||||
);
|
||||
|
||||
/* 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->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) ) );
|
||||
|
||||
if ( $property['custom'] ?? 0 )
|
||||
{
|
||||
$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;
|
||||
$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) ) );
|
||||
}
|
||||
|
||||
/* 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 )
|
||||
{
|
||||
/* Get our submitted values */
|
||||
$_values = array();
|
||||
if ( isset( $values['datalayer_property_enabled'] ) )
|
||||
{
|
||||
$_values['enabled'] = (bool) $values['datalayer_property_enabled'];
|
||||
}
|
||||
|
||||
if ( isset( $values['datalayer_property_formatted_name'] ) )
|
||||
{
|
||||
$_values['formatted_name'] = $values['datalayer_property_formatted_name'];
|
||||
}
|
||||
|
||||
if ( $property['custom'] ?? 0 )
|
||||
{
|
||||
foreach ( $values as $field => $value )
|
||||
{
|
||||
if ( isset( $_values[$field] ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$field = str_replace( 'datalayer_property_', '', $field );
|
||||
$_values[$field] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/* Save the property */
|
||||
if ( !empty( $_values ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\core\DataLayer::i()->savePropertyConfiguration( $property_key, $_values );
|
||||
}
|
||||
catch ( \InvalidArgumentException $e ) {}
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\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 = array();
|
||||
foreach( $_events as $key => $event )
|
||||
{
|
||||
$events[$key] = array(
|
||||
'name' => $event['formatted_name'],
|
||||
'key' => $key,
|
||||
'enabled' => $event['enabled'],
|
||||
'short' => $event['short'],
|
||||
);
|
||||
}
|
||||
|
||||
/* Property's events table */
|
||||
if ( empty( $events ) )
|
||||
{
|
||||
$eventTable = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
$eventTable = new \IPS\Helpers\Table\Custom(
|
||||
$events,
|
||||
\IPS\Http\Url::internal( 'app=core&module=settings&controller=dataLayer&tab=properties&property_key=' . $property_key )
|
||||
);
|
||||
|
||||
|
||||
|
||||
if ( !\IPS\Request::i()->sortby )
|
||||
{
|
||||
$eventTable->sortBy = 'name';
|
||||
}
|
||||
if ( !\IPS\Request::i()->sortdirection )
|
||||
{
|
||||
$eventTable->sortDirection = 'asc';
|
||||
}
|
||||
|
||||
$eventTable->langPrefix = 'datalayer_';
|
||||
$eventTable->exclude = array( 'description', 'key' );
|
||||
$eventTable->parsers = array(
|
||||
'name' => function ( $val, $row )
|
||||
{
|
||||
$url = \IPS\Http\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>";
|
||||
},
|
||||
'enabled' => array( $this, '_enabledDisabled' ),
|
||||
);
|
||||
}
|
||||
|
||||
/* Render Content */
|
||||
$content = \IPS\Theme::i()->getTemplate( 'settings', 'core', 'admin' )->dataLayerTitleContent(
|
||||
$property,
|
||||
$property_key,
|
||||
'property',
|
||||
$form,
|
||||
(string) $eventTable
|
||||
);
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'settings', 'core', 'admin' )->dataLayerTab( $propertySelector, $content );
|
||||
}
|
||||
|
||||
/**
|
||||
* Property settings and configuration
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function addProperty()
|
||||
{
|
||||
\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 ) );
|
||||
|
||||
$events = \IPS\core\DataLayer::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) ) );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
$_values = array();
|
||||
foreach ( $values as $field => $value )
|
||||
{
|
||||
$field = str_replace( 'datalayer_property_', '', $field );
|
||||
$_values[$field] = $value;
|
||||
}
|
||||
$values = $_values;
|
||||
|
||||
$values['enabled'] = true;
|
||||
$key = $values['formatted_name'];
|
||||
|
||||
\IPS\core\DataLayer::i()->savePropertyConfiguration( $key, $values, true );
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=settings&controller=dataLayer&tab=properties&property_key=' . $key ) );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = (string) $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a property
|
||||
*/
|
||||
protected function deleteProperty()
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
$key = \IPS\Request::i()->property_key;
|
||||
$propertiesUrl = \IPS\Http\Url::internal( 'app=core&module=settings&controller=dataLayer&tab=properties' );
|
||||
if ( empty( $key ) )
|
||||
{
|
||||
\IPS\Output::i()->redirect( $propertiesUrl );
|
||||
}
|
||||
|
||||
$properties = \IPS\core\DataLayer::i()->propertiesConfiguration;
|
||||
if ( isset( $properties[$key] ) )
|
||||
{
|
||||
if ( $properties[$key]['custom'] ?? 0 )
|
||||
{
|
||||
$setting = json_decode( \IPS\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();
|
||||
$_SESSION['deleted_datalayer_property'] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$propertiesUrl = $propertiesUrl->setQueryString([ 'property_key' => $key ]);
|
||||
}
|
||||
}
|
||||
\IPS\Output::i()->redirect( $propertiesUrl );
|
||||
}
|
||||
|
||||
/**
|
||||
* Event settings and configuration
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function events()
|
||||
{
|
||||
/* Load our events */
|
||||
$events = \IPS\core\DataLayer::i()->eventConfiguration;
|
||||
$event_key = \IPS\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' ]) );
|
||||
}
|
||||
$event = $events[$event_key];
|
||||
|
||||
foreach ( array_keys( $events ) as $_eventKey )
|
||||
{
|
||||
$events[$_eventKey]['description'] = 'Fires when ' . $events[$_eventKey]['description'];
|
||||
}
|
||||
|
||||
/* Create our sidebar */
|
||||
$eventSelector = \IPS\Theme::i()->getTemplate( 'settings', 'core', 'admin' )->dataLayerSelector(
|
||||
$events,
|
||||
'events',
|
||||
'event_key',
|
||||
'Data Layer Events',
|
||||
$event_key,
|
||||
true,
|
||||
array( $this, '_truncate' )
|
||||
);
|
||||
|
||||
/* 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->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 ) ) );
|
||||
|
||||
/* 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 )
|
||||
{
|
||||
/* Pull out the values to use */
|
||||
$_values = array();
|
||||
if ( isset( $values['datalayer_event_enabled'] ) )
|
||||
{
|
||||
$_values['enabled'] = (bool) $values['datalayer_event_enabled'];
|
||||
}
|
||||
|
||||
if ( isset( $values['datalayer_event_formatted_name'] ) )
|
||||
{
|
||||
$_values['formatted_name'] = $values['datalayer_event_formatted_name'];
|
||||
}
|
||||
|
||||
/* Save the event */
|
||||
if ( !empty( $_values ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\core\DataLayer::i()->saveEventConfiguration( $event_key, $_values );
|
||||
}
|
||||
catch ( \InvalidArgumentException $e ) {}
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\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 = array();
|
||||
foreach( $_properties as $key => $property )
|
||||
{
|
||||
$properties[$key] = array(
|
||||
'name' => $property['formatted_name'],
|
||||
'key' => $key,
|
||||
'type' => $property['type'],
|
||||
'enabled' => $property['enabled'],
|
||||
'pii' => $property['pii'],
|
||||
'custom' => $property['custom'] ?? 0,
|
||||
'short' => $property['short'],
|
||||
);
|
||||
}
|
||||
|
||||
/* Create our neat properties table */
|
||||
if ( empty( $properties ) )
|
||||
{
|
||||
$propertyTable = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
$propertyTable = new \IPS\Helpers\Table\Custom(
|
||||
$properties,
|
||||
\IPS\Http\Url::internal( 'app=core&module=settings&controller=dataLayer&tab=events&event_key=' . $event_key )
|
||||
);
|
||||
|
||||
if ( !\IPS\Request::i()->sortby )
|
||||
{
|
||||
$propertyTable->sortBy = 'name';
|
||||
}
|
||||
|
||||
if ( !\IPS\Request::i()->sortdirection )
|
||||
{
|
||||
$propertyTable->sortDirection = 'asc';
|
||||
}
|
||||
|
||||
$propertyTable->langPrefix = 'datalayer_';
|
||||
$propertyTable->exclude = array( 'custom', 'short', 'key' );
|
||||
$propertyTable->parsers = array(
|
||||
'enabled' => array( $this, '_enabledDisabled' ),
|
||||
'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'] );
|
||||
$title = $row['short'];
|
||||
return "<pre class='ipsMargin:none'><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(
|
||||
$event,
|
||||
$event_key,
|
||||
'event',
|
||||
(string) $form,
|
||||
(string) $propertyTable
|
||||
);
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'settings', 'core', 'admin' )->dataLayerTab( $eventSelector, $content );
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the value a valid property or event formatted name?
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
public function formattedNameValid( string $group='properties', ?string $current=null )
|
||||
{
|
||||
return function( $value ) use ( $group, $current )
|
||||
{
|
||||
if ( $group === 'properties' AND \strtolower( $value ) === 'event' )
|
||||
{
|
||||
throw new \InvalidArgumentException( "You cannot name a property '$value' because that key is reserved" );
|
||||
}
|
||||
|
||||
if ( preg_match( '/[^a-z,A-Z,\_]/', $value ) )
|
||||
{
|
||||
throw new \InvalidArgumentException( 'The name can only contain letters and underscores.' );
|
||||
}
|
||||
|
||||
$collection = ( $group === 'events' ) ? \IPS\core\DataLayer::i()->eventConfiguration : \IPS\core\DataLayer::i()->propertiesConfiguration;
|
||||
foreach ( $collection as $key => $data )
|
||||
{
|
||||
if ( $key === $current )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( isset( $data['formatted_name'] ) AND $data['formatted_name'] === $value )
|
||||
{
|
||||
throw new \InvalidArgumentException( 'This Data Layer name is already in use' );
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Formatter method to make code cleaner
|
||||
*
|
||||
* @param mixed $val
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function _enabledDisabled( $val, $row=null )
|
||||
{
|
||||
return $val ? 'Enabled' : 'Disabled';
|
||||
}
|
||||
|
||||
/**
|
||||
* Formatter method to make code cleaner
|
||||
*
|
||||
* @param mixed $val
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function _yesNo( $val, $row=null )
|
||||
{
|
||||
return $val ? 'Yes' : 'No';
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncates the string and removes tags. Ends in ... if the string is longer than the limit
|
||||
*
|
||||
* @param string $_string The string to truncate
|
||||
* @param int $length The desired length
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function _truncate( $_string, $length=100 )
|
||||
{
|
||||
$_string = strip_tags( $_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" ) . '...';
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -71,7 +71,7 @@ class _email extends \IPS\Dispatcher\Controller
|
||||
$method = \IPS\Settings::i()->mail_method;
|
||||
$disabled = array();
|
||||
|
||||
if ( \IPS\Settings::i()->sendgrid_api_key )
|
||||
if ( \IPS\Settings::i()->sendgrid_api_key AND \IPS\Settings::i()->sendgrid_use_for > 0 )
|
||||
{
|
||||
if ( \IPS\Settings::i()->sendgrid_use_for == 2 )
|
||||
{
|
||||
@@ -88,7 +88,7 @@ class _email extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
$method = 'php';
|
||||
}
|
||||
|
||||
|
||||
$settingsForm->add( new \IPS\Helpers\Form\Radio( 'mail_method', $method, TRUE, array(
|
||||
'options' => array( 'php' => ( \IPS\CIC ? 'mail_method_cic' : 'mail_method_php' ), 'smtp' => 'mail_method_smtp', 'sendgrid' => 'mail_method_sendgrid' ),
|
||||
'disabled' => $disabled,
|
||||
|
||||
@@ -57,10 +57,14 @@ class _general extends \IPS\Dispatcher\Controller
|
||||
$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 \IPS\Helpers\Form\CheckboxSet( 'diagnostics_reporting', array( 'usage' => ( (bool) \IPS\Settings::i()->usage_reporting ), 'diagnostics' => ( (bool) \IPS\Settings::i()->diagnostics_reporting ) ), FALSE, array( 'options' => array(
|
||||
'usage' => 'diagnostics_reporting_usage',
|
||||
'diagnostics' => 'diagnostics_reporting_diagnostics',
|
||||
) ) ) ); */
|
||||
) ) ) );
|
||||
*/
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
@@ -76,9 +80,9 @@ 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'] );
|
||||
// \IPS\Db::i()->update( 'core_tasks', array( 'enabled' => \intval( $values['usage_reporting'] ) ), array( '`key`=?', 'usagereporting' ) );
|
||||
//$values['usage_reporting'] = \in_array( 'usage', $values['diagnostics_reporting'] );
|
||||
//$values['diagnostics_reporting'] = \in_array( 'diagnostics', $values['diagnostics_reporting'] );
|
||||
//\IPS\Db::i()->update( 'core_tasks', array( 'enabled' => \intval( $values['usage_reporting'] ) ), array( '`key`=?', 'usagereporting' ) );
|
||||
|
||||
$form->saveAsSettings( $values );
|
||||
|
||||
|
||||
@@ -100,7 +100,14 @@ class _licensekey extends \IPS\Dispatcher\Controller
|
||||
unset( \IPS\Data\Store::i()->license_data );
|
||||
|
||||
/* Return the overview screen afterwards */
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=settings&controller=licensekey' ), 'license_key_refreshed' );
|
||||
if ( isset( \IPS\Request::i()->return ) and \IPS\Request::i()->return === 'cloud' and \IPS\Application::appIsEnabled('cloud') )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\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' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -308,7 +308,24 @@ class _posting extends \IPS\Dispatcher\Controller
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'links_external', \IPS\Settings::i()->links_external ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'posts_add_nofollow', \IPS\Settings::i()->posts_add_nofollow, FALSE, array( 'togglesOn' => array( 'posts_add_nofollow_exclude' ) ), NULL, NULL, NULL, 'posts_add_nofollow' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Stack( 'posts_add_nofollow_exclude', \IPS\Settings::i()->posts_add_nofollow_exclude ? json_decode( \IPS\Settings::i()->posts_add_nofollow_exclude ) : array(), FALSE, array( 'placeholder' => 'example.com' ), NULL, NULL, NULL, 'posts_add_nofollow_exclude' ) );
|
||||
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'email_filter_action', \IPS\Settings::i()->email_filter_action, FALSE, array(
|
||||
'options' => array(
|
||||
'allow' => 'email_filter_action_allow',
|
||||
'moderate' => 'email_filter_action_moderate',
|
||||
'replace' => 'email_filter_action_replace'
|
||||
),
|
||||
'description' => array(
|
||||
'allow' => 'email_filter_action_allow_desc',
|
||||
'moderate' => 'email_filter_action_moderate_desc',
|
||||
'replace' => 'email_filter_action_replace_desc'
|
||||
),
|
||||
'toggles' => array( 'replace' => array( 'email_filter_replace_text' ) )
|
||||
), NULL, NULL, NULL, 'email_filter_action' ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'email_filter_replace_text', \IPS\Settings::i()->email_filter_replace_text, FALSE, array(), NULL, NULL, NULL, 'email_filter_replace_text' ) );
|
||||
|
||||
|
||||
/* Save values */
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
@@ -770,21 +787,6 @@ class _posting extends \IPS\Dispatcher\Controller
|
||||
/* And redirect */
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=core&module=settings&controller=posting&tab=acronymExpansion" ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebuild attachment thumbnails
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function rebuildThumbnails()
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
\IPS\Task::queue( 'core', 'RebuildAttachmentThumbnails', array(), 4 );
|
||||
|
||||
/* And redirect */
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=core&module=settings&controller=posting" ), 'thumbnails_rebuilt' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebuild URL refs
|
||||
|
||||
Reference in new issue
Block a user