Version Description
- Added: track embedded YouTube/Vimeo/Soundcloud videos (experimental)
- Added: new checkbox - use product SKU for AdWords Dynamic Remarketing variables instead of product ID (experimental)
- Added: place your container code after the opening body tag without modifying your theme files (thx Yaniv Friedensohn)
- Added: automatic codeless container code injection for Genesis framework users
- Fixed: Possible PHP error with custom payment gateway (QuickPay) on the checkout page (thx Damiel for findig this)
Download this release
Release Info
Developer | duracelltomi |
Plugin | DuracellTomi's Google Tag Manager for WordPress |
Version | 1.1 |
Comparing to | |
See all releases |
Code changes from version 1.0 to 1.1
- admin/admin.php +48 -6
- common/readoptions.php +11 -2
- css/admin-gtm4wp.css +1 -1
- duracelltomi-google-tag-manager-for-wordpress.php +2 -2
- integration/soundcloud.php +28 -0
- integration/vimeo.php +23 -0
- integration/woocommerce.php +96 -23
- integration/youtube.php +14 -0
- js/admin-subtabs.js +14 -1
- js/admin-tabcreator.js +2 -2
- js/froogaloop.js +259 -0
- js/gtm4wp-soundcloud.js +137 -0
- js/gtm4wp-vimeo.js +105 -0
- js/gtm4wp-youtube.js +208 -0
- public/frontend.php +36 -5
- readme.txt +44 -12
admin/admin.php
CHANGED
@@ -129,6 +129,21 @@ $GLOBALS["gtm4wp_eventfieldtexts"] = array(
|
|
129 |
"description" => __( "Check this option to include a Tag Manager event when a visitor uses a social button to share/like content on a social network.", GTM4WP_TEXTDOMAIN ),
|
130 |
"phase" => GTM4WP_PHASE_STABLE
|
131 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
132 |
GTM4WP_OPTION_EVENTS_OUTBOUND => array(
|
133 |
"label" => __( "Outbound link click events (gtm4wp.outboundClick)", GTM4WP_TEXTDOMAIN ),
|
134 |
"description" => __( "Check this option to include a Tag Manager event when a visitor clicks on a link directing the visitor out of your website.", GTM4WP_TEXTDOMAIN ),
|
@@ -374,8 +389,13 @@ $GLOBALS["gtm4wp_integratefieldtexts"] = array(
|
|
374 |
GTM4WP_OPTION_INTEGRATE_WCREMARKETING => array(
|
375 |
"label" => __( "AdWords Remarketing", GTM4WP_TEXTDOMAIN ),
|
376 |
"description" => __( "Enable this to add Google AdWords dynamic remarketing variables to the dataLayer", GTM4WP_TEXTDOMAIN ),
|
377 |
-
"phase"
|
378 |
"plugintocheck" => "woocommerce/woocommerce.php"
|
|
|
|
|
|
|
|
|
|
|
379 |
)
|
380 |
);
|
381 |
|
@@ -460,8 +480,9 @@ function gtm4wp_admin_output_field( $args ) {
|
|
460 |
}
|
461 |
|
462 |
case GTM4WP_ADMIN_GROUP_PLACEMENT: {
|
463 |
-
echo '<input type="radio" id="' . GTM4WP_OPTIONS . '[' . GTM4WP_OPTION_GTM_PLACEMENT . ']
|
464 |
-
echo '<input type="radio" id="' . GTM4WP_OPTIONS . '[' . GTM4WP_OPTION_GTM_PLACEMENT . ']
|
|
|
465 |
|
466 |
break;
|
467 |
}
|
@@ -542,6 +563,8 @@ function gtm4wp_admin_output_field( $args ) {
|
|
542 |
}
|
543 |
|
544 |
function gtm4wp_sanitize_options($options) {
|
|
|
|
|
545 |
$output = gtm4wp_reload_options();
|
546 |
|
547 |
foreach($output as $optionname => $optionvalue) {
|
@@ -563,6 +586,17 @@ function gtm4wp_sanitize_options($options) {
|
|
563 |
} else if ( substr($optionname, 0, 6) == "event-" ) {
|
564 |
$output[$optionname] = (boolean) $newoptionvalue;
|
565 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
566 |
// integrations
|
567 |
} else if ( substr($optionname, 0, 10) == "integrate-" ) {
|
568 |
$output[$optionname] = (boolean) $newoptionvalue;
|
@@ -584,7 +618,7 @@ function gtm4wp_sanitize_options($options) {
|
|
584 |
// GTM container code placement
|
585 |
} else if ( $optionname == GTM4WP_OPTION_GTM_PLACEMENT ) {
|
586 |
$output[$optionname] = (int) $newoptionvalue;
|
587 |
-
if ( ( $output[$optionname] < 0) || ( $output[$optionname] >
|
588 |
$output[$optionname] = 0;
|
589 |
}
|
590 |
|
@@ -820,6 +854,11 @@ function gtm4wp_admin_init() {
|
|
820 |
)
|
821 |
);
|
822 |
|
|
|
|
|
|
|
|
|
|
|
823 |
}
|
824 |
|
825 |
function gtm4wp_show_admin_page() {
|
@@ -864,7 +903,10 @@ function gtm4wp_add_admin_js($hook) {
|
|
864 |
"blockmacrostabtitle" => __( "Blacklist macros" , GTM4WP_TEXTDOMAIN ),
|
865 |
"wpcf7tabtitle" => __( "Contact Form 7" , GTM4WP_TEXTDOMAIN ),
|
866 |
"wctabtitle" => __( "WooCommerce" , GTM4WP_TEXTDOMAIN ),
|
867 |
-
"weathertabtitle" => __( "Weather data" , GTM4WP_TEXTDOMAIN )
|
|
|
|
|
|
|
868 |
);
|
869 |
wp_localize_script( "admin-subtabs", 'gtm4wp', $subtabtexts );
|
870 |
wp_enqueue_script( "admin-subtabs" );
|
@@ -1019,4 +1061,4 @@ add_action( 'admin_enqueue_scripts', 'gtm4wp_add_admin_js' );
|
|
1019 |
add_action( 'admin_notices', 'gtm4wp_show_warning' );
|
1020 |
add_action( 'admin_head', 'gtm4wp_admin_head' );
|
1021 |
add_filter( 'plugin_action_links', 'gtm4wp_add_plugin_action_links', 10, 2 );
|
1022 |
-
add_action( 'wp_ajax_gtm4wp_dismiss_notice', 'gtm4wp_dismiss_notice' );
|
129 |
"description" => __( "Check this option to include a Tag Manager event when a visitor uses a social button to share/like content on a social network.", GTM4WP_TEXTDOMAIN ),
|
130 |
"phase" => GTM4WP_PHASE_STABLE
|
131 |
),
|
132 |
+
GTM4WP_OPTION_EVENTS_YOUTUBE => array(
|
133 |
+
"label" => __( "YouTube video events", GTM4WP_TEXTDOMAIN ),
|
134 |
+
"description" => __( "Check this option to include a Tag Manager event when a visitor interacts with a YouTube video embeded on your site.", GTM4WP_TEXTDOMAIN ),
|
135 |
+
"phase" => GTM4WP_PHASE_EXPERIMENTAL
|
136 |
+
),
|
137 |
+
GTM4WP_OPTION_EVENTS_VIMEO => array(
|
138 |
+
"label" => __( "Vimeo video events", GTM4WP_TEXTDOMAIN ),
|
139 |
+
"description" => __( "Check this option to include a Tag Manager event when a visitor interacts with a Vimeo video embeded on your site.", GTM4WP_TEXTDOMAIN ),
|
140 |
+
"phase" => GTM4WP_PHASE_EXPERIMENTAL
|
141 |
+
),
|
142 |
+
GTM4WP_OPTION_EVENTS_SOUNDCLOUD => array(
|
143 |
+
"label" => __( "Soundcloud events", GTM4WP_TEXTDOMAIN ),
|
144 |
+
"description" => __( "Check this option to include a Tag Manager event when a visitor interacts with a Soundcloud media embeded on your site.", GTM4WP_TEXTDOMAIN ),
|
145 |
+
"phase" => GTM4WP_PHASE_EXPERIMENTAL
|
146 |
+
),
|
147 |
GTM4WP_OPTION_EVENTS_OUTBOUND => array(
|
148 |
"label" => __( "Outbound link click events (gtm4wp.outboundClick)", GTM4WP_TEXTDOMAIN ),
|
149 |
"description" => __( "Check this option to include a Tag Manager event when a visitor clicks on a link directing the visitor out of your website.", GTM4WP_TEXTDOMAIN ),
|
389 |
GTM4WP_OPTION_INTEGRATE_WCREMARKETING => array(
|
390 |
"label" => __( "AdWords Remarketing", GTM4WP_TEXTDOMAIN ),
|
391 |
"description" => __( "Enable this to add Google AdWords dynamic remarketing variables to the dataLayer", GTM4WP_TEXTDOMAIN ),
|
392 |
+
"phase" => GTM4WP_PHASE_STABLE,
|
393 |
"plugintocheck" => "woocommerce/woocommerce.php"
|
394 |
+
),
|
395 |
+
GTM4WP_OPTION_INTEGRATE_WCREMARKETINGSKU => array(
|
396 |
+
"label" => __( "Use SKU instead of ID", GTM4WP_TEXTDOMAIN ),
|
397 |
+
"description" => __( "Check this to use product SKU in the dynamic remarketing variables instead of the ID of the products. Will fallback to ID if no SKU is set.", GTM4WP_TEXTDOMAIN ),
|
398 |
+
"phase" => GTM4WP_PHASE_EXPERIMENTAL
|
399 |
)
|
400 |
);
|
401 |
|
480 |
}
|
481 |
|
482 |
case GTM4WP_ADMIN_GROUP_PLACEMENT: {
|
483 |
+
echo '<input type="radio" id="' . GTM4WP_OPTIONS . '[' . GTM4WP_OPTION_GTM_PLACEMENT . ']_' . GTM4WP_PLACEMENT_FOOTER . '" name="' . GTM4WP_OPTIONS . '[' . GTM4WP_OPTION_GTM_PLACEMENT . ']" value="' . GTM4WP_PLACEMENT_FOOTER . '" ' . ( $gtm4wp_options[ GTM4WP_OPTION_GTM_PLACEMENT ] == GTM4WP_PLACEMENT_FOOTER ? 'checked="checked"' : '' ) . '/> ' . __( "Footer of the page (not recommended by Google, no tweak in your template required)", GTM4WP_TEXTDOMAIN ) . '<br />';
|
484 |
+
echo '<input type="radio" id="' . GTM4WP_OPTIONS . '[' . GTM4WP_OPTION_GTM_PLACEMENT . ']_' . GTM4WP_PLACEMENT_BODYOPEN . '" name="' . GTM4WP_OPTIONS . '[' . GTM4WP_OPTION_GTM_PLACEMENT . ']" value="' . GTM4WP_PLACEMENT_BODYOPEN . '" ' . ( $gtm4wp_options[ GTM4WP_OPTION_GTM_PLACEMENT ] == GTM4WP_PLACEMENT_BODYOPEN ? 'checked="checked"' : '' ) . '/> ' . __( "Custom (needs tweak in your template)", GTM4WP_TEXTDOMAIN ) . '<br />';
|
485 |
+
echo '<input type="radio" id="' . GTM4WP_OPTIONS . '[' . GTM4WP_OPTION_GTM_PLACEMENT . ']_' . GTM4WP_PLACEMENT_BODYOPEN_AUTO . '" name="' . GTM4WP_OPTIONS . '[' . GTM4WP_OPTION_GTM_PLACEMENT . ']" value="' . GTM4WP_PLACEMENT_BODYOPEN_AUTO . '" ' . ( $gtm4wp_options[ GTM4WP_OPTION_GTM_PLACEMENT ] == GTM4WP_PLACEMENT_BODYOPEN_AUTO ? 'checked="checked"' : '' ) . '/> ' . __( "Codeless injection (no tweak, right placement but experimental, could break your frontend)", GTM4WP_TEXTDOMAIN ) . '<br /><br />' . $args["description"];
|
486 |
|
487 |
break;
|
488 |
}
|
563 |
}
|
564 |
|
565 |
function gtm4wp_sanitize_options($options) {
|
566 |
+
global $wpdb;
|
567 |
+
|
568 |
$output = gtm4wp_reload_options();
|
569 |
|
570 |
foreach($output as $optionname => $optionvalue) {
|
586 |
} else if ( substr($optionname, 0, 6) == "event-" ) {
|
587 |
$output[$optionname] = (boolean) $newoptionvalue;
|
588 |
|
589 |
+
// clear oembed transients when feature is enabled because we need to hook into the oembed process to enable some 3rd party APIs
|
590 |
+
if ( $output[$optionname] && !$optionvalue ) {
|
591 |
+
if ( GTM4WP_OPTION_EVENTS_YOUTUBE == $optionname ) {
|
592 |
+
$wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_value LIKE '%youtube.com%' AND meta_key LIKE '_oembed_%'" );
|
593 |
+
}
|
594 |
+
|
595 |
+
if ( GTM4WP_OPTION_EVENTS_VIMEO == $optionname ) {
|
596 |
+
$wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_value LIKE '%vimeo.com%' AND meta_key LIKE '_oembed_%'" );
|
597 |
+
}
|
598 |
+
}
|
599 |
+
|
600 |
// integrations
|
601 |
} else if ( substr($optionname, 0, 10) == "integrate-" ) {
|
602 |
$output[$optionname] = (boolean) $newoptionvalue;
|
618 |
// GTM container code placement
|
619 |
} else if ( $optionname == GTM4WP_OPTION_GTM_PLACEMENT ) {
|
620 |
$output[$optionname] = (int) $newoptionvalue;
|
621 |
+
if ( ( $output[$optionname] < 0) || ( $output[$optionname] > 2 ) ) {
|
622 |
$output[$optionname] = 0;
|
623 |
}
|
624 |
|
854 |
)
|
855 |
);
|
856 |
|
857 |
+
// apply oembed code changes on the admin as well since the oembed call on the admin is cached by WordPress into a transient
|
858 |
+
// that is applied on the frontend later
|
859 |
+
require_once( dirname( __FILE__ ) . "/../integration/youtube.php" );
|
860 |
+
require_once( dirname( __FILE__ ) . "/../integration/vimeo.php" );
|
861 |
+
require_once( dirname( __FILE__ ) . "/../integration/soundcloud.php" );
|
862 |
}
|
863 |
|
864 |
function gtm4wp_show_admin_page() {
|
903 |
"blockmacrostabtitle" => __( "Blacklist macros" , GTM4WP_TEXTDOMAIN ),
|
904 |
"wpcf7tabtitle" => __( "Contact Form 7" , GTM4WP_TEXTDOMAIN ),
|
905 |
"wctabtitle" => __( "WooCommerce" , GTM4WP_TEXTDOMAIN ),
|
906 |
+
"weathertabtitle" => __( "Weather data" , GTM4WP_TEXTDOMAIN ),
|
907 |
+
"generaleventstabtitle" => __( "General events" , GTM4WP_TEXTDOMAIN ),
|
908 |
+
"mediaeventstabtitle" => __( "Media events" , GTM4WP_TEXTDOMAIN ),
|
909 |
+
"depecratedeventstabtitle" => __( "Depecrated" , GTM4WP_TEXTDOMAIN )
|
910 |
);
|
911 |
wp_localize_script( "admin-subtabs", 'gtm4wp', $subtabtexts );
|
912 |
wp_enqueue_script( "admin-subtabs" );
|
1061 |
add_action( 'admin_notices', 'gtm4wp_show_warning' );
|
1062 |
add_action( 'admin_head', 'gtm4wp_admin_head' );
|
1063 |
add_filter( 'plugin_action_links', 'gtm4wp_add_plugin_action_links', 10, 2 );
|
1064 |
+
add_action( 'wp_ajax_gtm4wp_dismiss_notice', 'gtm4wp_dismiss_notice' );
|
common/readoptions.php
CHANGED
@@ -28,6 +28,9 @@ define( 'GTM4WP_OPTION_EVENTS_DWLEXT', 'event-download-extensions' );
|
|
28 |
define( 'GTM4WP_OPTION_EVENTS_EMAILCLICKS', 'event-email-clicks' );
|
29 |
define( 'GTM4WP_OPTION_EVENTS_FORMMOVE', 'event-form-move' );
|
30 |
define( 'GTM4WP_OPTION_EVENTS_SOCIAL', 'event-social' );
|
|
|
|
|
|
|
31 |
|
32 |
define( 'GTM4WP_OPTION_SCROLLER_ENABLED', 'scroller-enabled' );
|
33 |
define( 'GTM4WP_OPTION_SCROLLER_DEBUGMODE', 'scroller-debug-mode' );
|
@@ -75,11 +78,13 @@ define( 'GTM4WP_OPTION_INTEGRATE_WOOCOMMERCE', 'integrate-woocommerce' );
|
|
75 |
define( 'GTM4WP_OPTION_INTEGRATE_WCTRACKCLASSICEC', 'integrate-woocommerce-track-classic-ecommerce' );
|
76 |
define( 'GTM4WP_OPTION_INTEGRATE_WCTRACKENHANCEDEC', 'integrate-woocommerce-track-enhanced-ecommerce' );
|
77 |
define( 'GTM4WP_OPTION_INTEGRATE_WCREMARKETING', 'integrate-woocommerce-remarketing' );
|
|
|
78 |
|
79 |
define( 'GTM4WP_OPTION_INTEGRATE_WPECOMMERCE', 'integrate-wp-e-commerce' );
|
80 |
|
81 |
-
define( 'GTM4WP_PLACEMENT_FOOTER',
|
82 |
-
define( 'GTM4WP_PLACEMENT_BODYOPEN',
|
|
|
83 |
|
84 |
$gtm4wp_options = array();
|
85 |
|
@@ -112,6 +117,9 @@ $gtm4wp_defaultoptions = array(
|
|
112 |
GTM4WP_OPTION_EVENTS_EMAILCLICKS => false,
|
113 |
GTM4WP_OPTION_EVENTS_FORMMOVE => true,
|
114 |
GTM4WP_OPTION_EVENTS_SOCIAL => false,
|
|
|
|
|
|
|
115 |
|
116 |
GTM4WP_OPTION_SCROLLER_ENABLED => false,
|
117 |
GTM4WP_OPTION_SCROLLER_DEBUGMODE => false,
|
@@ -159,6 +167,7 @@ $gtm4wp_defaultoptions = array(
|
|
159 |
GTM4WP_OPTION_INTEGRATE_WCTRACKCLASSICEC => false,
|
160 |
GTM4WP_OPTION_INTEGRATE_WCTRACKENHANCEDEC => false,
|
161 |
GTM4WP_OPTION_INTEGRATE_WCREMARKETING => false,
|
|
|
162 |
|
163 |
GTM4WP_OPTION_INTEGRATE_WPECOMMERCE => false
|
164 |
);
|
28 |
define( 'GTM4WP_OPTION_EVENTS_EMAILCLICKS', 'event-email-clicks' );
|
29 |
define( 'GTM4WP_OPTION_EVENTS_FORMMOVE', 'event-form-move' );
|
30 |
define( 'GTM4WP_OPTION_EVENTS_SOCIAL', 'event-social' );
|
31 |
+
define( 'GTM4WP_OPTION_EVENTS_YOUTUBE', 'event-youtube' );
|
32 |
+
define( 'GTM4WP_OPTION_EVENTS_VIMEO', 'event-vimeo' );
|
33 |
+
define( 'GTM4WP_OPTION_EVENTS_SOUNDCLOUD', 'event-soundcloud' );
|
34 |
|
35 |
define( 'GTM4WP_OPTION_SCROLLER_ENABLED', 'scroller-enabled' );
|
36 |
define( 'GTM4WP_OPTION_SCROLLER_DEBUGMODE', 'scroller-debug-mode' );
|
78 |
define( 'GTM4WP_OPTION_INTEGRATE_WCTRACKCLASSICEC', 'integrate-woocommerce-track-classic-ecommerce' );
|
79 |
define( 'GTM4WP_OPTION_INTEGRATE_WCTRACKENHANCEDEC', 'integrate-woocommerce-track-enhanced-ecommerce' );
|
80 |
define( 'GTM4WP_OPTION_INTEGRATE_WCREMARKETING', 'integrate-woocommerce-remarketing' );
|
81 |
+
define( 'GTM4WP_OPTION_INTEGRATE_WCREMARKETINGSKU', 'integrate-woocommerce-remarketing-usesku' );
|
82 |
|
83 |
define( 'GTM4WP_OPTION_INTEGRATE_WPECOMMERCE', 'integrate-wp-e-commerce' );
|
84 |
|
85 |
+
define( 'GTM4WP_PLACEMENT_FOOTER', 0 );
|
86 |
+
define( 'GTM4WP_PLACEMENT_BODYOPEN', 1 );
|
87 |
+
define( 'GTM4WP_PLACEMENT_BODYOPEN_AUTO', 2 );
|
88 |
|
89 |
$gtm4wp_options = array();
|
90 |
|
117 |
GTM4WP_OPTION_EVENTS_EMAILCLICKS => false,
|
118 |
GTM4WP_OPTION_EVENTS_FORMMOVE => true,
|
119 |
GTM4WP_OPTION_EVENTS_SOCIAL => false,
|
120 |
+
GTM4WP_OPTION_EVENTS_YOUTUBE => false,
|
121 |
+
GTM4WP_OPTION_EVENTS_VIMEO => false,
|
122 |
+
GTM4WP_OPTION_EVENTS_SOUNDCLOUD => false,
|
123 |
|
124 |
GTM4WP_OPTION_SCROLLER_ENABLED => false,
|
125 |
GTM4WP_OPTION_SCROLLER_DEBUGMODE => false,
|
167 |
GTM4WP_OPTION_INTEGRATE_WCTRACKCLASSICEC => false,
|
168 |
GTM4WP_OPTION_INTEGRATE_WCTRACKENHANCEDEC => false,
|
169 |
GTM4WP_OPTION_INTEGRATE_WCREMARKETING => false,
|
170 |
+
GTM4WP_OPTION_INTEGRATE_WCREMARKETINGSKU => false,
|
171 |
|
172 |
GTM4WP_OPTION_INTEGRATE_WPECOMMERCE => false
|
173 |
);
|
css/admin-gtm4wp.css
CHANGED
@@ -68,5 +68,5 @@
|
|
68 |
}
|
69 |
|
70 |
.gtm4wp-phase-deprecated:before {
|
71 |
-
content: "
|
72 |
}
|
68 |
}
|
69 |
|
70 |
.gtm4wp-phase-deprecated:before {
|
71 |
+
content: "deprecated";
|
72 |
}
|
duracelltomi-google-tag-manager-for-wordpress.php
CHANGED
@@ -1,14 +1,14 @@
|
|
1 |
<?php
|
2 |
/*
|
3 |
Plugin Name: Google Tag Manager for Wordpress
|
4 |
-
Version: 1.
|
5 |
Plugin URI: https://duracelltomi.com/google-tag-manager-for-wordpress/
|
6 |
Description: The first Google Tag Manager plugin for WordPress with business goals in mind
|
7 |
Author: Thomas Geiger
|
8 |
Author URI: https://duracelltomi.com/
|
9 |
*/
|
10 |
|
11 |
-
define( 'GTM4WP_VERSION', '1.
|
12 |
define( 'GTM4WP_PATH', plugin_dir_path( __FILE__ ) );
|
13 |
define( 'GTM4WP_TEXTDOMAIN', 'gtm4wp-lang' );
|
14 |
|
1 |
<?php
|
2 |
/*
|
3 |
Plugin Name: Google Tag Manager for Wordpress
|
4 |
+
Version: 1.1
|
5 |
Plugin URI: https://duracelltomi.com/google-tag-manager-for-wordpress/
|
6 |
Description: The first Google Tag Manager plugin for WordPress with business goals in mind
|
7 |
Author: Thomas Geiger
|
8 |
Author URI: https://duracelltomi.com/
|
9 |
*/
|
10 |
|
11 |
+
define( 'GTM4WP_VERSION', '1.1' );
|
12 |
define( 'GTM4WP_PATH', plugin_dir_path( __FILE__ ) );
|
13 |
define( 'GTM4WP_TEXTDOMAIN', 'gtm4wp-lang' );
|
14 |
|
integration/soundcloud.php
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
function gtm4wp_soundcloud( $return, $url, $data ) {
|
3 |
+
if ( false !== strpos( $return, "soundcloud.com" ) ) {
|
4 |
+
if ( false === strpos( $return, ' id="' ) ) {
|
5 |
+
if ( preg_match('/src="([^\"]+?)"/i', $return, $r) ) {
|
6 |
+
$_urlquery = parse_url( $r[1], PHP_URL_QUERY );
|
7 |
+
if ( false !== $_urlquery ) {
|
8 |
+
parse_str( $_urlquery, $_urlparts );
|
9 |
+
|
10 |
+
if ( isset( $_urlparts[ "url" ] ) ) {
|
11 |
+
$_urlpartsid = explode( "/", $_urlparts[ "url" ] );
|
12 |
+
$_playerid = "soundcloudplayer_" . $_urlpartsid[ count( $_urlpartsid )-1 ];
|
13 |
+
$return = str_replace( '<iframe ', '<iframe id="' . $_playerid . '" ', $return);
|
14 |
+
}
|
15 |
+
}
|
16 |
+
}
|
17 |
+
}
|
18 |
+
}
|
19 |
+
|
20 |
+
return $return;
|
21 |
+
}
|
22 |
+
|
23 |
+
add_filter( "oembed_result", "gtm4wp_soundcloud", 10, 3 );
|
24 |
+
|
25 |
+
if ( ! is_admin() ) {
|
26 |
+
wp_enqueue_script( "gtm4wp-soundcloud-api", "https://w.soundcloud.com/player/api.js", array(), "1.0", false );
|
27 |
+
wp_enqueue_script( "gtm4wp-soundcloud", $gtp4wp_plugin_url . "js/gtm4wp-soundcloud.js", array( "jquery" ), "1.0", false );
|
28 |
+
}
|
integration/vimeo.php
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
function gtm4wp_vimeo( $return, $url, $data ) {
|
3 |
+
if ( false !== strpos( $return, "vimeo.com" ) ) {
|
4 |
+
if ( false === strpos( $return, ' id="' ) ) {
|
5 |
+
$_urlparts = explode( "/", $url );
|
6 |
+
$_playerid = "vimeoplayer_" . $_urlparts[ count( $_urlparts )-1 ];
|
7 |
+
|
8 |
+
$return = str_replace( '<iframe ', '<iframe id="' . $_playerid . '" ', $return);
|
9 |
+
$return = str_replace( $url, $url . "?api=1&origin=" . site_url() . "&player_id=" . $_playerid, $return);
|
10 |
+
} else {
|
11 |
+
$return = str_replace( $url, $url . "?api=1&origin=" . site_url(), $return);
|
12 |
+
}
|
13 |
+
}
|
14 |
+
|
15 |
+
return $return;
|
16 |
+
}
|
17 |
+
|
18 |
+
add_filter( "oembed_result", "gtm4wp_vimeo", 10, 3 );
|
19 |
+
if ( ! is_admin() ) {
|
20 |
+
wp_enqueue_script( "gtm4wp-vimeo-froogaloop", $gtp4wp_plugin_url . "js/froogaloop.js", array(), "2.0", false );
|
21 |
+
//wp_enqueue_script( "gtm4wp-vimeo-froogaloop", "//f.vimeocdn.com/js/froogaloop2.min.js", array(), "2.0", false );
|
22 |
+
wp_enqueue_script( "gtm4wp-vimeo", $gtp4wp_plugin_url . "js/gtm4wp-vimeo.js", array( "jquery" ), "1.0", false );
|
23 |
+
}
|
integration/woocommerce.php
CHANGED
@@ -11,13 +11,17 @@ function gtm4wp_woocommerce_addjs( $js ) {
|
|
11 |
}
|
12 |
}
|
13 |
|
|
|
|
|
|
|
|
|
14 |
function gtm4wp_woocommerce_datalayer_filter_items( $dataLayer ) {
|
15 |
global $woocommerce, $gtm4wp_options, $wp_query, $gtm4wp_datalayer_name, $gtm4wp_product_counter;
|
16 |
|
17 |
if ( is_product_category() || is_product_tag() || is_front_page() || is_shop() ) {
|
18 |
if ( ( $gtm4wp_options[ GTM4WP_OPTION_INTEGRATE_WCREMARKETING ] ) || ( true === $gtm4wp_options[ GTM4WP_OPTION_INTEGRATE_WCTRACKENHANCEDEC ] ) ) {
|
19 |
if ( count( $woocommerce->query->filtered_product_ids ) > 0 ) {
|
20 |
-
// The following 5 lines
|
21 |
$paged = max( 1, $wp_query->get( 'paged' ) );
|
22 |
$per_page = $wp_query->get( 'posts_per_page' );
|
23 |
$total = $wp_query->found_posts;
|
@@ -47,9 +51,23 @@ function gtm4wp_woocommerce_datalayer_filter_items( $dataLayer ) {
|
|
47 |
$product_cat = "";
|
48 |
}
|
49 |
$sumprice += $product_price;
|
50 |
-
$product_ids[] = "'" . $oneproductid . "'";
|
51 |
|
52 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
|
54 |
$i++;
|
55 |
if ( $i>$last ) {
|
@@ -58,13 +76,13 @@ function gtm4wp_woocommerce_datalayer_filter_items( $dataLayer ) {
|
|
58 |
}
|
59 |
|
60 |
if ( $gtm4wp_options[ GTM4WP_OPTION_INTEGRATE_WCREMARKETING ] ) {
|
61 |
-
$dataLayer["ecomm_prodid"] =
|
62 |
$dataLayer["ecomm_pagetype"] = ( is_front_page() ? "home" : "category" );
|
63 |
-
$dataLayer["ecomm_totalvalue"] = $sumprice;
|
64 |
}
|
65 |
|
66 |
if ( true === $gtm4wp_options[ GTM4WP_OPTION_INTEGRATE_WCTRACKENHANCEDEC ] ) {
|
67 |
-
$dataLayer["ecommerce"] = "
|
68 |
}
|
69 |
}
|
70 |
}
|
@@ -73,7 +91,7 @@ function gtm4wp_woocommerce_datalayer_filter_items( $dataLayer ) {
|
|
73 |
$prodid = get_the_ID();
|
74 |
$product = get_product( $prodid );
|
75 |
$product_price = $product->get_price();
|
76 |
-
$_product_cats = get_the_terms($product->id, 'product_cat');
|
77 |
if ( ( is_array($_product_cats) ) && ( count( $_product_cats ) > 0 ) ) {
|
78 |
$product_cat = array_pop( $_product_cats );
|
79 |
$product_cat = $product_cat->name;
|
@@ -82,13 +100,30 @@ function gtm4wp_woocommerce_datalayer_filter_items( $dataLayer ) {
|
|
82 |
}
|
83 |
|
84 |
if ( $gtm4wp_options[ GTM4WP_OPTION_INTEGRATE_WCREMARKETING ] ) {
|
85 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
86 |
$dataLayer["ecomm_pagetype"] = "product";
|
87 |
-
$dataLayer["ecomm_totalvalue"] = $product_price;
|
88 |
}
|
89 |
|
90 |
if ( true === $gtm4wp_options[ GTM4WP_OPTION_INTEGRATE_WCTRACKENHANCEDEC ] ) {
|
91 |
-
$dataLayer["ecommerce"] =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
92 |
}
|
93 |
}
|
94 |
} else if ( is_cart() ) {
|
@@ -121,12 +156,20 @@ function gtm4wp_woocommerce_datalayer_filter_items( $dataLayer ) {
|
|
121 |
$products = $woocommerce->cart->get_cart();
|
122 |
$product_ids = array();
|
123 |
foreach( $products as $oneproduct ) {
|
124 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
125 |
}
|
126 |
|
127 |
-
$dataLayer["ecomm_prodid"] =
|
128 |
$dataLayer["ecomm_pagetype"] = "cart";
|
129 |
-
$dataLayer["ecomm_totalvalue"] = $woocommerce->cart->cart_contents_total;
|
130 |
}
|
131 |
} else if ( is_order_received_page() ) {
|
132 |
$order_id = apply_filters( 'woocommerce_thankyou_order_id', empty( $_GET['order'] ) ? ($GLOBALS["wp"]->query_vars["order-received"] ? $GLOBALS["wp"]->query_vars["order-received"] : 0) : absint( $_GET['order'] ) );
|
@@ -147,7 +190,7 @@ function gtm4wp_woocommerce_datalayer_filter_items( $dataLayer ) {
|
|
147 |
$dataLayer["transactionId"] = $order->get_order_number();
|
148 |
$dataLayer["transactionDate"] = date("c");
|
149 |
$dataLayer["transactionType"] = "sale";
|
150 |
-
$dataLayer["transactionAffiliation"] = get_bloginfo( 'name' );
|
151 |
$dataLayer["transactionTotal"] = $order->get_total();
|
152 |
$dataLayer["transactionShipping"] = $order->get_total_shipping();
|
153 |
$dataLayer["transactionTax"] = $order->get_total_tax();
|
@@ -158,7 +201,18 @@ function gtm4wp_woocommerce_datalayer_filter_items( $dataLayer ) {
|
|
158 |
}
|
159 |
|
160 |
if ( true === $gtm4wp_options[ GTM4WP_OPTION_INTEGRATE_WCTRACKENHANCEDEC ] ) {
|
161 |
-
$dataLayer["ecommerce"] =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
162 |
}
|
163 |
|
164 |
$_products = array();
|
@@ -190,11 +244,17 @@ function gtm4wp_woocommerce_datalayer_filter_items( $dataLayer ) {
|
|
190 |
$_category = implode( " / ", $out );
|
191 |
}
|
192 |
|
|
|
|
|
|
|
|
|
|
|
|
|
193 |
$_prodprice = $order->get_item_total( $item );
|
194 |
$_products[] = array(
|
195 |
"id" => $_product->id,
|
196 |
"name" => $item['name'],
|
197 |
-
"sku" => $
|
198 |
"category" => $_category,
|
199 |
"price" => $_prodprice,
|
200 |
"currency" => get_woocommerce_currency(),
|
@@ -202,7 +262,7 @@ function gtm4wp_woocommerce_datalayer_filter_items( $dataLayer ) {
|
|
202 |
);
|
203 |
|
204 |
$_sumprice += $_prodprice;
|
205 |
-
$_product_ids[] =
|
206 |
}
|
207 |
}
|
208 |
|
@@ -212,17 +272,17 @@ function gtm4wp_woocommerce_datalayer_filter_items( $dataLayer ) {
|
|
212 |
}
|
213 |
|
214 |
if ( true === $gtm4wp_options[ GTM4WP_OPTION_INTEGRATE_WCTRACKENHANCEDEC ] ) {
|
215 |
-
$dataLayer["ecommerce"]
|
216 |
$dataLayer["event"] = "gtm4wp.orderCompleted";
|
217 |
}
|
218 |
|
219 |
if ( $gtm4wp_options[ GTM4WP_OPTION_INTEGRATE_WCREMARKETING ] ) {
|
220 |
-
$dataLayer["ecomm_prodid"] =
|
221 |
$dataLayer["ecomm_pagetype"] = "purchase";
|
222 |
-
$dataLayer["ecomm_totalvalue"] = $_sumprice;
|
223 |
}
|
224 |
|
225 |
-
|
226 |
}
|
227 |
} else if ( is_checkout() ) {
|
228 |
if ( true === $gtm4wp_options[ GTM4WP_OPTION_INTEGRATE_WCTRACKENHANCEDEC ] ) {
|
@@ -236,10 +296,23 @@ function gtm4wp_woocommerce_datalayer_filter_items( $dataLayer ) {
|
|
236 |
$product_cat = "";
|
237 |
}
|
238 |
|
239 |
-
$gtm4wp_checkout_products[] =
|
|
|
|
|
|
|
|
|
|
|
|
|
240 |
}
|
241 |
|
242 |
-
$dataLayer["ecommerce"] =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
243 |
}
|
244 |
} else {
|
245 |
if ( $gtm4wp_options[ GTM4WP_OPTION_INTEGRATE_WCREMARKETING ] ) {
|
11 |
}
|
12 |
}
|
13 |
|
14 |
+
function gtm4wp_woocommerce_html_entity_decode( $val ) {
|
15 |
+
return html_entity_decode( $val, ENT_QUOTES, "utf-8" );
|
16 |
+
}
|
17 |
+
|
18 |
function gtm4wp_woocommerce_datalayer_filter_items( $dataLayer ) {
|
19 |
global $woocommerce, $gtm4wp_options, $wp_query, $gtm4wp_datalayer_name, $gtm4wp_product_counter;
|
20 |
|
21 |
if ( is_product_category() || is_product_tag() || is_front_page() || is_shop() ) {
|
22 |
if ( ( $gtm4wp_options[ GTM4WP_OPTION_INTEGRATE_WCREMARKETING ] ) || ( true === $gtm4wp_options[ GTM4WP_OPTION_INTEGRATE_WCTRACKENHANCEDEC ] ) ) {
|
23 |
if ( count( $woocommerce->query->filtered_product_ids ) > 0 ) {
|
24 |
+
// The following 5 lines was being borrowed from WC source
|
25 |
$paged = max( 1, $wp_query->get( 'paged' ) );
|
26 |
$per_page = $wp_query->get( 'posts_per_page' );
|
27 |
$total = $wp_query->found_posts;
|
51 |
$product_cat = "";
|
52 |
}
|
53 |
$sumprice += $product_price;
|
|
|
54 |
|
55 |
+
$remarketing_id = $oneproductid;
|
56 |
+
if ( $gtm4wp_options[ GTM4WP_OPTION_INTEGRATE_WCREMARKETINGSKU ] ) {
|
57 |
+
$product_sku = $product->get_sku();
|
58 |
+
if ( "" != $product_sku ) {
|
59 |
+
$remarketing_id = $product_sku;
|
60 |
+
}
|
61 |
+
}
|
62 |
+
$product_ids[] = $remarketing_id;
|
63 |
+
|
64 |
+
$product_impressions[] = array(
|
65 |
+
'name' => $product->get_title(),
|
66 |
+
'id' => $oneproductid,
|
67 |
+
'price' => $product_price,
|
68 |
+
'category' => $product_cat,
|
69 |
+
'position' => ($i+1)
|
70 |
+
);
|
71 |
|
72 |
$i++;
|
73 |
if ( $i>$last ) {
|
76 |
}
|
77 |
|
78 |
if ( $gtm4wp_options[ GTM4WP_OPTION_INTEGRATE_WCREMARKETING ] ) {
|
79 |
+
$dataLayer["ecomm_prodid"] = $product_ids;
|
80 |
$dataLayer["ecomm_pagetype"] = ( is_front_page() ? "home" : "category" );
|
81 |
+
$dataLayer["ecomm_totalvalue"] = (float)$sumprice;
|
82 |
}
|
83 |
|
84 |
if ( true === $gtm4wp_options[ GTM4WP_OPTION_INTEGRATE_WCTRACKENHANCEDEC ] ) {
|
85 |
+
$dataLayer["ecommerce"] = array("impressions" => $product_impressions);
|
86 |
}
|
87 |
}
|
88 |
}
|
91 |
$prodid = get_the_ID();
|
92 |
$product = get_product( $prodid );
|
93 |
$product_price = $product->get_price();
|
94 |
+
$_product_cats = get_the_terms( $product->id, 'product_cat' );
|
95 |
if ( ( is_array($_product_cats) ) && ( count( $_product_cats ) > 0 ) ) {
|
96 |
$product_cat = array_pop( $_product_cats );
|
97 |
$product_cat = $product_cat->name;
|
100 |
}
|
101 |
|
102 |
if ( $gtm4wp_options[ GTM4WP_OPTION_INTEGRATE_WCREMARKETING ] ) {
|
103 |
+
$remarketing_id = (string)$prodid;
|
104 |
+
if ( $gtm4wp_options[ GTM4WP_OPTION_INTEGRATE_WCREMARKETINGSKU ] ) {
|
105 |
+
$product_sku = $product->get_sku();
|
106 |
+
if ( "" != $product_sku ) {
|
107 |
+
$remarketing_id = $product_sku;
|
108 |
+
}
|
109 |
+
}
|
110 |
+
|
111 |
+
$dataLayer["ecomm_prodid"] = $remarketing_id;
|
112 |
$dataLayer["ecomm_pagetype"] = "product";
|
113 |
+
$dataLayer["ecomm_totalvalue"] = (float)$product_price;
|
114 |
}
|
115 |
|
116 |
if ( true === $gtm4wp_options[ GTM4WP_OPTION_INTEGRATE_WCTRACKENHANCEDEC ] ) {
|
117 |
+
$dataLayer["ecommerce"] = array(
|
118 |
+
"detail" => array(
|
119 |
+
"products" => array(array(
|
120 |
+
"name" => gtm4wp_woocommerce_html_entity_decode( get_the_title() ),
|
121 |
+
"id" => $prodid,
|
122 |
+
"price" => $product_price,
|
123 |
+
"category" => $product_cat,
|
124 |
+
))
|
125 |
+
)
|
126 |
+
);
|
127 |
}
|
128 |
}
|
129 |
} else if ( is_cart() ) {
|
156 |
$products = $woocommerce->cart->get_cart();
|
157 |
$product_ids = array();
|
158 |
foreach( $products as $oneproduct ) {
|
159 |
+
$remarketing_id = $oneproduct['product_id'];
|
160 |
+
if ( $gtm4wp_options[ GTM4WP_OPTION_INTEGRATE_WCREMARKETINGSKU ] ) {
|
161 |
+
$product_sku = $oneproduct['product_sku'];
|
162 |
+
if ( "" != $product_sku ) {
|
163 |
+
$remarketing_id = $product_sku;
|
164 |
+
}
|
165 |
+
}
|
166 |
+
|
167 |
+
$product_ids[] = $remarketing_id;
|
168 |
}
|
169 |
|
170 |
+
$dataLayer["ecomm_prodid"] = $product_ids;
|
171 |
$dataLayer["ecomm_pagetype"] = "cart";
|
172 |
+
$dataLayer["ecomm_totalvalue"] = (float)$woocommerce->cart->cart_contents_total;
|
173 |
}
|
174 |
} else if ( is_order_received_page() ) {
|
175 |
$order_id = apply_filters( 'woocommerce_thankyou_order_id', empty( $_GET['order'] ) ? ($GLOBALS["wp"]->query_vars["order-received"] ? $GLOBALS["wp"]->query_vars["order-received"] : 0) : absint( $_GET['order'] ) );
|
190 |
$dataLayer["transactionId"] = $order->get_order_number();
|
191 |
$dataLayer["transactionDate"] = date("c");
|
192 |
$dataLayer["transactionType"] = "sale";
|
193 |
+
$dataLayer["transactionAffiliation"] = gtm4wp_woocommerce_html_entity_decode( get_bloginfo( 'name' ) );
|
194 |
$dataLayer["transactionTotal"] = $order->get_total();
|
195 |
$dataLayer["transactionShipping"] = $order->get_total_shipping();
|
196 |
$dataLayer["transactionTax"] = $order->get_total_tax();
|
201 |
}
|
202 |
|
203 |
if ( true === $gtm4wp_options[ GTM4WP_OPTION_INTEGRATE_WCTRACKENHANCEDEC ] ) {
|
204 |
+
$dataLayer["ecommerce"] = array(
|
205 |
+
"purchase" => array(
|
206 |
+
"actionField" => array(
|
207 |
+
"id" => $order->get_order_number(),
|
208 |
+
"affiliation" => gtm4wp_woocommerce_html_entity_decode( get_bloginfo( 'name' ) ),
|
209 |
+
"revenue" => $order->get_total(),
|
210 |
+
"tax" => $order->get_total_tax(),
|
211 |
+
"shipping" => $order->get_total_shipping(),
|
212 |
+
"coupon" => implode( ", ", $order->get_used_coupons() )
|
213 |
+
)
|
214 |
+
)
|
215 |
+
);
|
216 |
}
|
217 |
|
218 |
$_products = array();
|
244 |
$_category = implode( " / ", $out );
|
245 |
}
|
246 |
|
247 |
+
$remarketing_id = $_product->id;
|
248 |
+
$product_sku = $_product->get_sku();
|
249 |
+
if ( $gtm4wp_options[ GTM4WP_OPTION_INTEGRATE_WCREMARKETINGSKU ] && ( "" != $product_sku ) ) {
|
250 |
+
$remarketing_id = $product_sku;
|
251 |
+
}
|
252 |
+
|
253 |
$_prodprice = $order->get_item_total( $item );
|
254 |
$_products[] = array(
|
255 |
"id" => $_product->id,
|
256 |
"name" => $item['name'],
|
257 |
+
"sku" => $product_sku ? __( 'SKU:', GTM4WP_TEXTDOMAIN ) . ' ' . $product_sku : $_product->id,
|
258 |
"category" => $_category,
|
259 |
"price" => $_prodprice,
|
260 |
"currency" => get_woocommerce_currency(),
|
262 |
);
|
263 |
|
264 |
$_sumprice += $_prodprice;
|
265 |
+
$_product_ids[] = $remarketing_id;
|
266 |
}
|
267 |
}
|
268 |
|
272 |
}
|
273 |
|
274 |
if ( true === $gtm4wp_options[ GTM4WP_OPTION_INTEGRATE_WCTRACKENHANCEDEC ] ) {
|
275 |
+
$dataLayer["ecommerce"]["purchase"]["products"] = $_products;
|
276 |
$dataLayer["event"] = "gtm4wp.orderCompleted";
|
277 |
}
|
278 |
|
279 |
if ( $gtm4wp_options[ GTM4WP_OPTION_INTEGRATE_WCREMARKETING ] ) {
|
280 |
+
$dataLayer["ecomm_prodid"] = $_product_ids;
|
281 |
$dataLayer["ecomm_pagetype"] = "purchase";
|
282 |
+
$dataLayer["ecomm_totalvalue"] = (float)$_sumprice;
|
283 |
}
|
284 |
|
285 |
+
update_post_meta( $order_id, '_ga_tracked', 1 );
|
286 |
}
|
287 |
} else if ( is_checkout() ) {
|
288 |
if ( true === $gtm4wp_options[ GTM4WP_OPTION_INTEGRATE_WCTRACKENHANCEDEC ] ) {
|
296 |
$product_cat = "";
|
297 |
}
|
298 |
|
299 |
+
$gtm4wp_checkout_products[] = array(
|
300 |
+
"id" => $product->id,
|
301 |
+
"name" => $product->post->post_title,
|
302 |
+
"price" => $product->get_price(),
|
303 |
+
"category" => $product_cat,
|
304 |
+
"quantity" => $cart_item_data["quantity"]
|
305 |
+
);
|
306 |
}
|
307 |
|
308 |
+
$dataLayer["ecommerce"] = array(
|
309 |
+
"checkout" => array(
|
310 |
+
"actionField" => array(
|
311 |
+
"step" => 1
|
312 |
+
),
|
313 |
+
"products" => $gtm4wp_checkout_products
|
314 |
+
)
|
315 |
+
);
|
316 |
}
|
317 |
} else {
|
318 |
if ( $gtm4wp_options[ GTM4WP_OPTION_INTEGRATE_WCREMARKETING ] ) {
|
integration/youtube.php
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
function gtm4wp_youtube( $return, $url, $data ) {
|
3 |
+
if ( false !== strpos( $return, "youtube.com" ) ) {
|
4 |
+
return str_replace( "feature=oembed", "feature=oembed&enablejsapi=1&origin=" . site_url(), $return );
|
5 |
+
} else {
|
6 |
+
return $return;
|
7 |
+
}
|
8 |
+
}
|
9 |
+
|
10 |
+
add_filter( "oembed_result", "gtm4wp_youtube", 10, 3 );
|
11 |
+
|
12 |
+
if ( ! is_admin() ) {
|
13 |
+
wp_enqueue_script( "gtm4wp-youtube", $gtp4wp_plugin_url . "js/gtm4wp-youtube.js", array( "jquery" ), "1.0", false );
|
14 |
+
}
|
js/admin-subtabs.js
CHANGED
@@ -27,7 +27,20 @@ var adminsubtabs = {
|
|
27 |
numitems: 2
|
28 |
}
|
29 |
},
|
30 |
-
2: {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
3: {},
|
32 |
4: {
|
33 |
"blocktags": {
|
27 |
numitems: 2
|
28 |
}
|
29 |
},
|
30 |
+
2: {
|
31 |
+
"generalevents": {
|
32 |
+
tabtext: gtm4wp.generaleventstabtitle,
|
33 |
+
numitems: 2
|
34 |
+
},
|
35 |
+
"mediaevents": {
|
36 |
+
tabtext: gtm4wp.mediaeventstabtitle,
|
37 |
+
numitems: 3
|
38 |
+
},
|
39 |
+
"depecratedevents": {
|
40 |
+
tabtext: gtm4wp.depecratedeventstabtitle,
|
41 |
+
numitems: 8
|
42 |
+
}
|
43 |
+
},
|
44 |
3: {},
|
45 |
4: {
|
46 |
"blocktags": {
|
js/admin-tabcreator.js
CHANGED
@@ -64,11 +64,11 @@
|
|
64 |
jQuery( '#wpbody form .tabinfo:eq(' + tabindex + '),#wpbody form .form-table:eq(' + tabindex + ')' )
|
65 |
.show();
|
66 |
|
67 |
-
jQuery( '#
|
68 |
.find( 'a:first' )
|
69 |
.trigger( 'click' );
|
70 |
|
71 |
-
jQuery( '#
|
72 |
.addClass( 'subtab-activated' )
|
73 |
.show();
|
74 |
|
64 |
jQuery( '#wpbody form .tabinfo:eq(' + tabindex + '),#wpbody form .form-table:eq(' + tabindex + ')' )
|
65 |
.show();
|
66 |
|
67 |
+
jQuery( '#adminsubtabs' + tabindex + ':not(.subtab-activated)' )
|
68 |
.find( 'a:first' )
|
69 |
.trigger( 'click' );
|
70 |
|
71 |
+
jQuery( '#adminsubtabs' + tabindex )
|
72 |
.addClass( 'subtab-activated' )
|
73 |
.show();
|
74 |
|
js/froogaloop.js
ADDED
@@ -0,0 +1,259 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// Init style shamelessly stolen from jQuery http://jquery.com
|
2 |
+
var Froogaloop = (function() {
|
3 |
+
// Define a local copy of Froogaloop
|
4 |
+
function Froogaloop(iframe) {
|
5 |
+
// The Froogaloop object is actually just the init constructor
|
6 |
+
return new Froogaloop.fn.init(iframe);
|
7 |
+
}
|
8 |
+
|
9 |
+
var eventCallbacks = {},
|
10 |
+
hasWindowEvent = false,
|
11 |
+
isReady = false,
|
12 |
+
slice = Array.prototype.slice,
|
13 |
+
playerOrigin = '*';
|
14 |
+
|
15 |
+
Froogaloop.fn = Froogaloop.prototype = {
|
16 |
+
element: null,
|
17 |
+
|
18 |
+
init: function(iframe) {
|
19 |
+
if (typeof iframe === "string") {
|
20 |
+
iframe = document.getElementById(iframe);
|
21 |
+
}
|
22 |
+
|
23 |
+
this.element = iframe;
|
24 |
+
|
25 |
+
return this;
|
26 |
+
},
|
27 |
+
|
28 |
+
/*
|
29 |
+
* Calls a function to act upon the player.
|
30 |
+
*
|
31 |
+
* @param {string} method The name of the Javascript API method to call. Eg: 'play'.
|
32 |
+
* @param {Array|Function} valueOrCallback params Array of parameters to pass when calling an API method
|
33 |
+
* or callback function when the method returns a value.
|
34 |
+
*/
|
35 |
+
api: function(method, valueOrCallback) {
|
36 |
+
if (!this.element || !method) {
|
37 |
+
return false;
|
38 |
+
}
|
39 |
+
|
40 |
+
var self = this,
|
41 |
+
element = self.element,
|
42 |
+
target_id = element.id !== '' ? element.id : null,
|
43 |
+
params = !isFunction(valueOrCallback) ? valueOrCallback : null,
|
44 |
+
callback = isFunction(valueOrCallback) ? valueOrCallback : null;
|
45 |
+
|
46 |
+
// Store the callback for get functions
|
47 |
+
if (callback) {
|
48 |
+
storeCallback(method, callback, target_id);
|
49 |
+
}
|
50 |
+
|
51 |
+
postMessage(method, params, element);
|
52 |
+
return self;
|
53 |
+
},
|
54 |
+
|
55 |
+
/*
|
56 |
+
* Registers an event listener and a callback function that gets called when the event fires.
|
57 |
+
*
|
58 |
+
* @param eventName (String): Name of the event to listen for.
|
59 |
+
* @param callback (Function): Function that should be called when the event fires.
|
60 |
+
*/
|
61 |
+
addEvent: function(eventName, callback) {
|
62 |
+
if (!this.element) {
|
63 |
+
return false;
|
64 |
+
}
|
65 |
+
|
66 |
+
var self = this,
|
67 |
+
element = self.element,
|
68 |
+
target_id = element.id !== '' ? element.id : null;
|
69 |
+
|
70 |
+
|
71 |
+
storeCallback(eventName, callback, target_id);
|
72 |
+
|
73 |
+
// The ready event is not registered via postMessage. It fires regardless.
|
74 |
+
if (eventName != 'ready') {
|
75 |
+
postMessage('addEventListener', eventName, element);
|
76 |
+
} else if (eventName == 'ready' && isReady) {
|
77 |
+
callback.call(null, target_id);
|
78 |
+
}
|
79 |
+
|
80 |
+
return self;
|
81 |
+
},
|
82 |
+
|
83 |
+
/*
|
84 |
+
* Unregisters an event listener that gets called when the event fires.
|
85 |
+
*
|
86 |
+
* @param eventName (String): Name of the event to stop listening for.
|
87 |
+
*/
|
88 |
+
removeEvent: function(eventName) {
|
89 |
+
if (!this.element) {
|
90 |
+
return false;
|
91 |
+
}
|
92 |
+
|
93 |
+
var self = this,
|
94 |
+
element = self.element,
|
95 |
+
target_id = element.id !== '' ? element.id : null,
|
96 |
+
removed = removeCallback(eventName, target_id);
|
97 |
+
|
98 |
+
// The ready event is not registered
|
99 |
+
if (eventName != 'ready' && removed) {
|
100 |
+
postMessage('removeEventListener', eventName, element);
|
101 |
+
}
|
102 |
+
}
|
103 |
+
};
|
104 |
+
|
105 |
+
/**
|
106 |
+
* Handles posting a message to the parent window.
|
107 |
+
*
|
108 |
+
* @param method (String): name of the method to call inside the player. For api calls
|
109 |
+
* this is the name of the api method (api_play or api_pause) while for events this method
|
110 |
+
* is api_addEventListener.
|
111 |
+
* @param params (Object or Array): List of parameters to submit to the method. Can be either
|
112 |
+
* a single param or an array list of parameters.
|
113 |
+
* @param target (HTMLElement): Target iframe to post the message to.
|
114 |
+
*/
|
115 |
+
|
116 |
+
function postMessage(method, params, target) {
|
117 |
+
if (!target.contentWindow.postMessage) {
|
118 |
+
return false;
|
119 |
+
}
|
120 |
+
|
121 |
+
var data = JSON.stringify({
|
122 |
+
method: method,
|
123 |
+
value: params
|
124 |
+
});
|
125 |
+
|
126 |
+
target.contentWindow.postMessage(data, playerOrigin);
|
127 |
+
}
|
128 |
+
|
129 |
+
/**
|
130 |
+
* Event that fires whenever the window receives a message from its parent
|
131 |
+
* via window.postMessage.
|
132 |
+
*/
|
133 |
+
|
134 |
+
function onMessageReceived(event) {
|
135 |
+
var data, method;
|
136 |
+
|
137 |
+
try {
|
138 |
+
data = JSON.parse(event.data);
|
139 |
+
method = data.event || data.method;
|
140 |
+
} catch (e) {
|
141 |
+
//fail silently... like a ninja!
|
142 |
+
}
|
143 |
+
|
144 |
+
if (method == 'ready' && !isReady) {
|
145 |
+
isReady = true;
|
146 |
+
}
|
147 |
+
|
148 |
+
// Handles messages from the vimeo player only
|
149 |
+
if (!(/^https?:\/\/player.vimeo.com/).test(event.origin)) {
|
150 |
+
return false;
|
151 |
+
}
|
152 |
+
|
153 |
+
if (playerOrigin === '*') {
|
154 |
+
playerOrigin = event.origin;
|
155 |
+
}
|
156 |
+
|
157 |
+
var value = data.value,
|
158 |
+
eventData = data.data,
|
159 |
+
target_id = target_id === '' ? null : data.player_id,
|
160 |
+
|
161 |
+
callback = getCallback(method, target_id),
|
162 |
+
params = [];
|
163 |
+
|
164 |
+
if (!callback) {
|
165 |
+
return false;
|
166 |
+
}
|
167 |
+
|
168 |
+
if (value !== undefined) {
|
169 |
+
params.push(value);
|
170 |
+
}
|
171 |
+
|
172 |
+
if (eventData) {
|
173 |
+
params.push(eventData);
|
174 |
+
}
|
175 |
+
|
176 |
+
if (target_id) {
|
177 |
+
params.push(target_id);
|
178 |
+
}
|
179 |
+
|
180 |
+
return params.length > 0 ? callback.apply(null, params) : callback.call();
|
181 |
+
}
|
182 |
+
|
183 |
+
|
184 |
+
/**
|
185 |
+
* Stores submitted callbacks for each iframe being tracked and each
|
186 |
+
* event for that iframe.
|
187 |
+
*
|
188 |
+
* @param eventName (String): Name of the event. Eg. api_onPlay
|
189 |
+
* @param callback (Function): Function that should get executed when the
|
190 |
+
* event is fired.
|
191 |
+
* @param target_id (String) [Optional]: If handling more than one iframe then
|
192 |
+
* it stores the different callbacks for different iframes based on the iframe's
|
193 |
+
* id.
|
194 |
+
*/
|
195 |
+
|
196 |
+
function storeCallback(eventName, callback, target_id) {
|
197 |
+
if (target_id) {
|
198 |
+
if (!eventCallbacks[target_id]) {
|
199 |
+
eventCallbacks[target_id] = {};
|
200 |
+
}
|
201 |
+
eventCallbacks[target_id][eventName] = callback;
|
202 |
+
} else {
|
203 |
+
eventCallbacks[eventName] = callback;
|
204 |
+
}
|
205 |
+
}
|
206 |
+
|
207 |
+
/**
|
208 |
+
* Retrieves stored callbacks.
|
209 |
+
*/
|
210 |
+
|
211 |
+
function getCallback(eventName, target_id) {
|
212 |
+
if (target_id) {
|
213 |
+
return eventCallbacks[target_id][eventName];
|
214 |
+
} else {
|
215 |
+
return eventCallbacks[eventName];
|
216 |
+
}
|
217 |
+
}
|
218 |
+
|
219 |
+
function removeCallback(eventName, target_id) {
|
220 |
+
if (target_id && eventCallbacks[target_id]) {
|
221 |
+
if (!eventCallbacks[target_id][eventName]) {
|
222 |
+
return false;
|
223 |
+
}
|
224 |
+
eventCallbacks[target_id][eventName] = null;
|
225 |
+
} else {
|
226 |
+
if (!eventCallbacks[eventName]) {
|
227 |
+
return false;
|
228 |
+
}
|
229 |
+
eventCallbacks[eventName] = null;
|
230 |
+
}
|
231 |
+
|
232 |
+
return true;
|
233 |
+
}
|
234 |
+
|
235 |
+
function isFunction(obj) {
|
236 |
+
return !!(obj && obj.constructor && obj.call && obj.apply);
|
237 |
+
}
|
238 |
+
|
239 |
+
function isArray(obj) {
|
240 |
+
return toString.call(obj) === '[object Array]';
|
241 |
+
}
|
242 |
+
|
243 |
+
// Give the init function the Froogaloop prototype for later instantiation
|
244 |
+
Froogaloop.fn.init.prototype = Froogaloop.fn;
|
245 |
+
|
246 |
+
// Listens for the message event.
|
247 |
+
// W3C
|
248 |
+
if (window.addEventListener) {
|
249 |
+
window.addEventListener('message', onMessageReceived, false);
|
250 |
+
}
|
251 |
+
// IE
|
252 |
+
else {
|
253 |
+
window.attachEvent('onmessage', onMessageReceived);
|
254 |
+
}
|
255 |
+
|
256 |
+
// Expose froogaloop to the global object
|
257 |
+
return (window.Froogaloop = window.$f = Froogaloop);
|
258 |
+
|
259 |
+
})();
|
js/gtm4wp-soundcloud.js
ADDED
@@ -0,0 +1,137 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
;
|
2 |
+
var gtm4wp_soundclound_percentage_tracking = 10;
|
3 |
+
var gtm4wp_soundclound_percentage_tracking_marks = {};
|
4 |
+
|
5 |
+
jQuery(function() {
|
6 |
+
jQuery( '[id^="soundcloudplayer_"]' ).each(function() {
|
7 |
+
var iframe = this,
|
8 |
+
widget = SC.Widget( this ),
|
9 |
+
jqframe = jQuery( iframe ),
|
10 |
+
sound = {};
|
11 |
+
|
12 |
+
widget.bind( SC.Widget.Events.READY, function() {
|
13 |
+
widget.getCurrentSound(function( soundData ) {
|
14 |
+
|
15 |
+
jqframe.attr( "data-player_id", soundData.id );
|
16 |
+
jqframe.attr( "data-player_author", soundData.user.username );
|
17 |
+
jqframe.attr( "data-player_title", soundData.title );
|
18 |
+
jqframe.attr( "data-player_url", soundData.permalink_url );
|
19 |
+
jqframe.attr( "data-player_duration", soundData.duration );
|
20 |
+
|
21 |
+
sound = soundData;
|
22 |
+
|
23 |
+
window[ gtm4wp_datalayer_name ].push({
|
24 |
+
'event': 'gtm4wp.mediaPlayerReady',
|
25 |
+
'mediaType': 'soundcloud',
|
26 |
+
'mediaData': {
|
27 |
+
'id': soundData.id,
|
28 |
+
'author': soundData.user.username,
|
29 |
+
'title': soundData.title,
|
30 |
+
'url': soundData.permalink_url,
|
31 |
+
'duration': soundData.duration
|
32 |
+
},
|
33 |
+
'mediaCurrentTime': 0
|
34 |
+
});
|
35 |
+
}); // end of api call getDuration
|
36 |
+
|
37 |
+
widget.bind( SC.Widget.Events.PLAY_PROGRESS, function( eventData ) {
|
38 |
+
gtm4wp_onSoundCloudPercentageChange( eventData );
|
39 |
+
});
|
40 |
+
|
41 |
+
widget.bind( SC.Widget.Events.PLAY, function( eventData ) {
|
42 |
+
gtm4wp_onSoundCloudPlayerStateChange( eventData, 'play' );
|
43 |
+
});
|
44 |
+
|
45 |
+
widget.bind( SC.Widget.Events.PAUSE, function( eventData ) {
|
46 |
+
gtm4wp_onSoundCloudPlayerStateChange( eventData, 'pause' );
|
47 |
+
});
|
48 |
+
|
49 |
+
widget.bind( SC.Widget.Events.FINISH, function( eventData ) {
|
50 |
+
gtm4wp_onSoundCloudPlayerStateChange( eventData, 'finish' );
|
51 |
+
});
|
52 |
+
|
53 |
+
widget.bind( SC.Widget.Events.SEEK, function( eventData ) {
|
54 |
+
gtm4wp_onSoundCloudPlayerStateChange( eventData, 'seek' );
|
55 |
+
});
|
56 |
+
|
57 |
+
widget.bind( SC.Widget.Events.CLICK_DOWNLOAD, function() {
|
58 |
+
gtm4wp_onSoundCloudPlayerEvent( 'click-download' );
|
59 |
+
});
|
60 |
+
|
61 |
+
widget.bind( SC.Widget.Events.CLICK_BUY, function() {
|
62 |
+
gtm4wp_onSoundCloudPlayerEvent( 'click-buy' );
|
63 |
+
});
|
64 |
+
|
65 |
+
widget.bind( SC.Widget.Events.OPEN_SHARE_PANEL, function() {
|
66 |
+
gtm4wp_onSoundCloudPlayerEvent( 'open-share-panel' );
|
67 |
+
});
|
68 |
+
|
69 |
+
widget.bind( SC.Widget.Events.ERROR, function() {
|
70 |
+
gtm4wp_onSoundCloudPlayerEvent( 'error' );
|
71 |
+
});
|
72 |
+
});
|
73 |
+
|
74 |
+
var gtm4wp_onSoundCloudPlayerStateChange = function( eventData, playerState ) {
|
75 |
+
window[ gtm4wp_datalayer_name ].push({
|
76 |
+
'event': 'gtm4wp.mediaPlayerStateChange',
|
77 |
+
'mediaType': 'soundcloud',
|
78 |
+
'mediaData': {
|
79 |
+
'id': sound.id,
|
80 |
+
'author': sound.user.username,
|
81 |
+
'title': sound.title,
|
82 |
+
'url': sound.permalink_url,
|
83 |
+
'duration': sound.duration
|
84 |
+
},
|
85 |
+
'mediaCurrentTime': eventData.currentPosition,
|
86 |
+
'mediaPlayerState': playerState
|
87 |
+
});
|
88 |
+
}
|
89 |
+
|
90 |
+
var gtm4wp_onSoundCloudPercentageChange = function( eventData ) {
|
91 |
+
var mediaPercentage = Math.floor( eventData.currentPosition / sound.duration * 100 );
|
92 |
+
|
93 |
+
if ( typeof gtm4wp_soundclound_percentage_tracking_marks[ sound.id ] == "undefined" ) {
|
94 |
+
gtm4wp_soundclound_percentage_tracking_marks[ sound.id ] = [];
|
95 |
+
}
|
96 |
+
|
97 |
+
for( var i=0; i<100; i+=gtm4wp_soundclound_percentage_tracking ) {
|
98 |
+
if ( ( mediaPercentage > i ) && ( gtm4wp_soundclound_percentage_tracking_marks[ sound.id ].indexOf( i ) == -1 ) ) {
|
99 |
+
gtm4wp_soundclound_percentage_tracking_marks[ sound.id ].push( i );
|
100 |
+
|
101 |
+
window[ gtm4wp_datalayer_name ].push({
|
102 |
+
'event': 'gtm4wp.mediaPlaybackPercentage',
|
103 |
+
'mediaType': 'soundcloud',
|
104 |
+
'mediaData': {
|
105 |
+
'id': sound.id,
|
106 |
+
'author': sound.user.username,
|
107 |
+
'title': sound.title,
|
108 |
+
'url': sound.permalink_url,
|
109 |
+
'duration': sound.duration
|
110 |
+
},
|
111 |
+
'mediaCurrentTime': eventData.currentPosition,
|
112 |
+
'mediaPercentage': i
|
113 |
+
});
|
114 |
+
}
|
115 |
+
}
|
116 |
+
}
|
117 |
+
|
118 |
+
var gtm4wp_onSoundCloudPlayerEvent = function( eventName ) {
|
119 |
+
widget.getPosition(function( currentPosition ) {
|
120 |
+
window[ gtm4wp_datalayer_name ].push({
|
121 |
+
'event': 'gtm4wp.mediaPlayerEvent',
|
122 |
+
'mediaType': 'soundcloud',
|
123 |
+
'mediaData': {
|
124 |
+
'id': sound.id,
|
125 |
+
'author': sound.user.username,
|
126 |
+
'title': sound.title,
|
127 |
+
'url': sound.permalink_url,
|
128 |
+
'duration': soundData.duration
|
129 |
+
},
|
130 |
+
'mediaCurrentTime': currentPosition,
|
131 |
+
'mediaPlayerEvent': eventName
|
132 |
+
});
|
133 |
+
});
|
134 |
+
}
|
135 |
+
|
136 |
+
});
|
137 |
+
});
|
js/gtm4wp-vimeo.js
ADDED
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
var gtm4wp_vimeo_percentage_tracking = 10;
|
2 |
+
var gtm4wp_vimeo_percentage_tracking_marks = {};
|
3 |
+
|
4 |
+
;jQuery(function() {
|
5 |
+
jQuery( '[id^="vimeoplayer_"]' ).each(function() {
|
6 |
+
var vimeoapi = $f( this ),
|
7 |
+
jqframe = jQuery( this ),
|
8 |
+
videourl = jqframe
|
9 |
+
.attr( "src" )
|
10 |
+
.split( "?" )
|
11 |
+
.shift(),
|
12 |
+
videoid = videourl.split( "/" ).pop();
|
13 |
+
|
14 |
+
jqframe.attr( "data-player_id", videoid );
|
15 |
+
jqframe.attr( "data-player_url", videourl );
|
16 |
+
|
17 |
+
vimeoapi.addEvent( 'ready', function( player_id ) {
|
18 |
+
vimeoapi.api( 'getDuration', function( value, player_id ) {
|
19 |
+
|
20 |
+
jqframe.attr( "data-player_duration", value );
|
21 |
+
|
22 |
+
window[ gtm4wp_datalayer_name ].push({
|
23 |
+
'event': 'gtm4wp.mediaPlayerReady',
|
24 |
+
'mediaType': 'vimeo',
|
25 |
+
'mediaData': {
|
26 |
+
'id': videoid,
|
27 |
+
'author': '',
|
28 |
+
'title': jqframe.attr( "title" ),
|
29 |
+
'url': videourl,
|
30 |
+
'duration': value
|
31 |
+
},
|
32 |
+
'mediaCurrentTime': 0
|
33 |
+
});
|
34 |
+
}); // end of api call getDuration
|
35 |
+
|
36 |
+
vimeoapi.addEvent( 'playProgress', function( value, player_id ) {
|
37 |
+
gtm4wp_onVimeoPercentageChange( value );
|
38 |
+
});
|
39 |
+
|
40 |
+
vimeoapi.addEvent( 'play', function( player_id ) {
|
41 |
+
gtm4wp_onVimeoPlayerStateChange( 'play' );
|
42 |
+
});
|
43 |
+
|
44 |
+
vimeoapi.addEvent( 'pause', function( player_id ) {
|
45 |
+
gtm4wp_onVimeoPlayerStateChange( 'pause' );
|
46 |
+
});
|
47 |
+
|
48 |
+
vimeoapi.addEvent( 'finish', function( player_id ) {
|
49 |
+
gtm4wp_onVimeoPlayerStateChange( 'finish' );
|
50 |
+
});
|
51 |
+
|
52 |
+
vimeoapi.addEvent( 'seek', function( value, player_id ) {
|
53 |
+
gtm4wp_onVimeoPlayerStateChange( 'seek' );
|
54 |
+
});
|
55 |
+
|
56 |
+
var gtm4wp_onVimeoPlayerStateChange = function( player_state ) {
|
57 |
+
vimeoapi.api( 'getCurrentTime', function( value, player_id ) {
|
58 |
+
window[ gtm4wp_datalayer_name ].push({
|
59 |
+
'event': 'gtm4wp.mediaPlayerStateChange',
|
60 |
+
'mediaType': 'vimeo',
|
61 |
+
'mediaData': {
|
62 |
+
'id': videoid,
|
63 |
+
'author': '',
|
64 |
+
'title': jqframe.attr( "title" ),
|
65 |
+
'url': jqframe.attr( "data-player_url" ),
|
66 |
+
'duration': parseInt( jqframe.attr( "data-player_duration" ) )
|
67 |
+
},
|
68 |
+
'mediaPlayerState': player_state,
|
69 |
+
'mediaCurrentTime': value
|
70 |
+
});
|
71 |
+
});
|
72 |
+
}
|
73 |
+
|
74 |
+
var gtm4wp_onVimeoPercentageChange = function( data ) {
|
75 |
+
var videoDuration = parseInt( jqframe.attr( "data-player_duration" ) );
|
76 |
+
var videoPercentage = Math.floor( data.seconds / videoDuration * 100 );
|
77 |
+
|
78 |
+
if ( typeof gtm4wp_vimeo_percentage_tracking_marks[ videoid ] == "undefined" ) {
|
79 |
+
gtm4wp_vimeo_percentage_tracking_marks[ videoid ] = [];
|
80 |
+
}
|
81 |
+
|
82 |
+
for( var i=0; i<100; i+=gtm4wp_vimeo_percentage_tracking ) {
|
83 |
+
if ( ( videoPercentage > i ) && ( gtm4wp_vimeo_percentage_tracking_marks[ videoid ].indexOf( i ) == -1 ) ) {
|
84 |
+
gtm4wp_vimeo_percentage_tracking_marks[ videoid ].push( i );
|
85 |
+
|
86 |
+
window[ gtm4wp_datalayer_name ].push({
|
87 |
+
'event': 'gtm4wp.mediaPlaybackPercentage',
|
88 |
+
'mediaType': 'vimeo',
|
89 |
+
'mediaData': {
|
90 |
+
'id': videoid,
|
91 |
+
'author': '',
|
92 |
+
'title': jqframe.attr( "title" ),
|
93 |
+
'url': jqframe.attr( "data-player_url" ),
|
94 |
+
'duration': videoDuration
|
95 |
+
},
|
96 |
+
'mediaCurrentTime': data.seconds,
|
97 |
+
'mediaPercentage': i
|
98 |
+
});
|
99 |
+
}
|
100 |
+
}
|
101 |
+
}
|
102 |
+
|
103 |
+
});
|
104 |
+
});
|
105 |
+
});
|
js/gtm4wp-youtube.js
ADDED
@@ -0,0 +1,208 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
var gtm4wp_youtube_percentage_tracking = 10;
|
2 |
+
var gtm4wp_youtube_percentage_tracking_timeouts = {};
|
3 |
+
var gtm4wp_youtube_percentage_tracking_marks = {};
|
4 |
+
|
5 |
+
if ( typeof onYouTubeIframeAPIReady === "undefined" ) {
|
6 |
+
window.onYouTubeIframeAPIReady = function() {
|
7 |
+
window[ gtm4wp_datalayer_name ].push({
|
8 |
+
'event': 'gtm4wp.mediaApiReady',
|
9 |
+
'mediaType': 'youtube'
|
10 |
+
});
|
11 |
+
|
12 |
+
jQuery( "iframe[src^='https://www.youtube.com/embed']" ).each( function() {
|
13 |
+
var playerID = jQuery( this ).attr( "id" );
|
14 |
+
if ( ( playerID == undefined ) || ( playerID == "" ) ) {
|
15 |
+
var _gtm4wp_temp = jQuery( this ).attr( "src" ).split( "?" );
|
16 |
+
var _gtm4wp_temp2 = _gtm4wp_temp[ 0 ].split( "/" );
|
17 |
+
|
18 |
+
var playerID = "youtubeplayer_" + _gtm4wp_temp2[ _gtm4wp_temp2.length-1 ];
|
19 |
+
jQuery( this ).attr( "id", playerID );
|
20 |
+
}
|
21 |
+
|
22 |
+
player = new YT.Player( playerID, {
|
23 |
+
events: {
|
24 |
+
'onReady': gtm4wp_onYouTubePlayerReady,
|
25 |
+
'onStateChange': gtm4wp_onYouTubePlayerStateChange,
|
26 |
+
'onPlaybackQualityChange': gtm4wp_onYouTubePlaybackQualityChange,
|
27 |
+
'onPlaybackRateChange': gtm4wp_onYouTubePlaybackRateChange,
|
28 |
+
'onError': gtm4wp_onYouTubeError,
|
29 |
+
'onApiChange': gtm4wp_onYouTubeApiChange
|
30 |
+
}
|
31 |
+
});
|
32 |
+
});
|
33 |
+
}
|
34 |
+
|
35 |
+
var tag = document.createElement( 'script' );
|
36 |
+
tag.src = "//www.youtube.com/iframe_api";
|
37 |
+
var firstScriptTag = document.getElementsByTagName( 'script' )[0];
|
38 |
+
firstScriptTag.parentNode.insertBefore( tag, firstScriptTag );
|
39 |
+
} else {
|
40 |
+
var gtm4wp_err = new Error( "Another code is already utilizing YouTube API, GTM4WP plugin can not load YouTube tracking!" );
|
41 |
+
throw gtm4wp_err;
|
42 |
+
}
|
43 |
+
|
44 |
+
function gtm4wp_onYouTubePlayerReady( event ) {
|
45 |
+
var videodata = event.target.getVideoData();
|
46 |
+
|
47 |
+
window[ gtm4wp_datalayer_name ].push({
|
48 |
+
'event': 'gtm4wp.mediaPlayerReady',
|
49 |
+
'mediaType': 'youtube',
|
50 |
+
'mediaData': {
|
51 |
+
'id': videodata.video_id,
|
52 |
+
'author': videodata.author,
|
53 |
+
'title': videodata.title,
|
54 |
+
'url': event.target.getVideoUrl(),
|
55 |
+
'duration': event.target.getDuration()
|
56 |
+
},
|
57 |
+
'mediaCurrentTime': event.target.getCurrentTime()
|
58 |
+
});
|
59 |
+
}
|
60 |
+
|
61 |
+
function gtm4wp_onYouTubePlayerStateChange( event ) {
|
62 |
+
var playerState = "unknown";
|
63 |
+
switch( event.data ) {
|
64 |
+
case -1: playerState = "unstarted"; break;
|
65 |
+
case YT.PlayerState.ENDED: playerState = "ended"; break;
|
66 |
+
case YT.PlayerState.PLAYING: playerState = "playing"; break;
|
67 |
+
case YT.PlayerState.PAUSED: playerState = "paused"; break;
|
68 |
+
case YT.PlayerState.BUFFERING: playerState = "buffering"; break;
|
69 |
+
case YT.PlayerState.CUED: playerState = "cued"; break;
|
70 |
+
}
|
71 |
+
|
72 |
+
var videoId = event.target.getVideoData().video_id;
|
73 |
+
|
74 |
+
if ( ( YT.PlayerState.PLAYING == event.data ) && ( gtm4wp_youtube_percentage_tracking > 0 ) ) {
|
75 |
+
gtm4wp_youtube_percentage_tracking_timeouts[ videoId ] = setInterval(function() {
|
76 |
+
gtm4wp_onYouTubePercentageChange( event );
|
77 |
+
}, 1000);
|
78 |
+
} else {
|
79 |
+
if ( gtm4wp_youtube_percentage_tracking_timeouts[ videoId ] ) {
|
80 |
+
clearInterval( gtm4wp_youtube_percentage_tracking_timeouts[ videoId ] );
|
81 |
+
}
|
82 |
+
}
|
83 |
+
|
84 |
+
var videodata = event.target.getVideoData();
|
85 |
+
|
86 |
+
window[ gtm4wp_datalayer_name ].push({
|
87 |
+
'event': 'gtm4wp.mediaPlayerStateChange',
|
88 |
+
'mediaType': 'youtube',
|
89 |
+
'mediaData': {
|
90 |
+
'id': videodata.video_id,
|
91 |
+
'author': videodata.author,
|
92 |
+
'title': videodata.title,
|
93 |
+
'url': event.target.getVideoUrl(),
|
94 |
+
'duration': event.target.getDuration()
|
95 |
+
},
|
96 |
+
'mediaPlayerState': playerState,
|
97 |
+
'mediaCurrentTime': event.target.getCurrentTime()
|
98 |
+
});
|
99 |
+
}
|
100 |
+
|
101 |
+
function gtm4wp_onYouTubePlaybackQualityChange( event ) {
|
102 |
+
var videodata = event.target.getVideoData();
|
103 |
+
|
104 |
+
window[ gtm4wp_datalayer_name ].push({
|
105 |
+
'event': 'gtm4wp.mediaPlayerEvent',
|
106 |
+
'mediaType': 'youtube',
|
107 |
+
'mediaData': {
|
108 |
+
'id': videodata.video_id,
|
109 |
+
'author': videodata.author,
|
110 |
+
'title': videodata.title,
|
111 |
+
'url': event.target.getVideoUrl(),
|
112 |
+
'duration': event.target.getDuration()
|
113 |
+
},
|
114 |
+
'mediaCurrentTime': event.target.getCurrentTime(),
|
115 |
+
'mediaPlayerEvent': 'quality-change',
|
116 |
+
'mediaPlayerEventParam': event.data
|
117 |
+
});
|
118 |
+
}
|
119 |
+
|
120 |
+
function gtm4wp_onYouTubePlaybackRateChange( event ) {
|
121 |
+
var videodata = event.target.getVideoData();
|
122 |
+
|
123 |
+
window[ gtm4wp_datalayer_name ].push({
|
124 |
+
'event': 'gtm4wp.mediaPlayerEvent',
|
125 |
+
'mediaType': 'youtube',
|
126 |
+
'mediaData': {
|
127 |
+
'id': videodata.video_id,
|
128 |
+
'author': videodata.author,
|
129 |
+
'title': videodata.title,
|
130 |
+
'url': event.target.getVideoUrl(),
|
131 |
+
'duration': event.target.getDuration()
|
132 |
+
},
|
133 |
+
'mediaCurrentTime': event.target.getCurrentTime(),
|
134 |
+
'mediaPlayerEvent': 'playback-rate-change',
|
135 |
+
'mediaPlayerEventParam': event.data
|
136 |
+
});
|
137 |
+
}
|
138 |
+
|
139 |
+
function gtm4wp_onYouTubeError( event ) {
|
140 |
+
var videodata = event.target.getVideoData();
|
141 |
+
|
142 |
+
window[ gtm4wp_datalayer_name ].push({
|
143 |
+
'event': 'gtm4wp.mediaPlayerEvent',
|
144 |
+
'mediaType': 'youtube',
|
145 |
+
'mediaData': {
|
146 |
+
'id': videodata.video_id,
|
147 |
+
'author': videodata.author,
|
148 |
+
'title': videodata.title,
|
149 |
+
'url': event.target.getVideoUrl(),
|
150 |
+
'duration': event.target.getDuration()
|
151 |
+
},
|
152 |
+
'mediaCurrentTime': event.target.getCurrentTime(),
|
153 |
+
'mediaPlayerEvent': 'error',
|
154 |
+
'mediaPlayerEventParam': event.data
|
155 |
+
});
|
156 |
+
}
|
157 |
+
|
158 |
+
function gtm4wp_onYouTubeApiChange( event ) {
|
159 |
+
var videodata = event.target.getVideoData();
|
160 |
+
|
161 |
+
window[ gtm4wp_datalayer_name ].push({
|
162 |
+
'event': 'gtm4wp.mediaPlayerEvent',
|
163 |
+
'mediaType': 'youtube',
|
164 |
+
'mediaData': {
|
165 |
+
'id': videodata.video_id,
|
166 |
+
'author': videodata.author,
|
167 |
+
'title': videodata.title,
|
168 |
+
'url': event.target.getVideoUrl(),
|
169 |
+
'duration': event.target.getDuration()
|
170 |
+
},
|
171 |
+
'mediaCurrentTime': event.target.getCurrentTime(),
|
172 |
+
'mediaPlayerEvent': 'api-change',
|
173 |
+
'mediaPlayerEventParam': event.data
|
174 |
+
});
|
175 |
+
}
|
176 |
+
|
177 |
+
function gtm4wp_onYouTubePercentageChange( event ) {
|
178 |
+
var videoId = event.target.getVideoData().video_id;
|
179 |
+
var videoCurrentTime = event.target.getCurrentTime();
|
180 |
+
var videoDuration = event.target.getDuration();
|
181 |
+
var videoPercentage = Math.floor( videoCurrentTime / videoDuration * 100 )
|
182 |
+
|
183 |
+
if ( typeof gtm4wp_youtube_percentage_tracking_marks[ videoId ] == "undefined" ) {
|
184 |
+
gtm4wp_youtube_percentage_tracking_marks[ videoId ] = [];
|
185 |
+
}
|
186 |
+
|
187 |
+
var videodata = event.target.getVideoData();
|
188 |
+
|
189 |
+
for( var i=0; i<100; i+=gtm4wp_youtube_percentage_tracking ) {
|
190 |
+
if ( ( videoPercentage > i ) && ( gtm4wp_youtube_percentage_tracking_marks[ videoId ].indexOf( i ) == -1 ) ) {
|
191 |
+
gtm4wp_youtube_percentage_tracking_marks[ videoId ].push( i );
|
192 |
+
|
193 |
+
window[ gtm4wp_datalayer_name ].push({
|
194 |
+
'event': 'gtm4wp.mediaPlaybackPercentage',
|
195 |
+
'mediaType': 'youtube',
|
196 |
+
'mediaData': {
|
197 |
+
'id': videodata.video_id,
|
198 |
+
'author': videodata.author,
|
199 |
+
'title': videodata.title,
|
200 |
+
'url': event.target.getVideoUrl(),
|
201 |
+
'duration': event.target.getDuration()
|
202 |
+
},
|
203 |
+
'mediaCurrentTime': event.target.getCurrentTime(),
|
204 |
+
'mediaPercentage': i
|
205 |
+
});
|
206 |
+
}
|
207 |
+
}
|
208 |
+
}
|
public/frontend.php
CHANGED
@@ -3,6 +3,8 @@ define( 'GTM4WP_WPFILTER_COMPILE_DATALAYER', 'gtm4wp_compile_datalayer' );
|
|
3 |
define( 'GTM4WP_WPFILTER_COMPILE_REMARKTING', 'gtm4wp_compile_remarkering' );
|
4 |
define( 'GTM4WP_WPFILTER_GETTHEGTMTAG', 'gtm4wp_get_the_gtm_tag' );
|
5 |
|
|
|
|
|
6 |
if ( $GLOBALS[ "gtm4wp_options" ][ GTM4WP_OPTION_DATALAYER_NAME ] == "" ) {
|
7 |
$GLOBALS[ "gtm4wp_datalayer_name" ] = "dataLayer";
|
8 |
} else {
|
@@ -382,11 +384,11 @@ function gtm4wp_wp_loaded() {
|
|
382 |
}
|
383 |
|
384 |
function gtm4wp_get_the_gtm_tag() {
|
385 |
-
global $gtm4wp_options, $gtm4wp_datalayer_name;
|
386 |
|
387 |
$_gtm_tag = '';
|
388 |
|
389 |
-
if ( $gtm4wp_options[ GTM4WP_OPTION_GTM_CODE ] != "" ) {
|
390 |
$_gtm_tag .= '
|
391 |
<noscript><iframe src="//www.googletagmanager.com/ns.html?id=' . $gtm4wp_options[ GTM4WP_OPTION_GTM_CODE ] . '"
|
392 |
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
|
@@ -396,9 +398,12 @@ j=d.createElement(s),dl=l!=\'dataLayer\'?\'&l=\'+l:\'\';j.async=true;j.src=
|
|
396 |
\'//www.googletagmanager.com/gtm.js?id=\'+i+dl;f.parentNode.insertBefore(j,f);
|
397 |
})(window,document,\'script\',\'' . $gtm4wp_datalayer_name . '\',\'' . $gtm4wp_options[ GTM4WP_OPTION_GTM_CODE ] . '\');</script>
|
398 |
<!-- End Google Tag Manager -->';
|
|
|
|
|
|
|
399 |
}
|
400 |
|
401 |
-
return
|
402 |
}
|
403 |
|
404 |
function gtm4wp_the_gtm_tag() {
|
@@ -436,6 +441,18 @@ function gtm4wp_enqueue_scripts() {
|
|
436 |
require_once( dirname( __FILE__ ) . "/../integration/woocommerce.php" );
|
437 |
}
|
438 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
439 |
if ( $gtm4wp_options[ GTM4WP_OPTION_SCROLLER_ENABLED ] ) {
|
440 |
wp_enqueue_script( "gtm4wp-scroll-tracking", $gtp4wp_plugin_url . "js/analytics-talk-content-tracking.js", array( "jquery" ), "1.0", false );
|
441 |
}
|
@@ -452,7 +469,7 @@ function gtm4wp_wp_footer() {
|
|
452 |
function gtm4wp_wp_body_open() {
|
453 |
global $gtm4wp_options;
|
454 |
|
455 |
-
if ( GTM4WP_PLACEMENT_BODYOPEN == $gtm4wp_options[ GTM4WP_OPTION_GTM_PLACEMENT ] ) {
|
456 |
gtm4wp_the_gtm_tag();
|
457 |
}
|
458 |
}
|
@@ -513,7 +530,7 @@ function gtm4wp_wp_header_end() {
|
|
513 |
gtm4wp_track_downloads( "' . str_replace( '"', '', $gtm4wp_options[ GTM4WP_OPTION_EVENTS_DWLEXT ] ) . '" );
|
514 |
});';
|
515 |
}
|
516 |
-
|
517 |
$_gtm_tag .= '
|
518 |
' . $gtm4wp_datalayer_name . '.push(' . str_replace(
|
519 |
array( '"-~-', '-~-"' ),
|
@@ -528,12 +545,26 @@ function gtm4wp_wp_header_end() {
|
|
528 |
echo $_gtm_tag;
|
529 |
}
|
530 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
531 |
add_action( "wp_enqueue_scripts", "gtm4wp_enqueue_scripts" );
|
532 |
add_action( "wp_head", "gtm4wp_wp_header_begin", 1 );
|
533 |
add_action( "wp_head", "gtm4wp_wp_header_end", 100 );
|
534 |
add_action( "wp_footer", "gtm4wp_wp_footer" );
|
535 |
add_action( "wp_loaded", "gtm4wp_wp_loaded" );
|
|
|
536 |
add_filter( GTM4WP_WPFILTER_COMPILE_DATALAYER, "gtm4wp_add_basic_datalayer_data" );
|
537 |
|
538 |
// to be able to easily migrate from other Google Tag Manager plugins
|
539 |
add_action( "body_open", "gtm4wp_wp_body_open" );
|
|
|
|
|
|
3 |
define( 'GTM4WP_WPFILTER_COMPILE_REMARKTING', 'gtm4wp_compile_remarkering' );
|
4 |
define( 'GTM4WP_WPFILTER_GETTHEGTMTAG', 'gtm4wp_get_the_gtm_tag' );
|
5 |
|
6 |
+
$GLOBALS[ "gtm4wp_container_code_written" ] = false;
|
7 |
+
|
8 |
if ( $GLOBALS[ "gtm4wp_options" ][ GTM4WP_OPTION_DATALAYER_NAME ] == "" ) {
|
9 |
$GLOBALS[ "gtm4wp_datalayer_name" ] = "dataLayer";
|
10 |
} else {
|
384 |
}
|
385 |
|
386 |
function gtm4wp_get_the_gtm_tag() {
|
387 |
+
global $gtm4wp_options, $gtm4wp_datalayer_name, $gtm4wp_container_code_written;
|
388 |
|
389 |
$_gtm_tag = '';
|
390 |
|
391 |
+
if ( ( $gtm4wp_options[ GTM4WP_OPTION_GTM_CODE ] != "" ) && ( ! $gtm4wp_container_code_written ) ) {
|
392 |
$_gtm_tag .= '
|
393 |
<noscript><iframe src="//www.googletagmanager.com/ns.html?id=' . $gtm4wp_options[ GTM4WP_OPTION_GTM_CODE ] . '"
|
394 |
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
|
398 |
\'//www.googletagmanager.com/gtm.js?id=\'+i+dl;f.parentNode.insertBefore(j,f);
|
399 |
})(window,document,\'script\',\'' . $gtm4wp_datalayer_name . '\',\'' . $gtm4wp_options[ GTM4WP_OPTION_GTM_CODE ] . '\');</script>
|
400 |
<!-- End Google Tag Manager -->';
|
401 |
+
|
402 |
+
$_gtm_tag = apply_filters( GTM4WP_WPFILTER_GETTHEGTMTAG, $_gtm_tag );
|
403 |
+
$gtm4wp_container_code_written = true;
|
404 |
}
|
405 |
|
406 |
+
return $_gtm_tag;
|
407 |
}
|
408 |
|
409 |
function gtm4wp_the_gtm_tag() {
|
441 |
require_once( dirname( __FILE__ ) . "/../integration/woocommerce.php" );
|
442 |
}
|
443 |
|
444 |
+
if ( $gtm4wp_options[ GTM4WP_OPTION_EVENTS_YOUTUBE ] ) {
|
445 |
+
require_once( dirname( __FILE__ ) . "/../integration/youtube.php" );
|
446 |
+
}
|
447 |
+
|
448 |
+
if ( $gtm4wp_options[ GTM4WP_OPTION_EVENTS_VIMEO ] ) {
|
449 |
+
require_once( dirname( __FILE__ ) . "/../integration/vimeo.php" );
|
450 |
+
}
|
451 |
+
|
452 |
+
if ( $gtm4wp_options[ GTM4WP_OPTION_EVENTS_SOUNDCLOUD ] ) {
|
453 |
+
require_once( dirname( __FILE__ ) . "/../integration/soundcloud.php" );
|
454 |
+
}
|
455 |
+
|
456 |
if ( $gtm4wp_options[ GTM4WP_OPTION_SCROLLER_ENABLED ] ) {
|
457 |
wp_enqueue_script( "gtm4wp-scroll-tracking", $gtp4wp_plugin_url . "js/analytics-talk-content-tracking.js", array( "jquery" ), "1.0", false );
|
458 |
}
|
469 |
function gtm4wp_wp_body_open() {
|
470 |
global $gtm4wp_options;
|
471 |
|
472 |
+
if ( ( GTM4WP_PLACEMENT_BODYOPEN == $gtm4wp_options[ GTM4WP_OPTION_GTM_PLACEMENT ] ) || ( GTM4WP_PLACEMENT_BODYOPEN_AUTO == $gtm4wp_options[ GTM4WP_OPTION_GTM_PLACEMENT ] ) ) {
|
473 |
gtm4wp_the_gtm_tag();
|
474 |
}
|
475 |
}
|
530 |
gtm4wp_track_downloads( "' . str_replace( '"', '', $gtm4wp_options[ GTM4WP_OPTION_EVENTS_DWLEXT ] ) . '" );
|
531 |
});';
|
532 |
}
|
533 |
+
//var_dump($gtm4wp_datalayer_data);
|
534 |
$_gtm_tag .= '
|
535 |
' . $gtm4wp_datalayer_name . '.push(' . str_replace(
|
536 |
array( '"-~-', '-~-"' ),
|
545 |
echo $_gtm_tag;
|
546 |
}
|
547 |
|
548 |
+
function gtm4wp_body_class( $classes ) {
|
549 |
+
// solution is based on the code of Yaniv Friedensohn
|
550 |
+
// http://www.affectivia.com/blog/placing-the-google-tag-manager-in-wordpress-after-the-body-tag/
|
551 |
+
if ( GTM4WP_PLACEMENT_BODYOPEN_AUTO == $gtm4wp_options[ GTM4WP_OPTION_GTM_PLACEMENT ] ) {
|
552 |
+
$classes[] = '">' . gtm4wp_get_the_gtm_tag() . '<br style="display:none;';
|
553 |
+
}
|
554 |
+
|
555 |
+
return $classes;
|
556 |
+
}
|
557 |
+
|
558 |
add_action( "wp_enqueue_scripts", "gtm4wp_enqueue_scripts" );
|
559 |
add_action( "wp_head", "gtm4wp_wp_header_begin", 1 );
|
560 |
add_action( "wp_head", "gtm4wp_wp_header_end", 100 );
|
561 |
add_action( "wp_footer", "gtm4wp_wp_footer" );
|
562 |
add_action( "wp_loaded", "gtm4wp_wp_loaded" );
|
563 |
+
add_filter( "body_class", "gtm4wp_body_class", 10000 );
|
564 |
add_filter( GTM4WP_WPFILTER_COMPILE_DATALAYER, "gtm4wp_add_basic_datalayer_data" );
|
565 |
|
566 |
// to be able to easily migrate from other Google Tag Manager plugins
|
567 |
add_action( "body_open", "gtm4wp_wp_body_open" );
|
568 |
+
|
569 |
+
// compatibility with existing themes that natively support code injection after opening body tag
|
570 |
+
add_action( "genesis_before", "gtm4wp_wp_body_open" );
|
readme.txt
CHANGED
@@ -4,7 +4,7 @@ Donate link: https://duracelltomi.com/
|
|
4 |
Tags: google tag manager, tag manager, gtm, google, adwords, google adwords, adwords remarketing, remarketing, google analytics, analytics
|
5 |
Requires at least: 3.0.1
|
6 |
Tested up to: 4.2.1
|
7 |
-
Stable tag: 1.
|
8 |
License: GPLv3
|
9 |
License URI: http://www.gnu.org/licenses/gpl.html
|
10 |
|
@@ -40,6 +40,15 @@ This is useful to see what people are searching for that is not available on you
|
|
40 |
Use post count to generate Analytics events when an empty result is being shown.
|
41 |
This can be useful to catch empty (product) categories.
|
42 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
= Browser / OS / Device data =
|
44 |
|
45 |
(beta)
|
@@ -78,9 +87,25 @@ This plugin can fire several Tag Manager event so that you can include special t
|
|
78 |
|
79 |
* the visitor moves between elements of a form (comment, contact, etc.)
|
80 |
* the visitor clicks on a Facebook like/share (limited feature) or Twitter button
|
81 |
-
* the visitor clicks on an outbound link (
|
82 |
-
* the visitor clicks on a download link (
|
83 |
-
* the visitor clicks on an email link (
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
|
85 |
= Scroll tracking =
|
86 |
|
@@ -142,10 +167,6 @@ Note: list of planned features can change as development goes on!
|
|
142 |
* 1.2
|
143 |
* MailChimp for WordPress support (request by I-Visio)
|
144 |
* Custom dataLayer elements: place your own items site-wide or per page/post
|
145 |
-
* 1.1
|
146 |
-
* YouTube video tracking using GTM events
|
147 |
-
* Vimeo video tracking using GTM events
|
148 |
-
* New code insertion option that does not require theme tweaking (request by Phil Pearce)
|
149 |
|
150 |
== Installation ==
|
151 |
|
@@ -235,6 +256,9 @@ In case you found the opening `<body>` tag, open a new line just after it and in
|
|
235 |
Be careful not to include this line inside any `<div>`, `<p>`, `<header>`, `<article>` and so on.
|
236 |
It can break you theme.
|
237 |
|
|
|
|
|
|
|
238 |
= Why can not this plugin insert the container snippet after the opening body tag automatically? =
|
239 |
|
240 |
Currently WordPress has two 'commands' or 'hooks' that a programmer can use: one for the `<head>` section and
|
@@ -262,6 +286,14 @@ If you or your social plugin inserts the Facebook buttons using IFRAMEs (like So
|
|
262 |
|
263 |
== Changelog ==
|
264 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
265 |
= 1.0 =
|
266 |
|
267 |
The plugin itself is now declared as stable. This means that it should work with most WordPress instances.
|
@@ -269,17 +301,17 @@ From now on each version will include features labeled as:
|
|
269 |
|
270 |
* Beta: the feature has been proven to work for several users but it can still have some bugs
|
271 |
* Experimental: new feature that needs proper testing with more users
|
272 |
-
*
|
273 |
|
274 |
If you see any issue with beta or experimental functions just disable the checkbox. Using this error messages should disappear.
|
275 |
Please report all bugs found in my plugin using the [contact form on my website](https://duracelltomi.com/contact).
|
276 |
|
277 |
* Fixed: wrong GTM container code when renaming default dataLayer variable name (thx Vassilis Papavassiliou)
|
278 |
* Fixed: Enhanced Ecommerce product click data was "undefined" in some cases (thx Sergio Alen)
|
279 |
-
* Fixed: wrong user role detection while
|
280 |
* Changed: only add visitorId to the dataLayer if there is a logged in user
|
281 |
-
* Added: feature labels so that you can see beta, experimental and
|
282 |
-
*
|
283 |
|
284 |
= 0.9.1 =
|
285 |
|
4 |
Tags: google tag manager, tag manager, gtm, google, adwords, google adwords, adwords remarketing, remarketing, google analytics, analytics
|
5 |
Requires at least: 3.0.1
|
6 |
Tested up to: 4.2.1
|
7 |
+
Stable tag: 1.1
|
8 |
License: GPLv3
|
9 |
License URI: http://www.gnu.org/licenses/gpl.html
|
10 |
|
40 |
Use post count to generate Analytics events when an empty result is being shown.
|
41 |
This can be useful to catch empty (product) categories.
|
42 |
|
43 |
+
= Codeless container code injection =
|
44 |
+
|
45 |
+
Yaniv Friedensohn showed me a solution that can add the GTM container code after the opening body tag
|
46 |
+
for almost every theme without modifying the theme files:
|
47 |
+
|
48 |
+
http://www.affectivia.com/blog/placing-the-google-tag-manager-in-wordpress-after-the-body-tag/
|
49 |
+
|
50 |
+
I added this solution to the plugin, currently as an experimental option.
|
51 |
+
|
52 |
= Browser / OS / Device data =
|
53 |
|
54 |
(beta)
|
87 |
|
88 |
* the visitor moves between elements of a form (comment, contact, etc.)
|
89 |
* the visitor clicks on a Facebook like/share (limited feature) or Twitter button
|
90 |
+
* the visitor clicks on an outbound link (deprecated)
|
91 |
+
* the visitor clicks on a download link (deprecated)
|
92 |
+
* the visitor clicks on an email link (deprecated)
|
93 |
+
|
94 |
+
= Media player events =
|
95 |
+
|
96 |
+
(experimental)
|
97 |
+
|
98 |
+
The plugin can track user interaction with your embeded media:
|
99 |
+
|
100 |
+
* YouTube
|
101 |
+
* Vimeo
|
102 |
+
* Soundcloud
|
103 |
+
|
104 |
+
It fires dataLayer events when a media player was being loaded on the page, when the media is being played, paused or stopped.
|
105 |
+
It can fire dataLayer events when the user reaches 10, 20, 30, ..., 90, 100% of the media duration.
|
106 |
+
|
107 |
+
Note: the plugin can only track media that was being embeded using the internal oEmbed feature of WordPress.
|
108 |
+
No 3rd party embedding plugin is currently supported.
|
109 |
|
110 |
= Scroll tracking =
|
111 |
|
167 |
* 1.2
|
168 |
* MailChimp for WordPress support (request by I-Visio)
|
169 |
* Custom dataLayer elements: place your own items site-wide or per page/post
|
|
|
|
|
|
|
|
|
170 |
|
171 |
== Installation ==
|
172 |
|
256 |
Be careful not to include this line inside any `<div>`, `<p>`, `<header>`, `<article>` and so on.
|
257 |
It can break you theme.
|
258 |
|
259 |
+
There is also a solution named "Codeless" which tries to add the container code to the right place but
|
260 |
+
without additional theme tweaking. This is still experimental, use it wisely.
|
261 |
+
|
262 |
= Why can not this plugin insert the container snippet after the opening body tag automatically? =
|
263 |
|
264 |
Currently WordPress has two 'commands' or 'hooks' that a programmer can use: one for the `<head>` section and
|
286 |
|
287 |
== Changelog ==
|
288 |
|
289 |
+
= 1.1 =
|
290 |
+
|
291 |
+
* Added: track embedded YouTube/Vimeo/Soundcloud videos (experimental)
|
292 |
+
* Added: new checkbox - use product SKU for AdWords Dynamic Remarketing variables instead of product ID (experimental)
|
293 |
+
* Added: place your container code after the opening body tag without modifying your theme files (thx Yaniv Friedensohn)
|
294 |
+
* Added: automatic codeless container code injection for Genesis framework users
|
295 |
+
* Fixed: Possible PHP error with custom payment gateway (QuickPay) on the checkout page (thx Damiel for findig this)
|
296 |
+
|
297 |
= 1.0 =
|
298 |
|
299 |
The plugin itself is now declared as stable. This means that it should work with most WordPress instances.
|
301 |
|
302 |
* Beta: the feature has been proven to work for several users but it can still have some bugs
|
303 |
* Experimental: new feature that needs proper testing with more users
|
304 |
+
* Deprecated: this feature will be removed in a future version
|
305 |
|
306 |
If you see any issue with beta or experimental functions just disable the checkbox. Using this error messages should disappear.
|
307 |
Please report all bugs found in my plugin using the [contact form on my website](https://duracelltomi.com/contact).
|
308 |
|
309 |
* Fixed: wrong GTM container code when renaming default dataLayer variable name (thx Vassilis Papavassiliou)
|
310 |
* Fixed: Enhanced Ecommerce product click data was "undefined" in some cases (thx Sergio Alen)
|
311 |
+
* Fixed: wrong user role detection while adding visitorType to the dataLayer (thx Philippe Vachon-Rivard)
|
312 |
* Changed: only add visitorId to the dataLayer if there is a logged in user
|
313 |
+
* Added: feature labels so that you can see beta, experimental and deprecated features
|
314 |
+
* Deprecated: outbound click, email click and download click events. You should use GTM trigger events instead
|
315 |
|
316 |
= 0.9.1 =
|
317 |
|