Version 5.0.13
This commit is contained in:
1 parent
b89858b2ff
commit
5efe744c5f
1407 files changed
+69690
-30177
No files matched your search
@@ -12,6 +12,7 @@ namespace IPS\core;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
|
||||
use Exception;
|
||||
use InvalidArgumentException;
|
||||
use IPS\core\modules\admin\settings\dataLayer as DataLayerController;
|
||||
use IPS\Data\Store;
|
||||
@@ -23,6 +24,7 @@ use IPS\Member;
|
||||
use IPS\Member\Group;
|
||||
use IPS\Output;
|
||||
use IPS\Patterns\Singleton;
|
||||
use IPS\Platform\Bridge;
|
||||
use IPS\Request;
|
||||
use IPS\Session;
|
||||
use IPS\Settings;
|
||||
@@ -284,6 +286,16 @@ HTML,
|
||||
'type' => 'string',
|
||||
'page_level' => true,
|
||||
],
|
||||
'content_is_followed' => [
|
||||
'event_keys' => ['content_*', 'filter_*', 'sort', 'file_download'],
|
||||
'pii' => false,
|
||||
'formatted_name' => 'content_is_followed',
|
||||
'description' => 'Whether the user if following the content item.',
|
||||
'short' => 'Content item followed',
|
||||
'enabled' => true,
|
||||
'type' => 'boolean',
|
||||
'page_level' => true,
|
||||
],
|
||||
'comment_type' => [
|
||||
'event_keys' => ['content_comment', 'content_react', 'content_quote'],
|
||||
'pii' => false,
|
||||
@@ -294,6 +306,17 @@ HTML,
|
||||
'type' => 'string',
|
||||
'page_level' => false,
|
||||
],
|
||||
'content_anonymous' => [
|
||||
'event_keys' => ['content_*', 'filter_*', 'sort', 'file_download'],
|
||||
'pii' => false,
|
||||
'formatted_name' => 'content_anonymous',
|
||||
'description' => 'Whether the relevant content (item/comment/review) was created anonymously. This attribute is only possible for certain content types, and when true the author ID and Name will be obfuscated',
|
||||
'short' => 'Content is anonymous',
|
||||
'enabled' => true,
|
||||
'type' => 'boolean',
|
||||
'page_level' => true,
|
||||
'default' => false,
|
||||
],
|
||||
'content_container_id' => [
|
||||
'event_keys' => ['content_*', 'filter_*', 'sort', 'file_download'],
|
||||
'pii' => false,
|
||||
@@ -334,6 +357,17 @@ HTML,
|
||||
'type' => 'string',
|
||||
'page_level' => true,
|
||||
],
|
||||
'message_recipient_count' => [
|
||||
'event_keys' => ['content_*', 'filter_*', 'sort', 'file_download'],
|
||||
'pii' => false,
|
||||
'formatted_name' => 'message_recipient_count',
|
||||
'description' => 'The number of recipients a message was sent to. If the content event or page context is not relevant to a message, this will be <code>null</code>',
|
||||
'short' => 'PM Recipient Count',
|
||||
'enabled' => true,
|
||||
'type' => 'number | null',
|
||||
'default' => null,
|
||||
'page_level' => true,
|
||||
],
|
||||
'ips_key' => [
|
||||
'event_keys' => ['*'],
|
||||
'pii' => false,
|
||||
@@ -700,7 +734,7 @@ HTML,
|
||||
$piiProperties = array_merge( $piiProperties, $this->relatedPiiProperties( $propertyKey ) );
|
||||
continue;
|
||||
}
|
||||
$value = $this->getSsoId( $value );
|
||||
$value = $value ? $this->getSsoId( $value ) : $value;
|
||||
}
|
||||
|
||||
$_values[$propertyKey] = $value;
|
||||
@@ -728,31 +762,28 @@ HTML,
|
||||
{
|
||||
$output = array();
|
||||
$piiExcludes = array();
|
||||
$pii = Settings::i()->core_datalayer_include_pii;
|
||||
foreach ( $this->propertiesConfiguration as $key => $property )
|
||||
{
|
||||
if ( $key === 'content_anonymous' and @$properties[$key] )
|
||||
{
|
||||
$piiExcludes = array_merge( $piiExcludes, $this->relatedPiiProperties( 'author_id' ) );
|
||||
}
|
||||
|
||||
if ( !$property['enabled'] OR !isset( $properties[$key] ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !$pii AND ( $property['pii'] ?? 0 ) )
|
||||
if ( !Settings::i()->core_datalayer_include_pii AND ( $property['pii'] ?? 0 ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check the member's pii preference. If we can verify the member's PII should NOT be exposed, don't allow it to be added */
|
||||
if ( Settings::i()->core_datalayer_member_pii_choice AND
|
||||
@$property['replace_with_sso'] AND
|
||||
( $originalID = array_search( $properties[$key], $this->ssoIds ) )
|
||||
)
|
||||
if ( @$property['replace_with_sso'] and ( $originalID = array_search( $properties[$key], $this->ssoIds ) ) and !$this->includeSSOForMember( $originalID ) )
|
||||
{
|
||||
$member = Member::load( $originalID );
|
||||
if ( $member->member_id AND $member->members_bitoptions['datalayer_pii_optout'] )
|
||||
{
|
||||
$piiExcludes = array_merge( $piiExcludes, $this->relatedPiiProperties( $key ) );
|
||||
continue;
|
||||
}
|
||||
$piiExcludes = array_merge( $piiExcludes, $this->relatedPiiProperties( $key ) );
|
||||
continue;
|
||||
}
|
||||
|
||||
$output[$key] = $properties[$key];
|
||||
@@ -832,13 +863,13 @@ HTML,
|
||||
}
|
||||
|
||||
/* If this has PII, is PII allowed? */
|
||||
if ( ( $properties[$key]['pii'] ?? 0 ) AND ! Settings::i()->core_datalayer_include_pii )
|
||||
if ( @$properties[$key]['pii'] AND !Settings::i()->core_datalayer_include_pii )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Replace with sso id if needed */
|
||||
if ( $properties[$key]['replace_with_sso'] ?? 0 )
|
||||
if ( @$properties[$key]['replace_with_sso'] )
|
||||
{
|
||||
$value = $this->getSsoId( $value );
|
||||
}
|
||||
@@ -942,7 +973,7 @@ HTML,
|
||||
}
|
||||
|
||||
/* Logged In Member PII */
|
||||
if ( Settings::i()->core_datalayer_include_pii AND ( !Settings::i()->core_datalayer_member_pii_choice OR !Member::loggedIn()->members_bitoptions['datalayer_pii_optout'] ) )
|
||||
if ( $this->includeSSOForMember() )
|
||||
{
|
||||
if ( $properties['member_id']['enabled'] )
|
||||
{
|
||||
@@ -1002,6 +1033,11 @@ HTML,
|
||||
$piiExcludes = array();
|
||||
foreach ( $properties as $key => $property )
|
||||
{
|
||||
if ( $key === 'content_anonymous' and @$_context[$key] )
|
||||
{
|
||||
$piiExcludes = array_merge( $piiExcludes, $this->relatedPiiProperties( 'author_id' ) );
|
||||
}
|
||||
|
||||
/* Make sure all are page level, enabled, and valid */
|
||||
if ( !$property['enabled'] or !$property['page_level'] )
|
||||
{
|
||||
@@ -1010,20 +1046,11 @@ HTML,
|
||||
$fkey = $property['formatted_name'];
|
||||
|
||||
/* If we can determine a member based on this property's PII, only include the related PII if we know that member hasn't opted out? */
|
||||
if (
|
||||
( $property['replace_with_sso'] ?? 0 ) AND
|
||||
Settings::i()->core_datalayer_include_pii AND
|
||||
Settings::i()->core_datalayer_member_pii_choice AND
|
||||
isset( $_context[ $key ] ) AND
|
||||
( $originalId = array_search( $_context[ $key ], $this->ssoIds ) )
|
||||
if ( @$property['replace_with_sso'] AND isset( $_context[ $key ] ) AND ( $originalId = array_search( $_context[ $key ], $this->ssoIds ) AND !( $this->includeSSOForMember( $originalId ) ) )
|
||||
)
|
||||
{
|
||||
$member = Member::load( $originalId );
|
||||
if ( !( $member->member_id AND !$member->members_bitoptions['datalayer_pii_optout'] ) )
|
||||
{
|
||||
$piiExcludes = array_merge( $piiExcludes, $this->relatedPiiProperties( $key ) );
|
||||
continue;
|
||||
}
|
||||
$piiExcludes = array_merge( $piiExcludes, $this->relatedPiiProperties( $key ) );
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Add context properties set by the system */
|
||||
@@ -1063,6 +1090,52 @@ HTML,
|
||||
return str_replace( ["\u{2028}", "\u{2029}"], ['', ''], $out );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Member|int|null $member
|
||||
* @return bool
|
||||
*/
|
||||
public function includeSSOForMember( Member|int|null $member=null ) :bool
|
||||
{
|
||||
/* Can we determine using settings? */
|
||||
if ( !Settings::i()->core_datalayer_include_pii )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( Settings::i()->core_datalayer_include_pii and !Settings::i()->core_datalayer_member_pii_choice )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( is_null( $member ) )
|
||||
{
|
||||
$member = Member::loggedIn();
|
||||
}
|
||||
|
||||
static $res = [];
|
||||
$memberId = ( is_int( $member ) ? $member : $member->member_id ) ?: 0;
|
||||
if ( array_key_exists( 'member_' . $memberId, $res ) )
|
||||
{
|
||||
return $res['member_'.$memberId];
|
||||
}
|
||||
|
||||
if ( is_int( $member ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$member = Member::load( $memberId );
|
||||
}
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
$res['member_'.$memberId] = false;
|
||||
return false; // edge case, but if the member doesn't exist, let's not expose PII on the grounds that there technically shouldn't really be PII to expose
|
||||
}
|
||||
}
|
||||
|
||||
$res['member_' . $memberId] = !$member->members_bitoptions['datalayer_pii_optout'];
|
||||
return $res['member_' . $memberId];
|
||||
}
|
||||
|
||||
|
||||
public static string $configCacheKey = 'dataLayerConfig';
|
||||
|
||||
@@ -1731,4 +1804,59 @@ HTML,
|
||||
|
||||
return array_merge( $properties, $additionalProperties );
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to determine whether
|
||||
*
|
||||
* @param string[]|string $features Features that must be available for this site's package for the data layer to be enabled.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function enabled( array|string $features=[] ) : bool
|
||||
{
|
||||
if ( !Settings::i()->core_datalayer_enabled or Output::i()->bypassDataLayer )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if ( empty( $features ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Now let's determine if the data layer is enabled for the provided features. We'll cache the result */
|
||||
static $results = [];
|
||||
if ( is_string( $features ) )
|
||||
{
|
||||
$cacheKey = $features;
|
||||
$features = [ $features];
|
||||
}
|
||||
else
|
||||
{
|
||||
$cacheKey = implode( ',', sort( $features ) );
|
||||
}
|
||||
|
||||
if ( !array_key_exists( $cacheKey, $results ) )
|
||||
{
|
||||
/* assume it's enabled till we find one that's not */
|
||||
$results[$cacheKey] = true;
|
||||
foreach ( $features as $feature )
|
||||
{
|
||||
try
|
||||
{
|
||||
if ( !Bridge::i()->featureIsEnabled( $feature ) )
|
||||
{
|
||||
$results[$cacheKey] = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch ( Exception )
|
||||
{
|
||||
$results[$cacheKey] = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $results[$cacheKey];
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user