ce, $plugins_path ); if ( '' !== $source ) { $handles_sources[] = $source; } } $handles_sources = array_unique( $handles_sources ); sort( $handles ); sort( $dependents ); sort( $dependents_sources ); sort( $handles_sources ); return array( 'context' => $context, 'page_type' => $this->get_current_page_type( $context ), 'handles' => implode( ',', $handles ), 'dependents' => implode( ',', $dependents ), 'dependents_sources' => implode( ',', $dependents_sources ), 'handles_sources' => implode( ',', $handles_sources ), ); } /** * Record a Tracks event. * * @param string $event_name Event name. * @param array $properties Event properties. * @return void * * @since 11.0.0 */ protected function record_event( string $event_name, array $properties ): void { if ( ! class_exists( 'WC_Tracks' ) ) { return; } \WC_Tracks::record_event( $event_name, $properties ); } /** * Add a storefront event to the WooCommerce Analytics client queue. * * @param string $event_name Event name. * @param array $properties Event properties. * @return void * * @since 11.0.0 */ protected function record_frontend_event( string $event_name, array $properties ): void { if ( ! $this->is_frontend_tracking_available() ) { return; } WC_Analytics_Tracking::add_event_to_queue( $event_name, $properties ); } /** * Whether the WooCommerce Analytics storefront tracker is initialized. * * @return bool * * @since 11.0.0 */ protected function is_frontend_tracking_available(): bool { return did_action( 'woocommerce_analytics_init' ) && class_exists( WC_Analytics_Tracking::class ) && is_callable( array( WC_Analytics_Tracking::class, 'add_event_to_queue' ) ); } /** * Whether this usage event was already checked recently. * * @param array $event Usage event. * @return bool */ private function was_recently_checked( array $event ): bool { return false !== get_transient( $this->get_transient_key( $event ) ); } /** * Mark this usage event as recently checked. * * @param array $event Usage event. * @return void */ private function mark_recently_checked( array $event ): void { set_transient( $this->get_transient_key( $event ), 'yes', WEEK_IN_SECONDS ); } /** * Check whether a legacy Select2 handle has been printed. * * @return bool */ private function is_legacy_select2_printed(): bool { foreach ( self::LEGACY_HANDLES as $handle ) { if ( wp_script_is( $handle, 'done' ) ) { return true; } } return false; } /** * Get the transient key for a usage event. * * @param array $event Usage event. * @return string */ private function get_transient_key( array $event ): string { ksort( $event ); $event_json = wp_json_encode( $event ); return self::TRANSIENT_KEY_PREFIX . md5( is_string( $event_json ) ? $event_json : '' ); } /** * Get legacy Select2 handles for a printed top-level handle. * * @param WP_Scripts $wp_scripts WordPress scripts registry. * @param string $handle Script handle. * @return array */ private function get_legacy_handles( WP_Scripts $wp_scripts, string $handle ): array { $legacy_handles = array(); if ( in_array( $handle, self::LEGACY_HANDLES, true ) ) { $legacy_handles[ $handle ] = true; return array_keys( $legacy_handles ); } if ( isset( $wp_scripts->registered[ $handle ] ) ) { foreach ( $wp_scripts->registered[ $handle ]->deps as $dependency_handle ) { if ( in_array( $dependency_handle, self::LEGACY_HANDLES, true ) ) { $legacy_handles[ $dependency_handle ] = true; } } } return array_keys( $legacy_handles ); } /** * Get a script source relative to the plugins directory. * * @param string|false $source Script source. * @param string|false|null $plugins_path Plugins directory URL path. * @return string */ private static function get_plugin_relative_source( $source, $plugins_path ): string { if ( ! is_string( $source ) || '' === $source || ! is_string( $plugins_path ) || '' === $plugins_path ) { return ''; } $source_path = wp_parse_url( $source, PHP_URL_PATH ); if ( ! is_string( $source_path ) || ! str_starts_with( $source_path, $plugins_path ) ) { return ''; } return ltrim( substr( $source_path, strlen( $plugins_path ) ), '/' ); } /** * Get the source for a legacy Select2 handle. * * @param WP_Scripts $wp_scripts WordPress scripts registry. * @param string $handle Script handle. * @return string */ private static function get_legacy_handle_source( WP_Scripts $wp_scripts, string $handle ): string { $source_handle = 'select2' === $handle ? 'wc-select2' : $handle; $registered_script = $wp_scripts->registered[ $source_handle ] ?? null; if ( null === $registered_script ) { return ''; } return is_string( $registered_script->src ) ? $registered_script->src : ''; } /** * Get the current admin screen ID. * * @return string */ private function get_current_screen_id(): string { if ( ! function_exists( 'get_current_screen' ) ) { return ''; } $screen = get_current_screen(); return $screen ? (string) $screen->id : ''; } /** * Get the current page type. * * @param string $context The request context. * @return string */ private function get_current_page_type( string $context ): string { if ( self::CONTEXT_ADMIN === $context ) { return $this->get_current_screen_id(); } if ( self::CONTEXT_FRONTEND === $context ) { return $this->get_current_frontend_page_type(); } return ''; } /** * Get the current frontend page type. * * @return string */ private function get_current_frontend_page_type(): string { if ( is_cart() ) { return 'cart'; } if ( is_checkout() ) { return 'checkout'; } if ( is_account_page() ) { return 'my_account'; } if ( is_shop() ) { return 'shop'; } if ( is_product() ) { return 'product'; } if ( is_product_category() ) { return 'product_category'; } if ( is_product_tag() ) { return 'product_tag'; } if ( is_product_taxonomy() ) { return 'product_taxonomy'; } if ( is_front_page() ) { return 'front_page'; } if ( is_home() ) { return 'home'; } if ( is_search() ) { return 'search'; } if ( is_archive() ) { return 'archive'; } if ( is_singular() ) { return 'singular'; } return 'other'; } }