Changeset 3205976
- Timestamp:
- 12/10/2024 10:42:07 PM (16 months ago)
- Location:
- activecampaign-for-woocommerce/trunk
- Files:
-
- 2 added
- 39 edited
-
CHANGELOG.txt (modified) (1 diff)
-
README.txt (modified) (3 diffs)
-
ac_vendor/autoload.php (modified) (1 diff)
-
ac_vendor/composer/autoload_classmap.php (modified) (1 diff)
-
ac_vendor/composer/autoload_real.php (modified) (5 diffs)
-
ac_vendor/composer/autoload_static.php (modified) (3 diffs)
-
activecampaign-for-woocommerce.php (modified) (1 diff)
-
admin/class-activecampaign-for-woocommerce-admin-product-sync.php (modified) (2 diffs)
-
admin/class-activecampaign-for-woocommerce-admin.php (modified) (6 diffs)
-
admin/scripts/activecampaign-for-woocommerce-product-sync.js (modified) (2 diffs)
-
admin/trait-activecampaign-for-woocommerce-admin-utilities.php (modified) (1 diff)
-
admin/views/activecampaign-for-woocommerce-admin-display.php (modified) (5 diffs)
-
admin/views/activecampaign-for-woocommerce-product-sync.php (modified) (2 diffs)
-
includes/abandoned_carts/class-activecampaign-for-woocommerce-run-abandonment-sync-command.php (modified) (3 diffs)
-
includes/abandoned_carts/trait-activecampaign-for-woocommerce-abandoned-cart-utilities.php (modified) (2 diffs)
-
includes/api-client/class-activecampaign-for-woocommerce-api-client.php (modified) (2 diffs)
-
includes/class-activecampaign-for-woocommerce.php (modified) (5 diffs)
-
includes/config/activecampaign-for-woocommerce-class-factories.php (modified) (1 diff)
-
includes/config/activecampaign-for-woocommerce-global-constants.php (modified) (1 diff)
-
includes/customers/class-activecampaign-for-woocommerce-customer-utilities.php (modified) (2 diffs)
-
includes/features/class-activecampaign-for-woocommerce-ac-features.php (modified) (1 diff)
-
includes/features/trait-activecampaign-for-woocommerce-features-checker.php (modified) (1 diff)
-
includes/models/class-activecampaign-for-woocommerce-ac-contact.php (modified) (4 diffs)
-
includes/models/factories/class-activecampaign-for-woocommerce-ecom-order-factory.php (modified) (5 diffs)
-
includes/orders/class-activecampaign-for-woocommerce-cofe-order-builder.php (modified) (2 diffs)
-
includes/orders/class-activecampaign-for-woocommerce-new-order-created-event.php (modified) (5 diffs)
-
includes/orders/class-activecampaign-for-woocommerce-new-order-sync-job.php (modified) (3 diffs)
-
includes/orders/class-activecampaign-for-woocommerce-order-action-events.php (modified) (6 diffs)
-
includes/orders/historical/class-activecampaign-for-woocommerce-historical-sync-runner-cofe.php (modified) (4 diffs)
-
includes/orders/trait-activecampaign-for-woocommerce-order-data-gathering.php (modified) (1 diff)
-
includes/orders/trait-activecampaign-for-woocommerce-synced-status-handler.php (modified) (2 diffs)
-
includes/products/class-activecampaign-for-woocommerce-product-sync-job.php (modified) (10 diffs)
-
includes/products/class-activecampaign-for-woocommerce-sync-status.php (modified) (4 diffs)
-
includes/repositories/class-activecampaign-for-woocommerce-ac-tracking-repository.php (added)
-
includes/repositories/class-activecampaign-for-woocommerce-cofe-order-repository.php (modified) (2 diffs)
-
includes/subscriptions/class-activecampaign-for-woocommerce-new-subscription-sync-job.php (modified) (2 diffs)
-
includes/subscriptions/class-activecampaign-for-woocommerce-subscription-events.php (modified) (4 diffs)
-
includes/traits/class-activecampaign-for-woocommerce-interacts-with-api-trait.php (modified) (1 diff)
-
includes/traits/trait-activecampaign-for-woocommerce-arg-data-gathering.php (modified) (3 diffs)
-
public/class-activecampaign-for-woocommerce-public.php (modified) (3 diffs)
-
public/js/site_tracking.js (added)
Legend:
- Unmodified
- Added
- Removed
-
activecampaign-for-woocommerce/trunk/CHANGELOG.txt
r3104234 r3205976 3 3 **ActiveCampaign for WooCommerce** 4 4 5 = 2.8.0 2024-12-10 = 6 * Feature - Product sync now has the option to directly pull products from the database 7 * Enhancement - Product sync will show the number of products available to sync for debugging purposes 8 * Bugfix - Fatal errors thrown by PHP 8.2 resolved 9 * Bugfix - Orders from WooCommerce sometimes synced to the wrong contact 10 * Bugfix - Products missing from product sync with some plugin customizations 11 * Bugfix - Edge case where some orders would convert to subscriptions and vanish from the store 12 13 = 2.7.11 2024-11-13 = 14 * Bugfix - URL correction for setup 15 * Bugfix - Order created date fix 16 * Bugfix - Abandoned cart int fix 17 18 = 2.7.10 2024-10-28 = 19 * Bugfix - Solving various issues with order update 20 * Bugfix - Abandoned cart created date error resolved 21 22 = 2.7.9 2024-10-16 = 23 * Bugfix - Issue with our order action event has been resolved 24 25 = 2.7.8 2024-10-15 = 26 * Bugfix - WooCommerce hook for stripe added to the order sync 27 * Bugfix - Order status changes should not get lost if done quickly 28 * Bugfix - Added debug display items for product sync 29 * Bugfix - Fixed product sync issue related to gathering records due to WC updates 30 31 = 2.7.7 2024-09-11 = 32 * Enhancement - WooCommerce checkout blocks supported for abandoned cart 33 * Fix - Order pages no longer cause errors in the AC block 34 * Fix - Various issues due to WooCommerce changes 35 36 = 2.7.6 2024-07-30 = 37 * Enhancement - Orders through Stripe will trigger the order updated hook 38 * Fix - WooCommerce Order with Stripe payment not updating correct status 39 * Fix - Product sync throws error on isVisible field 40 41 = 2.7.5 2024-07-19 = 42 * Fix - Grammar tokens issue resolved 43 * Fix - Fetch parent category if variation has none set or is "uncategorized" 44 45 = 2.7.4 2024-06-26 = 46 * Enhancement - New product sync option in settings for product description selection between full or short description 47 5 48 = 2.7.3 2024-06-17 = 6 * Fix for WCS not always returning all records in historical sync7 * Better error handling for bad records sent to ActiveCampaign8 * WooCommerce 9.0.0 compatibility updates49 * Update - WooCommerce 9.0.0 compatibility updates 50 * Tweak - Better error handling for bad records sent to ActiveCampaign 51 * Fix - WCS not always returning all records in historical sync 9 52 10 53 = 2.7.2 2024-06-10 = -
activecampaign-for-woocommerce/trunk/README.txt
r3189047 r3205976 3 3 Tags: marketing, ecommerce, woocommerce, email, activecampaign, abandoned cart 4 4 Requires at least: 6.0 5 Tested up to: 6.7. 06 Stable tag: 2. 7.115 Tested up to: 6.7.1 6 Stable tag: 2.8.0 7 7 Requires PHP: 7.4 8 8 License: GPLv2 or later … … 68 68 69 69 = WooCommerce Compatibility = 70 * Tested up to version: 9.4. 170 * Tested up to version: 9.4.3 71 71 * Minimal version requirement: 7.4.0 72 72 * HPOS Compatible … … 94 94 95 95 == Changelog == 96 97 = 2.8.0 2024-12-10 = 98 * Feature - Product sync now has the option to directly pull products from the database 99 * Enhancement - Product sync will show the number of products available to sync for debugging purposes 100 * Bugfix - Fatal errors thrown by PHP 8.2 resolved 101 * Bugfix - Orders from WooCommerce sometimes synced to the wrong contact 102 * Bugfix - Products missing from product sync with some plugin customizations 103 * Bugfix - Edge case where some orders would convert to subscriptions and vanish from the store 96 104 97 105 = 2.7.11 2024-11-13 = -
activecampaign-for-woocommerce/trunk/ac_vendor/autoload.php
r3189047 r3205976 5 5 require_once __DIR__ . '/composer/autoload_real.php'; 6 6 7 return ComposerAutoloaderInitd d516b1c42b8adb957397bd81974f415::getLoader();7 return ComposerAutoloaderInitd69e46321af071c131c0b9948fe62b79::getLoader(); -
activecampaign-for-woocommerce/trunk/ac_vendor/composer/autoload_classmap.php
r3089566 r3205976 291 291 'Activecampaign_For_Woocommerce_Ac_Features' => $baseDir . '/includes/features/class-activecampaign-for-woocommerce-ac-features.php', 292 292 'Activecampaign_For_Woocommerce_Ac_Features_Repository' => $baseDir . '/includes/repositories/class-activecampaign-for-woocommerce-ac-features-repository.php', 293 'Activecampaign_For_Woocommerce_Ac_Tracking_Repository' => $baseDir . '/includes/repositories/class-activecampaign-for-woocommerce-ac-tracking-repository.php', 293 294 'Activecampaign_For_Woocommerce_Activator' => $baseDir . '/includes/class-activecampaign-for-woocommerce-activator.php', 294 295 'Activecampaign_For_Woocommerce_Add_Accepts_Marketing_To_Customer_Meta_Command' => $baseDir . '/includes/commands/class-activecampaign-for-woocommerce-add-accepts-marketing-to-customer-meta-command.php', -
activecampaign-for-woocommerce/trunk/ac_vendor/composer/autoload_real.php
r3189047 r3205976 3 3 // autoload_real.php @generated by Composer 4 4 5 class ComposerAutoloaderInitd d516b1c42b8adb957397bd81974f4155 class ComposerAutoloaderInitd69e46321af071c131c0b9948fe62b79 6 6 { 7 7 private static $loader; … … 25 25 require __DIR__ . '/platform_check.php'; 26 26 27 spl_autoload_register(array('ComposerAutoloaderInitd d516b1c42b8adb957397bd81974f415', 'loadClassLoader'), true, true);27 spl_autoload_register(array('ComposerAutoloaderInitd69e46321af071c131c0b9948fe62b79', 'loadClassLoader'), true, true); 28 28 self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__))); 29 spl_autoload_unregister(array('ComposerAutoloaderInitd d516b1c42b8adb957397bd81974f415', 'loadClassLoader'));29 spl_autoload_unregister(array('ComposerAutoloaderInitd69e46321af071c131c0b9948fe62b79', 'loadClassLoader')); 30 30 31 31 $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); … … 33 33 require __DIR__ . '/autoload_static.php'; 34 34 35 call_user_func(\Composer\Autoload\ComposerStaticInitd d516b1c42b8adb957397bd81974f415::getInitializer($loader));35 call_user_func(\Composer\Autoload\ComposerStaticInitd69e46321af071c131c0b9948fe62b79::getInitializer($loader)); 36 36 } else { 37 37 $map = require __DIR__ . '/autoload_namespaces.php'; … … 54 54 55 55 if ($useStaticLoader) { 56 $includeFiles = Composer\Autoload\ComposerStaticInitd d516b1c42b8adb957397bd81974f415::$files;56 $includeFiles = Composer\Autoload\ComposerStaticInitd69e46321af071c131c0b9948fe62b79::$files; 57 57 } else { 58 58 $includeFiles = require __DIR__ . '/autoload_files.php'; 59 59 } 60 60 foreach ($includeFiles as $fileIdentifier => $file) { 61 composerRequired d516b1c42b8adb957397bd81974f415($fileIdentifier, $file);61 composerRequired69e46321af071c131c0b9948fe62b79($fileIdentifier, $file); 62 62 } 63 63 … … 66 66 } 67 67 68 function composerRequired d516b1c42b8adb957397bd81974f415($fileIdentifier, $file)68 function composerRequired69e46321af071c131c0b9948fe62b79($fileIdentifier, $file) 69 69 { 70 70 if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { -
activecampaign-for-woocommerce/trunk/ac_vendor/composer/autoload_static.php
r3189047 r3205976 5 5 namespace Composer\Autoload; 6 6 7 class ComposerStaticInitd d516b1c42b8adb957397bd81974f4157 class ComposerStaticInitd69e46321af071c131c0b9948fe62b79 8 8 { 9 9 public static $files = array ( … … 374 374 'Activecampaign_For_Woocommerce_Ac_Features' => __DIR__ . '/../..' . '/includes/features/class-activecampaign-for-woocommerce-ac-features.php', 375 375 'Activecampaign_For_Woocommerce_Ac_Features_Repository' => __DIR__ . '/../..' . '/includes/repositories/class-activecampaign-for-woocommerce-ac-features-repository.php', 376 'Activecampaign_For_Woocommerce_Ac_Tracking_Repository' => __DIR__ . '/../..' . '/includes/repositories/class-activecampaign-for-woocommerce-ac-tracking-repository.php', 376 377 'Activecampaign_For_Woocommerce_Activator' => __DIR__ . '/../..' . '/includes/class-activecampaign-for-woocommerce-activator.php', 377 378 'Activecampaign_For_Woocommerce_Add_Accepts_Marketing_To_Customer_Meta_Command' => __DIR__ . '/../..' . '/includes/commands/class-activecampaign-for-woocommerce-add-accepts-marketing-to-customer-meta-command.php', … … 487 488 { 488 489 return \Closure::bind(function () use ($loader) { 489 $loader->prefixLengthsPsr4 = ComposerStaticInitd d516b1c42b8adb957397bd81974f415::$prefixLengthsPsr4;490 $loader->prefixDirsPsr4 = ComposerStaticInitd d516b1c42b8adb957397bd81974f415::$prefixDirsPsr4;491 $loader->classMap = ComposerStaticInitd d516b1c42b8adb957397bd81974f415::$classMap;490 $loader->prefixLengthsPsr4 = ComposerStaticInitd69e46321af071c131c0b9948fe62b79::$prefixLengthsPsr4; 491 $loader->prefixDirsPsr4 = ComposerStaticInitd69e46321af071c131c0b9948fe62b79::$prefixDirsPsr4; 492 $loader->classMap = ComposerStaticInitd69e46321af071c131c0b9948fe62b79::$classMap; 492 493 493 494 }, null, ClassLoader::class); -
activecampaign-for-woocommerce/trunk/activecampaign-for-woocommerce.php
r3189047 r3205976 17 17 * Plugin URI: https://www.activecampaign.com/ 18 18 * Description: Add Abandoned Cart functionality to your WooCommerce store, synchronize order & customer information using ActiveCampaign. 19 * Version: 2. 7.1119 * Version: 2.8.0 20 20 * WC requires at least: 7.4.0 21 * WC tested up to: 9.4. 121 * WC tested up to: 9.4.3 22 22 * Requires at least: 6.0 23 23 * Requires PHP: 7.4 -
activecampaign-for-woocommerce/trunk/admin/class-activecampaign-for-woocommerce-admin-product-sync.php
r3169593 r3205976 66 66 ); 67 67 68 $data['products'] = $this->get_products_by_offset( -1, 15, true ); 68 $data['products'] = $this->get_all_product_ids_direct(); // Get the source 69 $data['products_wc'] = $this->get_products_by_offset( -1, 15, true ); // works but does not have all records 69 70 $data['event_status'] = wp_get_scheduled_event( ACTIVECAMPAIGN_FOR_WOOCOMMERCE_RUN_PRODUCT_SYNC_NAME ); 70 71 $data['page_url'] = esc_url( admin_url( 'admin.php?page=' . ACTIVECAMPAIGN_FOR_WOOCOMMERCE_PLUGIN_NAME_SNAKE . '_product_sync&activesync=1' ) ); … … 89 90 delete_option( ACTIVECAMPAIGN_FOR_WOOCOMMERCE_PRODUCT_SYNC_STOP_CHECK_NAME ); 90 91 do_action( 'activecampaign_for_woocommerce_run_sync_connection' ); 91 92 92 do_action( 'activecampaign_for_woocommerce_build_product_sync_schedules' ); 93 93 } -
activecampaign-for-woocommerce/trunk/admin/class-activecampaign-for-woocommerce-admin.php
r3189047 r3205976 18 18 use Activecampaign_For_Woocommerce_AC_Contact_Repository as Contact_Repository; 19 19 use Activecampaign_For_Woocommerce_Synced_Status_Interface as Synced_Status; 20 use Activecampaign_For_Woocommerce_Api_Client as Api_Client; 21 use Activecampaign_For_Woocommerce_Ac_Tracking_Repository as AC_Tracking; 20 22 21 23 /** 22 24 * The admin-specific functionality of the plugin. 23 * 25 * AC_User 24 26 * Defines the plugin name, version, and two examples hooks for how to 25 27 * enqueue the admin-specific stylesheet and JavaScript. … … 94 96 95 97 /** 98 * The class for the API client to connect to AC. 99 * 100 * @var Activecampaign_For_Woocommerce_Api_Client The client. 101 */ 102 private $api_client; 103 104 /** 96 105 * Initialize the class and set its properties. 97 106 * … … 105 114 * @since 1.0.0 106 115 */ 107 public function __construct( $plugin_name, $version, Validator $validator, Admin_Settings_Updated $event, Connection_Repository $connection_repository, Contact_Repository $contact_repository ) {116 public function __construct( $plugin_name, $version, Validator $validator, Admin_Settings_Updated $event, Connection_Repository $connection_repository, Contact_Repository $contact_repository, Api_Client $api_client ) { 108 117 $this->plugin_name = $plugin_name; 109 118 $this->version = $version; … … 112 121 $this->connection_repository = $connection_repository; 113 122 $this->contact_repository = $contact_repository; 123 $this->api_client = $api_client; 114 124 } 115 125 … … 841 851 $api_url_changing = $this->api_url_is_changing( $data, $current_settings ); 842 852 853 if ( 854 isset( $current_settings['browse_tracking'] ) && 855 in_array( $current_settings['browse_tracking'], [ 1, '1' ] ) && 856 ( 857 ! isset( $current_settings['tracking_id'] ) || 858 empty( $current_settings['tracking_id'] ) 859 ) 860 ) { 861 $tracking_id = $this->activecampaign_fetch_accountid(); 862 $data['tracking_id'] = $tracking_id; 863 } 864 843 865 if ( $current_settings ) { 844 866 $data = array_merge( $current_settings, $data ); … … 1388 1410 wp_send_json_success( 'Entitlement ready for refresh' ); 1389 1411 } 1412 1413 1414 /** 1415 * Gets the tracking/account ID from AC. 1416 * 1417 * @return string tracking ID returned. 1418 */ 1419 private function activecampaign_fetch_accountid() { 1420 $logger = new Logger(); 1421 1422 try { 1423 $ac_user = new AC_Tracking( $this->api_client ); 1424 $tracking_id = $ac_user->find_sitetracking_code(); 1425 1426 // $result = $this->api_client->get( 'user/me' )->execute(); 1427 1428 return $tracking_id; 1429 } catch ( Throwable $t ) { 1430 $logger->warning( 1431 'Could not fetch tracking ID from ActiveCampaign.', 1432 [ 1433 'message' => $t->getMessage(), 1434 'code' => 'ADMIN_1435', 1435 ] 1436 ); 1437 } 1438 } 1390 1439 } -
activecampaign-for-woocommerce/trunk/admin/scripts/activecampaign-for-woocommerce-product-sync.js
r2810439 r3205976 6 6 $('.sync-run-status').hide(); 7 7 $('#activecampaign-run-product-wait').show(); 8 // $('#activecampaign-run-product-sync').addClass('disabled');9 8 $('#activecampaign-product-sync-run-shortly').show(); 10 9 11 10 var batchLimit = 20; 11 var syncDirectMode = 0; 12 13 if($('.activecampaign-product-sync-direct-mode:checked').val() === '1') { 14 syncDirectMode = 1; 15 } 12 16 13 17 if($('#activecampaign-product-sync-limit').find(":selected").text()) { … … 20 24 'action': action, 21 25 'batchLimit': batchLimit, 26 'syncDirectMode': syncDirectMode, 22 27 'activecampaign_for_woocommerce_settings_nonce_field': $('#activecampaign_for_woocommerce_nonce_field').val() 23 28 }); -
activecampaign-for-woocommerce/trunk/admin/trait-activecampaign-for-woocommerce-admin-utilities.php
r3151035 r3205976 196 196 } 197 197 198 if ( ! isset( $current_options['browse_tracking'] ) ) { 199 $options_to_be_saved['browse_tracking'] = '0'; 200 } 201 198 202 if ( ! isset( $current_options['ac_debug'] ) ) { 199 203 $options_to_be_saved['ac_debug'] = '0'; -
activecampaign-for-woocommerce/trunk/admin/views/activecampaign-for-woocommerce-admin-display.php
r3189047 r3205976 37 37 $activecampaign_for_woocommerce_debug_excess = 0; 38 38 $activecampaign_for_woocommerce_desc_select = '0'; 39 $activecampaign_for_woocommerce_browse_tracking = '0'; 39 40 40 41 if ( is_array( $activecampaign_for_woocommerce_options ) ) { … … 150 151 } 151 152 $activecampaign_for_woocommerce_custom_email_field = esc_html( sanitize_text_field( $activecampaign_for_woocommerce_custom_email_field ) ); 153 154 if ( isset( $activecampaign_for_woocommerce_settings['browse_tracking'] ) ) { 155 $activecampaign_for_woocommerce_browse_tracking = $activecampaign_for_woocommerce_settings['browse_tracking']; 156 } 157 $activecampaign_for_woocommerce_browse_tracking = esc_html( sanitize_text_field( $activecampaign_for_woocommerce_browse_tracking ) ); 152 158 } 153 159 … … 180 186 ), 181 187 ); 188 182 189 ?> 183 190 <?php settings_errors(); ?> 191 <style> 192 .helptext { 193 padding-left: 23px; 194 font-style: italic; 195 } 196 </style> 184 197 <div id="activecampaign-for-woocommerce-app"> 185 198 <?php … … 241 254 </a> 242 255 <div> 243 <div id="activecampaign-manual-mode-container">244 or, <span id="activecampaign-manual-mode">manually configure the API</span>245 </div>256 <div id="activecampaign-manual-mode-container"> 257 or, <span id="activecampaign-manual-mode">manually configure the API</span> 258 </div> 246 259 </div> 247 260 </div> … … 322 335 </span><?php esc_html_e( 'ActiveCampaign Configurations', ACTIVECAMPAIGN_FOR_WOOCOMMERCE_LOCALIZATION_DOMAIN ); ?> 323 336 </label> 324 <div id="activecampaign_store" class="accordion-content"> 337 <div id="activecampaign_store" class="accordion-content"> 338 <div> 325 339 <div> 326 <div> 327 <?php 328 wp_nonce_field( 'activecampaign_for_woocommerce_settings_form', 'activecampaign_for_woocommerce_settings_nonce_field' ); 329 ?> 330 <section id="activecampaign_connection_list"> 331 <div> 332 <div id="activecampaign_connection_modal" class="hidden"> 333 <div class="modal-content"> 334 <div class="notice notice-success inline" style="display:none;"> 335 Connection Status 336 </div> 337 <input type="hidden" id="connection_id" name="connection_id" value=""> 338 <label>Site URL <small>(Your WordPress Address URL: <?php echo esc_html( site_url() ); ?>)</small></label> 339 <input type="text" id="connection_external_id" name="connection_external_id" value=""> 340 <label>Integration Name <small>(Used to identify your stores in ActiveCampaign. By default this is your Site Title.)</small></label> 341 <input type="text" id="connection_integration_name" name="connection_integration_name" value=""> 342 <label>Store URL <small>(Your main store page: <?php echo esc_html( get_permalink( wc_get_page_id( 'shop' ) ) ); ?>)</small></label> 343 <input type="text" id="connection_integration_link" name="connection_integration_link" value=""> 344 <input type="hidden" id="connection_integration_logo" name="connection_integration_logo" placeholder="Using default WooCommerce logo" value=""> 345 <div class="activecampaign-block-inputs"> 346 <a href="#" id="activecampaign-send-update-connection-button" 347 data-value="<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>" 348 class="activecampaign-for-woocommerce button secondary" style="display:none;"> 340 <?php 341 wp_nonce_field( 'activecampaign_for_woocommerce_settings_form', 'activecampaign_for_woocommerce_settings_nonce_field' ); 342 ?> 343 <section id="activecampaign_connection_list"> 344 <div> 345 <div id="activecampaign_connection_modal" class="hidden"> 346 <div class="modal-content"> 347 <div class="notice notice-success inline" style="display:none;"> 348 Connection Status 349 </div> 350 <input type="hidden" id="connection_id" name="connection_id" value=""> 351 <label>Site URL <small>(Your WordPress Address URL: <?php echo esc_html( site_url() ); ?>)</small></label> 352 <input type="text" id="connection_external_id" name="connection_external_id" value=""> 353 <label>Integration Name <small>(Used to identify your stores in ActiveCampaign. By default this is your Site Title.)</small></label> 354 <input type="text" id="connection_integration_name" name="connection_integration_name" value=""> 355 <label>Store URL <small>(Your main store page: <?php echo esc_html( get_permalink( wc_get_page_id( 'shop' ) ) ); ?>)</small></label> 356 <input type="text" id="connection_integration_link" name="connection_integration_link" value=""> 357 <input type="hidden" id="connection_integration_logo" name="connection_integration_logo" placeholder="Using default WooCommerce logo" value=""> 358 <div class="activecampaign-block-inputs"> 359 <a href="#" id="activecampaign-send-update-connection-button" 360 data-value="<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>" 361 class="activecampaign-for-woocommerce button secondary" style="display:none;"> 349 362 <span> 350 363 <?php esc_html_e( 'Update connection', ACTIVECAMPAIGN_FOR_WOOCOMMERCE_LOCALIZATION_DOMAIN ); ?> 351 364 </span> 352 </a>353 <a href="#" id="activecampaign-send-create-connection-button"354 data-value="<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>"355 class="activecampaign-for-woocommerce button secondary" style="display:none;">365 </a> 366 <a href="#" id="activecampaign-send-create-connection-button" 367 data-value="<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>" 368 class="activecampaign-for-woocommerce button secondary" style="display:none;"> 356 369 <span> 357 370 <?php esc_html_e( 'Create new connection', ACTIVECAMPAIGN_FOR_WOOCOMMERCE_LOCALIZATION_DOMAIN ); ?> 358 371 </span> 359 </a>360 <a href="#" id="activecampaign-cancel-connection-button"361 data-value="<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>"362 class="activecampaign-for-woocommerce button secondary">372 </a> 373 <a href="#" id="activecampaign-cancel-connection-button" 374 data-value="<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>" 375 class="activecampaign-for-woocommerce button secondary"> 363 376 <span> 364 377 Cancel 365 378 </span> 366 </a> 367 </div> 379 </a> 368 380 </div> 369 381 </div> 370 <div> 371 <h2 style="float:left;">WooCommerce Connections</h2> 372 <div style="float:right"> 373 <a href="#" id="activecampaign-new-connection-button" 374 data-value="<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>" 375 class="activecampaign-for-woocommerce"> 382 </div> 383 <div> 384 <h2 style="float:left;">WooCommerce Connections</h2> 385 <div style="float:right"> 386 <a href="#" id="activecampaign-new-connection-button" 387 data-value="<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>" 388 class="activecampaign-for-woocommerce"> 376 389 <span> 377 390 <?php esc_html_e( 'Create a new connection', ACTIVECAMPAIGN_FOR_WOOCOMMERCE_LOCALIZATION_DOMAIN ); ?> 378 391 </span> 379 </a> 380 </div> 381 <table class="wp-list-table widefat striped table-view-list comments"> 382 <thead> 383 <tr> 384 <th scope="col" > 385 Connection ID 386 </th> 387 <th scope="col"> 388 Site URL 389 </th> 390 <th scope="col"> 391 Integration Name 392 </th> 393 <th scope="col"> 394 Store URL 395 </th> 396 <th scope="col"> 397 Options 398 </th> 399 <th scope="col"> 400 Status 401 </th> 402 </tr> 403 </thead> 404 405 <tbody id="the-connection-list" data-wp-lists="list:connection"> 406 <tr><td colspan="6">Loading...</td></tr> 407 </tbody> 408 409 <tbody id="the-extra-comment-list" data-wp-lists="list:comment" style="display: none;"> 410 <tr class="no-items"><td class="colspanchange" colspan="5">No comments found.</td></tr> </tbody> 411 </table> 392 </a> 412 393 </div> 394 <table class="wp-list-table widefat striped table-view-list comments"> 395 <thead> 396 <tr> 397 <th scope="col" > 398 Connection ID 399 </th> 400 <th scope="col"> 401 Site URL 402 </th> 403 <th scope="col"> 404 Integration Name 405 </th> 406 <th scope="col"> 407 Store URL 408 </th> 409 <th scope="col"> 410 Options 411 </th> 412 <th scope="col"> 413 Status 414 </th> 415 </tr> 416 </thead> 417 418 <tbody id="the-connection-list" data-wp-lists="list:connection"> 419 <tr><td colspan="6">Loading...</td></tr> 420 </tbody> 421 422 <tbody id="the-extra-comment-list" data-wp-lists="list:comment" style="display: none;"> 423 <tr class="no-items"><td class="colspanchange" colspan="5">No comments found.</td></tr> </tbody> 424 </table> 413 425 </div> 414 </section> 415 </div> 416 <?php if ( $this->verify_ac_features( 'abandon' ) ) : ?> 417 <h2> 418 <?php esc_html_e( 'Abandoned Cart', ACTIVECAMPAIGN_FOR_WOOCOMMERCE_LOCALIZATION_DOMAIN ); ?> 419 </h2> 420 <p> 421 <?php esc_html_e( 'How long should the store will wait before considering a cart abandoned to send to ActiveCampaign?', ACTIVECAMPAIGN_FOR_WOOCOMMERCE_LOCALIZATION_DOMAIN ); ?> 422 </p> 423 <p> 424 <?php esc_html_e( 'For example a 1 hour setting would wait until 1 hour after the last activity on the cart and then queue the cart for abandoned cart sync to ActiveCampaign. This relies on a cron job that runs hourly. It may be longer before an abandoned cart goes from ready to synced depending on your cron frequency.', ACTIVECAMPAIGN_FOR_WOOCOMMERCE_LOCALIZATION_DOMAIN ); ?> 425 </p> 426 <label> 427 <?php esc_html_e( 'Select wait time:', ACTIVECAMPAIGN_FOR_WOOCOMMERCE_LOCALIZATION_DOMAIN ); ?> 428 </label> 429 <?php foreach ( $activecampaign_for_woocommerce_ab_cart_options as $activecampaign_for_woocommerce_ab_cart_options_value => $activecampaign_for_woocommerce_ab_cart_options_option ) : ?> 430 <label class="radio"> 431 <input type="radio" 432 id="abcart_wait<?php echo esc_html( $activecampaign_for_woocommerce_ab_cart_options_value ); ?>" 433 name="abcart_wait" 434 value="<?php echo esc_html( $activecampaign_for_woocommerce_ab_cart_options_value ); ?>" 435 <?php 436 if ( (string) $activecampaign_for_woocommerce_ab_cart_options_value === $activecampaign_for_woocommerce_abcart_wait ) { 437 echo 'checked'; 438 } 439 ?> 440 > 441 <?php echo esc_html( $activecampaign_for_woocommerce_ab_cart_options_option ); ?> 442 </label> 443 <?php endforeach; ?> 444 <?php endif; ?> 445 </div> 446 <hr/> 447 <div> 426 </div> 427 </section> 428 </div> 429 <?php if ( $this->verify_ac_features( 'abandon' ) ) : ?> 448 430 <h2> 449 <?php esc_html_e( ' Opt-in Checkbox', ACTIVECAMPAIGN_FOR_WOOCOMMERCE_LOCALIZATION_DOMAIN ); ?>431 <?php esc_html_e( 'Abandoned Cart', ACTIVECAMPAIGN_FOR_WOOCOMMERCE_LOCALIZATION_DOMAIN ); ?> 450 432 </h2> 451 433 <p> 452 <?php esc_html_e( ' Configure what text should appear next to the opt-in checkbox, and whether that checkbox should be visible and checked by default.', ACTIVECAMPAIGN_FOR_WOOCOMMERCE_LOCALIZATION_DOMAIN ); ?>434 <?php esc_html_e( 'How long should the store will wait before considering a cart abandoned to send to ActiveCampaign?', ACTIVECAMPAIGN_FOR_WOOCOMMERCE_LOCALIZATION_DOMAIN ); ?> 453 435 </p> 454 <div> 455 <label for="optin_checkbox_text"> 456 <?php esc_html_e( 'Checkbox text:', ACTIVECAMPAIGN_FOR_WOOCOMMERCE_LOCALIZATION_DOMAIN ); ?> 457 </label> 458 <input type="text" name="optin_checkbox_text" id="optin_checkbox_text" 459 value="<?php echo esc_html( $activecampaign_for_woocommerce_optin_checkbox_text ); ?>"> 460 </div> 461 <h3> 462 <?php esc_html_e( 'Checkbox display options:', ACTIVECAMPAIGN_FOR_WOOCOMMERCE_LOCALIZATION_DOMAIN ); ?> 463 </h3> 464 <?php foreach ( $activecampaign_for_woocommerce_checkbox_display_options as $activecampaign_for_woocommerce_checkbox_display_options_value => $activecampaign_for_woocommerce_checkbox_display_options_option ) : ?> 465 <label class="radio" 466 for="checkbox_display_option_<?php echo esc_html( $activecampaign_for_woocommerce_checkbox_display_options_value ); ?>"> 436 <p> 437 <?php esc_html_e( 'For example a 1 hour setting would wait until 1 hour after the last activity on the cart and then queue the cart for abandoned cart sync to ActiveCampaign. This relies on a cron job that runs hourly. It may be longer before an abandoned cart goes from ready to synced depending on your cron frequency.', ACTIVECAMPAIGN_FOR_WOOCOMMERCE_LOCALIZATION_DOMAIN ); ?> 438 </p> 439 <label> 440 <?php esc_html_e( 'Select wait time:', ACTIVECAMPAIGN_FOR_WOOCOMMERCE_LOCALIZATION_DOMAIN ); ?> 441 </label> 442 <?php foreach ( $activecampaign_for_woocommerce_ab_cart_options as $activecampaign_for_woocommerce_ab_cart_options_value => $activecampaign_for_woocommerce_ab_cart_options_option ) : ?> 443 <label class="radio"> 467 444 <input type="radio" 468 id=" checkbox_display_option_<?php echo esc_html( $activecampaign_for_woocommerce_checkbox_display_options_value ); ?>"469 name=" checkbox_display_option"470 value="<?php echo esc_html( $activecampaign_for_woocommerce_ checkbox_display_options_value ); ?>"445 id="abcart_wait<?php echo esc_html( $activecampaign_for_woocommerce_ab_cart_options_value ); ?>" 446 name="abcart_wait" 447 value="<?php echo esc_html( $activecampaign_for_woocommerce_ab_cart_options_value ); ?>" 471 448 <?php 472 if ( $activecampaign_for_woocommerce_checkbox_display_options_value === $activecampaign_for_woocommerce_optin_checkbox_display_option) {473 echo esc_html( 'checked' );449 if ( (string) $activecampaign_for_woocommerce_ab_cart_options_value === $activecampaign_for_woocommerce_abcart_wait ) { 450 echo 'checked'; 474 451 } 475 452 ?> 476 453 > 477 <?php echo esc_html( $activecampaign_for_woocommerce_ checkbox_display_options_option ); ?>454 <?php echo esc_html( $activecampaign_for_woocommerce_ab_cart_options_option ); ?> 478 455 </label> 479 456 <?php endforeach; ?> 480 </div> 481 <hr/> 482 <?php if ( $this->verify_ac_features( 'abandon' ) ) : ?> 457 <?php endif; ?> 458 </div> 459 <hr/> 460 <div> 461 <h2> 462 <?php esc_html_e( 'Opt-in Checkbox', ACTIVECAMPAIGN_FOR_WOOCOMMERCE_LOCALIZATION_DOMAIN ); ?> 463 </h2> 464 <p> 465 <?php esc_html_e( 'Configure what text should appear next to the opt-in checkbox, and whether that checkbox should be visible and checked by default.', ACTIVECAMPAIGN_FOR_WOOCOMMERCE_LOCALIZATION_DOMAIN ); ?> 466 </p> 467 <div> 468 <label for="optin_checkbox_text"> 469 <?php esc_html_e( 'Checkbox text:', ACTIVECAMPAIGN_FOR_WOOCOMMERCE_LOCALIZATION_DOMAIN ); ?> 470 </label> 471 <input type="text" name="optin_checkbox_text" id="optin_checkbox_text" 472 value="<?php echo esc_html( $activecampaign_for_woocommerce_optin_checkbox_text ); ?>"> 473 </div> 474 <h3> 475 <?php esc_html_e( 'Checkbox display options:', ACTIVECAMPAIGN_FOR_WOOCOMMERCE_LOCALIZATION_DOMAIN ); ?> 476 </h3> 477 <?php foreach ( $activecampaign_for_woocommerce_checkbox_display_options as $activecampaign_for_woocommerce_checkbox_display_options_value => $activecampaign_for_woocommerce_checkbox_display_options_option ) : ?> 478 <label class="radio" 479 for="checkbox_display_option_<?php echo esc_html( $activecampaign_for_woocommerce_checkbox_display_options_value ); ?>"> 480 <input type="radio" 481 id="checkbox_display_option_<?php echo esc_html( $activecampaign_for_woocommerce_checkbox_display_options_value ); ?>" 482 name="checkbox_display_option" 483 value="<?php echo esc_html( $activecampaign_for_woocommerce_checkbox_display_options_value ); ?>" 484 <?php 485 if ( $activecampaign_for_woocommerce_checkbox_display_options_value === $activecampaign_for_woocommerce_optin_checkbox_display_option ) { 486 echo esc_html( 'checked' ); 487 } 488 ?> 489 > 490 <?php echo esc_html( $activecampaign_for_woocommerce_checkbox_display_options_option ); ?> 491 </label> 492 <?php endforeach; ?> 493 </div> 494 <hr/> 495 <?php if ( $this->verify_ac_features( 'abandon' ) ) : ?> 496 <div> 497 <h2> 498 <?php esc_html_e( 'Historical Sync Options', ACTIVECAMPAIGN_FOR_WOOCOMMERCE_LOCALIZATION_DOMAIN ); ?> 499 </h2> 483 500 <div> 484 <h2> 485 <?php esc_html_e( 'Historical Sync Options', ACTIVECAMPAIGN_FOR_WOOCOMMERCE_LOCALIZATION_DOMAIN ); ?> 486 </h2> 487 <div> 488 Change these settings according to your hosting capabilities. Lower numbers will take longer but consume less resources. 489 </div> 490 <div> 491 <label>Runs Per Batch: <span class="help"> (ex: Every time the sync runs 10 batch groups of 50 will run)</span></label> 492 <input type="number" name="sync_batch_runs" id="sync_batch_runs" min="1" max="40" 493 value="<?php echo esc_html( $activecampaign_for_woocommerce_sync_batch_runs ); ?>"> 494 </div> 495 <div> 496 <label>Bulk Sync Batch Limit: <span class="help">(num of records synced to ActiveCampaign at a time)</span></label> 497 <input type="number" name="sync_batch_limit" id="sync_batch_limit" min="1" max="50" 498 value="<?php echo esc_html( $activecampaign_for_woocommerce_sync_batch_limit ); ?>"> Max 50 499 </div> 501 Change these settings according to your hosting capabilities. Lower numbers will take longer but consume less resources. 500 502 </div> 501 <?php endif; ?>502 <hr/>503 <?php if ( $this->verify_ac_features( 'product' ) ) : ?>504 503 <div> 505 <h2> 506 <?php esc_html_e( 'Product Sync Options', ACTIVECAMPAIGN_FOR_WOOCOMMERCE_LOCALIZATION_DOMAIN ); ?> 507 </h2> 508 <label> 509 <?php esc_html_e( 'Product Description:', ACTIVECAMPAIGN_FOR_WOOCOMMERCE_LOCALIZATION_DOMAIN ); ?> 510 </label> 511 <label class="radio"> 512 <input type="radio" id="ac_desc_select0" name="ac_desc_select" value="0" 513 <?php 514 if ( '0' === $activecampaign_for_woocommerce_desc_select ) { 515 echo 'checked'; 516 } 517 ?> 518 > Use full description only 519 <div style="padding-left: 23px;font-style:italic;"> 520 My product descriptions can be assumed to be readable in a small email content block 521 </div> 522 </label> 523 <label class="radio"> 524 <input type="radio" id="ac_desc_select1" name="ac_desc_select" value="1" 525 <?php 526 if ( '1' === $activecampaign_for_woocommerce_desc_select ) { 527 echo 'checked'; 528 } 529 ?> 530 > Use short description only 531 532 <div style="padding-left: 23px;font-style:italic;"> 533 (Will sync with description empty if short description is not included)<br/> 534 My full length descriptions are too long for a small email content block, I need the short description 535 </div> 536 </label> 537 <label class="radio"> 538 <input type="radio" id="ac_desc_select2" name="ac_desc_select" value="2" 539 <?php 540 if ( '2' === $activecampaign_for_woocommerce_desc_select ) { 541 echo 'checked'; 542 } 543 ?> 544 > Use short description but fall back to full description. <small>[Suggested]</small> 545 <div style="padding-left: 23px;font-style:italic;"> 546 (If the short description is not included it will fall back to the full description.)<br/> 547 I prefer the short description, but don’t want anything showing up empty 548 </div> 549 </label> 504 <label>Runs Per Batch: <span class="help"> (ex: Every time the sync runs 10 batch groups of 100 will run)</span></label> 505 <input type="number" name="sync_batch_runs" id="sync_batch_runs" min="1" max="40" 506 value="<?php echo esc_html( $activecampaign_for_woocommerce_sync_batch_runs ); ?>"> 550 507 </div> 551 <?php endif; ?> 552 </div> 508 <div> 509 <label>Bulk Sync Batch Limit: <span class="help">(num of records synced to ActiveCampaign at a time)</span></label> 510 <input type="number" name="sync_batch_limit" id="sync_batch_limit" min="1" max="50" 511 value="<?php echo esc_html( $activecampaign_for_woocommerce_sync_batch_limit ); ?>"> Max 50 512 </div> 513 </div> 514 <?php endif; ?> 515 <hr/> 516 <?php if ( $this->verify_ac_features( 'product' ) ) : ?> 517 <div> 518 <h2> 519 <?php esc_html_e( 'Product Sync Options', ACTIVECAMPAIGN_FOR_WOOCOMMERCE_LOCALIZATION_DOMAIN ); ?> 520 </h2> 521 <label> 522 <?php esc_html_e( 'Product Description:', ACTIVECAMPAIGN_FOR_WOOCOMMERCE_LOCALIZATION_DOMAIN ); ?> 523 </label> 524 <label class="radio"> 525 <input type="radio" id="ac_desc_select0" name="ac_desc_select" value="0" 526 <?php 527 if ( '0' === $activecampaign_for_woocommerce_desc_select ) { 528 echo 'checked'; 529 } 530 ?> 531 > Use full description only 532 <div style="padding-left: 23px;font-style:italic;"> 533 My product descriptions can be assumed to be readable in a small email content block 534 </div> 535 </label> 536 <label class="radio"> 537 <input type="radio" id="ac_desc_select1" name="ac_desc_select" value="1" 538 <?php 539 if ( '1' === $activecampaign_for_woocommerce_desc_select ) { 540 echo 'checked'; 541 } 542 ?> 543 > Use short description only 544 545 <div style="padding-left: 23px;font-style:italic;"> 546 (Will sync with description empty if short description is not included)<br/> 547 My full length descriptions are too long for a small email content block, I need the short description 548 </div> 549 </label> 550 <label class="radio"> 551 <input type="radio" id="ac_desc_select2" name="ac_desc_select" value="2" 552 <?php 553 if ( '2' === $activecampaign_for_woocommerce_desc_select ) { 554 echo 'checked'; 555 } 556 ?> 557 > Use short description but fall back to full description. <small>[Suggested]</small> 558 <div style="padding-left: 23px;font-style:italic;"> 559 (If the short description is not included it will fall back to the full description.)<br/> 560 I prefer the short description, but don’t want anything showing up empty 561 </div> 562 </label> 563 </div> 564 <?php endif; ?> 565 <?php if ( $this->verify_ac_features( 'browsetracking' ) ) : ?> 566 <div> 567 <h2> 568 <?php esc_html_e( 'Tracking & Browse Abandonment', ACTIVECAMPAIGN_FOR_WOOCOMMERCE_LOCALIZATION_DOMAIN ); ?> 569 </h2> 570 <label class="radio"> 571 <input type="radio" id="browse_tracking1" name="browse_tracking" value="1" 572 <?php 573 if ( '1' === $activecampaign_for_woocommerce_browse_tracking ) { 574 echo 'checked'; 575 } 576 ?> 577 > Enabled (Track by default) 578 <p class="helptext"> 579 This option will track all known contacts by default, and will not provide an additional tracking consent notice to your contacts. 580 </p> 581 </label> 582 <label class="radio"> 583 <input type="radio" id="browse_tracking2" name="browse_tracking" value="2" 584 <?php 585 if ( '2' === $activecampaign_for_woocommerce_browse_tracking ) { 586 echo 'checked'; 587 } 588 ?> 589 > Enabled (Do not track by default) 590 <p class="helptext"> 591 This option will not track all known contacts by default. 592 Your contacts will only be tracked after they confirm tracking consent. 593 You must develop a tracking consent notice, and connect it to this plugin, to use this option. You can call the hook [activecampaign_for_woocommerce_load_sitetracking] to then load the tracking. 594 </p> 595 </label> 596 <label class="radio"> 597 <input type="radio" id="browse_tracking0" name="browse_tracking" value="0" 598 <?php 599 if ( '0' === $activecampaign_for_woocommerce_browse_tracking ) { 600 echo 'checked'; 601 } 602 ?> 603 > Off 604 </label> 605 </div> 606 <?php endif; ?> 607 </div> 553 608 </section> 554 609 -
activecampaign-for-woocommerce/trunk/admin/views/activecampaign-for-woocommerce-product-sync.php
r3169593 r3205976 46 46 </div> 47 47 <div class="mb-500"> 48 There are <?php echo esc_html( count( $activecampaign_for_woocommerce_product_sync_data['products'] ) ); ?> products available to sync.49 </div>50 51 <div class="mb-500">52 48 <button type="button" id="activecampaign-run-product-sync" class="activecampaign-for-woocommerce button button-primary" style="padding: 0 10px"> 53 49 <?php … … 68 64 </div> 69 65 <div> 66 <div class="mb-500"> 67 <label>If these values match please choose the safe option.</label><br/> 68 <input type="radio" class="activecampaign-product-sync-direct-mode" name="activecampaign-product-sync-direct-mode" value="0" checked /> <?php echo esc_html( count( $activecampaign_for_woocommerce_product_sync_data['products_wc'] ) ); ?> records via WooCommerce safe methods<br/> 69 <input type="radio" class="activecampaign-product-sync-direct-mode" name="activecampaign-product-sync-direct-mode" value="1" /> <?php echo esc_html( count( $activecampaign_for_woocommerce_product_sync_data['products'] ) ); ?> records via direct data pull<br/> 70 </div> 70 71 <div> 71 72 <label>Batch Limit: </label> -
activecampaign-for-woocommerce/trunk/includes/abandoned_carts/class-activecampaign-for-woocommerce-run-abandonment-sync-command.php
r3177307 r3205976 712 712 if ( $synced_to_ac ) { 713 713 // Update the record to show we've synced so we don't sync it again 714 715 $wpdb->update( 716 $wpdb->prefix . ACTIVECAMPAIGN_FOR_WOOCOMMERCE_TABLE_NAME, 717 array( 714 if ($order_ac->get_email() !== $customer->email ) { 715 // The emails don't match! 716 $this->logger->warning( 717 'The returned email does not match. This could cause an issue with this contact record. Do not save customer ID in this case.', 718 [ 719 'ac_email' => $order_ac->get_email(), 720 'customer_email' => $customer->email, 721 ] 722 ); 723 $ab_data_save = array( 724 'synced_to_ac' => self::STATUS_ABANDONED_CART_AUTO_SYNCED, 725 'abandoned_date' => $this->calculate_abandoned_date( $abc_order ), 726 'ac_order_id' => self::validate_object( $order_ac, 'get_id' ) ? $order_ac->get_id() : null, 727 'ac_customer_id' => null, 728 ); 729 } else { 730 $ab_data_save = array( 718 731 'synced_to_ac' => self::STATUS_ABANDONED_CART_AUTO_SYNCED, 719 732 'abandoned_date' => $this->calculate_abandoned_date( $abc_order ), 720 733 'ac_order_id' => self::validate_object( $order_ac, 'get_id' ) ? $order_ac->get_id() : null, 721 734 'ac_customer_id' => self::validate_object( $order_ac, 'get_customerid' ) ? $order_ac->get_customerid() : null, 722 ), 735 ); 736 } 737 738 $wpdb->update( 739 $wpdb->prefix . ACTIVECAMPAIGN_FOR_WOOCOMMERCE_TABLE_NAME, 740 $ab_data_save, 723 741 array( 724 742 'id' => $abc_order->id, … … 1011 1029 1012 1030 if ( isset( $cart->last_access_time ) && ( ! isset( $cart->abandoned_date ) || empty( $cart->abandoned_date ) ) ) { 1013 try { 1031 1014 1032 $now = new DateTime( 'now', new DateTimeZone( 'UTC' ) ); 1015 1033 1016 if ( ! isset( $this->expire_time ) || empty( $this->expire_time ) ) { 1017 $this->expire_time = 1; 1018 } 1034 // 1 hour is the default 1035 if ( ! isset( $this->expire_time ) || empty( $this->expire_time ) ) { 1036 $this->expire_time = 1; 1037 } 1019 1038 1020 1039 $expire_datetime = new DateTime( 'now -' . $this->expire_time . ' hours', new DateTimeZone( 'UTC' ) ); 1021 1040 $ab_date = new DateTime( $cart->last_access_time . ' + ' . $this->expire_time . ' hours', new DateTimeZone( 'UTC' ) ); 1022 1041 1023 $diff = $expire_datetime->diff( $ab_date, true ); 1024 $i = 0 + ( $diff->days * 24 ); 1025 $i += $diff->hours; 1026 1042 $i = 0; 1043 $hourdiff = 0; 1044 1045 try { 1046 $diff = $expire_datetime->diff( $ab_date, true ); 1047 $hours_in_days = $diff->format( '%d' ) * 24; // get number of hours in days 1048 $hours_in_hours = $diff->format( '%h' ); // add number of hours in hours 1049 1050 if ( ! empty( $hours_in_days ) ) { 1051 $i += intval( $hours_in_days ); 1052 } 1053 1054 if ( ! empty( $hours_in_hours ) ) { 1055 $i += intval( $hours_in_hours ); 1056 } 1057 } catch ( Throwable $t ) { 1058 // cannot use this method on this install 1059 $this->logger->debug( 1060 'Primary time diff in hours could not be calculated for the abandoned cart.', 1061 [ 1062 'cartid' => $cart->id, 1063 'message' => $t->getMessage(), 1064 'trace' => $t->getTrace(), 1065 'last_access_time' => $cart->last_access_time, 1066 ] 1067 ); 1068 } 1069 1070 try { 1071 // secondary method to check 1072 $hourdiff = round( ( strtotime( $cart->last_access_time + $this->expire_time ) - strtotime( $expire_datetime->format( 'Y-m-d H:i:s' ) ) ) / 3600, 0 ); 1073 } catch ( Throwable $t ) { 1074 // cannot use this method 1075 $this->logger->debug( 1076 'Secondary time diff in hours could not be calculated for the abandoned cart.', 1077 [ 1078 'cartid' => $cart->id, 1079 'message' => $t->getMessage(), 1080 'trace' => $t->getTrace(), 1081 'last_access_time' => $cart->last_access_time, 1082 ] 1083 ); 1084 } 1085 try { 1027 1086 // calc_abandoned_date is calculated by the DB 1028 1087 if ( ! empty( $cart->calc_abandoned_date ) && empty( $cart->abandoned_date ) ) { … … 1031 1090 } elseif ( empty( $cart->calc_abandoned_date ) && empty( $cart->abandoned_date ) ) { 1032 1091 // If the DB somehow fails to calculate the date 1033 if ( intval( $i )>= $this->expire_time ) {1092 if ( $i >= $this->expire_time || $hourdiff >= $this->expire_time ) { 1034 1093 // If the expiration and abandonment difference is more than the expire time 1035 1094 return $ab_date->format( 'Y-m-d H:i:s e' ); -
activecampaign-for-woocommerce/trunk/includes/abandoned_carts/trait-activecampaign-for-woocommerce-abandoned-cart-utilities.php
r3189047 r3205976 128 128 $logger = new Logger(); 129 129 if ( isset( $order ) && ! empty( $order ) ) { 130 $customer_id = $customer_util->get_ customer_id( $order );130 $customer_id = $customer_util->get_wc_customer_id( $order ); 131 131 } 132 132 … … 154 154 public function delete_abandoned_cart_by_customer() { 155 155 $customer_util = new Customer_Utilities(); 156 $customer_id = $customer_util->get_ customer_id();156 $customer_id = $customer_util->get_wc_customer_id(); 157 157 $logger = new Logger(); 158 158 -
activecampaign-for-woocommerce/trunk/includes/api-client/class-activecampaign-for-woocommerce-api-client.php
r3089566 r3205976 163 163 'ecom/graphql', 164 164 'account/entitlements', 165 'user/me', 166 'siteTracking/code', 167 'account/info', 165 168 ); 166 169 … … 696 699 } 697 700 701 if ( 702 ( 703 'siteTracking/code' === $this->endpoint || 704 'siteTracking\/code' === $this->endpoint 705 ) 706 ) { 707 $this->logger->debug_calls( 708 'SiteTracking Code Response', 709 array( 710 'endpoint' => $this->endpoint, 711 'method' => $this->method, 712 'response_status_code' => self::validate_object( $response, 'getStatusCode' ) ? $response->getStatusCode() : null, 713 'response_headers' => self::validate_object( $response, 'getHeaders' ) ? $response->getHeaders() : null, 714 'response_body' => self::validate_object( $response, 'getBody' ) ? $response->getBody() : null, 715 'response_contents' => self::validate_object( $response, 'getBody' ) ? $response->getBody()->getContents() : null, 716 'response_string' => self::validate_object( $response, 'getBody' ) ? $response->getBody()->__toString() : null, 717 ) 718 ); 719 720 if ( self::validate_object( $response->getBody(), '__toString' ) ) { 721 return $response->getBody()->__toString(); 722 } 723 } 724 698 725 return $response; 699 726 } -
activecampaign-for-woocommerce/trunk/includes/class-activecampaign-for-woocommerce.php
r3169593 r3205976 506 506 */ 507 507 private function define_admin_commands() { 508 if ( $this-> verify_ac_features( 'historical' ) ) {508 if ( $this->is_configured() && $this->is_connected() && $this->verify_ac_features( 'historical' ) ) { 509 509 $this->define_historical_sync_commands(); 510 510 } 511 if ( $this->verify_ac_features( 'product' ) ) { 511 512 if ( $this->is_configured() && $this->is_connected() && $this->verify_ac_features( 'product' ) ) { 512 513 $this->define_product_sync(); 513 514 } … … 610 611 'woocommerce_order_edit_status', 611 612 $this->order_events, 612 'execute_order_edit_status ',613 'execute_order_edit_status_event', 613 614 20, 614 615 2 … … 674 675 'execute', 675 676 1, 676 1677 2 677 678 ); 678 679 … … 914 915 ); 915 916 917 $this->loader->add_action( 918 'activecampaign_for_woocommerce_miscat_order_to_subscription_historical', 919 $this->subscription_events, 920 'trigger_historical_order_to_historical_subscription', 921 2, 922 2 923 ); 924 916 925 // $this->loader->add_action( 917 926 // 'woocommerce_subscription_payment_complete', … … 947 956 948 957 $this->define_subscription_commands(); 958 959 $this->loader->add_action( 960 'activecampaign_for_woocommerce_load_sitetracking', 961 $this->admin, 962 'activecampaign_load_sitetracking' 963 ); 949 964 950 965 // custom hook for hourly abandoned cart -
activecampaign-for-woocommerce/trunk/includes/config/activecampaign-for-woocommerce-class-factories.php
r3049374 r3205976 137 137 $event = new Activecampaign_For_Woocommerce_Admin_Settings_Updated_Event(); 138 138 139 return new Admin( $plugin_name, $version, $validator, $event, $connection_repository, $contact_repository );139 return new Admin( $plugin_name, $version, $validator, $event, $connection_repository, $contact_repository, $api_client ); 140 140 }, 141 141 -
activecampaign-for-woocommerce/trunk/includes/config/activecampaign-for-woocommerce-global-constants.php
r3189047 r3205976 26 26 */ 27 27 if ( ! defined( 'ACTIVECAMPAIGN_FOR_WOOCOMMERCE_VERSION' ) ) { 28 define( 'ACTIVECAMPAIGN_FOR_WOOCOMMERCE_VERSION', '2. 7.11' );28 define( 'ACTIVECAMPAIGN_FOR_WOOCOMMERCE_VERSION', '2.8.0' ); 29 29 } 30 30 -
activecampaign-for-woocommerce/trunk/includes/customers/class-activecampaign-for-woocommerce-customer-utilities.php
r2968938 r3205976 133 133 134 134 /** 135 * Returns a customer ID if we can find one.135 * Returns a WooCommerce customer ID if we can find one. 136 136 * 137 137 * @param WC_Order|null $order The order object. … … 139 139 * @return bool|string 140 140 */ 141 public function get_ customer_id( $order = null ) {141 public function get_wc_customer_id( $order = null ) { 142 142 if ( is_null( $order ) && self::validate_object( wc()->session, 'get_customer_id' ) && ! empty( wc()->session->get_customer_id() ) ) { 143 143 return wc()->session->get_customer_id(); -
activecampaign-for-woocommerce/trunk/includes/features/class-activecampaign-for-woocommerce-ac-features.php
r3151035 r3205976 53 53 'ecom-product-catalog', 54 54 'ecom-recurring-payments', 55 'ecom-browse-abandonment', 55 56 ]; 56 57 -
activecampaign-for-woocommerce/trunk/includes/features/trait-activecampaign-for-woocommerce-features-checker.php
r3089566 r3205976 45 45 $logger = new Logger(); 46 46 $features = array( 47 'historical' => 'ecom-historical-sync', 48 'abandon' => 'ecom-core', 49 'activesync' => 'ecom-core', 50 'recurring' => 'ecom-recurring-payments', 51 'product' => 'ecom-product-catalog', 52 'ecommerce' => 'ecommerce', 47 'historical' => 'ecom-historical-sync', 48 'abandon' => 'ecom-core', 49 'activesync' => 'ecom-core', 50 'recurring' => 'ecom-recurring-payments', 51 'product' => 'ecom-product-catalog', 52 'ecommerce' => 'ecommerce', 53 'browsetracking' => 'ecom-browse-abandonment', 53 54 ); 54 55 -
activecampaign-for-woocommerce/trunk/includes/models/class-activecampaign-for-woocommerce-ac-contact.php
r2966088 r3205976 117 117 private $tags; 118 118 119 public function __construct() { 120 121 // Start completely empty 122 $this->id = null; 123 $this->externalid = ''; 124 $this->email = ''; 125 $this->first_name = ''; 126 $this->last_name = ''; 127 $this->phone = ''; 128 } 129 119 130 /** 120 131 * Returns a connection id. … … 304 315 * Creates the contact model from an order object. 305 316 * 306 * @param WC_Order $ order The WC Order.317 * @param WC_Order $wc_order_or_subscription The WC Order or Subscription. 307 318 * 308 319 * @return bool 309 320 */ 310 public function create_ecom_contact_from_order( $ order) {321 public function create_ecom_contact_from_order( $wc_order_or_subscription ) { 311 322 $logger = new Logger(); 312 if ( isset( $ order ) && self::validate_object( $order, 'get_id' ) && $order->get_id() ) {313 $ customer = null;314 if ( $ order->get_customer_id() ) {323 if ( isset( $wc_order_or_subscription ) && self::validate_object( $wc_order_or_subscription, 'get_id' ) && $wc_order_or_subscription->get_id() ) { 324 $wc_customer = null; 325 if ( $wc_order_or_subscription->get_customer_id() ) { 315 326 try { 316 327 // Use the customer information 317 $customer = new WC_Customer( $order->get_customer_id(), false ); 318 319 if ( $customer->get_id() ) { 320 $this->externalid = $customer->get_id(); 321 } 322 323 if ( $customer->get_email() ) { 324 $this->email = $customer->get_email(); 325 } elseif ( $customer->get_billing_email() ) { 326 $this->email = $customer->get_billing_email(); 327 } 328 329 if ( $customer->get_first_name() ) { 330 $this->first_name = $customer->get_first_name(); 331 } elseif ( $customer->get_billing_first_name() ) { 332 $this->first_name = $customer->get_billing_first_name(); 333 } 334 335 if ( $customer->get_last_name() ) { 336 $this->last_name = $customer->get_last_name(); 337 } elseif ( $customer->get_billing_last_name() ) { 338 $this->last_name = $customer->get_billing_last_name(); 339 } 340 341 if ( $customer->get_billing_phone() ) { 342 $this->phone = $customer->get_billing_phone(); 328 $wc_customer = new WC_Customer( $wc_order_or_subscription->get_customer_id(), false ); 329 330 if ( $wc_customer->get_id() ) { 331 // Note this is for WC customer ID specifically. 332 $this->externalid = $wc_customer->get_id(); 333 } 334 335 if ( $wc_customer->get_email() ) { 336 $this->email = $wc_customer->get_email(); 337 } elseif ( $wc_customer->get_billing_email() ) { 338 $this->email = $wc_customer->get_billing_email(); 339 } 340 341 if ( $wc_customer->get_first_name() ) { 342 $this->first_name = $wc_customer->get_first_name(); 343 } elseif ( $wc_customer->get_billing_first_name() ) { 344 $this->first_name = $wc_customer->get_billing_first_name(); 345 } 346 347 if ( $wc_customer->get_last_name() ) { 348 $this->last_name = $wc_customer->get_last_name(); 349 } elseif ( $wc_customer->get_billing_last_name() ) { 350 $this->last_name = $wc_customer->get_billing_last_name(); 351 } 352 353 if ( $wc_customer->get_billing_phone() ) { 354 $this->phone = $wc_customer->get_billing_phone(); 343 355 } 344 356 … … 354 366 } 355 367 356 if ( ! $ customer || ! $order->get_customer_id() || ! $customer->get_email() ) {368 if ( ! $wc_customer || ! $wc_order_or_subscription->get_customer_id() || ! $wc_customer->get_email() ) { 357 369 try { 358 370 $this->externalid = 0; 359 if ( self::validate_object( $ order, 'get_billing_email' ) ) {360 $this->email = $ order->get_billing_email();361 $this->first_name = $ order->get_billing_first_name();362 $this->last_name = $ order->get_billing_last_name();363 $this->phone = $ order->get_billing_phone();371 if ( self::validate_object( $wc_order_or_subscription, 'get_billing_email' ) ) { 372 $this->email = $wc_order_or_subscription->get_billing_email(); 373 $this->first_name = $wc_order_or_subscription->get_billing_first_name(); 374 $this->last_name = $wc_order_or_subscription->get_billing_last_name(); 375 $this->phone = $wc_order_or_subscription->get_billing_phone(); 364 376 365 377 return true; … … 369 381 'AC Contact: There was a problem preparing data for a record.', 370 382 [ 371 'customer_email' => self::validate_object( $ order, 'get_billing_email' ) ? $order->get_billing_email() : null,383 'customer_email' => self::validate_object( $wc_order_or_subscription, 'get_billing_email' ) ? $wc_order_or_subscription->get_billing_email() : null, 372 384 'message' => $t->getMessage(), 373 385 ] -
activecampaign-for-woocommerce/trunk/includes/models/factories/class-activecampaign-for-woocommerce-ecom-order-factory.php
r2966088 r3205976 62 62 */ 63 63 public function from_woocommerce( $cart, $customer ) { 64 $ order= new Ecom_Order();65 $logger = new Logger();64 $ecom_order = new Ecom_Order(); 65 $logger = new Logger(); 66 66 67 67 try { … … 69 69 $date = new DateTime( 'now', new DateTimeZone( 'UTC' ) ); 70 70 71 $ order->set_id( $this->get_ac_id() );71 $ecom_order->set_id( $this->get_ac_id() ); 72 72 73 73 $external_id = $this->generate_externalcheckoutid( … … 75 75 $customer->get_email() 76 76 ); 77 $ order->set_externalcheckoutid( $external_id );78 $ order->set_source( '1' );79 $ order->set_email( $customer->get_email() );80 $ order->set_total_price( $this->get_cart_total( $cart ) );81 $ order->set_currency( $this->get_woocommerce_currency() );82 $ order->set_connectionid( $this->admin->get_connection_storage()['connection_id'] );83 $ order->set_customerid( $this->get_ac_customer_id() );84 $ order->set_order_date( $date->format( DATE_ATOM ) );85 $ order->set_order_url( wc_get_cart_url() );77 $ecom_order->set_externalcheckoutid( $external_id ); 78 $ecom_order->set_source( '1' ); 79 $ecom_order->set_email( $customer->get_email() ); 80 $ecom_order->set_total_price( $this->get_cart_total( $cart ) ); 81 $ecom_order->set_currency( $this->get_woocommerce_currency() ); 82 $ecom_order->set_connectionid( $this->admin->get_connection_storage()['connection_id'] ); 83 $ecom_order->set_customerid( $this->get_ac_customer_id() ); 84 $ecom_order->set_order_date( $date->format( DATE_ATOM ) ); 85 $ecom_order->set_order_url( wc_get_cart_url() ); 86 86 } 87 87 } catch ( Throwable $t ) { … … 103 103 104 104 if ( count( $products ) > 0 ) { 105 array_walk( $products, [ $ order, 'push_order_product' ] );105 array_walk( $products, [ $ecom_order, 'push_order_product' ] ); 106 106 } else { 107 107 $logger->warning( … … 127 127 } 128 128 129 return $ order;129 return $ecom_order; 130 130 } 131 131 -
activecampaign-for-woocommerce/trunk/includes/orders/class-activecampaign-for-woocommerce-cofe-order-builder.php
r3189047 r3205976 96 96 * @param int $source The source. 97 97 * 98 * @return Activecampaign_For_Woocommerce_Cofe_Ecom_Order| null98 * @return Activecampaign_For_Woocommerce_Cofe_Ecom_Order|int|null 99 99 */ 100 100 public function setup_cofe_order_from_table( $wc_order, $source = 0 ) { … … 116 116 function_exists( 'wcs_is_subscription' ) && wcs_is_subscription( $wc_order->get_id() ) 117 117 ) { 118 $wc_subscription = wcs_get_subscription( $wc_order->get_id() ); 118 119 $logger->warning( 119 120 'This record was improperly triggered by WooCommerce as an order but is a subscription. It will be processed as a subscription instead.', 120 121 [ 121 'order_id' => $wc_order->get_id(), 122 'order_id' => self::validate_object( $wc_order, 'get_id' ) ? $wc_order->get_id() : null, 123 'source' => $source, 122 124 ] 123 125 ); 124 126 125 $wc_subscription = wcs_get_subscription( $wc_order->get_id() ); 126 127 if ( ! empty( $wc_subscription->get_id() ) ) { 128 $subscription_id = $wc_subscription->get_id(); 129 do_action( 'activecampaign_for_woocommerce_miscat_order_to_subscription', [ $subscription_id ] ); 130 131 return null; 127 $wc_subscription = wcs_get_subscription( $wc_order->get_id() ); 128 $wc_subscription_id = $wc_subscription->get_id(); 129 130 if ( ! empty( $wc_subscription_id ) ) { 131 if ( 0 === $source ) { 132 do_action( 'activecampaign_for_woocommerce_miscat_order_to_subscription_historical', [ $wc_subscription_id ] ); 133 } else { 134 do_action( 'activecampaign_for_woocommerce_miscat_order_to_subscription', [ $wc_subscription_id ] ); 135 } 136 137 return 30; // 30 is the designator for subscription status block 132 138 } 133 139 } -
activecampaign-for-woocommerce/trunk/includes/orders/class-activecampaign-for-woocommerce-new-order-created-event.php
r3169593 r3205976 256 256 257 257 if ( ! isset( $customer_data['id'] ) || empty( $customer_data['id'] ) ) { 258 $found_customer_id = $customer_utilities->get_ customer_id( $wc_order );258 $found_customer_id = $customer_utilities->get_wc_customer_id( $wc_order ); 259 259 if ( isset( $found_customer_id ) && ! empty( $found_customer_id ) ) { 260 $customer_data['id'] = $customer_utilities->get_ customer_id( $wc_order );260 $customer_data['id'] = $customer_utilities->get_wc_customer_id( $wc_order ); 261 261 } 262 262 } 263 263 264 264 if ( empty( $customer_data['id'] ) ) { 265 $customer_data['id'] = 0;265 $customer_data['id'] = null; 266 266 } 267 267 … … 293 293 294 294 if ( isset( $stored_row->wc_order_id ) && ! empty( $stored_row->wc_order_id ) ) { 295 $this->schedule_sync_job( $order_id ); 295 296 return; 296 297 } … … 307 308 if ( isset( $stored_row->wc_order_id ) && ! empty( $stored_row->wc_order_id ) ) { 308 309 // If we've saved the order we do not need to save again to stop redundant events 310 $this->schedule_sync_job( $order_id ); 309 311 return; 310 312 } … … 516 518 if ( ! wp_get_scheduled_event( ACTIVECAMPAIGN_FOR_WOOCOMMERCE_RUN_NEW_ORDER_SYNC_NAME, [ 'row_id' => $row_id ] ) ) { 517 519 wp_schedule_single_event( 518 time() + 30,520 time() + 10, 519 521 ACTIVECAMPAIGN_FOR_WOOCOMMERCE_RUN_NEW_ORDER_SYNC_NAME, 520 522 [ … … 528 530 [ 529 531 'row_id' => $row_id, 530 'current_time' => time() + 30,531 'schedule' => wp_get_scheduled_event( ACTIVECAMPAIGN_FOR_WOOCOMMERCE_RUN_NEW_ORDER_SYNC_NAME, [ ' id' => $row_id ] ),532 'current_time' => time() + 10, 533 'schedule' => wp_get_scheduled_event( ACTIVECAMPAIGN_FOR_WOOCOMMERCE_RUN_NEW_ORDER_SYNC_NAME, [ 'row_id' => $row_id ] ), 532 534 ] 533 535 ); -
activecampaign-for-woocommerce/trunk/includes/orders/class-activecampaign-for-woocommerce-new-order-sync-job.php
r3169593 r3205976 398 398 399 399 try { 400 if ( isset( $prep_order->ac_customer_id ) && ! empty( $prep_order->ac_customer_id ) ) { 401 $ac_customer_id = $prep_order->ac_customer_id; 402 } else { 400 $extract_email = $this->extract_email_from_order( $wc_order ); 401 if ( ! empty( $extract_email ) ) { 402 $ac_customer_id = $this->get_ac_customer_id( $extract_email ); 403 } elseif ( isset( $prep_order->customer_email ) && ! empty( $prep_order->customer_email ) ) { 403 404 $ac_customer_id = $this->get_ac_customer_id( $prep_order->customer_email ); 404 405 } … … 450 451 try { 451 452 // RECOVERED 452 if ( isset( $unsynced_recovered_order->ac_customer_id ) && ! empty( $unsynced_recovered_order->ac_customer_id ) ) { 453 $ac_customer_id = $unsynced_recovered_order->ac_customer_id; 454 } else { 453 $extract_email = $this->extract_email_from_order( $wc_order ); 454 if ( ! empty( $extract_email ) ) { 455 $ac_customer_id = $this->get_ac_customer_id( $extract_email ); 456 } elseif ( isset( $unsynced_recovered_order->customer_email ) && ! empty( $unsynced_recovered_order->customer_email ) ) { 455 457 $ac_customer_id = $this->get_ac_customer_id( $unsynced_recovered_order->customer_email ); 456 458 } … … 514 516 // Data for cofe order sync 515 517 $ecom_order = $cofe_order_builder->setup_cofe_order_from_table( $wc_order, 1 ); 516 if ( ! is_null( $status ) ) { 518 519 if ( ! is_null( $status ) && ! is_null( $ecom_order ) ) { 517 520 $ecom_order->set_wc_status( $status ); 518 521 } 522 519 523 if ( is_null( $ecom_order ) ) { 520 524 $this->logger->warning( 'Setup COFE order returned null. Something may have gone wrong or the data may not be missing/incompatible with AC.' ); 525 526 return false; 527 } elseif (30 === $ecom_order ) { 528 $this->logger->debug( 529 'Ecom order builder returned miscat. This order is actually a subscription.', 530 [ 531 'order_id' => ! empty( $wc_order->get_id() ) ? $wc_order->get_id() : null, 532 ] 533 ); 534 521 535 return false; 522 536 } -
activecampaign-for-woocommerce/trunk/includes/orders/class-activecampaign-for-woocommerce-order-action-events.php
r3177307 r3205976 86 86 87 87 if ( isset( $order_id ) && ! empty( $order_id ) ) { 88 $post_type = get_post_type( $order_id ); 89 88 90 $logger->debug_excess( 89 91 'Order update triggered', 90 92 [ 91 'order' => $order_id, 92 ] 93 ); 94 95 $post_type = get_post_type( $order_id ); 96 97 // If it's a subscription, route through sub update 98 if ( 'shop_subscription' === $post_type ) { 99 $wc_subscription = $this->get_wc_subscription( $order_id ); 100 101 if ( $this->check_update_validity( $wc_subscription ) ) { 102 do_action( 'activecampaign_for_woocommerce_route_order_update_to_subscription', [ $wc_subscription ] ); 103 } 104 93 'order' => $order_id, 94 'post_type' => $post_type, 95 ] 96 ); 97 98 if ($this->check_if_subscription_and_reroute( $order_id, $post_type ) ) { 105 99 return; 106 100 } … … 162 156 163 157 if ( isset( $order_id ) && ! empty( $order_id ) ) { 158 $post_type = get_post_type( $order_id ); 159 164 160 $logger->debug_excess( 165 161 'Order status update triggered', … … 168 164 'order_status' => $from_status, 169 165 'new_status' => $to_status, 170 ] 171 ); 172 173 $post_type = get_post_type( $order_id ); 174 175 // If it's a subscription, route through subscription update. 176 if ( 'shop_subscription' === $post_type ) { 177 $wc_subscription = $this->get_wc_subscription( $order_id ); 178 179 do_action( 'activecampaign_for_woocommerce_route_order_update_to_subscription', [ $wc_subscription ] ); 166 'post_type' => $post_type, 167 ] 168 ); 169 170 if ($this->check_if_subscription_and_reroute( $order_id, $post_type ) ) { 180 171 return; 181 172 } … … 228 219 } 229 220 230 public function execute_order_edit_status( $order_id, $new_status ) { 221 /** 222 * Executes the code based on an order status edit action event. 223 * 224 * @param string|int $order_id The order id. 225 * @param string $new_status The new updated status. 226 * 227 * @return void 228 */ 229 public function execute_order_edit_status_event( $order_id, $new_status ) { 231 230 $wc_order = $this->get_wc_order( $order_id ); 232 231 233 232 if ( self::validate_object( $wc_order, 'get_data' ) ) { 234 233 set_transient( 'acforwc_order_updated_hook', wp_date( DATE_ATOM ), 604800 ); 234 235 $post_type = get_post_type( $order_id ); 236 if ($this->check_if_subscription_and_reroute( $order_id, $post_type ) ) { 237 return; 238 } 235 239 236 240 if ( ! wp_get_scheduled_event( … … 406 410 */ 407 411 private function check_update_validity( $wc_order ) { 408 $logger = new Logger();409 $last_synced = $wc_order->get_meta( 'ac_order_last_synced_time' );410 $last_status = $wc_order->get_meta( 'ac_last_synced_status' );411 $ac_datahash = $wc_order->get_meta( 'ac_datahash' );412 $logger = new Logger(); 413 $last_synced = $wc_order->get_meta( 'ac_order_last_synced_time' ); 414 $last_status = $wc_order->get_meta( 'ac_last_synced_status' ); 415 $ac_datahash = $wc_order->get_meta( 'ac_datahash' ); 412 416 try { 413 417 $current_datahash = md5( wp_json_encode( $wc_order->get_data() ) ); … … 460 464 return true; 461 465 } 466 467 private function check_if_subscription_and_reroute( $order_id, $post_type ) { 468 $logger = new Logger(); 469 470 try { 471 // If it's a subscription, route through sub update 472 if ( 473 'shop_subscription' === $post_type || 474 'shop_order_placehold' === $post_type || 475 ( 476 function_exists( 'wcs_is_subscription' ) && 477 wcs_is_subscription( $order_id ) 478 ) 479 ) { 480 $wc_subscription = $this->get_wc_subscription( $order_id ); 481 $subscription_id = $wc_subscription->get_id(); 482 483 if ( wcs_is_subscription( $subscription_id ) ) { 484 $logger->debug( 485 'Order update accidentally triggered from subscription. Routing order to subscription instead.', 486 array( 487 'order_id' => $order_id, 488 'subscription_id' => $subscription_id, 489 'subscription item count' => $wc_subscription->get_item_count(), 490 'is_subscription on order' => wcs_is_subscription( $order_id ), 491 'is_subscription on subscription' => wcs_is_subscription( $subscription_id ), 492 ) 493 ); 494 495 if ( $this->check_update_validity( $wc_subscription ) ) { 496 do_action( 'activecampaign_for_woocommerce_route_order_update_to_subscription', [ $wc_subscription ] ); 497 } 498 499 return true; 500 } 501 } 502 } catch (Throwable $t ) { 503 $logger->warning( 504 'Something went wrong validating post type as shop_subscription', 505 [ 506 'message' => $t->getMessage(), 507 ] 508 ); 509 } 510 511 return false; 512 } 462 513 } -
activecampaign-for-woocommerce/trunk/includes/orders/historical/class-activecampaign-for-woocommerce-historical-sync-runner-cofe.php
r3122277 r3205976 206 206 '%d' // where format 207 207 ); 208 } else {208 } else if (false === $sync_response ) { 209 209 $wpdb->update( 210 210 ( $wpdb->prefix . ACTIVECAMPAIGN_FOR_WOOCOMMERCE_TABLE_NAME ), // table … … 393 393 394 394 if ( is_null( $cofe_ecom_order ) ) { 395 $this->logger->debug( 'Ecom order builder returned null. Something may have gone wrong with the sync.' ); 395 $this->logger->debug( 396 'Ecom order builder returned null. Something may have gone wrong with the sync or the order may have been miscategorized.', 397 [ 398 'order_id' => isset( $order_id ) ? $order_id : null, 399 ] 400 ); 401 396 402 $this->add_incompatible_order_to_status( $order_id ); 397 403 $this->mark_order_as_historical_incompatible( $order_id ); 404 unset( $order_ids[ $k ] ); 405 continue; 406 } elseif (30 === $cofe_ecom_order ) { 407 $this->logger->debug( 408 'Ecom order builder returned miscat. This order is actually a subscription.', 409 [ 410 'order_id' => isset( $order_id ) ? $order_id : null, 411 ] 412 ); 413 398 414 unset( $order_ids[ $k ] ); 399 415 continue; … … 442 458 } 443 459 } 460 } 461 462 if ( false === $r ) { 463 return null; 444 464 } 445 465 } … … 481 501 self::wpdb_update_in( 482 502 ( $wpdb->prefix . ACTIVECAMPAIGN_FOR_WOOCOMMERCE_TABLE_NAME ), // table 483 array( 'synced_to_ac' => self::STATUS_HISTORICAL_SYNC_ PREP), // data503 array( 'synced_to_ac' => self::STATUS_HISTORICAL_SYNC_QUEUE ), // data 484 504 array( 'wc_order_id' => $order_ids ), // where 485 505 array( '%d' ), // format -
activecampaign-for-woocommerce/trunk/includes/orders/trait-activecampaign-for-woocommerce-order-data-gathering.php
r3049374 r3205976 475 475 return get_site_url(); 476 476 } 477 478 /** 479 * Extract the email from an order. 480 * 481 * @param WC_Order $wc_order The WC Order. 482 * 483 * @return mixed|null 484 */ 485 public function extract_email_from_order( $wc_order ) { 486 if ( self::validate_object( $wc_order, 'get_billing_email' ) && $wc_order->get_billing_email() && ! empty( $wc_order->get_billing_email() ) ) { 487 return $wc_order->get_billing_email(); 488 } elseif ( self::validate_object( $wc_order, 'get_user' ) && $wc_order->get_user() && ! empty( $wc_order->get_user()->user_email ) ) { 489 // If we can't find the billing email for whatever reason look for the user email. 490 return $wc_order->get_user()->user_email; 491 } else { 492 return null; 493 } 494 } 477 495 } -
activecampaign-for-woocommerce/trunk/includes/orders/trait-activecampaign-for-woocommerce-synced-status-handler.php
r3104234 r3205976 364 364 self::STATUS_HISTORICAL_SYNC_PREP, 365 365 self::STATUS_HISTORICAL_SYNC_QUEUE, 366 self::STATUS_SYNC_INCOMPATIBLE, 366 367 self::STATUS_SUBSCRIPTION_HISTORICAL_SYNC_FINISH, 367 368 self::STATUS_SUBSCRIPTION_HISTORICAL_SYNC_PREP, 368 369 self::STATUS_SUBSCRIPTION_HISTORICAL_SYNC_QUEUE, 369 370 self::STATUS_SUBSCRIPTION_INCOMPATIBLE, 371 self::STATUS_SUBSCRIPTION_EXPIRED, 372 self::STATUS_SUBSCRIPTION_FAILED_SYNC, 373 self::STATUS_SUBSCRIPTION_FAILED_BILLING, 374 self::STATUS_FAIL, 375 self::STATUS_SYNCED, 370 376 ] 371 377 ); … … 374 380 $delete_count = $wpdb->query( 375 381 'DELETE FROM ' . $wpdb->prefix . ACTIVECAMPAIGN_FOR_WOOCOMMERCE_TABLE_NAME . 376 ' WHERE ( order_date < "' . $expire_2week . '" AND synced_to_ac IN (' . $synced_to_ac_implode . ') ) OR (order_date < "' . $expire_4week . '" AND synced_to_ac = 1) OR (order_date IS NULL AND abandoned_date IS NULL AND last_access_time IS NULL)'382 ' WHERE (synced_to_ac IN (' . $synced_to_ac_implode . ') ) OR (order_date < "' . $expire_4week . '" AND synced_to_ac = 0) OR (order_date IS NULL AND abandoned_date IS NULL AND last_access_time IS NULL)' 377 383 ); 378 384 -
activecampaign-for-woocommerce/trunk/includes/products/class-activecampaign-for-woocommerce-product-sync-job.php
r3169593 r3205976 57 57 */ 58 58 private $batch_limit; 59 60 /** 61 * Direct mode enabled. 1 = enabled = uses direct DB access. 62 * 63 * @var int 64 */ 65 private $direct_mode; 66 59 67 /** 60 68 * Activecampaign_For_Woocommerce_Product_Sync_Job constructor. … … 71 79 $this->start_record = 0; 72 80 $this->batch_limit = 20; 81 $this->direct_mode = 0; 73 82 } 74 83 … … 100 109 'batch_limit' => $this->batch_limit, 101 110 'start_record' => $this->start_record, 111 'direct_mode' => $this->direct_mode, 102 112 ) 103 113 ); … … 245 255 $offset = 0; 246 256 247 $wc_product_ids = $this->get_products_by_offset( $this->batch_limit, $offset, true ); 248 257 if ($this->direct_mode ) { 258 $wc_product_ids = $this->get_products_direct_by_offset( $this->batch_limit, $offset, true ); 259 } else { 260 $wc_product_ids = $this->get_products_by_offset( $this->batch_limit, $offset, true ); 261 } 249 262 while ( $wc_product_ids ) { 250 263 $this->schedule_background_product_sync( $offset, $this->batch_limit ); 251 264 252 265 $offset += count( $wc_product_ids ); 253 254 $wc_product_ids = $this->get_products_by_offset( $this->batch_limit, $offset, true ); 255 } 256 266 if ($this->direct_mode ) { 267 $wc_product_ids = $this->get_products_direct_by_offset( $this->batch_limit, $offset, true ); 268 } else { 269 $wc_product_ids = $this->get_products_by_offset( $this->batch_limit, $offset, true ); 270 } 271 } 272 273 $status = $this->add_args_to_status( $args ); 257 274 } 258 275 … … 301 318 $this->start_record = $args[0]->start_record; 302 319 } 320 if ( ! empty( $data->direct_mode ) || 1 === $data->direct_mode || '1' === $data->direct_mode ) { 321 $this->direct_mode = $args[0]->direct_mode; 322 } 303 323 } 304 324 … … 309 329 if ( ! empty( $data['start_record'] ) || 0 === $data['start_record'] || '0' === $data['start_record'] ) { 310 330 $this->start_record = $data['start_record']; 331 } 332 if ( ! empty( $data['direct_mode'] ) || 1 === $data['direct_mode'] || '1' === $data['direct_mode'] ) { 333 $this->direct_mode = $data['direct_mode']; 311 334 } 312 335 } … … 324 347 $this->start_record = $_post['startRecord']; 325 348 } 349 if ( isset( $_post['syncDirectMode'] ) && ! empty( $_post['syncDirectMode'] ) ) { 350 $this->direct_mode = $_post['syncDirectMode']; 351 } 326 352 } 327 353 328 354 $status->start_record = $this->start_record; 329 355 $status->batch_limit = $this->batch_limit; 356 $status->direct_mode = $this->direct_mode; 330 357 331 358 Sync_Status::update_status( ACTIVECAMPAIGN_FOR_WOOCOMMERCE_PRODUCT_SYNC_RUNNING_STATUS_NAME, $status ); … … 347 374 'start_record' => (int) $offset, 348 375 'batch_limit' => (int) $batch_limit, 376 'direct_mode' => (int) $this->direct_mode, 349 377 ], 350 378 ]; … … 435 463 $limit = $this->batch_limit; 436 464 437 $wc_products = $this->get_products_by_offset( $limit, $offset, false ); 465 if ($this->direct_mode ) { 466 $wc_products = $this->get_products_direct_by_offset( $limit, $offset, false ); 467 } else { 468 $wc_products = $this->get_products_by_offset( $limit, $offset, false ); 469 } 438 470 } else { 439 471 $wc_products = $products_list; … … 579 611 $p_data = Ecom_Cofe_Product::product_array_for_cofe( $product, $connection_id, $parent ); 580 612 if ( ! is_null( $p_data ) ) { 581 $product_data[ ] = $p_data;613 $product_data[ $p_data['storePrimaryId'] ] = $p_data; 582 614 } 583 615 } -
activecampaign-for-woocommerce/trunk/includes/products/class-activecampaign-for-woocommerce-sync-status.php
r3169593 r3205976 26 26 $status_name = 'none', 27 27 $is_halted = false, 28 $is_cancelled = false 28 $is_cancelled = false, 29 $direct_mode = false 29 30 ) { 30 31 $this->start_record = $start_record; // Required … … 40 41 $this->is_halted = $is_halted; // Required 41 42 $this->is_cancelled = $is_cancelled; // Required 43 $this->direct_mode = $direct_mode; 42 44 } 43 45 … … 53 55 $data['failed_id_array'], 54 56 $data['is_running'], 55 $data['status_name'] 57 $data['status_name'], 58 $data['direct_mode'] 56 59 ); 57 60 } … … 153 156 public $failed_order_id_array; 154 157 158 /** 159 * @var false|mixed 160 */ 161 public $direct_mode; 155 162 156 163 /** -
activecampaign-for-woocommerce/trunk/includes/repositories/class-activecampaign-for-woocommerce-cofe-order-repository.php
r3122277 r3205976 175 175 'message' => $t->getMessage(), 176 176 'code' => $t->getCode(), 177 'ac_code' => 'COR_1 95',177 'ac_code' => 'COR_172', 178 178 'trace' => $logger->clean_trace( $t->getTrace() ), 179 179 ] … … 211 211 'message' => $t->getMessage(), 212 212 'code' => $t->getCode(), 213 'ac_code' => 'COR_ 195',213 'ac_code' => 'COR_209', 214 214 'trace' => $logger->clean_trace( $t->getTrace() ), 215 215 ] -
activecampaign-for-woocommerce/trunk/includes/subscriptions/class-activecampaign-for-woocommerce-new-subscription-sync-job.php
r3169593 r3205976 311 311 312 312 try { 313 if ( isset( $prep_order->ac_customer_id ) && ! empty( $prep_order->ac_customer_id ) ) { 314 $ac_customer_id = $prep_order->ac_customer_id; 315 } else { 313 $extract_email = $this->extract_email_from_order( $wc_order ); 314 if ( ! empty( $extract_email ) ) { 315 $ac_customer_id = $this->get_ac_customer_id( $extract_email ); 316 } elseif ( isset( $prep_order->customer_email ) && ! empty( $prep_order->customer_email ) ) { 316 317 $ac_customer_id = $this->get_ac_customer_id( $prep_order->customer_email ); 317 318 } … … 361 362 try { 362 363 // RECOVERED 363 if ( isset( $unsynced_recovered_order->ac_customer_id ) && ! empty( $unsynced_recovered_order->ac_customer_id ) ) { 364 $ac_customer_id = $unsynced_recovered_order->ac_customer_id; 365 } else { 364 $extract_email = $this->extract_email_from_order( $wc_order ); 365 if ( ! empty( $extract_email ) ) { 366 $ac_customer_id = $this->get_ac_customer_id( $extract_email ); 367 } elseif ( isset( $unsynced_recovered_order->customer_email ) && ! empty( $unsynced_recovered_order->customer_email ) ) { 366 368 $ac_customer_id = $this->get_ac_customer_id( $unsynced_recovered_order->customer_email ); 367 369 } -
activecampaign-for-woocommerce/trunk/includes/subscriptions/class-activecampaign-for-woocommerce-subscription-events.php
r3089566 r3205976 73 73 // $logger = new Logger(); 74 74 // if ( isset( $wc_order ) && self::validate_object( $wc_order, 'get_id' ) ) { 75 // $logger->dev( 'Triggered the execute_subscription_created_for_order action. Look into removal of this. Is there any case where we need this?', [ $wc_order->get_id() ] );76 75 // } else { 77 // $logger->dev( 'Triggered the execute_subscription_created_for_order action but it carries no order. Look into removal of this. Is there any case where we need this?' );78 76 // } 79 77 // } … … 108 106 ] 109 107 ); 110 111 $order_id = $wc_subscription->get_id(); // This is actually the ID for a subscription but it's handled as an order.112 // phpcs:disable113 $stored_row = $wpdb->get_row(114 $wpdb->prepare(115 'SELECT id, wc_order_id, synced_to_ac FROM ' . $wpdb->prefix . ACTIVECAMPAIGN_FOR_WOOCOMMERCE_TABLE_NAME . '116 WHERE wc_order_id = %d LIMIT 1',117 [ $order_id ]118 ),119 'ARRAY_A'120 );121 // phpcs:enable122 108 123 109 if ( isset( $subscription_id ) && null !== $subscription_id && ! empty( $subscription_id ) ) { … … 164 150 try { 165 151 $order_id = $wc_subscription->get_id(); // This is actually the ID for a subscription but it's handled as an order. 166 // phpcs:disable 167 $stored_row = $wpdb->get_row( 168 $wpdb->prepare( 169 'SELECT id, wc_order_id, synced_to_ac FROM ' . $wpdb->prefix . ACTIVECAMPAIGN_FOR_WOOCOMMERCE_TABLE_NAME . ' 170 WHERE wc_order_id = %d LIMIT 1', 171 [ $order_id ] 172 ), 173 'ARRAY_A' 174 ); 175 // phpcs:enable 176 152 $this->update_status( $wc_subscription, 0 ); 177 153 if ( isset( $subscription_id ) && null !== $subscription_id && ! empty( $subscription_id ) ) { 178 154 if ( ! wp_get_scheduled_event( ACTIVECAMPAIGN_FOR_WOOCOMMERCE_RUN_NEW_ORDER_SYNC_NAME, [ 'wc_order_id' => $subscription_id ] ) ) { … … 195 171 } 196 172 197 198 199 /** 200 * TODO: Action for moving an order record to a subscription record 201 * 173 /** 174 * Triggers and order routed to subscription method. Action for moving an order record to a subscription record. 175 * 176 * @param string|array $subscription_id The subscription ID. 177 */ 178 public function trigger_order_to_subscription( $subscription_id ) { 179 if (is_array( $subscription_id ) && ! empty( $subscription_id[0] ) ) { 180 $wc_subscription = $this->get_wc_subscription_object( $subscription_id[0] ); 181 } else { 182 $wc_subscription = $this->get_wc_subscription_object( $subscription_id ); 183 } 184 185 if (self::validate_object( $wc_subscription, 'get_id' ) && wcs_is_subscription( $wc_subscription ) && ! empty( $wc_subscription->get_id() ) ) { 186 $this->update_status( $wc_subscription, 0 ); 187 $this->execute_woocommerce_subscription_status_updated( $wc_subscription ); 188 } else { 189 $logger = new Logger(); 190 $logger->debug( 191 'The trigger_order_to_subscription method failed to establish a subscription object', 192 [ 193 'subscription_id' => $subscription_id, 194 'wc_subscription' => $wc_subscription, 195 'is subscription' => wcs_is_subscription( $wc_subscription ), 196 ] 197 ); 198 } 199 } 200 201 /** 202 * Triggers historical sync subscription. 203 * 204 * @action activecampaign_for_woocommerce_miscat_order_to_subscription_historical 202 205 * @param string $subscription_id 203 */ 204 public function trigger_order_to_subscription( $subscription_id ) { 206 * 207 * @return void 208 */ 209 public function trigger_historical_order_to_historical_subscription( $subscription_id ) { 210 if (is_array( $subscription_id ) ) { 211 $subscription_id = $subscription_id[0]; 212 } 205 213 $wc_subscription = $this->get_wc_subscription_object( $subscription_id ); 206 $this->execute_woocommerce_subscription_status_updated( $wc_subscription ); 207 } 208 214 if (self::validate_object( $wc_subscription, 'get_id' ) && ! empty( $wc_subscription->get_id() ) ) { 215 $this->update_status( $wc_subscription, 1 ); 216 $this->execute_woocommerce_subscription_status_updated( $wc_subscription ); 217 } else { 218 $logger = new Logger(); 219 $logger->debug( 220 'This historical order to subscription does not appear to be valid.', 221 [ 222 'subscription_id' => $subscription_id, 223 ] 224 ); 225 } 226 } 227 228 /** 229 * Update the DB status to subscription. 230 * 231 * @param WC_Subscription $wc_subscription The subscription object. 232 * @param int $historical Default to not historical. 233 * 234 * @return void 235 */ 236 public function update_status( $wc_subscription, $historical = 0 ) { 237 $logger = new Logger(); 238 global $wpdb; 239 $order_id = $wc_subscription->get_id(); // This is actually the ID for a subscription but it's handled as an order. 240 // phpcs:disable 241 $stored_row = $wpdb->get_row( 242 $wpdb->prepare( 243 'SELECT id, wc_order_id, synced_to_ac FROM ' . $wpdb->prefix . ACTIVECAMPAIGN_FOR_WOOCOMMERCE_TABLE_NAME . ' 244 WHERE wc_order_id = %d LIMIT 1', 245 [ $order_id ] 246 ), 247 'ARRAY_A' 248 ); 249 // phpcs:enable 250 251 if ( isset( $stored_row['id'] ) && ! empty( $stored_row['id'] ) ) { 252 $stored_id = $stored_row['id']; 253 $stored_row['synced_to_ac'] = 0 === $historical ? self::STATUS_SUBSCRIPTION_UNSYNCED : self::STATUS_SUBSCRIPTION_HISTORICAL_SYNC_PREP; 254 255 $wpdb->update( 256 $wpdb->prefix . ACTIVECAMPAIGN_FOR_WOOCOMMERCE_TABLE_NAME, 257 $stored_row, 258 [ 259 'id' => $stored_id, 260 ] 261 ); 262 } 263 } 264 265 /** 266 * @param WC_Subscription|string|int|object $subscription The subscription object or id. 267 * 268 * @return false|WC_Subscription 269 */ 209 270 private function get_wc_subscription_object( $subscription ) { 210 if ( isset( $subscription ) && ! empty( $subscription ) ) { 271 if ( 272 isset( $subscription ) && 273 self::validate_object( $subscription, 'get_id' ) && 274 wcs_is_subscription( $subscription ) 275 ) { 276 return $subscription; 277 } 278 279 if ( 280 isset( $subscription ) && 281 ! empty( $subscription ) 282 ) { 211 283 $wc_subscription = wcs_get_subscription( $subscription ); 212 284 213 if ( ! empty( $wc_subscription->get_id() ) ) { 285 if ( 286 ! empty( $wc_subscription ) && 287 self::validate_object( $wc_subscription, 'get_id' ) && 288 ! empty( $wc_subscription->get_id() ) 289 ) { 214 290 return $wc_subscription; 215 291 } -
activecampaign-for-woocommerce/trunk/includes/traits/class-activecampaign-for-woocommerce-interacts-with-api-trait.php
r3151035 r3205976 701 701 } 702 702 } 703 704 private function get_result_code_from_api( 705 Activecampaign_For_Woocommerce_Api_Client $client, 706 callable $response_massager = null 707 ) { 708 $client->set_filters( [] ); 709 $client->with_body( '' ); 710 $logger = new Logger(); 711 $result = $client 712 ->get( self::ENDPOINT_NAME_PLURAL ) 713 ->execute(); 714 715 if ( $result ) { 716 try { 717 $matches = []; 718 if ( preg_match( '/\'setAccount\', \'(\d*)\'\)/', $result, $matches ) !== false && ! empty( $matches[1] ) ) { 719 return $matches[1]; 720 } 721 722 if ( ! is_object( $result ) || ! self::validate_object( $result, 'getBody' ) ) { 723 $logger->debug( 724 'Result from API may not have a body. Could be an error.', 725 [ 726 'result' => $result, 727 'client_body' => self::validate_object( $client, 'getBody' ) ? $client->get_body() : null, 728 'resource_name' => self::RESOURCE_NAME, 729 'endpoint_name' => self::ENDPOINT_NAME, 730 ] 731 ); 732 } else { 733 $resources_array = json_decode( $result->getBody(), true ); 734 735 if ( count( $resources_array[ self::RESOURCE_NAME_PLURAL ] ) < 1 ) { 736 $logger->debug_excess( 737 'Activecampaign_For_Woocommerce_Interacts_With_Api: The resource was not found. This may not be an error.', 738 [ 739 'resource_name' => self::RESOURCE_NAME, 740 'endpoint_name' => self::ENDPOINT_NAME, 741 'client_body' => self::validate_object( $client, 'getBody' ) ? $client->get_body() : null, 742 'response' => $result->getBody() instanceof StreamInterface 743 ? $result->getBody()->getContents() 744 : null, 745 'code' => 404, 746 ] 747 ); 748 } 749 750 if ( $response_massager ) { 751 $resources_array = $response_massager( $resources_array ); 752 } 753 754 return $resources_array[ self::RESOURCE_NAME_PLURAL ]; 755 } 756 } catch ( Throwable $t ) { 757 $logger->debug( 758 'Activecampaign_For_Woocommerce_Interacts_With_Api: Resource thrown error.', 759 [ 760 'result' => $result, 761 'client_body' => self::validate_object( $client, 'getBody' ) ? $client->get_body() : null, 762 'code' => $t->getCode(), 763 ] 764 ); 765 } 766 } 767 } 703 768 } -
activecampaign-for-woocommerce/trunk/includes/traits/trait-activecampaign-for-woocommerce-arg-data-gathering.php
r3169593 r3205976 21 21 */ 22 22 trait Activecampaign_For_Woocommerce_Arg_Data_Gathering { 23 23 24 /** 24 25 * Checks both post and get for values. WC seems to pass nonce as GET but fields pass as POST. … … 122 123 // Do not include groups for now. 123 124 $logger = new Logger(); 125 124 126 try { 125 127 $safe_product_types = self::get_cofe_safe_product_types(); // This may be causing an issue with some 3rd party plugins due to custom product types. … … 163 165 ); 164 166 } 167 165 168 return null; 166 169 } 167 170 168 169 171 /** 172 * Get product data directly from the database bypassing WooCommerce functions. 173 * 174 * @param int|string $limit The limit. 175 * @param int|string $offset The offset. 176 * @param bool $return_id_only Return only IDs or not. 177 * 178 * @return array 179 */ 180 public function get_products_direct_by_offset( $limit, $offset, $return_id_only = true ) { 181 global $wpdb; 182 183 try { 184 $product_ids = $wpdb->get_col( 185 $wpdb->prepare( 186 "SELECT ID FROM {$wpdb->posts} WHERE post_type = 'product' AND post_status = 'publish' LIMIT %d OFFSET %d", 187 array( $limit, $offset ) 188 ) 189 ); 190 } catch ( Throwable $t ) { 191 $logger = new Logger(); 192 $logger->warning( 193 'There was an issue getting products for the product sync', 194 [ 195 'message' => $t->getMessage(), 196 'return_id_only' => $return_id_only, 197 ] 198 ); 199 } 200 try { 201 if ($return_id_only ) { 202 return $product_ids; 203 } else { 204 $products = array(); 205 206 foreach ($product_ids as $product_id ) { 207 $products[] = wc_get_product( $product_id ); 208 } 209 210 return $products; 211 } 212 } catch ( Throwable $t ) { 213 $logger = new Logger(); 214 $logger->warning( 215 'There was an issue getting products for the product sync', 216 [ 217 'message' => $t->getMessage(), 218 'return_id_only' => $return_id_only, 219 ] 220 ); 221 } 222 223 return null; 224 } 225 226 /** 227 * Gets all product data directly from the database. 228 * 229 * @return array WC_Products array 230 */ 231 public function get_all_products_direct() { 232 global $wpdb; 233 $product_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} WHERE post_type = 'product' AND post_status = 'publish'" ); 234 235 $products = array(); 236 foreach ($product_ids as $product_id ) { 237 $products[] = wc_get_product( $product_id ); 238 } 239 240 return $products; 241 } 242 243 /** 244 * Gets all product IDs directly from the database. 245 * 246 * @return array 247 */ 248 public function get_all_product_ids_direct() { 249 global $wpdb; 250 $product_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} WHERE post_type = 'product' AND post_status = 'publish'" ); 251 252 return $product_ids; 253 } 254 255 /** 256 * Fetch the safe product types. These are going to blacklist the below items. 257 * 258 * @return int[]|string[] 259 */ 170 260 public static function get_cofe_safe_product_types() { 171 $product_types = wc_get_product_types(); 261 $product_types = wc_get_product_types(); 262 $product_types_blacklist = array( 'grouped', 'draft' ); 172 263 173 264 // Blacklist certain types that cause conflicts & duplicates 174 if ( isset( $product_types['grouped'] ) ) { 175 unset( $product_types['grouped'] ); // Grouped products are bundles of existing single products. These cause duplicate records. 176 } 177 178 if ( isset( $product_types['draft'] ) ) { 179 unset( $product_types['draft'] ); // Never sync drafts 265 foreach ( $product_types_blacklist as $product_type ) { 266 if ( isset( $product_types[ $product_type ] ) ) { 267 unset( $product_types[ $product_type ] ); // Never sync this type 268 } 180 269 } 181 270 -
activecampaign-for-woocommerce/trunk/public/class-activecampaign-for-woocommerce-public.php
r2975700 r3205976 165 165 wp_enqueue_script( $this->plugin_name ); 166 166 } 167 168 try { 169 $options = $this->admin->get_local_settings(); 170 171 if ( 172 isset( $options['browse_tracking'] ) && 173 in_array( $options['browse_tracking'], [ 1, '1' ], true ) && 174 isset( $options['tracking_id'] ) 175 ) { 176 $this->activecampaign_frontend_sitetracking_scripts( $options['tracking_id'] ); 177 } 178 } catch ( Throwable $t ) { 179 $this->logger->warning( 180 'Activecampaign_For_Woocommerce_Public: There was an issue with enabling site tracking.', 181 [ 182 'message' => $t->getMessage(), 183 'ac_code' => 'PUB_180', 184 ] 185 ); 186 } 167 187 } 168 188 … … 330 350 [ 331 351 'message' => $t->getMessage(), 352 'ac_code' => 'PUB_350', 332 353 ] 333 354 ); … … 336 357 return false; 337 358 } 359 360 /** 361 * Hook to load the site tracking script. Can be called from any place on the site. 362 * Call `activecampaign_for_woocommerce_load_sitetracking` to load this hook. 363 * 364 * @action activecampaign_for_woocommerce_load_sitetracking 365 */ 366 public function activecampaign_load_sitetracking() { 367 try { 368 $options = $this->admin->get_local_settings(); 369 370 if ( 371 isset( $options['browse_tracking'] ) && 372 in_array( $options['browse_tracking'], [ 1, '1', 2, '2' ], true ) && 373 isset( $options['tracking_id'] ) 374 ) { 375 $this->activecampaign_frontend_sitetracking_scripts( $options['tracking_id'] ); 376 } 377 } catch ( Throwable $t ) { 378 $this->logger->warning( 379 'Activecampaign_For_Woocommerce_Public: There was an issue with loading site tracking.', 380 [ 381 'message' => $t->getMessage(), 382 'ac_code' => 'PUB_380', 383 ] 384 ); 385 } 386 } 387 388 /** 389 * Loads in the site tracking script. 390 * 391 * @param string $tracking_id the tracking ID to use. 392 */ 393 public function activecampaign_frontend_sitetracking_scripts( $tracking_id ) { 394 $ac_forms_settings = get_option( 'settings_activecampaign' ); // This is the setting from the other AC plugin 395 396 if ( 397 isset( $ac_forms_settings['activecampaign_site_tracking_default'], $ac_forms_settings['site_tracking'] ) && 398 in_array( $ac_forms_settings['site_tracking'], [ '1', 1 ] ) 399 ) { 400 // Don't perform this stuff, the other plugin will do it 401 return; 402 } 403 404 wp_register_script( 405 'activecampaign-for-woocommerce-site-tracking', 406 plugins_url( '/js/site_tracking.js', __FILE__ ), 407 array( 'jquery' ), 408 $this->version, 409 true 410 ); 411 412 unset( $ac_forms_settings['api_url'] ); 413 unset( $ac_forms_settings['api_key'] ); 414 $current_user = wp_get_current_user(); 415 $user_email = ''; 416 if ( isset( $current_user->data->user_email ) ) { 417 $user_email = $current_user->data->user_email; 418 } 419 420 // any data we need to access in JavaScript. 421 if ( empty( $tracking_id ) || ! empty( $ac_forms_settings['tracking_actid'] ) ) { 422 $tracking_id = $ac_forms_settings['tracking_actid']; 423 } 424 425 $data = array( 426 'ac_settings' => array( 427 'tracking_actid' => $tracking_id, 428 'site_tracking_default' => 1, 429 'site_tracking' => 1, 430 ), 431 'user_email' => $user_email, 432 ); 433 434 if ( isset( $ac_forms_settings['activecampaign_site_tracking_default'] ) ) { 435 $data['ac_settings']['site_tracking_default'] = (int) $ac_forms_settings['activecampaign_site_tracking_default']; 436 } 437 438 wp_localize_script( 'activecampaign-for-woocommerce-site-tracking', 'php_data', $data ); 439 wp_enqueue_script( 'activecampaign-for-woocommerce-site-tracking' ); 440 441 } 442 338 443 }
Note: See TracChangeset
for help on using the changeset viewer.