You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

286 lines
8.0 KiB
PHP

<?php
/**
* Class Analytics
*
* @link https://github.com/googleforcreators/web-stories-wp
*
* @copyright 2020 Google LLC
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
*/
/**
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
declare(strict_types = 1);
namespace Google\Web_Stories;
/**
* Class Analytics
*/
class Analytics extends Service_Base {
/**
* Settings instance.
*
* @var Settings Settings instance.
*/
private Settings $settings;
/**
* Analytics constructor.
*
* @since 1.12.0
*
* @param Settings $settings Settings instance.
* @return void
*/
public function __construct( Settings $settings ) {
$this->settings = $settings;
}
/**
* Initializes all hooks.
*
* @since 1.0.0
*/
public function register(): void {
add_action( 'web_stories_print_analytics', [ $this, 'print_analytics_tag' ] );
}
/**
* Returns the Google Analytics tracking ID.
*
* @since 1.0.0
*
* @return string Tracking ID.
*/
public function get_tracking_id(): string {
/**
* Tracking ID.
*
* @var string $tracking_id
*/
$tracking_id = $this->settings->get_setting( $this->settings::SETTING_NAME_TRACKING_ID );
// For some reasons, some sites use the plugin's own tracking ID (as used in the admin)
// for their stories. Prevent accidental erroneous tracking in such a case.
if ( Tracking::TRACKING_ID === $tracking_id ) {
return '';
}
return $tracking_id;
}
/**
* Returns the default analytics configuration.
*
* Note: variables in single quotes will be substituted by <amp-analytics>.
*
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*
* @see https://github.com/ampproject/amphtml/blob/main/docs/spec/amp-var-substitutions.md
*
* @param string $tracking_id Tracking ID.
* @return array<string, array<string, mixed>> <amp-analytics> configuration.
*/
public function get_default_configuration( string $tracking_id ): array {
$config = [
'vars' => [
'gtag_id' => $tracking_id,
'config' => [
$tracking_id => [ 'groups' => 'default' ],
],
],
'triggers' => [
// Fired when a story page becomes visible.
'storyProgress' => [
'on' => 'story-page-visible',
'request' => 'event',
'vars' => [
'event_name' => 'custom',
'event_action' => 'story_progress',
'event_category' => '${title}',
'event_label' => '${storyPageIndex}',
'event_value' => '${storyProgress}',
'send_to' => $tracking_id,
],
],
// Fired when the last page in the story is shown to the user.
// This can be used to measure completion rate.
'storyEnd' => [
'on' => 'story-last-page-visible',
'request' => 'event',
'vars' => [
'event_name' => 'custom',
'event_action' => 'story_complete',
'event_category' => '${title}',
'event_label' => '${storyPageCount}',
'send_to' => $tracking_id,
],
],
// Fired when clicking an element that opens a tooltip (<a> or <amp-twitter>).
'trackFocusState' => [
'on' => 'story-focus',
'tagName' => 'a',
'request' => 'click ',
'vars' => [
'event_name' => 'custom',
'event_action' => 'story_focus',
'event_category' => '${title}',
'send_to' => $tracking_id,
],
],
// Fired when clicking on a tooltip.
'trackClickThrough' => [
'on' => 'story-click-through',
'tagName' => 'a',
'request' => 'click ',
'vars' => [
'event_name' => 'custom',
'event_action' => 'story_click_through',
'event_category' => '${title}',
'send_to' => $tracking_id,
],
],
// Fired when opening a drawer or dialog inside a story (e.g. page attachment).
'storyOpen' => [
'on' => 'story-open',
'request' => 'event',
'vars' => [
'event_name' => 'custom',
'event_action' => 'story_open',
'event_category' => '${title}',
'send_to' => $tracking_id,
],
],
// Fired when closing a drawer or dialog inside a story (e.g. page attachment).
'storyClose' => [
'on' => 'story-close',
'request' => 'event',
'vars' => [
'event_name' => 'custom',
'event_action' => 'story_close',
'event_category' => '${title}',
'send_to' => $tracking_id,
],
],
// Fired when the user initiates an interaction to mute the audio for the current story.
'audioMuted' => [
'on' => 'story-audio-muted',
'request' => 'event',
'vars' => [
'event_name' => 'custom',
'event_action' => 'story_audio_muted',
'event_category' => '${title}',
'send_to' => $tracking_id,
],
],
// Fired when the user initiates an interaction to unmute the audio for the current story.
'audioUnmuted' => [
'on' => 'story-audio-unmuted',
'request' => 'event',
'vars' => [
'event_name' => 'custom',
'event_action' => 'story_audio_unmuted',
'event_category' => '${title}',
'send_to' => $tracking_id,
],
],
// Fired when a page attachment is opened by the user.
'pageAttachmentEnter' => [
'on' => 'story-page-attachment-enter',
'request' => 'event',
'vars' => [
'event_name' => 'custom',
'event_action' => 'story_page_attachment_enter',
'event_category' => '${title}',
'send_to' => $tracking_id,
],
],
// Fired when a page attachment is dismissed by the user.
'pageAttachmentExit' => [
'on' => 'story-page-attachment-exit',
'request' => 'event',
'vars' => [
'event_name' => 'custom',
'event_action' => 'story_page_attachment_exit',
'event_category' => '${title}',
'send_to' => $tracking_id,
],
],
],
];
/**
* Filters the Web Stories Google Analytics configuration.
*
* Only used when not using <amp-story-auto-analytics>, which is the default.
*
* @param array $config Analytics configuration.
*/
return apply_filters( 'web_stories_analytics_configuration', $config );
}
/**
* Prints the analytics tag for single stories.
*
* @since 1.0.0
*/
public function print_analytics_tag(): void {
$tracking_id = $this->get_tracking_id();
if ( ! $tracking_id ) {
return;
}
if ( $this->settings->get_setting( $this->settings::SETTING_NAME_USING_LEGACY_ANALYTICS ) ) {
$this->print_amp_analytics_tag( $tracking_id );
} else {
$this->print_amp_story_auto_analytics_tag( $tracking_id );
}
}
/**
* Prints the legacy <amp-analytics> tag for single stories.
*
* @since 1.12.0
*
* @param string $tracking_id Tracking ID.
*/
private function print_amp_analytics_tag( string $tracking_id ): void {
?>
<amp-analytics type="gtag" data-credentials="include">
<script type="application/json">
<?php echo wp_json_encode( $this->get_default_configuration( $tracking_id ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
</script>
</amp-analytics>
<?php
}
/**
* Prints the <amp-story-auto-analytics> tag for single stories.
*
* @since 1.12.0
*
* @param string $tracking_id Tracking ID.
*/
private function print_amp_story_auto_analytics_tag( string $tracking_id ): void {
?>
<amp-story-auto-analytics gtag-id="<?php echo esc_attr( $tracking_id ); ?>"></amp-story-auto-analytics>
<?php
}
}