$settings The settings (Settings::all()). * @return list */ public static function active_platforms( array $settings ): array { $active = array(); foreach ( Platforms::keys() as $key ) { if ( self::is_active( $key, $settings ) ) { $active[] = $key; } } return $active; } /** * The events of every platform that is on, keyed by platform. * * @param array $settings The settings (Settings::all()). * @return array> */ public static function active( array $settings ): array { $events = array(); foreach ( self::active_platforms( $settings ) as $key ) { $events[ $key ] = self::for_platform( $key, $settings ); } return $events; } /** * The events one platform sends, in the registry's order, starting with * page_view. Empty when the platform is not on. * * @param string $key Platform key. * @param array $settings The settings (Settings::all()). * @return list */ public static function for_platform( string $key, array $settings ): array { if ( ! self::is_active( $key, $settings ) ) { return array(); } $chosen = self::chosen( self::row( $key, $settings ), $settings ); return self::limit( $key, array_keys( array_filter( $chosen ) ), $settings ); } /** * Narrows a list of wanted events to what the platform can send: page_view * first, then each of view_content, search, lead and contact that is * wanted, that the platform supports (Snap has no contact event; LinkedIn, * X and Google Ads take no view_content or search) and, for the platforms * that count conversions through an ID or label the owner creates, that * has that value filled in. * * @param string $key Platform key. * @param array $wanted The events wanted. * @param array $settings The settings (Settings::all()). * @return list */ private static function limit( string $key, array $wanted, array $settings ): array { $platform = Platforms::get( $key ); $events = array( 'page_view' ); if ( null === $platform ) { return $events; } $row = self::row( $key, $settings ); $needing = $platform['conversion']['events'] ?? array(); foreach ( Platforms::CHOICES as $event ) { if ( ! in_array( $event, $wanted, true ) || ! in_array( $event, $platform['events'], true ) ) { continue; } if ( in_array( $event, $needing, true ) && ! self::has_conversion( $key, $row, $event ) ) { continue; } $events[] = $event; } return $events; } /** * Whether any platform that is on sends the event. * * @param string $event A normalized event. * @param array $settings The settings (Settings::all()). */ public static function any_has( string $event, array $settings ): bool { foreach ( self::active( $settings ) as $events ) { if ( in_array( $event, $events, true ) ) { return true; } } return false; } /** * GA4's share of the events: lead (generate_lead) and contact, when the * shared choices include them (research section 8). Null when the Google * tag is not set up (tracking off, or no Measurement ID). The events list * can be empty: the tag is there but sends neither. * * @param array $settings The settings (Settings::all()). * @return array{id: string, events: list}|null */ public static function for_ga4( array $settings ): ?array { $id = $settings['measurement_id'] ?? ''; if ( empty( $settings['tracking_enabled'] ) || ! is_string( $id ) || '' === $id ) { return null; } $shared = self::shared( $settings ); return array( 'id' => $id, 'events' => array_values( array_filter( array( 'lead', 'contact' ), static fn( string $event ): bool => ! empty( $shared[ $event ] ) ) ), ); } /** * Whether the platform is switched on with an ID that is valid for it. * The ID is checked again here, so a row edited by hand never prints. * * @param string $key Platform key. * @param array $settings The settings. */ private static function is_active( string $key, array $settings ): bool { $row = self::row( $key, $settings ); if ( empty( $row['enabled'] ) ) { return false; } $id = Platforms::normalize_id( $key, $row['id'] ?? '' ); return null !== $id && '' !== $id; } /** * One platform's stored settings. * * @param string $key Platform key. * @param array $settings The settings. * @return array */ private static function row( string $key, array $settings ): array { $row = $settings['pixels'][ $key ] ?? null; return is_array( $row ) ? $row : array(); } /** * The shared event choices; a missing or mistyped group reads as all on. * * @param array $settings The settings. * @return array */ private static function shared( array $settings ): array { $shared = $settings['pixel_events'] ?? null; return is_array( $shared ) ? array_merge( Platforms::default_events(), $shared ) : Platforms::default_events(); } /** * The event choices that apply to a platform: its own when it has all * four, otherwise the shared ones. * * @param array $row The platform's stored settings. * @param array $settings The settings. * @return array */ private static function chosen( array $row, array $settings ): array { $custom = $row['custom_events'] ?? null; if ( is_array( $custom ) && array() === array_diff( Platforms::CHOICES, array_keys( $custom ) ) ) { return $custom; } return self::shared( $settings ); } /** * Whether the platform's conversion ID or label for an event is filled in * and valid. * * @param string $key Platform key. * @param array $row The platform's stored settings. * @param string $event The event. */ private static function has_conversion( string $key, array $row, string $event ): bool { $conversions = $row['conversions'] ?? null; $value = is_array( $conversions ) ? Platforms::normalize_conversion( $key, $conversions[ $event ] ?? '' ) : null; return null !== $value && '' !== $value; } }