Version 4.7.0

This commit is contained in:
Neo committed 2025-12-19 16:00:35 -08:00
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