roles, $excluded_roles ) ) { return true; } // Network admins often have no role on a sub-site. Treat them as administrators. return is_multisite() && is_super_admin( $user->ID ) && in_array( 'administrator', $excluded_roles, true ); } /** * Whether the current request path matches an excluded URL pattern. * * @param string $excluded_urls Patterns, one per line. * @return bool */ private static function is_excluded_url( $excluded_urls ) { $patterns = FullSession_Settings::parse_url_patterns( $excluded_urls ); if ( empty( $patterns ) || ! isset( $_SERVER['REQUEST_URI'] ) ) { return false; } $uri = sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ); $path = wp_parse_url( $uri, PHP_URL_PATH ); $path = $path ? rawurldecode( $path ) : '/'; if ( FullSession_Settings::path_matches( $path, $patterns ) ) { return true; } // Also match paths relative to the site, so `/about` works for a site in a // subfolder (e.g. example.com/shop/about, or a multisite sub-site). $home_path = untrailingslashit( (string) wp_parse_url( home_url(), PHP_URL_PATH ) ); if ( '' !== $home_path && 0 === stripos( $path . '/', $home_path . '/' ) ) { return FullSession_Settings::path_matches( substr( $path, strlen( $home_path ) ), $patterns ); } return false; } /** * Enqueue the loader and pass it the config. */ public static function enqueue() { if ( ! self::should_track() ) { return; } wp_enqueue_script( self::HANDLE, FULLSESSION_URL . 'assets/js/fullsession-loader.js', array(), FULLSESSION_VERSION, false ); wp_add_inline_script( self::HANDLE, 'window.fullsessionConfig = ' . self::encode( self::config() ) . ';', 'before' ); } /** * Config passed to fullsession-loader.js. * * @return array */ private static function config() { $settings = FullSession_Settings::get(); $config = array( 'customerId' => $settings['customer_id'], 'scriptUrl' => FULLSESSION_SCRIPT_URL, 'consentMode' => $settings['consent_mode'], 'consentCategory' => $settings['consent_category'], 'calls' => array(), ); if ( $settings['identify_users'] && is_user_logged_in() ) { $user = wp_get_current_user(); $traits = array(); if ( $settings['identify_send_name_email'] ) { $traits['name'] = $user->display_name; $traits['email'] = $user->user_email; } $config['calls'][] = array( 'identify', array( (string) $user->ID, (object) $traits ) ); $roles = (array) $user->roles; if ( $roles ) { $config['calls'][] = array( 'setSessionAttributes', array( array( 'wp_role' => implode( ',', $roles ) ) ) ); } } /** * Filters the custom events sent on this page load. * * @param array $events List of array( 'name' => string, 'data' => array ) items. */ $events = apply_filters( 'fullsession_page_events', array() ); foreach ( (array) $events as $event ) { if ( ! empty( $event['name'] ) && ! empty( $event['data'] ) ) { $config['calls'][] = array( 'event', array( (string) $event['name'], (object) $event['data'] ) ); } } // This page now carries data for this visitor only (identity or their shop events). // Ask page cache plugins not to store it, so it's never served to someone else. if ( $config['calls'] && ! defined( 'DONOTCACHEPAGE' ) ) { define( 'DONOTCACHEPAGE', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedConstantFound -- Standard constant read by page cache plugins. } return $config; } /** * JSON for an inline script. Escapes `<`, `>` and `&` so values can't close the script tag. * * @param mixed $data Data. * @return string */ public static function encode( $data ) { return (string) wp_json_encode( $data, JSON_HEX_TAG | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE ); } }