Changeset 2882488
- Timestamp:
- 03/18/2023 09:56:46 AM (3 years ago)
- Location:
- gtm-ecommerce-woo/trunk
- Files:
-
- 10 edited
-
gtm-ecommerce-woo.php (modified) (3 diffs)
-
lib/Container.php (modified) (4 diffs)
-
lib/EventStrategy/AddToCartStrategy.php (modified) (2 diffs)
-
lib/GaEcommerceEntity/Event.php (modified) (3 diffs)
-
lib/Service/EventStrategiesService.php (modified) (2 diffs)
-
lib/Service/MonitorService.php (modified) (3 diffs)
-
lib/Service/PluginService.php (modified) (2 diffs)
-
lib/Util/WcOutputUtil.php (modified) (2 diffs)
-
readme.txt (modified) (5 diffs)
-
vendor/composer/installed.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
gtm-ecommerce-woo/trunk/gtm-ecommerce-woo.php
r2819367 r2882488 1 1 <?php 2 2 /** 3 * Plugin Name: G oogle Tag Managerfor WooCommerce FREE3 * Plugin Name: GTM for WooCommerce FREE 4 4 * Plugin URI: https://wordpress.org/plugins/gtm-ecommerce-woo 5 5 * Description: Push WooCommerce eCommerce (GA4 and UA compatible) information to GTM DataLayer. Use any GTM integration to measure your customers' activities. 6 * Version: 1.10. 66 * Version: 1.10.7 7 7 * Author: Handcraft Byte 8 8 * Author URI: https://handcraftbyte.com/ … … 13 13 * 14 14 * WC requires at least: 4.0 15 * WC tested up to: 7. 1.015 * WC tested up to: 7.5.0 16 16 */ 17 17 … … 44 44 register_activation_hook( __FILE__, [$pluginService, 'activationHook'] ); 45 45 register_deactivation_hook( __FILE__, [$monitorService, 'deactivationHook'] ); 46 -
gtm-ecommerce-woo/trunk/lib/Container.php
r2773695 r2882488 18 18 class Container { 19 19 20 public function __construct( $pluginVersion ) { 20 /** @var EventStrategiesService */ 21 public $eventStrategiesService; 22 23 /** @var GtmSnippetService */ 24 public $gtmSnippetService; 25 26 /** @var SettingsService */ 27 public $settingsService; 28 29 /** @var PluginService */ 30 public $pluginService; 31 32 /** @var MonitorService */ 33 public $monitorService; 34 35 /** @var ThemeValidatorService */ 36 public $themeValidatorService; 37 38 /** @var EventInspectorService */ 39 public $eventInspectorService; 40 41 public function __construct( string $pluginVersion ) { 21 42 $snakeCaseNamespace = 'gtm_ecommerce_woo'; 22 43 $spineCaseNamespace = 'gtm-ecommerce-woo'; … … 38 59 // 'refund', 39 60 ]; 40 $tagConciergeApiUrl = getenv('TAG_CONCIERGE_API_URL') ? getenv('TAG_CONCIERGE_API_URL'): 'https://api.tagconcierge.com';41 $tagConciergeEdgeUrl = getenv('TAG_CONCIERGE_EDGE_URL') ? getenv('TAG_CONCIERGE_EDGE_URL'): 'https://edge.tagconcierge.com';61 $tagConciergeApiUrl = getenv('TAG_CONCIERGE_API_URL') ?: 'https://api.tagconcierge.com'; 62 $tagConciergeEdgeUrl = getenv('TAG_CONCIERGE_EDGE_URL') ?: 'https://edge.tagconcierge.com'; 42 63 43 64 $wpSettingsUtil = new WpSettingsUtil($snakeCaseNamespace, $spineCaseNamespace); 44 65 $wcTransformerUtil = new WcTransformerUtil(); 45 $wcOutputUtil = new WcOutputUtil( );66 $wcOutputUtil = new WcOutputUtil($pluginVersion); 46 67 47 68 $eventStrategies = [ … … 50 71 ]; 51 72 52 $events = array_map( function( $eventStrategy) {73 $events = array_map(static function( $eventStrategy) { 53 74 return $eventStrategy->getEventName(); 54 75 }, $eventStrategies); 55 76 56 $this->eventStrategiesService = new EventStrategiesService($wpSettingsUtil, $ eventStrategies);77 $this->eventStrategiesService = new EventStrategiesService($wpSettingsUtil, $wcOutputUtil, $eventStrategies); 57 78 $this->gtmSnippetService = new GtmSnippetService($wpSettingsUtil); 58 79 $this->settingsService = new SettingsService($wpSettingsUtil, $events, $proEvents, $serverEvents, $tagConciergeApiUrl, $pluginVersion); 59 $this->pluginService = new PluginService($spineCaseNamespace, $wpSettingsUtil, $ pluginVersion);80 $this->pluginService = new PluginService($spineCaseNamespace, $wpSettingsUtil, $wcOutputUtil, $pluginVersion); 60 81 $this->monitorService = new MonitorService($snakeCaseNamespace, $spineCaseNamespace, $wcTransformerUtil, $wpSettingsUtil, $wcOutputUtil, $tagConciergeApiUrl, $tagConciergeEdgeUrl); 61 82 $this->themeValidatorService = new ThemeValidatorService($snakeCaseNamespace, $spineCaseNamespace, $wcTransformerUtil, $wpSettingsUtil, $wcOutputUtil, $events, $tagConciergeApiUrl, $pluginVersion); … … 64 85 } 65 86 66 public function getSettingsService() {87 public function getSettingsService(): SettingsService { 67 88 return $this->settingsService; 68 89 } 69 90 70 public function getGtmSnippetService() {91 public function getGtmSnippetService(): GtmSnippetService { 71 92 return $this->gtmSnippetService; 72 93 } 73 94 74 public function getEventStrategiesService() {95 public function getEventStrategiesService(): EventStrategiesService { 75 96 return $this->eventStrategiesService; 76 97 } 77 98 78 public function getPluginService() {99 public function getPluginService(): PluginService { 79 100 return $this->pluginService; 80 101 } 81 102 82 public function getMonitorService() {103 public function getMonitorService(): MonitorService { 83 104 return $this->monitorService; 84 105 } 85 106 86 public function getThemeValidatorService() {107 public function getThemeValidatorService(): ThemeValidatorService { 87 108 return $this->themeValidatorService; 88 109 } 89 110 90 public function getEventInspectorService() {111 public function getEventInspectorService(): EventInspectorService { 91 112 return $this->eventInspectorService; 92 113 } -
gtm-ecommerce-woo/trunk/lib/EventStrategy/AddToCartStrategy.php
r2764750 r2882488 63 63 */ 64 64 public function onCartSubmitScript( $item) { 65 $this->wcOutput->globalVariable('gtm_ecommerce_woo_item', $item); 66 $this->wcOutput->script(<<<'EOD' 65 $bypassUnquote = <<<'EOD' 66 var $form = jQuery(ev.currentTarget).parents('form.cart'); 67 var quantity = jQuery('[name="quantity"]', $form).val(); 68 var product_id = jQuery('[name="add-to-cart"]', $form).val(); 69 EOD; 70 71 $jsonItem = json_encode($item); 72 $this->wcOutput->script(<<<EOD 67 73 jQuery(document).on('click', '.cart .single_add_to_cart_button', function(ev) { 68 var $form = jQuery(ev.currentTarget).parents('form.cart'); 69 var quantity = jQuery('[name="quantity"]', $form).val(); 70 var product_id = jQuery('[name="add-to-cart"]', $form).val(); 74 ${bypassUnquote} 71 75 72 var item = gtm_ecommerce_woo_item;76 var item = ${jsonItem}; 73 77 item.quantity = parseInt(quantity); 74 78 dataLayer.push({ … … 89 93 */ 90 94 public function onCartLinkClick( $items) { 91 $this->wcOutput->globalVariable('gtm_ecommerce_woo_items_by_product_id', $items); 95 if (true === method_exists($this->wcOutput,'addItems')) { 96 $this->wcOutput->addItems($items, 'product_id'); 97 } else { 98 $this->wcOutput->globalVariable('gtm_ecommerce_woo_items_by_product_id', $items); 99 } 100 92 101 $this->wcOutput->script(<<<'EOD' 93 102 jQuery(document).on('click', '.ajax_add_to_cart', function(ev) { 94 var quantity = jQuery(ev.currentTarget).data('quantity'); 95 var product_id = jQuery(ev.currentTarget).data('product_id'); 96 var item = gtm_ecommerce_woo_items_by_product_id[product_id]; 97 item.quantity = parseInt(quantity); 103 var targetElement = jQuery(ev.currentTarget); 104 if (0 === targetElement.length) { 105 return; 106 } 107 var product_id = targetElement.data('product_id'); 108 if (undefined === product_id) { 109 return; 110 } 111 var quantity = targetElement.data('quantity') ?? 1; 112 var item = {}; 113 114 if ('undefined' === typeof gtm_ecommerce_pro) { 115 item = gtm_ecommerce_woo_items_by_product_id[product_id]; 116 } else { 117 item = gtm_ecommerce_pro.getItemByProductId(product_id); 118 } 119 120 item.quantity = parseInt(quantity); 98 121 dataLayer.push({ 99 122 'event': 'add_to_cart', -
gtm-ecommerce-woo/trunk/lib/GaEcommerceEntity/Event.php
r2773695 r2882488 21 21 } 22 22 23 public function setItems( $items ) { 23 public function setItems( array $items ): Event 24 { 24 25 $this->items = array_values($items); 25 26 return $this; 26 27 } 27 28 28 public function addItem( $item ) { 29 public function addItem( Item $item ): Event 30 { 29 31 $this->items[] = $item; 30 32 return $this; 31 33 } 32 34 33 public function setCurrency( $currency ) { 35 public function setCurrency( string $currency ): Event 36 { 34 37 $this->currency = $currency; 35 38 return $this; 36 39 } 37 40 38 public function setTransactionId( $transactionId ) { 41 public function setTransactionId( $transactionId ): Event 42 { 39 43 $this->transactionId = $transactionId; 40 44 return $this; 41 45 } 42 46 43 public function setAffiliation( $affiliation ) { 47 public function setAffiliation( string $affiliation ): Event 48 { 44 49 $this->affiliation = $affiliation; 45 50 return $this; 46 51 } 47 52 48 public function setValue( $value ) { 53 public function setValue( float $value ): Event 54 { 49 55 $this->value = $value; 50 56 return $this; 51 57 } 52 58 53 public function setTax( $tax ) { 59 public function setTax( float $tax ): Event 60 { 54 61 $this->tax = $tax; 55 62 return $this; 56 63 } 57 64 58 public function setShipping( $shipping ) { 65 public function setShipping( float $shipping ): Event 66 { 59 67 $this->shipping = $shipping; 60 68 return $this; 61 69 } 62 70 63 public function setCoupon( $coupon ) { 71 public function setCoupon( string $coupon ): Event 72 { 64 73 $this->coupon = $coupon; 65 74 return $this; 66 75 } 67 76 68 public function setExtraProperty( $propName, $propValue ) { 77 public function setExtraProperty( string $propName, string $propValue ): Event 78 { 69 79 $this->extraProps[$propName] = $propValue; 70 80 return $this; 71 81 } 72 82 73 public function getValue() { 83 public function getValue(): float 84 { 85 if (null !== $this->value) { 86 return $this->value; 87 } 88 74 89 if (!is_array($this->items) || count($this->items) === 0) { 75 90 return 0; 76 91 } 77 return array_reduce($this->items, function( $carry, $item ) { 78 $itemPrice = isset($item->price) ? $item->price : 0; 79 $itemQuantity = isset($item->quantity) ? $item->quantity : 1; 92 93 $value = array_reduce($this->items, static function( $carry, $item ) { 94 $itemPrice = $item->price ?? 0; 95 $itemQuantity = $item->quantity ?? 1; 80 96 return $carry + ((float) $itemPrice * (float) $itemQuantity); 81 97 }, 0); 98 99 return round($value, 2); 82 100 } 83 101 84 102 public function jsonSerialize() { 103 apply_filters('gtm_ecommerce_woo_event_middleware', $this); 104 85 105 /** 86 106 * Allow to customize the ecommerce event properties … … 117 137 'event' => $this->name, 118 138 'ecommerce' => [ 139 'coupon' => $this->coupon, 119 140 'value' => $this->getValue(), 120 141 'items' => $this->items, … … 123 144 } 124 145 146 if (null === $this->coupon || true === empty($this->coupon)) { 147 unset($jsonEvent['ecommerce']['coupon'], $jsonEvent['ecommerce']['purchase']['coupon']); 148 } 149 125 150 foreach ($this->extraProps as $propName => $propValue) { 126 151 $jsonEvent[$propName] = $propValue; 127 152 } 128 153 129 return array_filter($jsonEvent, function( $value ) {154 return array_filter($jsonEvent, static function( $value ) { 130 155 return !is_null($value) && '' !== $value; 131 156 }); -
gtm-ecommerce-woo/trunk/lib/Service/EventStrategiesService.php
r2773695 r2882488 2 2 3 3 namespace GtmEcommerceWoo\Lib\Service; 4 5 use GtmEcommerceWoo\Lib\EventStrategy\AbstractEventStrategy; 6 use GtmEcommerceWoo\Lib\Util\WcOutputUtil; 7 use GtmEcommerceWoo\Lib\Util\WpSettingsUtil; 4 8 5 9 /** … … 8 12 class EventStrategiesService { 9 13 14 /** @var AbstractEventStrategy[] */ 10 15 protected $eventStrategies = []; 16 17 /** @var WpSettingsUtil */ 11 18 protected $wpSettingsUtil; 12 19 13 public function __construct( $wpSettingsUtil, $eventStrategies) { 20 /** @var WcOutputUtil */ 21 protected $wcOutputUtil; 22 23 /** 24 * @param WpSettingsUtil $wpSettingsUtil 25 * @param AbstractEventStrategy[] $eventStrategies 26 */ 27 public function __construct( WpSettingsUtil $wpSettingsUtil, WcOutputUtil $wcOutputUtil, array $eventStrategies) { 14 28 $this->eventStrategies = $eventStrategies; 15 29 $this->wpSettingsUtil = $wpSettingsUtil; 30 $this->wcOutputUtil = $wcOutputUtil; 16 31 } 17 32 -
gtm-ecommerce-woo/trunk/lib/Service/MonitorService.php
r2773695 r2882488 27 27 28 28 public function initialize() { 29 if ($this->wpSettingsUtil->getOption('monitor_enabled') !== '1') { 30 return; 31 } 32 29 33 $cronName = $this->snakeCaseNamespace . '_cron_monitor'; 30 if ($this->wpSettingsUtil->getOption('monitor_enabled') !== '1') { 31 $timestamp = wp_next_scheduled( $cronName ); 34 if ($timestamp = wp_next_scheduled( $cronName )) { 32 35 wp_unschedule_event( $timestamp, $cronName ); 33 return; 34 } 35 36 add_action( $cronName, [$this, 'cronJob'] ); 37 if ( ! wp_next_scheduled( $cronName ) ) { 38 wp_schedule_event( time(), 'hourly', $cronName ); 39 } 40 41 // add_action( 'rest_api_init', function () { 42 // register_rest_route( 'gtm-ecommerce-woo/v1', '/track', array( 43 // 'methods' => 'POST', 44 // 'callback' => [$this, 'trackEvents'], 45 // ) ); 46 // } ); 36 } 47 37 48 38 add_action( 'wp_head', [$this, 'uuidHash'] ); … … 53 43 add_action( 'woocommerce_order_status_changed', [$this, 'orderStatusChanged']); 54 44 } 55 56 public function deactivationHook() {57 $cronName = $this->snakeCaseNamespace . '_cron_debugger';58 $timestamp = wp_next_scheduled( $cronName );59 wp_unschedule_event( $timestamp, $cronName );60 }61 62 // function63 45 64 46 public function uuidHash() { … … 71 53 echo '})(dataLayer);'; 72 54 echo "</script>\n"; 73 }74 75 76 // switch to save_post_shop_order hook77 public function cronJob() {78 $lastRun = get_transient( $this->snakeCaseNamespace . '_monitor_last_run' );79 if (false === $lastRun) {80 $lastRun = time() - HOUR_IN_SECONDS * 24;81 }82 83 set_transient( $this->snakeCaseNamespace . '_monitor_last_run', time() );84 55 } 85 56 -
gtm-ecommerce-woo/trunk/lib/Service/PluginService.php
r2773695 r2882488 2 2 3 3 namespace GtmEcommerceWoo\Lib\Service; 4 5 use GtmEcommerceWoo\Lib\Util\WcOutputUtil; 6 use GtmEcommerceWoo\Lib\Util\WpSettingsUtil; 4 7 5 8 /** … … 7 10 */ 8 11 class PluginService { 12 /** @var WpSettingsUtil */ 13 protected $wpSettingsUtil; 14 15 /** @var WcOutputUtil */ 16 protected $wcOutputUtil; 9 17 protected $spineCaseNamespace; 10 protected $wpSettingsUtil;11 18 protected $pluginVersion; 12 19 protected $feedbackUrl = 'https://wordpress.org/plugins/gtm-ecommerce-woo/#reviews'; 13 20 protected $feedbackDays = 7; 14 21 15 public function __construct( $spineCaseNamespace, $wpSettingsUtil, $ pluginVersion ) {22 public function __construct( $spineCaseNamespace, $wpSettingsUtil, $wcOutputUtil, $pluginVersion ) { 16 23 $this->spineCaseNamespace = $spineCaseNamespace; 17 24 $this->wpSettingsUtil = $wpSettingsUtil; 25 $this->wcOutputUtil = $wcOutputUtil; 18 26 $this->pluginVersion = $pluginVersion; 19 27 } -
gtm-ecommerce-woo/trunk/lib/Util/WcOutputUtil.php
r2773695 r2882488 4 4 5 5 class WcOutputUtil { 6 6 protected $pluginDir = __DIR__; 7 protected $pluginVersion = ''; 7 8 protected $scripts = []; 8 9 protected $scriptFiles = []; 9 10 10 public function __construct() { 11 public function __construct($pluginVersion) { 12 $this->pluginVersion = $pluginVersion; 11 13 add_action( 'wp_footer', [$this, 'wpFooter'], 20 ); 12 14 add_action( 'wp_enqueue_scripts', [$this, 'wpEnqueueScripts'] ); … … 56 58 wp_enqueue_script( 57 59 $scriptFile['name'], 58 plugin s_url( 'js/' . $scriptFile['name'] . '.js', MAIN_FILE ),60 plugin_dir_url( dirname( $this->pluginDir ) ) . 'js/' . $scriptFile['name'] . '.js', 59 61 $scriptFile['deps'], 60 '1.0.0',62 $this->pluginVersion, 61 63 $scriptFile['in_footer'] 62 64 ); -
gtm-ecommerce-woo/trunk/readme.txt
r2819367 r2882488 1 === G oogle Tag Managerfor WooCommerce FREE ===1 === GTM for WooCommerce FREE === 2 2 Contributors: Handcraft Byte 3 3 Tags: google tag manager, GA4, ecommerce events, Google Analytics, Facebook Pixel, shopping behavior 4 4 Requires at least: 5.1.0 5 5 Tested up to: 6.1.1 6 Requires PHP: 7. 26 Requires PHP: 7.0 7 7 Stable tag: trunk 8 8 License: GPLv2 or later 9 9 License URI: http://www.gnu.org/licenses/gpl-2.0.html 10 10 11 Push WooCommerce eCommerce information (**GA4 Ecommerce and UA Enhanced Ecommerce compatible**) to GTM DataLayer. Use any G TMintegration to measure your customers' activities.11 Push WooCommerce eCommerce information (**GA4 Ecommerce and UA Enhanced Ecommerce compatible**) to GTM DataLayer. Use any Google Tag Manager integration to measure your customers' activities. 12 12 13 13 == Description == … … 44 44 ### Only single plugin needed 45 45 46 Without G oogle Tag Managerfor WooCommerce plugin, you would need a separate plugin for each of those integrations. And each additional plugin may make your Wordpress setup more complex.47 With G oogle Tag Managerfor WooCommerce, all data is sent in standardized Google format to GTM and everything else is configured there.46 Without GTM for WooCommerce plugin, you would need a separate plugin for each of those integrations. And each additional plugin may make your Wordpress setup more complex. 47 With GTM for WooCommerce, all data is sent in standardized Google format to GTM and everything else is configured there. 48 48 49 49 ### Reporting consistency … … 58 58 == Installation == 59 59 60 1. Upload or install G oogle Tag Managerfor WooCommerce plugin from WordPress plugins directory.60 1. Upload or install GTM for WooCommerce plugin from WordPress plugins directory. 61 61 2. Activate the plugin through the `Plugins` menu in WordPress. 62 62 3. That's it! If GTM is already implemented in your WordPress your eCommerce data will be pushed to GTM DataLayer. If not head to `Settings > Google Tag Manager` and paste in GTM snippets. … … 106 106 == Screenshots == 107 107 108 1. **G oogle Tag Managerfor WooCommerce** settings and GTM snippets108 1. **GTM for WooCommerce** settings and GTM snippets 109 109 2. eCommerce results in GA4 property 110 110 3. eCommerce results in Universal Analytics property … … 118 118 == Changelog == 119 119 120 = 1.10.7 = 121 122 * adjust the name to WordPress directory requirements 123 * tested against latest versions of WordPress and WooCommerce 124 * adjust required PHP version 125 120 126 = 1.10.6 = 121 127 -
gtm-ecommerce-woo/trunk/vendor/composer/installed.php
r2773695 r2882488 4 4 'pretty_version' => 'dev-main', 5 5 'version' => 'dev-main', 6 'reference' => ' 87db683de6ac50748828aeb06590c3c5b74deb91',6 'reference' => '04baf68a97233e399c89e24640356308844ef967', 7 7 'type' => 'project', 8 8 'install_path' => __DIR__ . '/../../../', … … 14 14 'pretty_version' => 'dev-main', 15 15 'version' => 'dev-main', 16 'reference' => ' 87db683de6ac50748828aeb06590c3c5b74deb91',16 'reference' => '04baf68a97233e399c89e24640356308844ef967', 17 17 'type' => 'project', 18 18 'install_path' => __DIR__ . '/../../../',
Note: See TracChangeset
for help on using the changeset viewer.