Plugin Directory

Changeset 2977226


Ignore:
Timestamp:
10/10/2023 09:41:46 PM (2 years ago)
Author:
acteamintegrations
Message:

Version 2.4.9

Location:
activecampaign-for-woocommerce
Files:
5 deleted
17 edited
117 copied

Legend:

Unmodified
Added
Removed
  • activecampaign-for-woocommerce/tags/2.4.8/README.txt

    r2973117 r2977226  
    44Requires at least: 6.0
    55Tested up to: 6.3
    6 Stable tag: 2.4.7
     6Stable tag: 2.4.8
    77Requires PHP: 7.4
    88License: GPLv2 or later
     
    8383
    8484== Changelog ==
     85
     86== 2.4.8 2023-10-06 ==
     87* Workaround for custom checkouts not loading abandoned cart script
     88* Limiting extremely large numbers for ints
    8589
    8690== 2.4.7 2023-09-29 ==
  • activecampaign-for-woocommerce/tags/2.4.8/ac_vendor/autoload.php

    r2973117 r2977226  
    55require_once __DIR__ . '/composer/autoload_real.php';
    66
    7 return ComposerAutoloaderInit1b80feeddfb6dd4ad28a709696d32324::getLoader();
     7return ComposerAutoloaderInit2873218b414b46cb51cdb48bdd59ce9a::getLoader();
  • activecampaign-for-woocommerce/tags/2.4.8/ac_vendor/composer/autoload_real.php

    r2973117 r2977226  
    33// autoload_real.php @generated by Composer
    44
    5 class ComposerAutoloaderInit1b80feeddfb6dd4ad28a709696d32324
     5class ComposerAutoloaderInit2873218b414b46cb51cdb48bdd59ce9a
    66{
    77    private static $loader;
     
    2525        require __DIR__ . '/platform_check.php';
    2626
    27         spl_autoload_register(array('ComposerAutoloaderInit1b80feeddfb6dd4ad28a709696d32324', 'loadClassLoader'), true, true);
     27        spl_autoload_register(array('ComposerAutoloaderInit2873218b414b46cb51cdb48bdd59ce9a', 'loadClassLoader'), true, true);
    2828        self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
    29         spl_autoload_unregister(array('ComposerAutoloaderInit1b80feeddfb6dd4ad28a709696d32324', 'loadClassLoader'));
     29        spl_autoload_unregister(array('ComposerAutoloaderInit2873218b414b46cb51cdb48bdd59ce9a', 'loadClassLoader'));
    3030
    3131        $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
     
    3333            require __DIR__ . '/autoload_static.php';
    3434
    35             call_user_func(\Composer\Autoload\ComposerStaticInit1b80feeddfb6dd4ad28a709696d32324::getInitializer($loader));
     35            call_user_func(\Composer\Autoload\ComposerStaticInit2873218b414b46cb51cdb48bdd59ce9a::getInitializer($loader));
    3636        } else {
    3737            $map = require __DIR__ . '/autoload_namespaces.php';
     
    5454
    5555        if ($useStaticLoader) {
    56             $includeFiles = Composer\Autoload\ComposerStaticInit1b80feeddfb6dd4ad28a709696d32324::$files;
     56            $includeFiles = Composer\Autoload\ComposerStaticInit2873218b414b46cb51cdb48bdd59ce9a::$files;
    5757        } else {
    5858            $includeFiles = require __DIR__ . '/autoload_files.php';
    5959        }
    6060        foreach ($includeFiles as $fileIdentifier => $file) {
    61             composerRequire1b80feeddfb6dd4ad28a709696d32324($fileIdentifier, $file);
     61            composerRequire2873218b414b46cb51cdb48bdd59ce9a($fileIdentifier, $file);
    6262        }
    6363
     
    6666}
    6767
    68 function composerRequire1b80feeddfb6dd4ad28a709696d32324($fileIdentifier, $file)
     68function composerRequire2873218b414b46cb51cdb48bdd59ce9a($fileIdentifier, $file)
    6969{
    7070    if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
  • activecampaign-for-woocommerce/tags/2.4.8/ac_vendor/composer/autoload_static.php

    r2973117 r2977226  
    55namespace Composer\Autoload;
    66
    7 class ComposerStaticInit1b80feeddfb6dd4ad28a709696d32324
     7class ComposerStaticInit2873218b414b46cb51cdb48bdd59ce9a
    88{
    99    public static $files = array (
     
    476476    {
    477477        return \Closure::bind(function () use ($loader) {
    478             $loader->prefixLengthsPsr4 = ComposerStaticInit1b80feeddfb6dd4ad28a709696d32324::$prefixLengthsPsr4;
    479             $loader->prefixDirsPsr4 = ComposerStaticInit1b80feeddfb6dd4ad28a709696d32324::$prefixDirsPsr4;
    480             $loader->classMap = ComposerStaticInit1b80feeddfb6dd4ad28a709696d32324::$classMap;
     478            $loader->prefixLengthsPsr4 = ComposerStaticInit2873218b414b46cb51cdb48bdd59ce9a::$prefixLengthsPsr4;
     479            $loader->prefixDirsPsr4 = ComposerStaticInit2873218b414b46cb51cdb48bdd59ce9a::$prefixDirsPsr4;
     480            $loader->classMap = ComposerStaticInit2873218b414b46cb51cdb48bdd59ce9a::$classMap;
    481481
    482482        }, null, ClassLoader::class);
  • activecampaign-for-woocommerce/tags/2.4.8/activecampaign-for-woocommerce.php

    r2973117 r2977226  
    1717 * Plugin URI:           https://www.activecampaign.com/
    1818 * Description:          Add Abandoned Cart functionality to your WooCommerce store, synchronize order & customer information using ActiveCampaign.
    19  * Version:              2.4.7
     19 * Version:              2.4.8
    2020 * WC requires at least: 7.4
    2121 * WC tested up to:      8.1.0
  • activecampaign-for-woocommerce/tags/2.4.8/includes/config/activecampaign-for-woocommerce-global-constants.php

    r2973117 r2977226  
    2626 */
    2727if ( ! defined( 'ACTIVECAMPAIGN_FOR_WOOCOMMERCE_VERSION' ) ) {
    28     define( 'ACTIVECAMPAIGN_FOR_WOOCOMMERCE_VERSION', '2.4.7' );
     28    define( 'ACTIVECAMPAIGN_FOR_WOOCOMMERCE_VERSION', '2.4.8' );
    2929}
    3030
  • activecampaign-for-woocommerce/tags/2.4.8/includes/models/serializers/class-activecampaign-for-woocommerce-ecom-cofe-product-serializer.php

    r2966088 r2977226  
    302302
    303303    private static function int_field( $stringy ) {
    304         $int_val = intval( $stringy );
     304        if ( isset( $stringy ) && $stringy >= 2147483647 ) {
     305            // Int max cap
     306            $int_val = 2147483647;
     307            $logger  = new Logger();
     308            $logger->debug_excess(
     309                'Int was too big for cofe product serializer and must be capped',
     310                [
     311                    'num_passed' => $stringy,
     312                ]
     313            );
     314        } else {
     315            $int_val = intval( $stringy );
     316        }
     317
    305318        if ( 0 !== $int_val ) {
    306319            return $int_val;
  • activecampaign-for-woocommerce/tags/2.4.8/public/class-activecampaign-for-woocommerce-public.php

    r2966088 r2977226  
    103103     */
    104104    public function enqueue_styles_scripts() {
    105         if ( is_page( 'checkout' ) ) {
     105        if ( $this->better_is_checkout() ) {
    106106            $this->init();
    107107
     
    290290        }
    291291    }
     292
     293    /**
     294     * Better method for checking if we are on the checkout page.
     295     *
     296     * @return bool
     297     */
     298    private function better_is_checkout() {
     299        $logger = new Logger();
     300
     301        try {
     302            if ( function_exists( 'is_checkout' ) && is_checkout() ) {
     303                return true;
     304            }
     305
     306            $checkout_path = wp_parse_url( wc_get_checkout_url(), PHP_URL_PATH );
     307            if ( isset( $_SERVER['HTTP_HOST'], $_SERVER['REQUEST_URI'] ) ) {
     308                $host_name = esc_url_raw( wp_unslash( $_SERVER['HTTP_HOST'] ) . wp_unslash( $_SERVER['REQUEST_URI'] ) );
     309            } else {
     310                $host_name = '';
     311            }
     312
     313            $current_url_path = wp_parse_url( "http://$host_name", PHP_URL_PATH );
     314
     315            if (
     316               (
     317                   null !== $checkout_path &&
     318                   null !== $current_url_path &&
     319                   trailingslashit( $checkout_path ) === trailingslashit( $current_url_path )
     320               ) ||
     321               is_page( 'checkout' )
     322            ) {
     323
     324                return true;
     325            }
     326        } catch ( Throwable $t ) {
     327
     328            $logger->warning(
     329                'There may be an issue checking for the checkout page',
     330                [
     331                    'message' => $t->getMessage(),
     332                ]
     333            );
     334        }
     335
     336        return false;
     337    }
    292338}
  • activecampaign-for-woocommerce/trunk/README.txt

    r2975700 r2977226  
    44Requires at least: 6.0
    55Tested up to: 6.3
    6 Stable tag: 2.4.8
     6Stable tag: 2.4.9
    77Requires PHP: 7.4
    88License: GPLv2 or later
     
    8484== Changelog ==
    8585
     86== 2.4.9 2023-10-09 ==
     87* Fixing the abandoned cart starter times
     88* Adding more clear text for abandoned cart settings
     89
    8690== 2.4.8 2023-10-06 ==
    8791* Workaround for custom checkouts not loading abandoned cart script
  • activecampaign-for-woocommerce/trunk/ac_vendor/autoload.php

    r2975700 r2977226  
    55require_once __DIR__ . '/composer/autoload_real.php';
    66
    7 return ComposerAutoloaderInit2873218b414b46cb51cdb48bdd59ce9a::getLoader();
     7return ComposerAutoloaderInit6549c600be47fc05f98b462ebf011f67::getLoader();
  • activecampaign-for-woocommerce/trunk/ac_vendor/composer/autoload_real.php

    r2975700 r2977226  
    33// autoload_real.php @generated by Composer
    44
    5 class ComposerAutoloaderInit2873218b414b46cb51cdb48bdd59ce9a
     5class ComposerAutoloaderInit6549c600be47fc05f98b462ebf011f67
    66{
    77    private static $loader;
     
    2525        require __DIR__ . '/platform_check.php';
    2626
    27         spl_autoload_register(array('ComposerAutoloaderInit2873218b414b46cb51cdb48bdd59ce9a', 'loadClassLoader'), true, true);
     27        spl_autoload_register(array('ComposerAutoloaderInit6549c600be47fc05f98b462ebf011f67', 'loadClassLoader'), true, true);
    2828        self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
    29         spl_autoload_unregister(array('ComposerAutoloaderInit2873218b414b46cb51cdb48bdd59ce9a', 'loadClassLoader'));
     29        spl_autoload_unregister(array('ComposerAutoloaderInit6549c600be47fc05f98b462ebf011f67', 'loadClassLoader'));
    3030
    3131        $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
     
    3333            require __DIR__ . '/autoload_static.php';
    3434
    35             call_user_func(\Composer\Autoload\ComposerStaticInit2873218b414b46cb51cdb48bdd59ce9a::getInitializer($loader));
     35            call_user_func(\Composer\Autoload\ComposerStaticInit6549c600be47fc05f98b462ebf011f67::getInitializer($loader));
    3636        } else {
    3737            $map = require __DIR__ . '/autoload_namespaces.php';
     
    5454
    5555        if ($useStaticLoader) {
    56             $includeFiles = Composer\Autoload\ComposerStaticInit2873218b414b46cb51cdb48bdd59ce9a::$files;
     56            $includeFiles = Composer\Autoload\ComposerStaticInit6549c600be47fc05f98b462ebf011f67::$files;
    5757        } else {
    5858            $includeFiles = require __DIR__ . '/autoload_files.php';
    5959        }
    6060        foreach ($includeFiles as $fileIdentifier => $file) {
    61             composerRequire2873218b414b46cb51cdb48bdd59ce9a($fileIdentifier, $file);
     61            composerRequire6549c600be47fc05f98b462ebf011f67($fileIdentifier, $file);
    6262        }
    6363
     
    6666}
    6767
    68 function composerRequire2873218b414b46cb51cdb48bdd59ce9a($fileIdentifier, $file)
     68function composerRequire6549c600be47fc05f98b462ebf011f67($fileIdentifier, $file)
    6969{
    7070    if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
  • activecampaign-for-woocommerce/trunk/ac_vendor/composer/autoload_static.php

    r2975700 r2977226  
    55namespace Composer\Autoload;
    66
    7 class ComposerStaticInit2873218b414b46cb51cdb48bdd59ce9a
     7class ComposerStaticInit6549c600be47fc05f98b462ebf011f67
    88{
    99    public static $files = array (
     
    476476    {
    477477        return \Closure::bind(function () use ($loader) {
    478             $loader->prefixLengthsPsr4 = ComposerStaticInit2873218b414b46cb51cdb48bdd59ce9a::$prefixLengthsPsr4;
    479             $loader->prefixDirsPsr4 = ComposerStaticInit2873218b414b46cb51cdb48bdd59ce9a::$prefixDirsPsr4;
    480             $loader->classMap = ComposerStaticInit2873218b414b46cb51cdb48bdd59ce9a::$classMap;
     478            $loader->prefixLengthsPsr4 = ComposerStaticInit6549c600be47fc05f98b462ebf011f67::$prefixLengthsPsr4;
     479            $loader->prefixDirsPsr4 = ComposerStaticInit6549c600be47fc05f98b462ebf011f67::$prefixDirsPsr4;
     480            $loader->classMap = ComposerStaticInit6549c600be47fc05f98b462ebf011f67::$classMap;
    481481
    482482        }, null, ClassLoader::class);
  • activecampaign-for-woocommerce/trunk/activecampaign-for-woocommerce.php

    r2975700 r2977226  
    1717 * Plugin URI:           https://www.activecampaign.com/
    1818 * Description:          Add Abandoned Cart functionality to your WooCommerce store, synchronize order & customer information using ActiveCampaign.
    19  * Version:              2.4.8
     19 * Version:              2.4.9
    2020 * WC requires at least: 7.4
    2121 * WC tested up to:      8.1.0
  • activecampaign-for-woocommerce/trunk/admin/class-activecampaign-for-woocommerce-admin-abandoned-cart.php

    r2931548 r2977226  
    5151            do_action( 'activecampaign_for_woocommerce_verify_tables' );
    5252
    53             $limit  = 40;
    54             $offset = $page * $limit;
     53            $expire_time                             = 1;
     54            $limit                                   = 40;
     55            $offset                                  = $page * $limit;
     56            $activecampaign_for_woocommerce_settings = get_option( ACTIVECAMPAIGN_FOR_WOOCOMMERCE_DB_SETTINGS_NAME );
     57
     58            if ( isset( $activecampaign_for_woocommerce_settings['abcart_wait'] ) && ! empty( $activecampaign_for_woocommerce_settings['abcart_wait'] ) ) {
     59                $expire_time = $activecampaign_for_woocommerce_settings['abcart_wait'];
     60            }
     61
     62            $expire_datetime = new DateTime( 'now -' . $expire_time . ' hours', new DateTimeZone( 'UTC' ) );
    5563
    5664            $result = $wpdb->get_results(
     
    6876                       last_access_time,
    6977                       activecampaignfwc_order_external_uuid,
    70                        cart_ref_json,
    71                        customer_ref_json
     78                       cart_ref_json,
     79                       customer_ref_json,
     80                       ( last_access_time < "' . $expire_datetime->format( 'Y-m-d H:i:s' ) . '" OR last_access_time < str_to_date("' . $expire_datetime->format( 'Y-m-d H:i:s' ) . '", "Y-m-d H:i:s") ) AS ready_state
    7281                    FROM `' . $wpdb->prefix . ACTIVECAMPAIGN_FOR_WOOCOMMERCE_TABLE_NAME . '`
    73                     WHERE (order_date IS NULL OR abandoned_date IS NOT NULL) AND last_access_time IS NOT NULL AND ((synced_to_ac >= 20 AND synced_to_ac <= 29) OR synced_to_ac = 1 OR synced_to_ac = 0)
     82                    WHERE
     83                    (order_date IS NULL OR abandoned_date IS NOT NULL) AND
     84                    last_access_time IS NOT NULL AND
     85                    (
     86                        (
     87                            synced_to_ac >= 20 AND synced_to_ac <= 29
     88                        )
     89                        OR
     90                        (
     91                            synced_to_ac = 1 OR synced_to_ac = 0
     92                        )
     93                    )
    7494                    LIMIT %d,%d',
    7595                    [ $offset, $limit ]
  • activecampaign-for-woocommerce/trunk/admin/class-activecampaign-for-woocommerce-admin-historical-sync.php

    r2950993 r2977226  
    5555                // Sync all the contacts from the orders
    5656
    57                 wp_schedule_single_event(
    58                     time() + 50,
    59                     'activecampaign_for_woocommerce_run_historical_sync_contacts'
    60                 );
     57                do_action( 'activecampaign_for_woocommerce_run_historical_sync_contacts' );
     58
    6159                update_option(
    6260                    ACTIVECAMPAIGN_FOR_WOOCOMMERCE_HISTORICAL_SYNC_SCHEDULED_STATUS_NAME,
  • activecampaign-for-woocommerce/trunk/admin/views/activecampaign-for-woocommerce-abandoned-cart-display.php

    r2968938 r2977226  
    5151
    5252function activecampaign_for_woocommerce_convert_date_to_local( $datetime ) {
    53     return wp_date( 'Y-m-d H:i:s', strtotime( $datetime ) ) . ' ' . wp_timezone_string();
     53    return wp_date( 'Y-m-d H:i:s e', strtotime( $datetime ) );
    5454}
    5555/**
     
    245245                                            ) ) :
    246246                                            ?>
    247                                             Synced<br/>Abandoned On: <?php echo esc_html( $activecampaign_for_woocommerce_ab_cart->abandoned_date ); ?>
    248                                         <?php endif; ?>
    249 
    250                                         <?php if ( ( empty( $activecampaign_for_woocommerce_ab_cart->order_date ) && empty( $activecampaign_for_woocommerce_ab_cart->abandoned_date ) ) || in_array( $activecampaign_for_woocommerce_ab_cart->synced_to_ac, [ 0, 20, '0', '20' ], true ) ) : ?>
    251                                             <?php if ( $activecampaign_for_woocommerce_ab_cart->last_access_time < $activecampaign_for_woocommerce_expire_datetime->format( 'Y-m-d H:i:s' ) ) : ?>
     247                                            Synced<br/>Abandoned On: <?php echo esc_html( activecampaign_for_woocommerce_convert_date_to_local( $activecampaign_for_woocommerce_ab_cart->abandoned_date ) ); ?>
     248                                        <?php endif; ?>
     249
     250                                        <?php
     251                                        if (
     252                                                ( empty( $activecampaign_for_woocommerce_ab_cart->order_date ) && empty( $activecampaign_for_woocommerce_ab_cart->abandoned_date ) ) ||
     253                                                in_array( $activecampaign_for_woocommerce_ab_cart->synced_to_ac, [ 0, 20, '0', '20' ], true )
     254                                        ) :
     255                                            ?>
     256                                            <?php if ( isset( $activecampaign_for_woocommerce_ab_cart->ready_state ) && in_array( $activecampaign_for_woocommerce_ab_cart->ready_state, [ '1', 1 ], true ) ) : ?>
    252257                                                Abandoned Cart Ready to Sync
    253258                                            <?php else : ?>
  • activecampaign-for-woocommerce/trunk/admin/views/activecampaign-for-woocommerce-admin-display.php

    r2973117 r2977226  
    411411                    </h2>
    412412                    <p>
    413                         <?php esc_html_e( 'How long should ActiveCampaign wait after a contact abandons a cart before triggering abandoned cart automations?', ACTIVECAMPAIGN_FOR_WOOCOMMERCE_LOCALIZATION_DOMAIN ); ?>
     413                        <?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 ); ?>
     414                    </p>
     415                    <p>
     416                        <?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 ); ?>
    414417                    </p>
    415418                    <label>
  • activecampaign-for-woocommerce/trunk/includes/abandoned_carts/class-activecampaign-for-woocommerce-run-abandonment-sync-command.php

    r2971988 r2977226  
    7979
    8080    /**
     81     * The abandoned date.
     82     *
     83     * @since 2.4.5
     84     * @var DateTime The abandoned date.
     85     */
     86    private $abandoned_date;
     87
     88    /**
     89     * The time set in settings for expiration..
     90     *
     91     * @since 2.4.5
     92     * @var String|int The expiration time.
     93     */
     94    private $expire_time;
     95
     96    /**
    8197     * Activecampaign_For_Woocommerce_Update_Cart_Command constructor.
    8298     *
     
    186202        $cart_count = $this->run_abandoned_carts();
    187203
    188         if ( ! empty( $cart_count ) && $cart_count > 0 ) {
    189             wp_send_json_success( 'Finished sync of abandoned cart. Processed ' . count( $cart_count ) . ' carts.' );
     204        if ( isset( $cart_count ) && ! empty( $cart_count ) && $cart_count > 0 ) {
     205            wp_send_json_success( 'Finished sync of abandoned cart. Processed ' . $cart_count . ' carts.' );
    190206        } else {
    191207            wp_send_json_success( 'No abandoned carts to process.' );
     
    211227
    212228    /**
    213      * Forces the sync of a specific row.
    214      *
    215      * @param     int $id     The row id.
     229     * Forces the sync of a specific abandoned cart row manually.
     230     *
     231     * @param     int $id     The abandoned cart row id.
    216232     */
    217233    public function force_sync_row( $id ) {
     
    253269
    254270        // default is 1 hour abandon cart expiration
    255         $expire_time = 1;
     271        $this->expire_time = 1;
    256272
    257273        // Get the expire time period from the db
     
    260276
    261277        if ( isset( $activecampaign_for_woocommerce_settings['abcart_wait'] ) && ! empty( $activecampaign_for_woocommerce_settings['abcart_wait'] ) ) {
    262             $expire_time = $activecampaign_for_woocommerce_settings['abcart_wait'];
    263         }
    264 
    265         $expire_datetime = new DateTime( 'now -' . $expire_time . ' hours', new DateTimeZone( 'UTC' ) );
     278            $this->expire_time = $activecampaign_for_woocommerce_settings['abcart_wait'];
     279        }
     280
     281        $expire_datetime = new DateTime( 'now -' . $this->expire_time . ' hours', new DateTimeZone( 'UTC' ) );
     282
     283        try {
     284            // Get the expired carts from our table
     285            // phpcs:disable
     286            $abandoned_carts = $wpdb->get_results( '
     287                SELECT
     288                    id, synced_to_ac, customer_ref_json, cart_ref_json, cart_totals_ref_json, removed_cart_contents_ref_json, activecampaignfwc_order_external_uuid, last_access_time, abandoned_date,
     289                    ADDTIME(last_access_time, "' . $this->expire_time . ':00:00") as calc_abandoned_date
     290                FROM
     291                    `' . $wpdb->prefix . ACTIVECAMPAIGN_FOR_WOOCOMMERCE_TABLE_NAME . '`
     292                WHERE
     293                    (
     294                        last_access_time < "' . $expire_datetime->format( 'Y-m-d H:i:s' ) . '"
     295                        OR last_access_time < str_to_date("' . $expire_datetime->format( 'Y-m-d H:i:s' ) . '", "Y-m-d H:i:s")
     296                    )
     297                    AND order_date IS NULL
     298                    AND synced_to_ac = ' . $synced_to_ac . ';'
     299            );
     300            // phpcs:enable
     301
     302            if ( $wpdb->last_error ) {
     303                $this->logger->error(
     304                    'A database error was encountered while getting results for abandoned cart records.',
     305                    [
     306                        'wpdb_last_error'  => $wpdb->last_error,
     307                        'wpdb_last_query'  => $wpdb->last_query,
     308                        'suggested_action' => 'Please verify that the query is correct and cron process has read access to the ' . ACTIVECAMPAIGN_FOR_WOOCOMMERCE_TABLE_NAME . ' table',
     309                        'ac_code'          => 'RASC_301',
     310                    ]
     311                );
     312            }
     313
     314            $this->clean_old_synced_abandoned_carts();
     315            $this->clean_all_old_abandoned_carts();
     316
     317            if ( ! empty( $abandoned_carts ) ) {
     318                return $abandoned_carts; // abandoned carts found
     319            } else {
     320                return false; // no abandoned carts to process
     321            }
     322        } catch ( Throwable $t ) {
     323            $this->logger->error(
     324                'An error was thrown while preparing or getting abandoned cart results.',
     325                [
     326                    'message' => $t->getMessage(),
     327                    'ac_code' => 'RASC_320',
     328                    'trace'   => $this->logger->clean_trace( $t->getTrace() ),
     329                ]
     330            );
     331        }
     332    }
     333
     334    /**
     335     * Get all active carts.
     336     *
     337     * @deprecated This will need to be removed after a few versions as we moved from a common unsynced value of 0 to 20 for abandoned carts specifically.
     338     *
     339     * @return mixed Whether or not there are abandoned carts.
     340     * @throws Throwable Thrown message.
     341     */
     342    private function get_all_abandoned_carts_from_table_legacy() {
     343        global $wpdb;
     344
     345        // default is 1 hour abandon cart expiration
     346        $this->expire_time = 1;
     347
     348        // Get the expire time period from the db
     349        $activecampaign_for_woocommerce_settings = get_option( ACTIVECAMPAIGN_FOR_WOOCOMMERCE_DB_SETTINGS_NAME );
     350        $activecampaign_for_woocommerce_settings = stripslashes_deep( $activecampaign_for_woocommerce_settings );
     351
     352        if ( isset( $activecampaign_for_woocommerce_settings['abcart_wait'] ) && ! empty( $activecampaign_for_woocommerce_settings['abcart_wait'] ) ) {
     353            $this->expire_time = $activecampaign_for_woocommerce_settings['abcart_wait'];
     354        }
     355
     356        $expire_datetime = new DateTime( 'now -' . $this->expire_time . ' hours', new DateTimeZone( 'UTC' ) );
    266357
    267358        try {
     
    269360            // phpcs:disable
    270361            $abandoned_carts = $wpdb->get_results(
    271                 'SELECT id, synced_to_ac, customer_ref_json, cart_ref_json, cart_totals_ref_json, removed_cart_contents_ref_json, activecampaignfwc_order_external_uuid, last_access_time
    272                     FROM
    273                         `' . $wpdb->prefix . ACTIVECAMPAIGN_FOR_WOOCOMMERCE_TABLE_NAME . '`
    274                     WHERE
    275                         ( last_access_time < "' . $expire_datetime->format( 'Y-m-d H:i:s' ) . '"
    276                         OR last_access_time < str_to_date("' . $expire_datetime->format( 'Y-m-d H:i:s' ) . '", "Y-m-d H:i:s") )
    277                         AND order_date IS NULL
    278                         AND synced_to_ac = ' . $synced_to_ac . ';'
    279             );
    280             // phpcs:enable
    281 
    282             if ( $wpdb->last_error ) {
    283                 $this->logger->error(
    284                     'A database error was encountered while getting results for abandoned cart records.',
    285                     [
    286                         'wpdb_last_error'  => $wpdb->last_error,
    287                         'suggested_action' => 'Please verify that the cron process has read access to the ' . ACTIVECAMPAIGN_FOR_WOOCOMMERCE_TABLE_NAME . ' table',
    288                         'ac_code'          => 'RASC_301',
    289                     ]
    290                 );
    291             }
    292 
    293             $this->clean_old_synced_abandoned_carts();
    294             $this->clean_all_old_abandoned_carts();
    295 
    296             if ( ! empty( $abandoned_carts ) ) {
    297                 return $abandoned_carts; // abandoned carts found
    298             } else {
    299                 return false; // no abandoned carts to process
    300             }
    301         } catch ( Throwable $t ) {
    302             $this->logger->error(
    303                 'An error was thrown while preparing or getting abandoned cart results.',
    304                 [
    305                     'message' => $t->getMessage(),
    306                     'ac_code' => 'RASC_320',
    307                     'trace'   => $this->logger->clean_trace( $t->getTrace() ),
    308                 ]
    309             );
    310         }
    311     }
    312 
    313     /**
    314      * Get all active carts.
    315      *
    316      * @deprecated This will need to be removed after a few versions as we moved from a common unsynced value of 0 to 20 for abandoned carts specifically.
    317      *
    318      * @return mixed Whether or not there are abandoned carts.
    319      * @throws Throwable Thrown message.
    320      */
    321     private function get_all_abandoned_carts_from_table_legacy() {
    322         global $wpdb;
    323 
    324         // default is 1 hour abandon cart expiration
    325         $expire_time = 1;
    326 
    327         // Get the expire time period from the db
    328         $activecampaign_for_woocommerce_settings = get_option( ACTIVECAMPAIGN_FOR_WOOCOMMERCE_DB_SETTINGS_NAME );
    329         $activecampaign_for_woocommerce_settings = stripslashes_deep( $activecampaign_for_woocommerce_settings );
    330 
    331         if ( isset( $activecampaign_for_woocommerce_settings['abcart_wait'] ) && ! empty( $activecampaign_for_woocommerce_settings['abcart_wait'] ) ) {
    332             $expire_time = $activecampaign_for_woocommerce_settings['abcart_wait'];
    333         }
    334 
    335         $expire_datetime = new DateTime( 'now -' . $expire_time . ' hours', new DateTimeZone( 'UTC' ) );
    336 
    337         try {
    338             // Get the expired carts from our table
    339             // phpcs:disable
    340             $abandoned_carts = $wpdb->get_results(
    341                 'SELECT id, synced_to_ac, customer_ref_json, cart_ref_json, cart_totals_ref_json, removed_cart_contents_ref_json, activecampaignfwc_order_external_uuid, last_access_time
     362                'SELECT id, synced_to_ac, customer_ref_json, cart_ref_json, cart_totals_ref_json, removed_cart_contents_ref_json, activecampaignfwc_order_external_uuid, last_access_time, ADDTIME(last_access_time, "' . $this->expire_time . ':00:00") as calc_abandoned_date
    342363                    FROM
    343364                        `' . $wpdb->prefix . ACTIVECAMPAIGN_FOR_WOOCOMMERCE_TABLE_NAME . '`
     
    578599        if ( isset( $order_ac ) && ! empty( $order_ac->get_id() ) && $externalcheckout_id === $order_ac->get_externalcheckoutid() ) {
    579600            try {
    580                 $updated_date = new DateTime( $abc_order->last_access_time, new DateTimeZone( 'UTC' ) );
    581                 $ecom_order->set_external_updated_date( $updated_date->format( DATE_ATOM ) );
     601
     602                $ab_datetime = $this->calculate_abandoned_date( $abc_order );
     603
     604                $ecom_order->set_external_updated_date( $ab_datetime );
     605                $ecom_order->set_external_created_date( $ab_datetime );
     606                $ecom_order->set_abandoned_date( $ab_datetime );
     607
     608                $ecom_order->set_source( 0 );
    582609                $ecom_order->set_id( $order_ac->get_id() );
    583610
     
    619646                );
    620647
    621                 $date = new DateTime( $abc_order->last_access_time, new DateTimeZone( 'UTC' ) );
    622                 $ecom_order->set_abandoned_date( $date->format( DATE_ATOM ) );
    623                 $ecom_order->set_external_created_date( $date->format( DATE_ATOM ) );
     648                $ab_datetime = $this->calculate_abandoned_date( $abc_order );
     649                $ecom_order->set_abandoned_date( $ab_datetime );
     650                $ecom_order->set_external_updated_date( $ab_datetime );
     651                $ecom_order->set_external_created_date( $ab_datetime );
    624652
    625653                $order_ac = $this->order_repository->create( $ecom_order );
     
    687715                    [
    688716                        'synced_to_ac'   => self::STATUS_ABANDONED_CART_AUTO_SYNCED,
    689                         'abandoned_date' => $abc_order->last_access_time,
     717                        'abandoned_date' => $this->calculate_abandoned_date( $abc_order ),
    690718                        'ac_order_id'    => self::validate_object( $order_ac, 'get_id' ) ? $order_ac->get_id() : null,
    691719                        'ac_customer_id' => self::validate_object( $order_ac, 'get_customerid' ) ? $order_ac->get_customerid() : null,
     
    969997        return $customer_ac;
    970998    }
     999
     1000    /**
     1001     * Sets/Gets the abandoned sync date. This is the time when a sync is performed which should be close to the actual abandonment time.
     1002     *
     1003     * @param object $cart The abandoned cart object.
     1004     *
     1005     * @return string The date formatted.
     1006     */
     1007    private function calculate_abandoned_date( $cart ) {
     1008        $logger = new Logger();
     1009
     1010        if ( isset( $cart->last_access_time ) && ( ! isset( $cart->abandoned_date ) || empty( $cart->abandoned_date ) ) ) {
     1011            try {
     1012                $now = new DateTime( 'now', new DateTimeZone( 'UTC' ) );
     1013
     1014                if ( ! isset( $this->expire_time ) || empty( $this->expire_time ) ) {
     1015                    $this->expire_time = 1;
     1016                }
     1017
     1018                $last_access_date = new DateTime( $cart->last_access_time, new DateTimeZone( 'UTC' ) );
     1019                $expire_datetime  = new DateTime( 'now -' . $this->expire_time . ' hours', new DateTimeZone( 'UTC' ) );
     1020                $ab_date          = new DateTime( $cart->last_access_time . ' + ' . $this->expire_time . ' hours', new DateTimeZone( 'UTC' ) );
     1021
     1022                $diff = $expire_datetime->diff( $ab_date, true );
     1023                $i    = 0 + ( $diff->days * 24 );
     1024                $i   += $diff->hours;
     1025
     1026                // calc_abandoned_date is calculated by the DB
     1027                if ( ! empty( $cart->calc_abandoned_date ) && empty( $cart->abandoned_date ) ) {
     1028                    $c_ab_date = new DateTime( $cart->calc_abandoned_date, new DateTimeZone( 'UTC' ) );
     1029                    return $c_ab_date->format( 'Y-m-d H:i:s e' );
     1030                } elseif ( empty( $cart->calc_abandoned_date ) && empty( $cart->abandoned_date ) ) {
     1031                    // If the DB somehow fails to calculate the date
     1032                    if ( intval( $i ) >= $this->expire_time ) {
     1033                        // If the expiration and abandonment difference is more than the expire time
     1034                        return $ab_date->format( 'Y-m-d H:i:s e' );
     1035                    }
     1036                }
     1037
     1038                // If this is manually force synced and not old enough use now as the time
     1039                return $now->format( 'Y-m-d H:i:s e' );
     1040            } catch ( Throwable $t ) {
     1041                $logger->warning(
     1042                    'Could not set a date time for abandoned cart.',
     1043                    [
     1044                        'message' => $t->getMessage(),
     1045                        'trace'   => $t->getTrace(),
     1046                    ]
     1047                );
     1048            }
     1049        }
     1050
     1051    }
    9711052}
  • activecampaign-for-woocommerce/trunk/includes/abandoned_carts/class-activecampaign-for-woocommerce-save-abandoned-cart-command.php

    r2960798 r2977226  
    274274                    'customer_first_name'            => $customer_data['first_name'],
    275275                    'customer_last_name'             => $customer_data['last_name'],
    276                     'last_access_time'               => $dt->format( 'Y-m-d H:i:s' ),
     276                    'last_access_time'               => $dt->format( 'Y-m-d H:i:s e' ),
    277277                    'customer_ref_json'              => wp_json_encode( $customer_data, JSON_UNESCAPED_UNICODE ),
    278278                    'user_ref_json'                  => wp_json_encode( $current_user, JSON_UNESCAPED_UNICODE ),
  • activecampaign-for-woocommerce/trunk/includes/abandoned_carts/trait-activecampaign-for-woocommerce-abandoned-cart-utilities.php

    r2971988 r2977226  
    3838            $abandoned_cart = $wpdb->get_results(
    3939            // phpcs:disable
    40                 $wpdb->prepare( 'SELECT id, synced_to_ac, last_access_time, customer_ref_json, cart_ref_json, cart_totals_ref_json, removed_cart_contents_ref_json, activecampaignfwc_order_external_uuid
     40                $wpdb->prepare( 'SELECT id, synced_to_ac, last_access_time, customer_ref_json, cart_ref_json, cart_totals_ref_json, removed_cart_contents_ref_json, activecampaignfwc_order_external_uuid, abandoned_date
    4141                    FROM
    4242                        `' . $wpdb->prefix . ACTIVECAMPAIGN_FOR_WOOCOMMERCE_TABLE_NAME . '`
     
    4848            // phpcs:enable
    4949            );
     50
     51            $activecampaign_for_woocommerce_settings = get_option( ACTIVECAMPAIGN_FOR_WOOCOMMERCE_DB_SETTINGS_NAME );
     52            $activecampaign_for_woocommerce_settings = stripslashes_deep( $activecampaign_for_woocommerce_settings );
     53
     54            if ( isset( $activecampaign_for_woocommerce_settings['abcart_wait'] ) && ! empty( $activecampaign_for_woocommerce_settings['abcart_wait'] ) ) {
     55                $this->expire_time = $activecampaign_for_woocommerce_settings['abcart_wait'];
     56            }
    5057
    5158            if ( $wpdb->last_error ) {
  • activecampaign-for-woocommerce/trunk/includes/class-activecampaign-for-woocommerce.php

    r2966088 r2977226  
    637637
    638638        $this->loader->add_action(
     639            ACTIVECAMPAIGN_FOR_WOOCOMMERCE_RUN_NEW_ORDER_SYNC_NAME,
     640            $this->historical_sync,
     641            'run_historical_sync_contacts',
     642            6,
     643            2
     644        );
     645
     646        $this->loader->add_action(
    639647            'activecampaign_for_woocommerce_prep_historical_data',
    640648            $this->historical_sync,
     
    661669            'activecampaign_for_woocommerce_run_historical_sync_contacts',
    662670            $this->historical_sync,
    663             'run_historical_sync_contacts',
     671            'prep_historical_sync_contacts',
    664672            3,
    665673            2
  • activecampaign-for-woocommerce/trunk/includes/config/activecampaign-for-woocommerce-global-constants.php

    r2975700 r2977226  
    2626 */
    2727if ( ! defined( 'ACTIVECAMPAIGN_FOR_WOOCOMMERCE_VERSION' ) ) {
    28     define( 'ACTIVECAMPAIGN_FOR_WOOCOMMERCE_VERSION', '2.4.8' );
     28    define( 'ACTIVECAMPAIGN_FOR_WOOCOMMERCE_VERSION', '2.4.9' );
    2929}
    3030
  • activecampaign-for-woocommerce/trunk/includes/models/class-activecampaign-for-woocommerce-ecom-order.php

    r2966088 r2977226  
    456456    /**
    457457     * Sets the source.
    458      *
    459      * @param string $source The source (1 or 0).
     458     * 0 = historical
     459     * 1 = active (will trigger automations)
     460     *
     461     * @param string $source The source (1=active or 0=historical).
    460462     */
    461463    public function set_source( $source ) {
  • activecampaign-for-woocommerce/trunk/includes/orders/historical/class-activecampaign-for-woocommerce-historical-sync-contacts.php

    r2966088 r2977226  
    6161        }
    6262
    63         $this->logger->debug( 'Contact historical sync started.' );
    64 
    6563        $this->status['contact_total'] = $wpdb->get_var( 'SELECT count(email) FROM ' . $wpdb->prefix . 'wc_customer_lookup WHERE email != "";' );
    6664        $this->update_sync_status();
     
    6967        $limit           = 200;
    7068        $synced_contacts = 0;
     69        $last_record     = 0;
     70        $start           = get_transient( 'activecampaign_for_woocommerce_hs_contacts' );
     71
     72        $this->logger->debug( 'Contact historical sync started.', [ 'start transient' => $start ] );
     73
     74        if ( ! empty( $start ) ) {
     75            $last_record     = $start;
     76            $synced_contacts = $this->status['contact_count'];
     77        }
     78
    7179        // phpcs:disable
    7280        wp_suspend_cache_addition(true); // Do not add to cache for session
    7381        while ( $wc_customers = $wpdb->get_results(
    7482            $wpdb->prepare(
    75                 'SELECT first_name, last_name, email, user_id, customer_id FROM ' . $wpdb->prefix . 'wc_customer_lookup WHERE email != "" ORDER BY customer_id LIMIT %d, %d;',
    76                 [ $c, $limit ]
     83                'SELECT first_name, last_name, email, user_id, customer_id FROM ' . $wpdb->prefix . 'wc_customer_lookup WHERE email != "" AND customer_id > %d ORDER BY customer_id ASC LIMIT %d, %d;',
     84                [ $start, $c, $limit ]
    7785            )
    7886        ) ) {
     
    120128                    );
    121129                }
    122             }
    123 
     130
     131                $last_record = $wc_customer->customer_id;
     132            }
     133
     134            // Sync the contact batch
    124135            try {
    125136                $ac_contact_batch = new AC_Contact_Batch();
     
    137148                );
    138149
     150                if ( is_array( $response ) && isset( $response['type'] ) && 'error' === $response['type'] ) {
     151                    $synced_contacts                      -= count( $bulk_contacts );
     152                    $this->status['contact_failed_count'] += count( $bulk_contacts );
     153                }
     154
     155                $this->status['contact_count'] = $synced_contacts;
    139156                $c                            += $limit;
    140                 $this->status['contact_count'] = $synced_contacts;
    141157                $this->update_sync_status();
    142158
    143                 if ( is_array( $response ) && isset( $response['type'] ) && 'error' === $response['type'] ) {
    144                     $synced_contacts -= count( $bulk_contacts );
    145 
    146                     $this->status['contact_count']         = $synced_contacts;
    147                     $this->status['contact_failed_count'] += count( $bulk_contacts );
    148                 }
    149159            } catch ( Throwable $t ) {
    150160                $synced_contacts -= count( $bulk_contacts );
     
    157167                );
    158168            }
     169
     170            set_transient( 'activecampaign_for_woocommerce_hs_contacts', $last_record, 3600 );
     171            if ( $c > 2000 ) {
     172                break;
     173            }
     174        }
     175
     176        if ( 0 === $c ) {
     177            delete_transient( 'activecampaign_for_woocommerce_hs_contacts' );
    159178        }
    160179
     
    166185                'count' => $c,
    167186            ]
     187        );
     188    }
     189
     190    private function schedule_next( $start ) {
     191        wp_schedule_single_event(
     192            time() + 50,
     193            'activecampaign_for_woocommerce_run_historical_sync_contacts',
     194            [ 'start' => $start ]
    168195        );
    169196    }
  • activecampaign-for-woocommerce/trunk/includes/orders/historical/class-activecampaign-for-woocommerce-historical-sync-handler.php

    r2966088 r2977226  
    161161    }
    162162
     163    public function prep_historical_sync_contacts() {
     164        set_transient( 'activecampaign_for_woocommerce_hs_contacts', 0, 3600 );
     165    }
     166
    163167    /**
    164168     * Runs historical sync for contacts.
     
    167171     */
    168172    public function run_historical_sync_contacts( ...$args ) {
    169         $this->update_sync_running_status( 'contacts', 'syncing' );
    170 
    171         $historical_contacts = new Historical_Contacts(
    172             $this->logger,
    173             $this->contact_batch_repository
    174         );
    175 
    176         $historical_contacts->execute( $args );
    177 
    178         $this->update_sync_running_status( 'contacts', 'finished' );
     173        if ( get_transient( 'activecampaign_for_woocommerce_hs_contacts' ) !== false ) {
     174            $this->update_sync_running_status( 'contacts', 'syncing' );
     175
     176            $historical_contacts = new Historical_Contacts(
     177                $this->logger,
     178                $this->contact_batch_repository
     179            );
     180
     181            $historical_contacts->execute( $args );
     182        }
     183
     184        // $this->update_sync_running_status( 'contacts', 'finished' );
    179185    }
    180186
Note: See TracChangeset for help on using the changeset viewer.