diff --git a/includes/Core/Tags/GTag.php b/includes/Core/Tags/GTag.php new file mode 100644 index 00000000000..489afb1e1bb --- /dev/null +++ b/includes/Core/Tags/GTag.php @@ -0,0 +1,104 @@ +get_method_proxy( 'enqueue_gtag_script' ), 20 ); + + add_filter( + 'wp_resource_hints', + function ( $urls, $relation_type ) { + if ( 'dns-prefetch' === $relation_type ) { + $urls[] = '//www.googletagmanager.com'; + } + + return $urls; + }, + 10, + 2 + ); + } + + public function add_tag( $tag_id, $config = array() ) { + $this->tags[] = array( + 'tag_id' => $tag_id, + 'config' => $config, + ); + } + + public function add_command( $command, ...$parameters ) { + $this->commands[] = array( + 'command' => $command, + 'parameters' => $parameters, + ); + } + + protected function enqueue_gtag_script() { + // $this->tags and $this->commands will be populated via this action's handlers. + do_action( 'googlesitekit_setup_gtag', $this ); + + if ( empty( $this->tags ) ) { + return; + } + + // Load the GTag scripts using the first tag ID - it doesn't matter which is used, all registered tags will be setup with a + // config command regardless of which is used to load the source. + $gtag_src = 'https://www.googletagmanager.com/gtag/js?id=' . rawurlencode( $this->tags[0]['tag_id'] ); + + // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion + wp_enqueue_script( self::HANDLE, $gtag_src, false, null, false ); + wp_script_add_data( self::HANDLE, 'script_execution', 'async' ); + wp_add_inline_script( self::HANDLE, 'window.dataLayer = window.dataLayer || [];function gtag(){dataLayer.push(arguments);}' ); + wp_add_inline_script( self::HANDLE, 'gtag("js", new Date());' ); + wp_add_inline_script( self::HANDLE, 'gtag("set", "developer_id.dZTNiMT", true);' ); // Site Kit developer ID. + + foreach ( $this->tags as $tag ) { + wp_add_inline_script( self::HANDLE, $this->get_gtag_call_for_tag( $tag ) ); + } + + foreach ( $this->commands as $command ) { + wp_add_inline_script( self::HANDLE, $this->get_gtag_call_for_command( $command ) ); + } + + $filter_google_gtagjs = function ( $tag, $handle ) { + if ( self::HANDLE !== $handle ) { + return $tag; + } + + $snippet_comment_begin = sprintf( "\n\n", esc_html__( 'Google tag (gtag.js)snippet added by Site Kit', 'google-site-kit' ) ); + $snippet_comment_end = sprintf( "\n\n", esc_html__( 'End Google tag (gtag.js) snippet added by Site Kit', 'google-site-kit' ) ); + + return $snippet_comment_begin . $tag . $snippet_comment_end; + }; + + add_filter( 'script_loader_tag', $filter_google_gtagjs, 20, 2 ); + } + + protected function get_gtag_call_for_tag( $tag ) { + return empty( $tag['config'] ) + ? sprintf( 'gtag("config", "%s");', esc_js( $tag['tag_id'] ) ) + : sprintf( 'gtag("config", "%s", %s);', esc_js( $tag['tag_id'] ), wp_json_encode( $tag['config'] ) ); + } + + protected function get_gtag_call_for_command( $command ) { + $gtag_args = array_merge( array( $command['command'] ), $command['parameters'] ); + $gtag_args = array_map( + function( $arg ) { + return wp_json_encode( $arg ); + }, + $gtag_args + ); + + return sprintf( 'gtag(%s);', implode( ',', $gtag_args ) ); + } +} diff --git a/includes/Modules/Analytics_4/Web_Tag.php b/includes/Modules/Analytics_4/Web_Tag.php index bc856043a73..e1983d1286a 100644 --- a/includes/Modules/Analytics_4/Web_Tag.php +++ b/includes/Modules/Analytics_4/Web_Tag.php @@ -11,6 +11,7 @@ namespace Google\Site_Kit\Modules\Analytics_4; use Google\Site_Kit\Core\Modules\Tags\Module_Web_Tag; +use Google\Site_Kit\Core\Tags\GTag; use Google\Site_Kit\Core\Tags\Tag_With_DNS_Prefetch_Trait; use Google\Site_Kit\Core\Util\Method_Proxy_Trait; @@ -88,13 +89,8 @@ public function set_ads_conversion_id( $ads_conversion_id ) { * @since 1.31.0 */ public function register() { - add_action( 'wp_enqueue_scripts', $this->get_method_proxy( 'enqueue_gtag_script' ), 20 ); - add_filter( - 'wp_resource_hints', - $this->get_dns_prefetch_hints_callback( '//www.googletagmanager.com' ), - 10, - 2 - ); + add_action( 'googlesitekit_setup_gtag', $this->get_method_proxy( 'setup_gtag' ) ); + $this->do_init_tag_action(); } @@ -108,18 +104,15 @@ protected function render() { } /** - * Enqueues gtag script. + * Configures gtag script. * * @since 1.24.0 + * @since n.e.x.t Changed name and refactored. + * + * @param GTag $gtag GTag instance. */ - protected function enqueue_gtag_script() { + protected function setup_gtag( $gtag ) { $gtag_opt = $this->get_tag_config(); - $gtag_src = 'https://www.googletagmanager.com/gtag/js?id=' . rawurlencode( $this->tag_id ); - - // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion - wp_enqueue_script( 'google_gtagjs', $gtag_src, false, null, false ); - wp_script_add_data( 'google_gtagjs', 'script_execution', 'async' ); - wp_add_inline_script( 'google_gtagjs', 'window.dataLayer = window.dataLayer || [];function gtag(){dataLayer.push(arguments);}' ); /** * Filters the gtag configuration options for the Analytics snippet. @@ -135,81 +128,32 @@ protected function enqueue_gtag_script() { $gtag_opt = apply_filters( 'googlesitekit_gtag_opt', $gtag_opt ); if ( ! empty( $gtag_opt['linker'] ) ) { - $linker = wp_json_encode( $gtag_opt['linker'] ); - $linker = sprintf( "gtag('set', 'linker', %s );", $linker ); - wp_add_inline_script( 'google_gtagjs', $linker ); - } + $gtag->add_command( 'set', 'linker', $gtag_opt['linker'] ); - unset( $gtag_opt['linker'] ); - - wp_add_inline_script( 'google_gtagjs', 'gtag("js", new Date());' ); - wp_add_inline_script( 'google_gtagjs', 'gtag("set", "developer_id.dZTNiMT", true);' ); // Site Kit developer ID. + unset( $gtag_opt['linker'] ); + } - $this->add_inline_config( $this->tag_id, $gtag_opt ); - $this->add_inline_ads_conversion_id_config(); + $gtag->add_tag( $this->tag_id, $gtag_opt ); - $block_on_consent_attrs = $this->get_tag_blocked_on_consent_attribute(); + // TODO: Lift this out to the Ads module when it's ready. + if ( $this->ads_conversion_id ) { + $gtag->add_tag( $this->ads_conversion_id ); + } - $filter_google_gtagjs = function ( $tag, $handle ) use ( $block_on_consent_attrs, $gtag_src ) { - if ( 'google_gtagjs' !== $handle ) { + $filter_google_gtagjs = function ( $tag, $handle ) { + if ( GTag::HANDLE !== $handle ) { return $tag; } - $snippet_comment_begin = sprintf( "\n\n", esc_html__( 'Google Analytics snippet added by Site Kit', 'google-site-kit' ) ); - $snippet_comment_end = sprintf( "\n\n", esc_html__( 'End Google Analytics snippet added by Site Kit', 'google-site-kit' ) ); - - if ( $block_on_consent_attrs ) { - $tag = str_replace( - array( - "