array( 'post', 'page' ), 'tracking_mode' => 'all', 'selected_post_ids' => array(), 'exclude_administrators' => true, 'exclude_logged_in_users' => false, 'store_referrer_details' => true, 'debug_full_referrers' => true, 'store_utm_parameters' => true, 'delete_data_on_uninstall' => false, 'retention_days' => 0, 'exclude_bots' => true, 'exclude_cron' => true, 'exclude_cli' => true, 'ignore_prefetch' => true, 'key_events' => array( 'phone_click', 'email_click', 'form_submit' ), ); } /** * Get settings. * * @return array */ public static function get() { $settings = get_option( self::OPTION_NAME, array() ); if ( ! is_array( $settings ) ) { $settings = array(); } return wp_parse_args( $settings, self::defaults() ); } /** * Get one setting. * * @param string $key Setting key. * @param mixed $default Default value. * @return mixed */ public static function get_value( $key, $default = null ) { $settings = self::get(); return array_key_exists( $key, $settings ) ? $settings[ $key ] : $default; } /** * Get public post types. * * @return array */ public static function public_post_types() { $post_types = get_post_types( array( 'public' => true, ), 'objects' ); unset( $post_types['attachment'] ); return $post_types; } /** * Sanitize settings before saving. * * @param array $input Raw input. * @return array */ public static function sanitize( $input ) { $input = is_array( $input ) ? $input : array(); $defaults = self::defaults(); $available_post_types = array_keys( self::public_post_types() ); $post_types = isset( $input['post_types'] ) && is_array( $input['post_types'] ) ? array_map( 'sanitize_key', wp_unslash( $input['post_types'] ) ) : array(); $post_types = array_values( array_intersect( $post_types, $available_post_types ) ); if ( empty( $post_types ) ) { // Empty means: tracking disabled for all post types. $post_types = array_values( array_unique( $post_types ) ); } $tracking_mode = isset( $input['tracking_mode'] ) ? sanitize_key( wp_unslash( $input['tracking_mode'] ) ) : 'all'; if ( ! in_array( $tracking_mode, array( 'all', 'include', 'exclude' ), true ) ) { $tracking_mode = 'all'; } $selected_post_ids = self::sanitize_post_ids( $input['selected_post_ids'] ?? '' ); $retention_days = isset( $input['retention_days'] ) ? absint( $input['retention_days'] ) : 0; if ( ! in_array( $retention_days, array( 0, 30, 90, 180, 365 ), true ) ) { $retention_days = 0; } $key_events = isset( $input['key_events'] ) && is_array( $input['key_events'] ) ? array_map( 'sanitize_key', wp_unslash( $input['key_events'] ) ) : $defaults['key_events']; $key_events = array_values( array_intersect( $key_events, self::available_key_events() ) ); return array( 'post_types' => $post_types, 'tracking_mode' => $tracking_mode, 'selected_post_ids' => $selected_post_ids, 'exclude_administrators' => ! empty( $input['exclude_administrators'] ), 'exclude_logged_in_users' => ! empty( $input['exclude_logged_in_users'] ), 'store_referrer_details' => ! empty( $input['store_referrer_details'] ), 'debug_full_referrers' => ! empty( $input['debug_full_referrers'] ), 'store_utm_parameters' => ! empty( $input['store_utm_parameters'] ), 'delete_data_on_uninstall' => ! empty( $input['delete_data_on_uninstall'] ), 'retention_days' => $retention_days, 'exclude_bots' => ! empty( $input['exclude_bots'] ), 'exclude_cron' => ! empty( $input['exclude_cron'] ), 'exclude_cli' => ! empty( $input['exclude_cli'] ), 'ignore_prefetch' => ! empty( $input['ignore_prefetch'] ), 'key_events' => $key_events, ); } /** * Events that can be treated as key events. * * @return array */ public static function available_key_events() { return array( 'outbound_click', 'file_download', 'phone_click', 'email_click', 'form_start', 'form_submit', 'scroll_75', 'scroll_90', ); } /** * Sanitize comma, whitespace or newline separated post IDs. * * @param string|array $value Raw value. * @return array */ public static function sanitize_post_ids( $value ) { if ( is_array( $value ) ) { $value = implode( ',', $value ); } $value = (string) wp_unslash( $value ); $ids = preg_split( '/[\s,;]+/', $value ); if ( ! is_array( $ids ) ) { return array(); } $ids = array_filter( array_map( 'absint', $ids ) ); $ids = array_values( array_unique( $ids ) ); return $ids; } /** * Determine whether a post should be tracked. * * @param int $post_id Post ID. * @return bool */ public static function should_track_post( $post_id ) { $post_id = absint( $post_id ); $settings = self::get(); if ( ! $post_id ) { return false; } $post_type = get_post_type( $post_id ); if ( ! $post_type || ! in_array( $post_type, (array) $settings['post_types'], true ) ) { return false; } $selected = array_map( 'absint', (array) $settings['selected_post_ids'] ); if ( 'include' === $settings['tracking_mode'] ) { return in_array( $post_id, $selected, true ); } if ( 'exclude' === $settings['tracking_mode'] ) { return ! in_array( $post_id, $selected, true ); } return true; } }