diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 198a7380..0d0fcfeb 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,4 +1,9 @@ == Changelog == += 4.0 = +* Allow orders to be sent to Mailchimp even if a Wordpress user role isn't set +* Support for custom order IDs +* Updated dependabot issues related to block-based checkouts +* Refreshed plugin interface = 3.7 = * Allow orders to be sent to Mailchimp even if a Wordpress user role isn't set * Support for custom order IDs diff --git a/README.txt b/README.txt index 3c3a6027..d2d3c31d 100644 --- a/README.txt +++ b/README.txt @@ -4,10 +4,10 @@ Tags: ecommerce,email,workflows,mailchimp Donate link: https://mailchimp.com Requires at least: 4.9 Tested up to: 6.5 -Stable tag: 3.7 +Stable tag: 4.0 Requires PHP: 7.4 WC requires at least: 4.2 -WC tested up to: 8.7 +WC tested up to: 8.8 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html Connect your store to your Mailchimp audience to track sales, create targeted emails, send abandoned cart emails, and more. @@ -77,8 +77,10 @@ At this time, the synchronization of product categories from WooCommerce to Mail = My question is not listed = If you are unable to sync or connect with Mailchimp, you can open a ticket on our [Github plugin page](https://github.com/mailchimp/mc-woocommerce/issues). Please provide the version of the plugin and PHP you're using, any fatal errors in the WooCommerce logs (WooCommerce -> Status -> Logs) you're seeing, along with relevant information to the problem you're experiencing. -== Changelog == -= 3.7 = + += 4.0 = * Allow orders to be sent to Mailchimp even if a Wordpress user role isn't set * Support for custom order IDs * Updated dependabot issues related to block-based checkouts +* Refreshed plugin interface + diff --git a/admin/class-mailchimp-woocommerce-admin.php b/admin/class-mailchimp-woocommerce-admin.php index 0320d76d..9a602eb1 100644 --- a/admin/class-mailchimp-woocommerce-admin.php +++ b/admin/class-mailchimp-woocommerce-admin.php @@ -84,7 +84,7 @@ private function disconnect_store() { */ private function is_disconnecting() { return isset( $_REQUEST['mailchimp_woocommerce_disconnect_store'] ) - && current_user_can( 'manage_options' ) + && current_user_can( mailchimp_get_allowed_capability() ) && $_REQUEST['mailchimp_woocommerce_disconnect_store'] == 1 && isset( $_REQUEST['_disconnect-nonce'] ) && wp_verify_nonce( $_REQUEST['_disconnect-nonce'], '_disconnect-nonce-' . mailchimp_get_store_id() ); @@ -95,7 +95,7 @@ private function is_disconnecting() { */ private function is_resyncing() { return isset( $_REQUEST['mailchimp_woocommerce_resync'] ) - && current_user_can( 'manage_options' ) + && current_user_can( mailchimp_get_allowed_capability() ) && $_REQUEST['mailchimp_woocommerce_resync'] == 1 && isset( $_REQUEST['_resync-nonce'] ) && wp_verify_nonce( $_REQUEST['_resync-nonce'], '_resync-nonce-' . mailchimp_get_store_id() ); @@ -113,6 +113,9 @@ public function enqueue_styles( $hook ) { wp_enqueue_style( $this->plugin_name . '-settings', plugin_dir_url( __FILE__ ) . 'css/mailchimp-woocommerce-admin-settings-5.2.css', array(), $this->version ); } wp_enqueue_style( $this->plugin_name . '-settings', plugin_dir_url( __FILE__ ) . 'css/mailchimp-woocommerce-admin-settings.css', array(), $this->version . '.01' ); + // Update v2 + wp_enqueue_style( $this->plugin_name . '-settings-v2', plugin_dir_url( __FILE__ ) . 'v2/assets/css/styles.css', array(), $this->version); + // End update v2 wp_style_add_data( $this->plugin_name . '-settings', 'rtl', 'replace' ); } } @@ -132,6 +135,7 @@ public function enqueue_scripts( $hook ) { $options = get_option( $this->plugin_name, array() ); $checkbox_default_settings = ( array_key_exists( 'mailchimp_checkbox_defaults', $options ) && ! is_null( $options['mailchimp_checkbox_defaults'] ) ) ? $options['mailchimp_checkbox_defaults'] : 'check'; wp_register_script( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'js/mailchimp-woocommerce-admin.js', array( 'jquery', 'swal' ), $this->version ); + wp_register_script( $this->plugin_name . '-v2', plugin_dir_url( __FILE__ ) . 'v2/assets/js/scripts.js', array( 'jquery', 'swal' ), $this->version ); wp_localize_script( $this->plugin_name, 'phpVars', @@ -155,11 +159,15 @@ public function enqueue_scripts( $hook ) { 'support_message_ok' => __( 'Message received', 'mailchimp-for-woocommerce' ), 'support_message_desc' => __( 'Thanks, your message has been received.', 'mailchimp-for-woocommerce' ), 'subscribe_newsletter' => $label, + 'option_update_success' => __( 'Changes Saved', 'mailchimp-for-woocommerce' ), + 'option_update_error' => __( 'Save error', 'mailchimp-for-woocommerce' ), ), 'current_optin_state' => $checkbox_default_settings, + 'ajax_url_option' => admin_url( 'options.php' ) ) ); wp_enqueue_script( $this->plugin_name ); + wp_enqueue_script( $this->plugin_name . '-v2'); wp_enqueue_script( 'swal', '//cdn.jsdelivr.net/npm/sweetalert2@8', '', $this->version ); } } @@ -199,6 +207,40 @@ public function add_plugin_admin_menu() { ); } + /** + * Register the administration menu for this plugin into the WordPress Dashboard menu. + * + * @since 1.0.0 + */ + public function add_plugin_admin_menu_2() { + + $cap = mailchimp_get_allowed_capability(); + + // Add woocommerce menu subitem + add_submenu_page( + 'woocommerce', // Parent Slug + __( 'Mailchimp for WooCommerce', 'mailchimp-for-woocommerce' ), + __( 'Mailchimp', 'mailchimp-for-woocommerce' ), + $cap, + $this->plugin_name, + array( $this, 'display_plugin_setup_page') // Callback function to display content + ); + + // Add the WooCommerce navigation items if the feauture exists. + if ( ! class_exists( '\Automattic\WooCommerce\Admin\Features\Navigation\Menu' ) ) { + return; + } + + Menu::add_plugin_item( + array( + 'id' => 'mailchimp-for-woocommerce', + 'title' => __( 'Mailchimp', 'mailchimp-for-woocommerce' ), + 'capability' => $cap, + 'url' => $this->plugin_name, + ) + ); + } + /** * Include the new Navigation Bar the Admin page. */ @@ -265,7 +307,12 @@ public function add_action_links( $links ) { * @since 1.0.0 */ public function display_plugin_setup_page() { - include_once 'partials/mailchimp-woocommerce-admin-tabs.php'; + // Comment: [Old UI] + // include_once 'partials/mailchimp-woocommerce-admin-tabs.php'; + + // [New UI] + include_once 'v2/helpers/helper.php'; + include_once 'v2/templates/mailchimp-woocommerce-admin-pages.php'; } public function display_user_profile_info( $user ) { @@ -349,10 +396,10 @@ public function options_update() { } } - $active_tab = isset( $_GET['tab'] ) ? sanitize_text_field( $_GET['tab'] ) : ( $this->getOption( 'active_tab' ) ? $this->getOption( 'active_tab' ) : 'api_key' ); - if ( $active_tab == 'sync' && get_option( 'mailchimp-woocommerce-sync.initial_sync' ) == 1 && get_option( 'mailchimp-woocommerce-sync.completed_at' ) > 0 ) { - $this->mailchimp_show_initial_sync_message(); - } +// $active_tab = isset( $_GET['tab'] ) ? sanitize_text_field( $_GET['tab'] ) : ( $this->getOption( 'active_tab' ) ? $this->getOption( 'active_tab' ) : 'api_key' ); +// if ( $active_tab == 'sync' && get_option( 'mailchimp-woocommerce-sync.initial_sync' ) == 1 && get_option( 'mailchimp-woocommerce-sync.completed_at' ) > 0 ) { +// $this->mailchimp_show_initial_sync_message(); +// } if ( isset( $_GET['log_removed'] ) && $_GET['log_removed'] == '1' ) { add_settings_error( 'mailchimp_log_settings', '', __( 'Log file deleted.', 'mailchimp-for-woocommerce' ), 'info' ); } @@ -456,7 +503,7 @@ public function update_db_check() { // set permission_cap in case there's none set. if ( ! isset( $options['mailchimp_permission_cap'] ) || empty( $options['mailchimp_permission_cap'] ) ) { - $options['mailchimp_permission_cap'] = 'manage_options'; + $options['mailchimp_permission_cap'] = 'administrator'; update_option( $this->plugin_name, $options ); } @@ -731,8 +778,7 @@ protected function handle_abandoned_cart_table() { * @throws MailChimp_WooCommerce_ServerError */ public function validate( $input ) { - - $active_tab = isset( $input['mailchimp_active_tab'] ) ? $input['mailchimp_active_tab'] : null; + $active_tab = isset( $input['mailchimp_active_tab'] ) ? $input['mailchimp_active_tab'] : (isset( $input['mailchimp_active_settings_tab'] ) ? $input['mailchimp_active_settings_tab']: null); if ( empty( $active_tab ) && isset( $input['woocommerce_settings_save_general'] ) && $input['woocommerce_settings_save_general'] ) { unset( $input['woocommerce_settings_save_general'] ); @@ -752,6 +798,10 @@ public function validate( $input ) { case 'api_key': $data = $this->validatePostApiKey( $input ); + if (!empty($data) && empty($data['api_ping_error'])) { + mailchimp_set_transient('oauth_success', true, 10); + mailchimp_flush_sync_pointers(); + } break; case 'store_info': @@ -770,7 +820,7 @@ public function validate( $input ) { $service = new MailChimp_Service(); $service->removePointers(); $this->startSync(); - $this->showSyncStartedMessage(); + //$this->showSyncStartedMessage(); $this->setData( 'sync.config.resync', true ); } break; @@ -830,19 +880,30 @@ public function validate( $input ) { */ protected function validatePostApiKey( $input ) { $data = array( - 'mailchimp_api_key' => isset( $input['mailchimp_api_key'] ) ? trim( $input['mailchimp_api_key'] ) : false, + 'mailchimp_api_key' => isset( $input['mailchimp_api_key'] ) ? trim( $input['mailchimp_api_key'] ) : $this->getOption('mailchimp_api_key'), 'mailchimp_debugging' => isset( $input['mailchimp_debugging'] ) ? $input['mailchimp_debugging'] : false, 'mailchimp_account_info_id' => null, 'mailchimp_account_info_username' => null, + 'api_ping_error' => null, + 'store_name' => get_option( 'blogname' ), ); + if (empty($data['mailchimp_api_key'])) { + mailchimp_error("admin", "The Mailchimp API key was empty while validating."); + add_settings_error( 'mailchimp_store_settings', $e->getCode(), $e->getMessage() ); + unset( $data['mailchimp_api_key'] ); + $data['active_tab'] = 'api_key'; + $data['api_ping_error'] = "No API key detected."; + return $data; + } + $api = new MailChimp_WooCommerce_MailChimpApi( $data['mailchimp_api_key'] ); try { $profile = $api->ping( true, true ); // tell our reporting system whether or not we had a valid ping. $this->setData( 'validation.api.ping', true ); - $data['active_tab'] = 'store_info'; + $data['active_tab'] = 'newsletter_settings'; if ( isset( $profile ) && is_array( $profile ) && array_key_exists( 'account_id', $profile ) ) { $data['mailchimp_account_info_id'] = $profile['account_id']; $data['mailchimp_account_info_username'] = $profile['username']; @@ -927,8 +988,9 @@ public function mailchimp_woocommerce_ajax_oauth_status() { * Mailchimp OAuth connection finish */ public function mailchimp_woocommerce_ajax_oauth_finish() { + mailchimp_log('admin', 'right before middleware oauth finish'); $this->adminOnlyMiddleware(); - + mailchimp_log('admin', 'right after middleware oauth finish'); $args = array( 'domain' => site_url(), 'secret' => get_site_transient( 'mailchimp-woocommerce-oauth-secret' ), @@ -944,6 +1006,8 @@ public function mailchimp_woocommerce_ajax_oauth_finish() { $response = wp_remote_post( 'https://woocommerce.mailchimpapp.com/api/finish', $pload ); + mailchimp_log('admin', "finished oauth", array('response' => $response)); + // need to return the error message if this is the problem. if ( $response instanceof WP_Error ) { wp_send_json_error( $response ); @@ -952,6 +1016,14 @@ public function mailchimp_woocommerce_ajax_oauth_finish() { if ( $response['response']['code'] == 200 ) { delete_site_transient( 'mailchimp-woocommerce-oauth-secret' ); // save api_key? If yes, we can skip api key validation for validatePostApiKey(); + $result = json_decode( $response['body'], true); + $options = get_option($this->plugin_name); + $options['mailchimp_api_key'] = $result['access_token'].'-'.$result['data_center']; + + mailchimp_log('admin', "got access token - updating options", array('response' => $response['body'])); + + update_option( $this->plugin_name, $options ); + wp_send_json_success( $response ); } else { wp_send_json_error( $response ); @@ -1111,26 +1183,28 @@ public function mailchimp_woocommerce_ajax_create_account_signup() { protected function validatePostStoreInfo( $input ) { $data = $this->compileStoreInfoData( $input ); - if ( ! $this->hasValidStoreInfo( $data ) ) { - - if ( $this->hasInvalidStoreAddress( $data ) ) { - $this->addInvalidAddressAlert(); - } - - if ( $this->hasInvalidStorePhone( $data ) ) { - $this->addInvalidPhoneAlert(); - } - - if ( $this->hasInvalidStoreName( $data ) ) { - $this->addInvalidStoreNameAlert(); - } - - $this->setData( 'validation.store_info', false ); +// if ( ! $this->hasValidStoreInfo( $data ) ) { +// +// if ( $this->hasInvalidStoreAddress( $data ) ) { +// $this->addInvalidAddressAlert(); +// } +// +// if ( $this->hasInvalidStorePhone( $data ) ) { +// $this->addInvalidPhoneAlert(); +// } +// +// if ( $this->hasInvalidStoreName( $data ) ) { +// $this->addInvalidStoreNameAlert(); +// } +// +// $this->setData( 'validation.store_info', false ); +// +// $data['active_tab'] = 'store_info'; +// +// return $input; +// } - $data['active_tab'] = 'store_info'; - return $input; - } // change communication status options $comm_opt = get_option( 'mailchimp-woocommerce-comm.opt', 0 ); @@ -1150,6 +1224,11 @@ protected function validatePostStoreInfo( $input ) { } } + // run sync all products if the image size has changed + if ( mailchimp_get_option( 'mailchimp_product_image_key', 'medium' ) !== $data['mailchimp_product_image_key'] ) { + mailchimp_handle_or_queue(new MailChimp_WooCommerce_Process_Products()); + } + $data['active_tab'] = 'newsletter_settings'; $data['store_currency_code'] = get_woocommerce_currency(); @@ -1162,26 +1241,50 @@ protected function validatePostStoreInfo( $input ) { * @return array */ protected function compileStoreInfoData( $input ) { - $checkbox = $this->getOption( 'mailchimp_permission_cap', 'check' ); + $permissions = $this->getOption( 'mailchimp_permission_cap', 'manage_woocommerce' ); // see if it's posted in the form. if ( isset( $input['mailchimp_permission_cap'] ) && ! empty( $input['mailchimp_permission_cap'] ) ) { - $checkbox = $input['mailchimp_permission_cap']; + $permissions = $input['mailchimp_permission_cap']; } + + // default value. + $checkbox = $this->getOption( 'mailchimp_checkbox_defaults', 'check' ); + + // see if it's posted in the form. + if ( isset( $input['mailchimp_checkbox_defaults'] ) && ! empty( $input['mailchimp_checkbox_defaults'] ) ) { + $checkbox = $input['mailchimp_checkbox_defaults']; + } + + $allowed_html = array( + 'a' => array( + 'href' => array(), + 'title' => array(), + 'target' => array(), + ), + 'br' => array(), + ); + return array( // store basics - 'store_name' => trim( ( isset( $input['store_name'] ) ? $input['store_name'] : get_option( 'blogname' ) ) ), - 'store_street' => isset( $input['store_street'] ) ? $input['store_street'] : false, - 'store_city' => isset( $input['store_city'] ) ? $input['store_city'] : false, - 'store_state' => isset( $input['store_state'] ) ? $input['store_state'] : false, - 'store_postal_code' => isset( $input['store_postal_code'] ) ? $input['store_postal_code'] : false, - 'store_country' => isset( $input['store_country'] ) ? $input['store_country'] : false, - 'store_phone' => isset( $input['store_phone'] ) ? $input['store_phone'] : false, + 'store_name' => trim( ( isset( $input['store_name'] ) ? $input['store_name'] : get_option( 'blogname' ) ) ), + 'store_street' => isset( $input['store_street'] ) ? $input['store_street'] : false, + 'store_city' => isset( $input['store_city'] ) ? $input['store_city'] : false, + 'store_state' => isset( $input['store_state'] ) ? $input['store_state'] : false, + 'store_postal_code' => isset( $input['store_postal_code'] ) ? $input['store_postal_code'] : false, + 'store_country' => isset( $input['store_country'] ) ? $input['store_country'] : false, +// 'store_phone' => isset( $input['store_phone'] ) ? $input['store_phone'] : false, // locale info - 'store_locale' => isset( $input['store_locale'] ) ? $input['store_locale'] : false, - 'store_timezone' => mailchimp_get_timezone(), - 'admin_email' => isset( $input['admin_email'] ) && is_email( $input['admin_email'] ) ? $input['admin_email'] : $this->getOption( 'admin_email', false ), - 'mailchimp_permission_cap' => $checkbox, + 'store_currency_code' => get_woocommerce_currency(), + 'store_locale' => isset( $input['store_locale'] ) ? $input['store_locale'] : get_locale(), + 'store_timezone' => mailchimp_get_timezone(), + 'admin_email' => isset( $input['admin_email'] ) && is_email( $input['admin_email'] ) ? $input['admin_email'] : get_option( 'admin_email' ), + 'mailchimp_permission_cap' => $permissions, + 'mailchimp_checkbox_action' => isset( $input['mailchimp_checkbox_action'] ) ? $input['mailchimp_checkbox_action'] : $this->getOption( 'mailchimp_checkbox_action', 'woocommerce_after_checkout_billing_form' ), + 'mailchimp_product_image_key' => isset( $input['mailchimp_product_image_key'] ) ? $input['mailchimp_product_image_key'] : 'medium', + + 'newsletter_label' => ( isset( $input['newsletter_label'] ) ) ? wp_kses( $input['newsletter_label'], $allowed_html ) : $this->getOption( 'newsletter_label', __( 'Subscribe to our newsletter', 'mailchimp-for-woocommerce' ) ), + 'mailchimp_checkbox_defaults' => $checkbox, ); } @@ -1252,44 +1355,24 @@ protected function addInvalidStoreNameAlert() { * @return array|string[] */ protected function validatePostNewsletterSettings( $input ) { - // default value. - $checkbox = $this->getOption( 'mailchimp_checkbox_defaults', 'check' ); - - // see if it's posted in the form. - if ( isset( $input['mailchimp_checkbox_defaults'] ) && ! empty( $input['mailchimp_checkbox_defaults'] ) ) { - $checkbox = $input['mailchimp_checkbox_defaults']; - } $sanitized_tags = array_map( 'sanitize_text_field', explode( ',', $input['mailchimp_user_tags'] ) ); - $allowed_html = array( - 'a' => array( - 'href' => array(), - 'title' => array(), - 'target' => array(), - ), - 'br' => array(), - ); - $data = array( 'mailchimp_list' => isset( $input['mailchimp_list'] ) ? $input['mailchimp_list'] : $this->getOption( 'mailchimp_list', '' ), - 'newsletter_label' => ( isset( $input['newsletter_label'] ) ) ? wp_kses( $input['newsletter_label'], $allowed_html ) : $this->getOption( 'newsletter_label', __( 'Subscribe to our newsletter', 'mailchimp-for-woocommerce' ) ), - 'mailchimp_auto_subscribe' => isset( $input['mailchimp_auto_subscribe'] ) ? (bool) $input['mailchimp_auto_subscribe'] : false, - 'mailchimp_ongoing_sync_status' => isset( $input['mailchimp_ongoing_sync_status'] ) ? (bool) $input['mailchimp_ongoing_sync_status'] : false, - 'mailchimp_checkbox_defaults' => $checkbox, - 'mailchimp_checkbox_action' => isset( $input['mailchimp_checkbox_action'] ) ? $input['mailchimp_checkbox_action'] : $this->getOption( 'mailchimp_checkbox_action', 'woocommerce_after_checkout_billing_form' ), + 'mailchimp_auto_subscribe' => isset( $input['mailchimp_auto_subscribe'] ) ? (string) $input['mailchimp_auto_subscribe'] : $this->getOption( 'mailchimp_auto_subscribe', '1' ), + 'mailchimp_ongoing_sync_status' => isset( $input['mailchimp_ongoing_sync_status'] ) ? (bool) $input['mailchimp_ongoing_sync_status'] : $this->getOption('mailchimp_ongoing_sync_status', '1'), 'mailchimp_user_tags' => isset( $input['mailchimp_user_tags'] ) ? implode( ',', $sanitized_tags ) : $this->getOption( 'mailchimp_user_tags' ), - 'mailchimp_product_image_key' => isset( $input['mailchimp_product_image_key'] ) ? $input['mailchimp_product_image_key'] : 'medium', 'mailchimp_cart_tracking' => isset( $input['mailchimp_cart_tracking'] ) ? $input['mailchimp_cart_tracking'] : 'all', - 'campaign_from_name' => isset( $input['campaign_from_name'] ) ? $input['campaign_from_name'] : false, - 'campaign_from_email' => isset( $input['campaign_from_email'] ) && is_email( $input['campaign_from_email'] ) ? $input['campaign_from_email'] : false, - 'campaign_subject' => isset( $input['campaign_subject'] ) ? $input['campaign_subject'] : get_option( 'blogname' ), + 'campaign_from_name' => isset( $input['campaign_from_name'] ) ? $input['campaign_from_name'] : get_option( 'blogname' ), + 'campaign_from_email' => isset( $input['campaign_from_email'] ) && is_email( $input['campaign_from_email'] ) ? $input['campaign_from_email'] : $this->getOption( 'admin_email' , get_option('admin_email')), + 'campaign_subject' => isset( $input['campaign_subject'] ) ? $input['campaign_subject'] : esc_html__( 'Store Newsletter', 'mailchimp-for-woocommerce' ), 'campaign_language' => isset( $input['campaign_language'] ) ? $input['campaign_language'] : $this->getOption( 'store_locale' , 'en'), 'campaign_permission_reminder' => isset( $input['campaign_permission_reminder'] ) ? $input['campaign_permission_reminder'] : sprintf( /* translators: %s - plugin name. */esc_html__( 'You were subscribed to the newsletter from %s', 'mailchimp-for-woocommerce' ), get_option( 'blogname' ) ), ); if ( ! $this->hasValidCampaignDefaults( $data ) ) { $this->setData( 'validation.newsletter_settings', false ); - add_settings_error( 'mailchimp_list_settings', '', __( 'One or more fields were not updated', 'mailchimp-for-woocommerce' ) ); + //add_settings_error( 'mailchimp_list_settings', '', __( 'One or more fields were not updated', 'mailchimp-for-woocommerce' ) ); return array( 'active_tab' => 'newsletter_settings' ); } $this->setData( 'validation.newsletter_settings', true ); @@ -1326,17 +1409,12 @@ protected function validatePostNewsletterSettings( $input ) { $data['mailchimp_list'] = $this->swapped_list_id; } - // run sync all products if the image size has changed - if ( mailchimp_get_option( 'mailchimp_product_image_key', 'medium' ) !== $data['mailchimp_product_image_key'] ) { - mailchimp_handle_or_queue(new MailChimp_WooCommerce_Process_Products()); - } - // start the sync automatically if the sync is false if ( $store_created && ( (bool) $this->getData( 'sync.started_at', false ) === false ) ) { // tell the next page view to start the sync with a transient since the data isn't available yet set_site_transient( 'mailchimp_woocommerce_start_sync', microtime(), 300 ); - $this->showSyncStartedMessage(); + //$this->showSyncStartedMessage(); } $data['active_tab'] = 'sync'; @@ -1346,7 +1424,7 @@ protected function validatePostNewsletterSettings( $input ) { $this->setData( 'validation.newsletter_settings', false ); - add_settings_error( 'mailchimp_newsletter_settings', '', __( 'One or more fields were not updated', 'mailchimp-for-woocommerce' ) ); + //add_settings_error( 'mailchimp_newsletter_settings', '', __( 'One or more fields were not updated', 'mailchimp-for-woocommerce' ) ); $data['active_tab'] = 'newsletter_settings'; @@ -1422,6 +1500,11 @@ public function hasValidApiKey( $data = null, $throw_if_not_valid = false ) { if ( ( $pinged = $this->getCached( 'api-ping-check' ) ) === null ) { if ( ( $pinged = $this->api()->ping( false, $throw_if_not_valid === true ) ) ) { $this->setCached( 'api-ping-check', true, 120 ); + if (mailchimp_get_option('api_ping_error')) { + $options = get_option($this->plugin_name); + $options['api_ping_error'] = null; + update_option( $this->plugin_name, $options ); + } } } @@ -1462,7 +1545,7 @@ public function getAccountDetails() { try { if ( ( $account = $this->getCached( 'api-account-name' ) ) === null ) { if ( ( $account = $this->api()->getProfile() ) ) { - $this->setCached( 'api-account-name', $account, 120 ); + $this->setCached( 'api-account-name', $account, 300 ); } } return $account; @@ -1487,7 +1570,8 @@ public function getMailChimpLists() { if ( ( $pinged = $this->getCached( 'api-lists' ) ) === null ) { $pinged = $this->api()->getLists( true ); if ( $pinged ) { - $this->setCached( 'api-lists', $pinged, 120 ); + $this->setCached( 'api-lists', $pinged, 300 ); + $this->safelyUpdateGDPRFields(); } return $pinged; } @@ -1497,6 +1581,23 @@ public function getMailChimpLists() { } } + /** + * @return bool + */ + public function safelyUpdateGDPRFields() + { + try { + if (($list_id = mailchimp_get_list_id())) { + $this->updateGDPRFields($list_id); + return true; + } + return false; + } catch (Exception $e) { + mailchimp_log('admin', 'safelyUpdateGDPRFields error', array('message' => $e->getMessage())); + return false; + } + } + /** * @return false|mixed */ @@ -1513,7 +1614,8 @@ public function getListName() { if ( ( $lists = $this->getCached( 'api-lists' ) ) === null ) { $lists = $this->api()->getLists( true ); if ( $lists ) { - $this->setCached( 'api-lists', $lists, 120 ); + $this->setCached( 'api-lists', $lists, 300 ); + $this->safelyUpdateGDPRFields(); } } @@ -1523,6 +1625,28 @@ public function getListName() { } } + /** + * @return false|string + */ + public function getAccountName() + { + if ( ! $this->validateApiKey() ) { + return false; + } + + if ( ( $account_name = $this->getData( 'account_name', false ) ) ) { + return $account_name; + } + + $root = $this->api()->ping(true); + + $name = is_array($root) && array_key_exists('account_name', $root) ? $root['account_name'] : false; + + $this->setData('account_name', $name); + + return $name; + } + /** * @return bool * @throws MailChimp_WooCommerce_Error @@ -1561,12 +1685,110 @@ public function inject_sync_ajax_call() { var productProgress = 0; if (on_sync_tab === 'yes') { - var call_mailchimp_for_stats = function (showSpinner = false) { - let mc_last_updated = jQuery('#mailchimp_last_updated'); - if (showSpinner ) mc_last_updated.next('.spinner').css('visibility', 'visible'); + + // This function is for the old UI + // var call_mailchimp_for_stats = function (showSpinner = false) { + // let mc_last_updated = jQuery('#mailchimp_last_updated'); + // if (showSpinner ) mc_last_updated.next('.spinner').css('visibility', 'visible'); + // jQuery.get(endpoint, function(response) { + // if (response.success) { + + // // if the response is now finished - but the original sync status was "historical" + // // perform a page refresh because we need the re-sync buttons to show up again. + // if (response.has_finished === true && sync_status === 'historical') { + // return document.location.reload(true); + // } + + // if (response.has_started && !response.has_finished) { + // jQuery('.sync-stats-audience .sync-loader').css('visibility', 'visible'); + // jQuery('.sync-stats-audience .card_count').hide(); + + // jQuery('.sync-stats-store .card_count').hide(); + + // jQuery('.sync-stats-card .progress-bar-wrapper').show(); + + // if (response.promo_rules_page === 'complete') { + // promo_rulesProgress = 100; + // jQuery('#mailchimp_promo_rules_count').html(response.promo_rules_in_mailchimp.toLocaleString(undefined, {maximumFractionDigits: 0})).css('display', 'inline-block'); + // jQuery('.sync-stats-card.promo_rules .progress-bar-wrapper').hide(); + // } else { + // if (response.promo_rules_in_mailchimp === 0) { + // promo_rulesProgress = 0; + // promo_rulesPartial = "0 / " + response.promo_rules_in_store; + // } else { + // promo_rulesProgress = response.promo_rules_in_mailchimp / response.promo_rules_in_store * 100 + // promo_rulesPartial = response.promo_rules_in_mailchimp + " / " + response.promo_rules_in_store; + // } + // if (promo_rulesProgress > 100) promo_rulesProgress = 100; + // jQuery('.mailchimp_promo_rules_count_partial').html(promo_rulesPartial); + // } + // jQuery('.sync-stats-card.promo_rules .progress-bar').width(promo_rulesProgress+"%"); + + // if (response.products_page === 'complete') { + // productsProgress = 100; + // jQuery('#mailchimp_product_count').html(response.products_in_mailchimp.toLocaleString(undefined, {maximumFractionDigits: 0})).css('display', 'inline-block'); + // jQuery('.sync-stats-card.products .progress-bar-wrapper').hide(); + // } else { + // if (response.products_in_mailchimp === 0) { + // productsProgress = 0; + // productsPartial = "0 / " + response.products_in_store; + // } else { + // productsProgress = response.products_in_mailchimp / response.products_in_store * 100 + // productsPartial = response.products_in_mailchimp + " / " + response.products_in_store; + // } + // if (productsProgress > 100) productsProgress = 100; + // jQuery('.mailchimp_product_count_partial').html(productsPartial); + // } + // jQuery('.sync-stats-card.products .progress-bar').width(productsProgress+"%"); + + // if (response.orders_page === 'complete') { + // ordersProgress = 100; + // jQuery('#mailchimp_order_count').html(response.orders_in_mailchimp.toLocaleString(undefined, {maximumFractionDigits: 0})).css('display', 'inline-block'); + // jQuery('.sync-stats-card.orders .progress-bar-wrapper').hide(); + // } else { + // if (response.orders_in_mailchimp === 0) { + // ordersProgress = 0; + // ordersPartial = "0 / " + response.orders_in_store; + // } else { + // ordersProgress = response.orders_in_mailchimp / response.orders_in_store * 100 + // ordersPartial = response.orders_in_mailchimp + " / " + response.orders_in_store; + // } + // if (ordersProgress > 100) ordersProgress = 100; + // jQuery('.mailchimp_order_count_partial').html(ordersPartial); + // } + // jQuery('.sync-stats-card.orders .progress-bar').width(ordersProgress+"%"); + + // mc_last_updated.html(response.date); + + // // only call status again if sync is running. + // setTimeout(function() { + // call_mailchimp_for_stats(true); + // }, 10000); + // mc_last_updated.next('.spinner').css('visibility', 'hidden'); + // } + // else { + // mc_last_updated.next('.spinner').css('visibility', 'hidden'); + // jQuery('.sync-stats-card .progress-bar-wrapper').hide(); + // jQuery('#mailchimp_order_count').css('display', 'inline-block'); + // jQuery('#mailchimp_product_count').css('display', 'inline-block'); + // jQuery('#mailchimp_promo_rules_count').css('display', 'inline-block'); + // } + // } + // }); + // }; + + // New UI for overview tab + var call_mailchimp_for_stats_new = function (showSpinner = false) { + + if (showSpinner) { + jQuery('.sync-status-icon-wrapper span').addClass('mc-wc-d-none'); + jQuery('.sync-status-time').addClass('mc-wc-d-none'); + jQuery('.sync-status-icon-wrapper img').removeClass('mc-wc-d-none'); + } + jQuery.get(endpoint, function(response) { + //console.log('sync stats', response); if (response.success) { - // if the response is now finished - but the original sync status was "historical" // perform a page refresh because we need the re-sync buttons to show up again. if (response.has_finished === true && sync_status === 'historical') { @@ -1574,84 +1796,30 @@ public function inject_sync_ajax_call() { } if (response.has_started && !response.has_finished) { - jQuery('.sync-stats-audience .sync-loader').css('visibility', 'visible'); - jQuery('.sync-stats-audience .card_count').hide(); - - jQuery('.sync-stats-store .card_count').hide(); - - jQuery('.sync-stats-card .progress-bar-wrapper').show(); - - if (response.promo_rules_page === 'complete') { - promo_rulesProgress = 100; - jQuery('#mailchimp_promo_rules_count').html(response.promo_rules_in_mailchimp.toLocaleString(undefined, {maximumFractionDigits: 0})).css('display', 'inline-block'); - jQuery('.sync-stats-card.promo_rules .progress-bar-wrapper').hide(); - } else { - if (response.promo_rules_in_mailchimp === 0) { - promo_rulesProgress = 0; - promo_rulesPartial = "0 / " + response.promo_rules_in_store; - } else { - promo_rulesProgress = response.promo_rules_in_mailchimp / response.promo_rules_in_store * 100 - promo_rulesPartial = response.promo_rules_in_mailchimp + " / " + response.promo_rules_in_store; - } - if (promo_rulesProgress > 100) promo_rulesProgress = 100; - jQuery('.mailchimp_promo_rules_count_partial').html(promo_rulesPartial); - } - jQuery('.sync-stats-card.promo_rules .progress-bar').width(promo_rulesProgress+"%"); - - if (response.products_page === 'complete') { - productsProgress = 100; - jQuery('#mailchimp_product_count').html(response.products_in_mailchimp.toLocaleString(undefined, {maximumFractionDigits: 0})).css('display', 'inline-block'); - jQuery('.sync-stats-card.products .progress-bar-wrapper').hide(); - } else { - if (response.products_in_mailchimp === 0) { - productsProgress = 0; - productsPartial = "0 / " + response.products_in_store; - } else { - productsProgress = response.products_in_mailchimp / response.products_in_store * 100 - productsPartial = response.products_in_mailchimp + " / " + response.products_in_store; - } - if (productsProgress > 100) productsProgress = 100; - jQuery('.mailchimp_product_count_partial').html(productsPartial); - } - jQuery('.sync-stats-card.products .progress-bar').width(productsProgress+"%"); - - if (response.orders_page === 'complete') { - ordersProgress = 100; - jQuery('#mailchimp_order_count').html(response.orders_in_mailchimp.toLocaleString(undefined, {maximumFractionDigits: 0})).css('display', 'inline-block'); - jQuery('.sync-stats-card.orders .progress-bar-wrapper').hide(); - } else { - if (response.orders_in_mailchimp === 0) { - ordersProgress = 0; - ordersPartial = "0 / " + response.orders_in_store; - } else { - ordersProgress = response.orders_in_mailchimp / response.orders_in_store * 100 - ordersPartial = response.orders_in_mailchimp + " / " + response.orders_in_store; - } - if (ordersProgress > 100) ordersProgress = 100; - jQuery('.mailchimp_order_count_partial').html(ordersPartial); - } - jQuery('.sync-stats-card.orders .progress-bar').width(ordersProgress+"%"); - - mc_last_updated.html(response.date); + // Promo codes + jQuery('.sync-promo-codes .sync-number-finished').html(response.promo_rules_in_mailchimp.toLocaleString(undefined, {maximumFractionDigits: 0})); + // Products + jQuery('.sync-products .sync-number-finished').html(response.products_in_mailchimp.toLocaleString(undefined, {maximumFractionDigits: 0})); + // Orders + jQuery('.sync-orders .sync-number-finished').html(response.orders_in_mailchimp.toLocaleString(undefined, {maximumFractionDigits: 0})); + // Contacts + jQuery('.sync-contacts .sync-number-total span').html(response.customers_in_mailchimp.toLocaleString(undefined, {maximumFractionDigits: 0})); // only call status again if sync is running. setTimeout(function() { - call_mailchimp_for_stats(true); - }, 10000); - mc_last_updated.next('.spinner').css('visibility', 'hidden'); - } - else { - mc_last_updated.next('.spinner').css('visibility', 'hidden'); - jQuery('.sync-stats-card .progress-bar-wrapper').hide(); - jQuery('#mailchimp_order_count').css('display', 'inline-block'); - jQuery('#mailchimp_product_count').css('display', 'inline-block'); - jQuery('#mailchimp_promo_rules_count').css('display', 'inline-block'); + call_mailchimp_for_stats_new(showSpinner); + }, 15000); + } else { + jQuery('.sync-status-icon-wrapper img').addClass('mc-wc-d-none'); + jQuery('.sync-status-time').removeClass('mc-wc-d-none'); + jQuery('.sync-status-icon-wrapper span').removeClass('mc-wc-d-none'); + jQuery('.sync-status-icon-wrapper span').removeClass('mc-wc-d-none'); } } }); }; - call_mailchimp_for_stats(); + call_mailchimp_for_stats_new(); } }); @@ -1665,6 +1833,7 @@ public function inject_sync_ajax_call() { * @return false|mixed|null */ private function updateMailChimpList( $data = null, $list_id = null ) { + mailchimp_log('admin', 'updating mailchimp list', array('data' => $data)); if ( empty( $data ) ) { $data = $this->getOptions(); } @@ -1684,7 +1853,8 @@ private function updateMailChimpList( $data = null, $list_id = null ) { foreach ( $required as $requirement ) { if ( ! isset( $data[ $requirement ] ) || empty( $data[ $requirement ] ) ) { - mailchimp_log( 'admin', 'does not have enough data to update the mailchimp list.' ); + mailchimp_log( 'admin', 'does not have enough data to update the mailchimp list.', array('requirement' => $requirement)); + $this->updateGDPRFields($list_id); return false; } } @@ -1730,22 +1900,7 @@ private function updateMailChimpList( $data = null, $list_id = null ) { $this->setData( 'errors.mailchimp_list', false ); - try { - if ( ! empty( $list_id ) ) { - $transient = "mailchimp-woocommerce-gdpr-fields.{$list_id}"; - $GDPRfields = mailchimp_get_api()->getGDPRFields( $list_id ); - set_site_transient( $transient, $GDPRfields ); - mailchimp_log( - 'admin', - 'updated GDPR fields', - array( - 'fields' => $GDPRfields, - ) - ); - } - } catch ( Exception $e ) { - set_site_transient( $transient, array(), 60 ); - } + $this->updateGDPRFields($list_id); return $list_id; @@ -1756,6 +1911,28 @@ private function updateMailChimpList( $data = null, $list_id = null ) { } } + protected function updateGDPRFields($list_id) + { + try { + if ( ! empty( $list_id ) && !get_site_transient("mailchimp-woocommerce-gdpr-fields.{$list_id}.last_saved")) { + $transient = "mailchimp-woocommerce-gdpr-fields.{$list_id}"; + $GDPRfields = mailchimp_get_api()->getGDPRFields( $list_id ); + set_site_transient( $transient, $GDPRfields ); + set_site_transient("mailchimp-woocommerce-gdpr-fields.{$list_id}.last_saved", true, 120); + mailchimp_log( + 'admin', + 'updated GDPR fields', + array( + 'fields' => $GDPRfields, + ) + ); + } + } catch ( Exception $e ) { + set_site_transient( $transient, array(), 60 ); + mailchimp_error( 'admin', 'updating GDPR fields failed '.$e->getMessage() ); + } + } + /** * @param null $data * @param bool $update_campaign_defaults @@ -1771,15 +1948,15 @@ public function syncStore( $data = null, $update_campaign_defaults = false ) { } $list_id = $this->array_get( $data, 'mailchimp_list', false ); - $site_url = $this->getUniqueStoreID(); + $store_id = $this->getUniqueStoreID(); - if ( empty( $list_id ) || empty( $site_url ) ) { + if ( empty( $list_id ) || empty( $store_id ) ) { return false; } $new = false; - if ( ! ( $store = $this->api()->getStore( $site_url ) ) ) { + if ( ! ( $store = $this->api()->getStore( $store_id ) ) ) { $new = true; $store = new MailChimp_WooCommerce_Store(); } @@ -1787,7 +1964,7 @@ public function syncStore( $data = null, $update_campaign_defaults = false ) { $call = $new ? 'addStore' : 'updateStore'; $time_key = $new ? 'store_created_at' : 'store_updated_at'; - $store->setId( $site_url ); + $store->setId( $store_id ); $store->setPlatform( 'woocommerce' ); // set the locale data @@ -1805,7 +1982,7 @@ public function syncStore( $data = null, $update_campaign_defaults = false ) { $store->setEmailAddress( $this->array_get( $data, 'admin_email' ) ); $store->setAddress( $this->address( $data ) ); - $store->setPhone( $this->array_get( $data, 'store_phone' ) ); +// $store->setPhone( $this->array_get( $data, 'store_phone' ) ); $store->setListId( $list_id ); try { @@ -1822,7 +1999,8 @@ public function syncStore( $data = null, $update_campaign_defaults = false ) { mailchimp_update_connected_site_script(); // we need to update the list again with the campaign defaults - if (!$update_campaign_defaults) { + + if ($update_campaign_defaults) { $this->updateMailChimpList( $data, $list_id ); } @@ -1861,39 +2039,23 @@ public function syncStore( $data = null, $update_campaign_defaults = false ) { * @return MailChimp_WooCommerce_Address */ private function address( array $data ) { + $nodes = array( + 'store_street' => 'setAddress1', + 'store_city' => 'setCity', + 'store_state' => 'setProvince', + 'store_country' => 'setCountry', + 'store_postal_code' => 'setPostalCode', + 'store_name' => 'setCompany', + 'store_phone' => 'setPhone' + ); $address = new MailChimp_WooCommerce_Address(); - - if ( isset( $data['store_street'] ) && $data['store_street'] ) { - $address->setAddress1( $data['store_street'] ); - } - - if ( isset( $data['store_city'] ) && $data['store_city'] ) { - $address->setCity( $data['store_city'] ); - } - - if ( isset( $data['store_state'] ) && $data['store_state'] ) { - $address->setProvince( $data['store_state'] ); - } - - if ( isset( $data['store_country'] ) && $data['store_country'] ) { - $address->setCountry( $data['store_country'] ); - } - - if ( isset( $data['store_postal_code'] ) && $data['store_postal_code'] ) { - $address->setPostalCode( $data['store_postal_code'] ); - } - - if ( isset( $data['store_name'] ) && $data['store_name'] ) { - $address->setCompany( $data['store_name'] ); - } - - if ( isset( $data['store_phone'] ) && $data['store_phone'] ) { - $address->setPhone( $data['store_phone'] ); - } - + foreach ($nodes as $key => $fn) { + if ( isset( $data[$key] ) && $data[$key] ) { + $address->$fn( $data[$key] ); + } + } $woo_countries = new WC_Countries(); $address->setCountryCode( $woo_countries->get_base_country() ); - return $address; } @@ -2044,7 +2206,7 @@ public function mailchimp_woocommerce_tower_status() { // if error, keep option to original value wp_send_json_error( array( - 'error' => __( 'Error setting tower support status', 'mailchimp-for-woocommerce' ), + 'error' => $response_body->message, 'opt' => $original_opt, ) ); diff --git a/admin/js/mailchimp-woocommerce-admin.js b/admin/js/mailchimp-woocommerce-admin.js index 954c93e4..ff92ce3f 100644 --- a/admin/js/mailchimp-woocommerce-admin.js +++ b/admin/js/mailchimp-woocommerce-admin.js @@ -17,6 +17,10 @@ } }); + $('#mc_notice_button').on('click', function() { + $('.mc-wc-notice').fadeOut() + }); + // re-enable disable select input on audience settings submit $('#mailchimp_woocommerce_options').on('submit', function() { $('select[name="mailchimp-woocommerce[mailchimp_list]"]').prop('disabled', false); @@ -331,11 +335,12 @@ $('#mailchimp-oauth-error').hide(); $('#mailchimp-oauth-connecting').hide(); $('#mailchimp-oauth-connected').show(); - + + let body = JSON.parse(finishResponse.data.body); // get access_token from finishResponse and fill api-key field value including data_center - var accessToken = JSON.parse(finishResponse.data.body).access_token + '-' + JSON.parse(finishResponse.data.body).data_center + var accessToken = body.access_token + '-' + body.data_center $('#mailchimp-woocommerce-mailchimp-api-key').val(accessToken); - + // always go to next step on success, so change url of wp_http_referer if ($('input[name=mailchimp_woocommerce_wizard_on]').val() == 1) { var query = window.location.href.match(/^(.*)\&/); @@ -374,6 +379,14 @@ $('#tower_box_switch').change(function (e){ var switch_button = this; var opt = this.checked ? 1 : 0; + var notice = $('.mc-wc-notice'); + let notice_content = $('#mc_notice_text'); + var content = $('.mc-wc-tab-content'); + + //content.addClass('loading'); + + notice_content.text(''); + notice.removeClass('error success'); var data = { action: 'mailchimp_woocommerce_tower_status', @@ -384,14 +397,14 @@ $('#tower_box_status_' + opt).show(); $.post(ajaxurl, data, function(response) { + content.removeClass('loading'); if (response.success) { - $('#mc-tower-save').html(response.data); - $('#mc-tower-save').css('color', '#628735').show().fadeOut(3000); + notice_content.text(response.data); + notice.addClass('success').fadeIn(); switch_button.checked = opt; } else { - $('#mc-tower-save').html(response.data.error); - $('#mc-tower-save').css('color', 'red').show().fadeOut(3000); + $('

' + response.data.error +'

').insertAfter('.mc-wc-tab-buttons'); switch_button.checked = 1 - opt; $('.tower_box_status').hide(); $('#tower_box_status_' + (1 - opt)).show(); @@ -402,9 +415,17 @@ $('#comm_box_switch').change(function (e){ var switch_button = this; var opt = this.checked ? 1 : 0; - + var notice = $('.mc-wc-notice'); + let notice_content = $('#mc_notice_text'); + var content = $('.mc-wc-tab-content'); + + //content.addClass('loading'); + + notice_content.text(''); + notice.removeClass('error success'); + var data = { - action: 'mailchimp_woocommerce_communication_status', + action: 'mailchimp_woocommerce_communication_status', opt: opt } @@ -412,14 +433,16 @@ $('#comm_box_status_' + opt).show(); $.post(ajaxurl, data, function(response) { + content.removeClass('loading'); if (response.success) { - $('#mc-comm-save').html(response.data); - $('#mc-comm-save').css('color', '#628735').show().fadeOut(3000); + notice_content.text(response.data); + notice + .addClass('success') + .fadeIn(); switch_button.checked = opt; } else { - $('#mc-comm-save').html(response.data.error); - $('#mc-comm-save').css('color', 'red').show().fadeOut(3000); + $('

' + response.data.error +'

').insertAfter('.mc-wc-tab-buttons'); switch_button.checked = 1 - opt; $('.comm_box_status').hide(); $('#comm_box_status_' + (1 - opt)).show(); diff --git a/admin/partials/tabs/api-key.php b/admin/partials/tabs/api-key.php index cd5b7b50..51e4c98f 100644 --- a/admin/partials/tabs/api-key.php +++ b/admin/partials/tabs/api-key.php @@ -12,12 +12,9 @@ - + Create account - -

-

diff --git a/admin/partials/tabs/newsletter-settings.php b/admin/partials/tabs/newsletter-settings.php index 8b80f30b..b808034c 100644 --- a/admin/partials/tabs/newsletter-settings.php +++ b/admin/partials/tabs/newsletter-settings.php @@ -111,13 +111,13 @@
+
@@ -200,7 +200,7 @@

- +

checkout page.', 'mailchimp-for-woocommerce'), get_the_permalink($checkout_page_id) ) ?>

diff --git a/admin/v2/assets/css/styles.css b/admin/v2/assets/css/styles.css new file mode 100644 index 00000000..45ef0778 --- /dev/null +++ b/admin/v2/assets/css/styles.css @@ -0,0 +1,1901 @@ +/* Import fonts */ +@import url('../fonts/Means/fonts.css'); +@import url('../fonts/graphik/fonts.css'); + +/* Roboto */ +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 300; + src: local('Roboto'), url('../fonts/Roboto/Roboto-Light.ttf') format('truetype'); +} + +@font-face { + font-family: 'Roboto'; + font-style: italic; + font-weight: 300; + src: local('Roboto'), url('../fonts/Roboto/Roboto-LightItalic.ttf') format('truetype'); +} + + +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: normal; + src: local('Roboto'), url('../fonts/Roboto/Roboto-Regular.ttf') format('truetype'); +} + +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 500; + src: local('Roboto'), url('../fonts/Roboto/Roboto-Medium.ttf') format('truetype'); +} + +@font-face { + font-family: 'Roboto'; + font-style: italic; + font-weight: 500; + src: local('Roboto'), url('../fonts/Roboto/Roboto-MediumItalic.ttf') format('truetype'); +} + +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: bold; + src: local('Roboto'), url('../fonts/Roboto/Roboto-Bold.ttf') format('truetype'); +} + +@font-face { + font-family: 'Roboto'; + font-style: italic; + font-weight: bold; + src: local('Roboto'), url('../fonts/Roboto/Roboto-BoldItalic.ttf') format('truetype'); +} + +:root { + --mc-wc-primary: #734FA8; + --mc-wc-underline-primary: #7D57A4; + --mc-wc-disabled: #241C154D; + --mc-wc-border-color: #DFE5EB; + --mc-wc-border-radius: 8px; + --mc-wc-text-color: #202223; + +} + +#wpcontent { + padding-left: 59px; +} + +.mc-wc-d-none { + display: none !important; +} + +.mc-wc-settings-title { + font-family: 'Roboto'; + font-size: 28px; + font-weight: 500; + line-height: 36px; + letter-spacing: 0; + text-align: left; + color: #000624; + margin-block: 72px 26px; + padding-inline: 11px; +} + +.mc-wc-actions { + display: inline-flex; + gap: 13px; + align-items: center; +} + +.mc-wc-btn { + display: inline-block; + padding: 7.5px 24.5px; + border-radius: 38px; + text-decoration: none; + color: var(--mc-wc-text-color); + font-size: 13px; + font-weight: 500; + transition: 0.1s all; + border: 1px solid var(--mc-wc-text-color); + cursor: pointer; +} + +input.mc-wc-btn { + margin: 0; + line-height: 20px; +} + +.mc-wc-btn:focus { + box-shadow: none; +} + +.mc-wc-btn-primary { + background: linear-gradient(180deg, #674399 0%, #8661C1 100%); + color: #fff; + padding-block: 8.5px; + border: 0; +} + +.mc-wc-btn.mc-wc-btn-md.mc-wc-btn-primary { + padding: 16.65px 37.27px; +} + +.mc-wc-btn-primary-outline { + border: double 1px transparent; + background-image: linear-gradient(white, white), linear-gradient(180deg, #7652AC 92.66%, rgba(118, 82, 172, 0.69) 100%); + background-origin: border-box; + background-clip: padding-box, border-box; + color: var(--mc-wc-primary); +} + +.mc-wc-btn:hover { + opacity: 0.7; + color: inherit; +} + +.mc-wc-btn-primary-outline:hover { + color: var(--mc-wc-primary); +} + +.mc-wc-btn-primary:hover { + color: #fff; +} + + +.mc-wc-btn:disabled { + cursor: default !important; + color: #a7aaad !important; + border-color: #dcdcde !important; + background-color: #f6f7f7 !important; +} + +.mc-wc-btn:disabled { + opacity: 1; +} + +.mc-wc-btn.mc-wc-btn-primary:disabled { + border: 0 !important; + background: linear-gradient(180deg, #674399 0%, #8661C1 100%); + color: #fff !important; + opacity: 0.7; +} + +.mc-wc-row { + display: flex; + flex-direction: row; +} + +.mc-wc-col { + display: flex; + flex-direction: column; +} + +.mc-wc-image img { + max-width: 100%; +} + +.mc-wc-settings-wrapper { + font-family: 'Roboto'; + font-style: normal; + font-weight: normal; + font-size: 14px; + line-height: 20px; + width: 100%; + max-width: 728px; + color: var(--mc-wc-text-color); +} + +.mc-wc-setting-header { + background-color: #fff; + box-shadow: 0 4px 8px 0 #97979717; + border-radius: var(--mc-wc-border-radius); +} + +.mc-wc-breadcrumbs { + border-bottom: 1px solid #DFE5EB; +} + +.mc-wc-breadcrumbs-wrapper { + list-style: none; + display: flex; + gap: 24px; + font-size: 13px; + margin: 0; + padding: 18px 27px; + flex-wrap: wrap; +} + +.mc-wc-breadcrumbs-wrapper > li { + padding-block: 2px; +} + +.mc-wc-breadcrumbs-wrapper > li { + position: relative; +} + +.mc-wc-breadcrumbs-wrapper > li.current::before { + content: ""; + background-color: var(--mc-wc-underline-primary); + height: 2px; + width: 100%; + display: block; + left: 0; + bottom: 0; + position: absolute; + border-radius: 38px; +} + +.mc-wc-breadcrumbs-wrapper > li:not(:last-child)::after { + content: ">"; + font-family: 'Roboto'; + position: absolute; + right: -16px; + top: calc(50% - 10px); +} + +.mc-wc-breadcrumbs-wrapper > li.disabled, .mc-wc-breadcrumbs-wrapper > li:not(.mc-wc-breadcrumb-nextable)::after { + color: var(--mc-wc-disabled); +} + +.mc-wc-header-content-wrapper { + overflow: hidden; + padding: 77px 57px 77px; + position: relative; +} + +.mc-wc-btn-acctions-wrapper { + padding: 0 57px 119px; + margin-top: -72px; + position: relative; + z-index: 1; +} + +.mc-wc-header-content.connect-account { + position: relative; +} + +.mc-wc-header-content.connect-account .mc-wc-header-content-details { + max-width: 294px; + position: relative; + z-index: 1; +} + +.mc-wc-header-content.connect-account .mc-wc-header-content-image { + position: absolute; + top: 17px; + right: -110.82px; +} + +.mc-wc-header-content-details .mc-wc-title { + font-family: 'Means Web'; + font-size: 32px; + font-weight: 400; + line-height: 36px; + letter-spacing: 0; + text-align: left; + margin-block: 0 20px; +} + +.mc-wc-header-content-details .mc-wc-description { + margin-block: 0 30px; + font-size: 14px; + line-height: 20px; +} + +.mc-wc-breadcrumb-text.a { + font-size: 13px; + text-decoration: none; + color: var(--mc-wc-text-color); + line-height: 20px; + display: block; +} + +.mc-wc-breadcrumb-text:hover, .mc-wc-breadcrumb-text:focus { + border: 0; + outline: 0; + box-shadow: none; + text-decoration: none; +} + +.mc-wc-header-content.review-sync-settings .mc-wc-header-content-wrapper { + display: flex; + justify-content: center; + align-items: center; + padding: 28px 86px 40px 57px; +} + +.mc-wc-header-account { + border-top: 1px solid var(--mc-wc-border-color); +} + +.mc-wc-header-account-wrapper { + padding: 6px 77px 10px 57px; + display: flex; + justify-content: space-between; + align-items: center; +} + +.mc-wc-header-account-logos { + display: flex; + gap: 38px; + align-items: center; + line-height: 0; +} + +.mc-wc-header-account-logo-text .account-name-text { + font-family: 'Roboto'; + font-size: 14px; + font-weight: 700; + line-height: 24px; + letter-spacing: 0; + text-align: left; +} + +.mc-wc-header-account-logo-text .authorized-text { + font-family: 'Roboto'; + font-size: 14px; + font-style: italic; + font-weight: 500; + line-height: 24px; + letter-spacing: 0; + text-align: left; +} + +.mc-wc-header-account-switch-account a.mc-wc-text-link { + font-size: 12px; + color: #2C6ECB; +} + +.mc-wc-header-account-switch-account { + padding-right: 21px; +} + +.mc-wc-header-content-footer { + border-top: 1px solid var(--mc-wc-border-color); +} + +.mc-wc-header-content-footer-wrapper { + padding: 34px 77px 30px 56px; +} + +.mc-wc-header-content-footer-wrapper .mc-wc-description { + max-width: 540px; + font-family: Roboto; + font-size: 14px; + font-weight: 400; + line-height: 20px; + letter-spacing: 0; + text-align: left; + margin-block: 0 35px; +} + +.mc-wc-settings-wrapper.conformation { + max-width: 786px; +} + +.mc-wc-header-content-footer-wrapper .mc-wc-descripition { + margin-block: 0 30px; + max-width: 605px; +} + +.mc-wc-header-content.confirmation .mc-wc-header-content-wrapper { + display: flex; + justify-content: space-between; + align-items: center; + padding: 32px 80px 19px 57px; +} + +.mc-woocommerce-modal .reveal-modal { + margin-bottom: 50px; +} + +#mc-woocommerce-create-account { + top: -340px; +} + +.mc-wc-setting-content { + margin-top: 25px; +} + +.mc-wc-review-sync-settings-content { + padding: 49px 77px 57px 57px; + margin-top: 25px; + box-shadow: 0 1px 2px 0 #00000026, 0 0 5px 0 #0000000D; + border-radius: 8px; + background-color: #fff; +} + +.mc-wc-review-sync-settings-content > *:not(:last-child) { + border-bottom: 1px solid #D6D6D6; + padding-bottom: 20px; + margin-bottom: 30px; +} + +.mc-wc-setting-footer-buttons { + text-align: right; + margin-top: 22px; +} + +.mc-wc-linked-audience-list { + display: flex; + justify-content: space-between; + margin-bottom: 40px; +} + +.mc-wc-import-list-sync-item { + display: flex; + gap: 32px; + margin-bottom: 30px; +} + +.mc-wc-import-list-sync-item > *:first-child { + width: 169px; +} + +.mc-wc-import-list-sync-item > *:last-child { + width: calc(100% - 166px); +} + +.mc-wc-tag-show-tagged { + display: inline-flex; + gap: 13px; + margin-top: 14px; + flex-wrap: wrap; + max-width: 451px; +} + +.mc-wc-tag-show-tagged > div { + display: flex; + align-items: center; + justify-content: space-between; + background-color: #E4E5E7; + padding: 2px 4px 2px 8px; + gap: 4px; + border-radius: 4px; +} + +.mc-wc-tag-show-tagged > div > *:first-child { + font-family: 'Roboto'; + font-size: 12px; + font-weight: 400; + line-height: 16px; +} + +.mc-wc-tag-show-tagged > div > *:last-child { + display: inline-flex; +} + +.mc-wc-tag-icon-del { + cursor: pointer; + width: 20px; + height: 20px; + background-image: url('../images/icon-delete.svg'); + background-repeat: no-repeat; + background-position: center; + border-radius: 2px; +} + +.mc-wc-tag-icon-del:hover { + background-color: #c7c9cd; +} + +.mc-wc-tag-form-input { + display: inline-flex; + gap: 14px; +} + +.mc-wc-tag-list { + display: flex; + flex-direction: column; +} + +.mc-wc-btn-2 { + padding: 8px 16px; + border-radius: 4px; + border: 1px solid #7D57A4; + box-shadow: 0 1px 0 0 #0000000D; + background-color: #fff; + font-family: 'Roboto'; + font-size: 14px; + font-weight: 500; + line-height: 20px; + display: flex; + justify-content: space-between; + align-items: center; + gap: 6px; + color: #7D57A4; + cursor: pointer; +} + +.mc-wc-btn-2:hover { + opacity: 0.7; + color: #7D57A4; +} + +.mc-wc-linked-audience-list select { + min-width: 264px; +} + +.mc-wc-settings-content-title { + font-size: 16px; + font-weight: 500; + line-height: 24px; + margin-block: 0 16px; +} + +.mc-wc-linked-audience-description { + font-size: 13px; + font-weight: 400; + line-height: 20px; + letter-spacing: 0; + text-align: left; + margin: 0; +} + +.mc-wc-text-md { + font-size: 13px; + font-weight: 500; +} + +.wp-core-ui .mc-wc-select { + border: 1px solid #D6E6FE; + background: #fff url('data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%2220%22%20height%3D%2220%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M5%206l5%205%205-5%202%201-7%207-7-7%202-1z%22%20fill%3D%22%232C6ECB%22%2F%3E%3C%2Fsvg%3E') no-repeat right 5px top 55%; + border-radius: 6px; + color: #000624; + font-family: Roboto; + font-size: 16px; + font-weight: 400 !important; + line-height: 24px; + padding: 5px 6px 5px 12px; +} + +.pb-text { + padding-bottom: 12px; +} + +.wp-core-ui select:not(:disabled):hover { + color: #000624; +} + +.mc-wc-import-customers-initial .mc-wc-text-1 { + font-family: Roboto; + font-size: 12px; + font-weight: 400; + line-height: 18px; + letter-spacing: 0; + text-align: left; +} + +.mc-wc-import-customers-initial .mc-wc-text-2 { + font-family: Roboto; + font-size: 11px; + font-weight: 400; + line-height: 18px; +} + +.mc-wc-import-customers-initial .mc-wc-text-2 a { + font-family: Roboto; + font-size: 11px; + font-weight: 400; + line-height: 18px; + letter-spacing: 0; + text-align: left; + +} + +.mc-wc-radio-label, .mc-wc-checkbox-label { + font-family: Roboto; + font-size: 13px; + font-weight: 400; + line-height: 20px; + letter-spacing: 0; + text-align: left; + position: relative; + padding-left: 40px; +} + +.fw-200 { + font-weight:200; +} + +.fw-300 { + font-weight:300; +} + +.fw-400 { + font-weight:400; +} + +.fw-500 { + font-weight:500; +} + +.fw-600 { + font-weight:600; +} + +.fw-700 { + font-weight: 700; +} + +.mc-wc-radio, .mc-wc-checkbox { + display: flex; + align-items: center; + gap: 16px; + position: relative; +} + +.mc-wc-import-list-sync-description { + font-family: Roboto; + font-size: 12px; + font-weight: 400; + line-height: 18px; + letter-spacing: 0; +} + +.mc-wc-import-list-sync-description a { + font-family: Roboto; + font-size: 12px; + font-weight: 400; + line-height: 18px; + letter-spacing: 0; + +} + +.mc-wc-tag-customer .mc-wc-text-1 { + font-family: Roboto; + font-size: 12px; + font-weight: 400; + line-height: 20px; + letter-spacing: 0; + text-align: left; + margin-block: 0 30px; +} + +.mc-wc-input[type=text] { + border: 1px solid #BDC1CC; + box-shadow: 0 1px 0 0 #0000000D; + font-family: 'Roboto'; + font-size: 12px; + font-weight: 400; + line-height: 20px; + letter-spacing: 0; + text-align: left; + padding: 0 12px; + margin: 0; +} + +.mc-wc-tag-form-input input { + width: 76%; +} + +.mc-wc-input[type=text]::placeholder { + color: #979797; + opacity: 1; /* Firefox */ +} + +.mc-wc-input[type=text]::-ms-input-placeholder { /* Edge 12 -18 */ + color: #979797; +} + +.mc-wc-radio input { + border-radius: 50%; +} + +.mc-wc-radio input:checked::before { + content: ""; + border-radius: 50%; + width: 24px; + height: 24px; + background-color: #7F5AB7; + margin: -1px; + box-shadow: none; + border: 1px solid #7F5AB7; +} + +.mc-wc-radio input:focus, .mc-wc-checkbox input:focus { + border-color: #7F5AB7; + box-shadow: none; + outline: 0; +} + +.mc-wc-radio input:checked::after { + content: ""; + border-radius: 50%; + width: 24px; + height: 24px; + display: block; + background-image: url('../images/tick-small.svg'); + background-repeat: no-repeat; + z-index: 1; + position: absolute; + background-position: center; + top: 0; + left: 0; +} + +.mc-wc-radio input, .mc-wc-checkbox input { + position: absolute; + left: 0; + top: calc(50% - 12px); + width: 24px; + height: 24px; + margin: 0; + border: 1px solid #241C15A6; + box-shadow: none; +} + +.mc-wc-checkbox input { + border-radius: 4px; +} + +.mc-wc-checkbox input:checked::before { + border-radius: 4px; + content: ""; + width: 22px; + height: 22px; + background-color: #7F5AB7; + margin: -1px; + box-shadow: none; + border: 1px solid #7F5AB7; +} + +.mc-wc-checkbox input:checked::after { + border-radius: 4px; + content: ""; + width: 22px; + height: 22px; + display: block; + background-image: url('../images/tick-small.svg'); + background-repeat: no-repeat; + z-index: 1; + position: absolute; + background-position: center; + top: 0; + left: 0; +} + +.mc-wc-input[type=text]:focus { + border-color: #7F5AB7; + box-shadow: 0 0 0 1px #7F5AB7; + outline: 2px solid transparent; +} + +.mc-wc-tab-page-wrapper { + display: flex; + flex-direction: column; + gap: 23px; +} + +.mc-wc-tab-buttons-wrapper { + list-style: none; + padding: 0; + display: flex; + gap: 40px; + font-size: 13px; + margin: 0; + border-bottom: 1px solid #DBD9D2; + flex-wrap: wrap; +} + +.mc-wc-tab-button-text { + text-decoration: none; + color: #241C15A6; + display: block; + padding: 12px 8px; + font-family: Roboto; + font-size: 16px; + font-weight: 500; + line-height: 24px; + letter-spacing: 0; + text-align: center; +} + +.mc-wc-tab-buttons-wrapper li { + position: relative; + margin: 0 !important; +} + +.mc-wc-tab-buttons-wrapper li.current::before, .mc-wc-tab-buttons-wrapper li:hover::before { + content: ""; + height: 2.5px; + width: calc(100% - 16px); + display: block; + left: 8px; + bottom: -1px; + position: absolute; + border-radius: 38px; + background: linear-gradient(180deg, #7652AC 0%, rgba(127, 90, 184, 0.693278) 99.99%, rgba(127, 90, 184, 0) 100%); +} + +.mc-wc-tab-buttons-wrapper li.current .mc-wc-tab-button-text, .mc-wc-tab-button-text:hover, .mc-wc-tab-button-text:active { + color: #7D59B6; +} + +.mc-wc-tab-buttons-wrapper li a:focus { + color: #7D59B6; + box-shadow: none; + outline: none; +} + +.mc-wc-tab-content { + position: relative; + box-shadow: 0 1px 2px 0 #00000026, 0 0 5px 0 #0000000D; + background-color: #fff; + border-radius: 8px; + padding: 12px 51px 80px 55px; + overflow: hidden; +} + +.mc-wc-tab-content.loading::before { + content: ''; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 2; + background-color: rgba(255, 255, 255, 0.2); + backdrop-filter: blur(2px); + animation: fadeIn 0.3s linear; +} + +@keyframes fadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +.mc-wc-tab-content-title { + display: flex; + justify-content: space-between; + align-items: center; + padding-block: 20px 13px; +} + +.mc-wc-tab-content-title.has-underline { + border-bottom: 1px solid #D9D9D9; +} + +.mc-wc-tab-content-title h3 { + font-family: Roboto; + font-size: 16px; + font-weight: 500; + line-height: 24px; + letter-spacing: 0; + text-align: left; + margin: 0; +} + +.mc-wc-text-review { + display: inline-flex; + gap: 2px; +} + +.mc-wc-text-review span { + font-family: 'Roboto'; + font-size: 13px; + font-weight: 400; + line-height: 24px; + letter-spacing: 0; + text-align: left; +} + +.mc-wc-text-review a { + font-family: 'Graphik Mailchimp Web'; + font-size: 13px; + font-weight: 400; + line-height: 24px; + letter-spacing: 0; + text-align: left; + color: #7D59B6; + text-decoration: none; +} + +.mc-wc-text-review a:hover { + text-decoration: underline; +} + +.mc-wc-tab-content-sync { + display: flex; + flex-direction: row; + gap: 11.5%; + margin-top: 45px; +} + +.sync-status-icon { + height: 161px; + width: 161px; + border-radius: 50%; + border: 16px solid #D9D9D9; +} + +.sync-status-icon-wrapper img { + width: 30px; +} + +.sync-status-icon-wrapper { + width: calc(100% - 32px); + height: calc(100% - 32px); + border-radius: 50%; + display: inline-flex; + align-items: center; + justify-content: center; + border: 16px solid #805BB9; +} + +.mc-wc-tab-content-sync-status { + display: flex; + flex-direction: column; + gap: 26px; +} + +.sync-status-text { + font-family: Roboto; + font-size: 14px; + font-weight: 500; + line-height: 20px; + letter-spacing: 1px; + color: #000000; + margin-bottom: 16px; + display: flex; + justify-content: center; + gap: 4px; + text-align: left; +} + +.sync-status-time { + display: flex; + flex-direction: column; + text-align: center; +} + +.mc-wc-tab-content-sync-detail { + display: grid; + grid-template-columns: repeat(2, 1fr); /* Two columns with equal width */ + grid-gap: 0; /* Gap between grid items */ + width: 100%; +} + +.mc-wc-tab-content-sync-detail > *:nth-child(1) { + border-bottom: 1px solid #D9D9D9; +} + +.mc-wc-tab-content-sync-detail > *:nth-child(2) { + border-left: 1px solid #D9D9D9; + border-bottom: 1px solid #D9D9D9; +} + +.mc-wc-tab-content-sync-detail > *:nth-child(4) { + border-left: 1px solid #D9D9D9; +} + +.mc-wc-tab-content-sync-detail > * { + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + gap: 20px; + padding-block: 30px; +} + +.sync-number { + display: flex; + flex-direction: column; + text-align: center; + gap: 3px; + font-family: 'Means Web'; + color: #241C15; +} + +.sync-text { + display: flex; + align-items: center; + gap: 6px; + font-family: Roboto; + font-size: 16px; + font-weight: 600; + line-height: 24px; + letter-spacing: 0; + text-align: left; + color: #000; +} + +.sync-text > * { + display: inline-flex; +} + +span.sync-number-finished { + font-size: 25px; + font-weight: 400; + line-height: 28px; + letter-spacing: 0; + text-align: center; +} + +span.sync-number-total { + font-size: 14px; + font-weight: 300; + line-height: 28px; + letter-spacing: 0; + text-align: center; +} + +.mc-wc-tab-content-wrapper > *:not(:last-child) { + margin-bottom: 40px; +} + +.mc-wc-tab-content-wrapper:not(.sync) { + padding-top: 20px; +} + +.mc-wc-tab-content-blogs { + display: flex; + flex-direction: column; + margin-top: 4px; +} + +.mc-wc-tab-content-blogs-item { + display: flex; + gap: 50px; + padding-block: 32px 24px; +} + +.mc-wc-tab-content-blogs-detail h4 { + font-family: Roboto; + font-size: 14px; + font-weight: 500; + line-height: 20px; + letter-spacing: 0; + text-align: left; + margin-block: 0 8px; +} + +.mc-wc-tab-content-blogs-detail p { + font-family: Roboto; + font-size: 14px; + font-weight: 400; + line-height: 20px; + letter-spacing: 0; + text-align: left; + margin-block: 0 25px; +} + +.mc-wc-tab-content-blogs-item:not(:last-child) { + border-bottom: 1px solid #D9D9D9; +} + +.mc-wc-tab-content-blogs-detail span { + font-family: Roboto; + font-size: 11px; + font-weight: 400; + line-height: 20px; + letter-spacing: 0; + text-align: left; + display: block; + color: #241C15A6; + margin-top: 15px; +} + +.mc-wc-tab-content-blogs-item:last-child { + padding-bottom: 0; +} + +.mc-wc-tab-content-blogs-detail p a { + font-family: Roboto; + font-size: 14px; + font-weight: 400; + line-height: 20px; + letter-spacing: 0; + text-align: left; + margin-block: 0 25px; + +} + +.mc-wc-settings-wrapper.confirmation { + max-width: 788px; +} + +.mc-wc-tab-content-description { + font-family: Roboto; + font-size: 14px; + font-weight: 400; + line-height: 20px; + letter-spacing: 0; +} + +.mc-wc-tab-content-description a { + font-family: 'Graphik Mailchimp Web'; + font-size: 14px; + font-weight: 400; + line-height: 20px; + letter-spacing: 0; + text-align: left; + +} + +.mc-wc-tab-content-description b { + font-weight: 500; +} + +.wp-core-ui .mc-wc-select.mc-wc-select-not-bold { + font-family: 'Graphik Mailchimp Web'; + font-size: 13px; + font-weight: 400; + line-height: 24px; + letter-spacing: 0; + color: #241C15; + border: 1px solid #241C15A6; + background: #fff url(data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%2220%22%20height%3D%2220%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M5%206l5%205%205-5%202%201-7%207-7-7%202-1z%22%20fill%3D%22%23241C15B%22%2F%3E%3C%2Fsvg%3E) no-repeat right 5px top 55%; + min-width: 300px; + padding-right: 30px; +} + +.mc-wc-locale { + display: flex; + align-items: center; + margin-block: 35px 9px; +} + +.mc-wc-locale > label, .mc-wc-permission-wrapper > label, .opt-in-checkbox-label { + font-family: Roboto; + font-size: 12px; + font-weight: 600; + line-height: 20px; + letter-spacing: 0; + text-align: left; + color: #202223; + width: 166px; +} + +.mc-wc-tab-content-wrapper.store-info > *:not(:last-child) { + border-bottom: 1px solid #D6D6D6; + padding-bottom: 30px; + margin-bottom: 17px; +} + +.mc-wc-tab-content-wrapper.store-info > * { + display: inline-block; + max-width: 100%; +} + +.mc-wc-permission-wrapper { + display: flex; + align-items: start; + margin-block: 40px 10px; + flex-wrap: wrap; + gap: 15px; +} + +.mc-wc-permission-wrapper p { + margin: 0; +} + +.mc-wc-permission-choose { + display: flex; + flex-direction: column; + gap: 20px; +} + +.opt-in-checkbox-text { + border: 1px solid #241C15A6 !important; + outline: none; + min-height: 135px; + font-family: 'Graphik Mailchimp Web' !important; + font-size: 14px !important; + font-weight: 400; + line-height: 24px; + letter-spacing: 0; + text-align: left; + color: #241C15A6 !important; + padding: 10px 16px !important; + width: 77%; +} + +.mc-wc-tab-content.store_info { + padding: 0 142px 75px 55px; +} + +input.mc-wc-input.style-2 { + font-family: 'Graphik Mailchimp Web'; + font-size: 13px; + font-weight: 400; + line-height: 24px; + letter-spacing: 0; + text-align: left; + padding: 5px; + padding-inline: 16px 21px; + border: 1px solid #241C15A6; + width: 77%; + color: #241C15; +} + +.mc-wc-tab-content-box.checkout-page-setting .mc-wc-input-wrapper { + margin-top: 30px; +} + +.mc-wc-tab-content-box.checkout-page-setting .description { + font-family: Roboto; + font-size: 13px !important; + font-weight: 400; + line-height: 24px !important; + letter-spacing: 0; + text-align: left; + margin-top: 8px; + color: #241C15A6 !important; +} + +.mc-wc-product-images { + margin-top: 30px; +} + +.mc-wc-product-images select { + width: 68%; +} + +.mc-wc-tab-content-box.checkout-page-setting .mc-wc-tab-content-description { + font-size: 13px; + line-height: 18px; +} + +.mc-wc-tab-content-box.checkout-page-setting .mc-wc-tab-content-description a { + font-size: 13px; + line-height: 18px; + +} + +.mc-wc-tab-content-box.product-image-setting .mc-wc-tab-content-description { + font-size: 13px; + line-height: 18px; +} + +.mc-wc-tab-content-wrapper.store-info .mc-wc-tab-content-title { + padding-bottom: 30px; +} + +.mc-wc-tab-content-box.permission-setting { + padding-top: 20px; +} + +.mc-wc-tab-content-box.product-image-setting .mc-wc-tab-content-title { + padding-bottom: 13px; +} + +.mc-wc-warning-info { + margin-top: 7px; +} + + +.mc-wc-warning-info-wrapper { + border: 1px solid #241C1526; + background-color: #F6F6F4; + box-shadow: 4px 0 0 0 #241C15 inset; + display: flex; + padding: 14px 16px; + gap: 16px; + flex-direction: row; + align-items: center; +} + +.mc-wc-warning-info-wrapper p { + margin: 0; + font-family: Roboto; + font-size: 13px; + font-weight: 400; + line-height: 18px; +} + +.mc-wc-warning-info-wrapper p a { + font-family: 'Graphik Mailchimp Web'; + font-weight: 400; + line-height: 20px; + letter-spacing: 0; + text-align: left; + font-size: 13px; +} + +.mc-wc-warning-info-wrapper p b { + font-family: Roboto; + font-size: 13px; + font-weight: 700; + line-height: 18px; + letter-spacing: 0; + text-align: left; +} + +.mc-wc-warning-info-wrapper > div { + display: inline-flex; +} + +.mc-wc-tab-content-wrapper.audience > *:first-child { + margin-bottom: 6px; +} + +.mc-wc-tab-content-description-small { + font-family: Roboto; + font-size: 12px; + font-weight: 400; + line-height: 20px; + letter-spacing: 0; + text-align: left; +} + +.mc-wc-tab-content-wrapper.audience .mc-wc-tab-content-description-small { + color: #202020; +} + +.mc-wc-tracking-choose { + margin-top: 23px; + display: flex; + flex-direction: column; + gap: 18px; +} + +.mc-wc-tab-content-box.has-underline { + padding-bottom: 32px; + border-bottom: 1px solid #D9D9D9; + margin-bottom: 10px; +} + +.mc-wc-tab-content-box.has-underline { + padding-bottom: 32px; + border-bottom: 1px solid #D9D9D9; + margin-bottom: 10px; +} + +.mc-wc-tab-content-wrapper.audience { + margin-bottom: 30px; +} + +.mc-wc-tab-content-wrapper.audience > *:nth-child(3) { + padding-bottom: 0; +} + +.mc-wc-tab-content-wrapper.audience > *:nth-child(4) { + padding-top: 10px; +} + +.mc-wc-tab-content-wrapper.audience > *:nth-child(4) .mc-wc-tag-list { + margin-top: 30px; +} + +.mc-wc-fz-13 { + font-size: 13px !important; +} + +.mc-wc-tab-content-wrapper.logs > *:first-child .mc-wc-tab-content-title { + padding-bottom: 30px; +} + +.mc-wc-logs-list-choose { + flex-wrap: wrap; + display: flex; + margin-top: 50px; + gap: 21px; + width: 100%; + max-width: 562px; + align-items: center; +} + +.mc-wc-logs-list-choose > p { + width: 164px; + font-family: Roboto; + font-size: 14px; + font-weight: 600; + line-height: 20px; + letter-spacing: 0; + text-align: left; + margin: 0; +} + +.mc-wc-logs-list-choose select { + width: 374px; +} + +.mc-wc-tab-content-wrapper.logs > *:first-child { + padding-bottom: 60px; +} + +.mc-wc-tab-content-wrapper.logs > *:nth-child(2) { + padding-top: 30px; + max-width: 562px; +} + +.mc-wc-logs-recent-list > p { + font-family: Roboto; + font-size: 14px; + font-weight: 500; + line-height: 24px; + letter-spacing: 0; + text-align: left; + margin: 0; + padding-block: 10px 13px; +} + +.mc-wc-tab-content-wrapper.logs { + max-width: 604px; +} + +.mc-wc-logs-recent-list-header .log-file-actions select { + width: 100%; + max-width: 100%; +} + +select#log_file {} + +.mc-wc-logs-recent-list-header #log-actions { + display: flex; + gap: 6px; + flex: auto; + margin: 0; +} + +.mc-wc-logs-recent-list-header #log-actions > * { + padding: 11px 9px 6px 9px !important; + border: 1px solid #716B67 !important; + border-radius: 4px; + height: 25px; + width: 21px; +} + +.mc-wc-logs-recent-list-header { + margin-bottom: 13px; +} + +.mc-wc-logs-recent-list-show #log-content { + border: 1px solid #241C15A6 !important; + outline: none; + min-height: 135px; + font-family: 'Graphik Mailchimp Web' !important; + font-size: 14px !important; + font-weight: 400; + line-height: 24px; + letter-spacing: 0; + text-align: left; + color: #241C15A6 !important; + padding: 10px 16px !important; +} + +.mc-wc-logs-recent-list-show { + display: block; + width: 100%; + border: 0; +} + +.mc-wc-logs-recent-list-show #log-viewer { + border: 0; + box-shadow: none; +} + +.mailchimp-select-wrapper.view-log-select { + display: flex; +} + +.mc-wc-logs-recent-list-header .log-file-actions { + display: flex; + gap: 10px; +} + +.mc-wc-radio-checkbox-list-item { + display: flex; + gap: 32px; + margin-bottom: 30px; +} + +.mc-wc-radio-checkbox-list-item > *:first-child { + width: 169px; +} + +.mc-wc-radio-checkbox-list-item > *:last-child { + width: calc(100% - 166px); +} + +.mc-wc-tab-content-wrapper.advanced > *:first-child .mc-wc-tab-content-title { + padding-bottom: 40px; +} + +.mc-wc-tab-content-wrapper.advanced > *:first-child { + max-width: 588px; +} + +.mc-wc-tab-content-wrapper.advanced > *:nth-child(2) { + max-width: 644px; +} + +.mc-wc-tab-content-wrapper.advanced > *:nth-child(2) .mc-wc-tab-content-title { + padding-bottom: 30px; +} + +.mc-wc-button-disconnect { + margin-top: 30px; +} + +.mc-wc-button-disconnect .tab-content-submit:not(.create-account):not(.mc-woocommerce-disconnect-button):not(.disconnect-confirm) { + width: 161px !important; + text-align: center; + height: 40px !important; + padding: 0 !important; + display: flex; + justify-content: center; + align-items: center; + box-shadow: none !important; + text-shadow: none !important; + background-color: #fff !important; + color: var(--mc-wc-primary) !important; + text-transform: capitalize !important; + border: 1px solid #7C58B4 !important; +} + +.mc-wc-tooltip { + position: relative; +} + +.mc-wc-tooltip-text { + position: absolute; + top: -10px; + left: 50%; + z-index: 1; + transform: translate(-50%, -100%); + min-width: 200px; + padding: 10px; + font-size: 15px; + font-weight: normal; + background-color: #fff; + border-radius: var(--mc-wc-border-radius); + box-shadow: 0 1px 8px rgba(0, 0, 0, 0.5); + box-sizing: border-box; + visibility: hidden; + opacity: 0; + transition: opacity 0.8s; +} + +.mc-wc-tooltip:hover .mc-wc-tooltip-text { + opacity: 1; + visibility: visible; +} + +.mc-wc-notice { + position:fixed; + bottom: 40px; + width: 500px; + left: 50%; + margin-left: -250px; + background-color: #241c15; + padding: 12px 16px; + border-radius: 8px; + max-width: 70ch; + box-shadow: 0 0 0 1px hsla(0, 0%, 100%, 0.1), 0 16px 24px rgba(0, 0, 0, 0.24); + border-color: hsla(0, 0%, 100%, .5); + display: none; +} + +.mc-wc-notice.success { + color: #fff; +} + +.mc-wc-notice.error { + color: #DB241D; +} + +.flex { + display:flex; +} + +.justify-between { + justify-content: space-between; +} + +.items-center { + align-items: center; +} + +.wink-visually-hidden { + display:none; +} + +.mc-wc-notice button.wink { + -webkit-transition: background-color .2s ease-in-out 0s, -webkit-box-shadow .2s ease-in-out 0s; + transition: background-color .2s ease-in-out 0s, -webkit-box-shadow .2s ease-in-out 0s; + transition: box-shadow .2s ease-in-out 0s, background-color .2s ease-in-out 0s; + transition: box-shadow .2s ease-in-out 0s, background-color .2s ease-in-out 0s, -webkit-box-shadow .2s ease-in-out 0s; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + background-color: transparent; + border-radius: 100%; + cursor: pointer; + display: -webkit-inline-box; + display: -ms-inline-flexbox; + display: inline-flex; + height: 32px; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + line-height: normal; + margin: 0; + overflow: hidden; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + vertical-align: middle; + width: 32px; + -webkit-transition: -webkit-transform .2s ease-in-out 0s; + transition: -webkit-transform .2s ease-in-out 0s; + transition: transform .2s ease-in-out 0s; + transition: transform .2s ease-in-out 0s, -webkit-transform .2s ease-in-out 0s; + padding: 0; + border: 0; +} + +.mc-wc-notice button:active { + -webkit-box-shadow: 0 0 0 2px #4bc4c2; + box-shadow: 0 0 0 2px #4bc4c2; + outline: 2px solid transparent; +} + +.mc-wc-notice button:hover { + background-color: rgba(75,196,194,0.2); +} + +.mc-wc-notice button svg { + fill: #fff; + width: 2.4rem; + height: 2.4rem; + padding:6px; +} + +@media screen and (max-width: 782px) { + #wpcontent { + padding-right: 10px; + } + + .mc-wc-tooltip-text { + left: auto; + right: -20px; + transform: translate(0, -100%); + min-width: 150px; + } +} + +@media screen and (max-width: 680px) { + .mc-wc-header-content-wrapper { + padding: 50px 57px 50px; + } + + .mc-wc-header-content.connect-account .mc-wc-header-content-image { + position: relative; + width: 100%; + right: 0; + margin-top: -20px; + } + + .mc-wc-header-content.connect-account .mc-wc-header-content-details { + max-width: 100%; + } + + .mc-wc-btn-acctions-wrapper { + margin-top: -60px; + text-align: center; + padding: 0 57px 50px; + } + + .mc-wc-btn-acctions-wrapper { + padding: 30px 25px 30px; + margin-top: -40px; + } + + .mc-wc-header-content.review-sync-settings .mc-wc-header-content-wrapper { + flex-direction: column; + } + + .mc-wc-header-content.confirmation .mc-wc-header-content-wrapper { + padding: 32px 30px 19px 30px; + flex-direction: column; + } + + ul.mc-wc-tab-buttons-wrapper { + gap: 0; + } + + ul.mc-wc-tab-buttons-wrapper li { + margin-right: 24px !important; + margin-top: 15px; + } + + .mc-wc-setting-content { + /* margin-top: 21px; */ + } + + .mc-wc-tab-content-sync { + flex-direction: column; + align-items: center; + gap: 40px; + } + + .mc-wc-tab-content-sync-detail > * { + padding-block: 15px; + } + + .mc-wc-tab-content-title.has-underline { + flex-direction: column; + align-items: start; + } + + .mc-wc-tab-content-blogs-item { + flex-direction: column-reverse; + align-items: center; + gap: 25px; + } + + .mc-wc-tab-content-blogs-item img { + max-width: 100%; + } + + .mc-wc-tab-content.store_info { + padding: 0 55px 75px 55px; + } + +} + +@media screen and (max-width: 567px) { + .mc-wc-header-content-wrapper { + padding: 30px 25px 30px; + } + + .mc-wc-btn-acctions-wrapper { + padding: 0 25px 60px; + margin-top: -30px; + } + + .mc-wc-header-content.review-sync-settings .mc-wc-header-content-wrapper { + flex-direction: column; + padding: 30px 25px 30px; + } + + .mc-wc-header-account-wrapper { + padding: 6px 30px 10px; + } + + .mc-wc-header-content-footer-wrapper { + padding: 25px 30px 25px 30px; + } + + .mc-wc-linked-audience-list { + flex-direction: column; + } + + .mc-wc-review-sync-settings-content { + padding: 38px 30px 38px 30px; + } + + .mc-wc-header-content.confirmation .mc-wc-header-content-wrapper { + padding: 32px 30px 19px 30px; + flex-direction: column; + } + + .mc-wc-tab-content, .mc-wc-tab-content.store_info { + padding: 12px 30px 50px 30px; + } + + .mc-wc-breadcrumbs-wrapper { + gap: unset; + } + + li.mc-wc-breadcrumb-link.mc-wc-breadcrumb-nextable { + margin-right: 24px; + } + + .mc-wc-locale { + flex-direction: column; + align-items: start; + gap: 12px; + } + + .mc-wc-locale select { + min-width: 100% !important; + width: 100%; + } + + .wp-core-ui .mc-wc-select.mc-wc-select-not-bold { + min-width: 100%; + } + + .mc-wc-select-wrapper { + width: 100%; + } + + .wp-core-ui .mc-wc-select.mc-wc-select-not-bold { + min-width: 100%; + width: 100%; + } + + .mc-wc-logs-recent-list-header .log-file-actions { + position: relative; + } + + .mc-wc-logs-recent-list-header #log-actions { + position: absolute; + top: -42px; + right: 0; + } + + .mc-wc-logs-recent-list-header #log-actions a { + padding: 6px 5px 2px 7px !important; + } + + .mailchimp-select-wrapper.view-log-select { + margin-bottom: 0; + } + + .mc-wc-radio-checkbox-list-item { + gap: 15px; + } + + .mc-wc-notice { + right: 30px; + } +} + +@media screen and (max-width: 400px) { + .mc-wc-actions { + flex-direction: column; + } + + .mc-wc-header-account-wrapper { + flex-direction: column; + gap: 16px; + align-items: start; + } + + .mc-wc-linked-audience-list { + flex-direction: column; + } + + .mc-wc-review-sync-settings-content { + padding: 38px 30px 38px 30px; + } + + .mc-wc-import-list-sync-item { + flex-direction: column; + gap: 7px; + } + + .mc-wc-import-list-sync-item > * { + width: calc(100% - 35px) !important; + } + + .mc-wc-radio-label, .mc-wc-checkbox-label { + padding-left: 35px !important; + } + + .mc-wc-import-list-sync-description { + padding-left: 35px; + } + + .mc-wc-linked-audience-list select { + min-width: 100%; + } + + input.mc-wc-input.style-2 { + width: 100%; + } + + .mc-wc-radio-checkbox-list-item > * { + width: calc(100% - 35px) !important; + } + + .mc-wc-radio-checkbox-list-item { + flex-direction: column; + gap: 7px; + } + + .mc-wc-radio-checkbox-description { + padding-left: 35px; + } +} \ No newline at end of file diff --git a/admin/v2/assets/fonts/Mark Simonson - Proxima Nova Alt Light.woff b/admin/v2/assets/fonts/Mark Simonson - Proxima Nova Alt Light.woff new file mode 100644 index 00000000..792e0dd8 Binary files /dev/null and b/admin/v2/assets/fonts/Mark Simonson - Proxima Nova Alt Light.woff differ diff --git a/admin/v2/assets/fonts/Means/Means-Bold-Web.woff b/admin/v2/assets/fonts/Means/Means-Bold-Web.woff new file mode 100644 index 00000000..43c9bb9b Binary files /dev/null and b/admin/v2/assets/fonts/Means/Means-Bold-Web.woff differ diff --git a/admin/v2/assets/fonts/Means/Means-Bold-Web.woff2 b/admin/v2/assets/fonts/Means/Means-Bold-Web.woff2 new file mode 100644 index 00000000..9744467e Binary files /dev/null and b/admin/v2/assets/fonts/Means/Means-Bold-Web.woff2 differ diff --git a/admin/v2/assets/fonts/Means/Means-BoldItalic-Web.woff b/admin/v2/assets/fonts/Means/Means-BoldItalic-Web.woff new file mode 100644 index 00000000..d2c69bac Binary files /dev/null and b/admin/v2/assets/fonts/Means/Means-BoldItalic-Web.woff differ diff --git a/admin/v2/assets/fonts/Means/Means-BoldItalic-Web.woff2 b/admin/v2/assets/fonts/Means/Means-BoldItalic-Web.woff2 new file mode 100644 index 00000000..f0a4f174 Binary files /dev/null and b/admin/v2/assets/fonts/Means/Means-BoldItalic-Web.woff2 differ diff --git a/admin/v2/assets/fonts/Means/Means-Light-Web.woff b/admin/v2/assets/fonts/Means/Means-Light-Web.woff new file mode 100644 index 00000000..17be1cc3 Binary files /dev/null and b/admin/v2/assets/fonts/Means/Means-Light-Web.woff differ diff --git a/admin/v2/assets/fonts/Means/Means-Light-Web.woff2 b/admin/v2/assets/fonts/Means/Means-Light-Web.woff2 new file mode 100644 index 00000000..10a17f00 Binary files /dev/null and b/admin/v2/assets/fonts/Means/Means-Light-Web.woff2 differ diff --git a/admin/v2/assets/fonts/Means/Means-LightItalic-Web.woff b/admin/v2/assets/fonts/Means/Means-LightItalic-Web.woff new file mode 100644 index 00000000..47954efe Binary files /dev/null and b/admin/v2/assets/fonts/Means/Means-LightItalic-Web.woff differ diff --git a/admin/v2/assets/fonts/Means/Means-LightItalic-Web.woff2 b/admin/v2/assets/fonts/Means/Means-LightItalic-Web.woff2 new file mode 100644 index 00000000..6b68f7c4 Binary files /dev/null and b/admin/v2/assets/fonts/Means/Means-LightItalic-Web.woff2 differ diff --git a/admin/v2/assets/fonts/Means/Means-Medium-Web.woff b/admin/v2/assets/fonts/Means/Means-Medium-Web.woff new file mode 100644 index 00000000..58c44e12 Binary files /dev/null and b/admin/v2/assets/fonts/Means/Means-Medium-Web.woff differ diff --git a/admin/v2/assets/fonts/Means/Means-MediumItalic-Web.woff2 b/admin/v2/assets/fonts/Means/Means-MediumItalic-Web.woff2 new file mode 100644 index 00000000..657b8184 Binary files /dev/null and b/admin/v2/assets/fonts/Means/Means-MediumItalic-Web.woff2 differ diff --git a/admin/v2/assets/fonts/Means/Means-Regular-Web.woff b/admin/v2/assets/fonts/Means/Means-Regular-Web.woff new file mode 100644 index 00000000..31d70b15 Binary files /dev/null and b/admin/v2/assets/fonts/Means/Means-Regular-Web.woff differ diff --git a/admin/v2/assets/fonts/Means/Means-Regular-Web.woff2 b/admin/v2/assets/fonts/Means/Means-Regular-Web.woff2 new file mode 100644 index 00000000..cb4b65bf Binary files /dev/null and b/admin/v2/assets/fonts/Means/Means-Regular-Web.woff2 differ diff --git a/admin/v2/assets/fonts/Means/Means-RegularItalic-Web.woff b/admin/v2/assets/fonts/Means/Means-RegularItalic-Web.woff new file mode 100644 index 00000000..d0945b94 Binary files /dev/null and b/admin/v2/assets/fonts/Means/Means-RegularItalic-Web.woff differ diff --git a/admin/v2/assets/fonts/Means/Means-RegularItalic-Web.woff2 b/admin/v2/assets/fonts/Means/Means-RegularItalic-Web.woff2 new file mode 100644 index 00000000..cff47d96 Binary files /dev/null and b/admin/v2/assets/fonts/Means/Means-RegularItalic-Web.woff2 differ diff --git a/admin/v2/assets/fonts/Means/fonts.css b/admin/v2/assets/fonts/Means/fonts.css new file mode 100644 index 00000000..f77fb6b4 --- /dev/null +++ b/admin/v2/assets/fonts/Means/fonts.css @@ -0,0 +1,132 @@ +/* + This font software is the property of Commercial Type. + + You may not modify the font software, use it on another website, or install it on a computer. + + License information is available at http://commercialtype.com/eula + For more information please visit Commercial Type at http://commercialtype.com or email us at info[at]commercialtype.com + + Copyright (C) 2016 Schwartzco Inc. + +*/ + + +.Means-Light-Web { + font-family: "Means Web"; + font-weight: 300; + font-style: normal; + font-stretch: normal; +} + +.Means-LightItalic-Web { + font-family: "Means Web"; + font-weight: 300; + font-style: italic; + font-stretch: normal; +} + +.Means-Regular-Web { + font-family: "Means Web"; + font-weight: 400; + font-style: normal; + font-stretch: normal; +} + +.Means-RegularItalic-Web { + font-family: "Means Web"; + font-weight: 400; + font-style: italic; + font-stretch: normal; +} + +.Means-Medium-Web { + font-family: "Means Web"; + font-weight: 500; + font-style: normal; + font-stretch: normal; +} + +.Means-MediumItalic-Web { + font-family: "Means Web"; + font-weight: 500; + font-style: italic; + font-stretch: normal; +} + +.Means-Bold-Web { + font-family: "Means Web"; + font-weight: 700; + font-style: normal; + font-stretch: normal; +} + +.Means-BoldItalic-Web { + font-family: "Means Web"; + font-weight: 700; + font-style: italic; + font-stretch: normal; +} + +@font-face { + font-family: "Means Web"; + src: url("Means-Light-Web.woff2") format("woff2"), + url("Means-Light-Web.woff") format("woff"); + font-weight: 300; + font-style: normal; + } + +@font-face { + font-family: "Means Web"; + src: url("Means-LightItalic-Web.woff2") format("woff2"), + url("Means-LightItalic-Web.woff") format("woff"); + font-weight: 300; + font-style: italic; + } + +@font-face { + font-family: "Means Web"; + src: url("Means-Regular-Web.woff2") format("woff2"), + url("Means-Regular-Web.woff") format("woff"); + font-weight: 400; + font-style: normal; + } + +@font-face { + font-family: "Means Web"; + src: url("Means-RegularItalic-Web.woff2") format("woff2"), + url("Means-RegularItalic-Web.woff") format("woff"); + font-weight: 400; + font-style: italic; + } + +@font-face { + font-family: "Means Web"; + src: url("Means-Medium-Web.woff2") format("woff2"), + url("Means-Medium-Web.woff") format("woff"); + font-weight: 500; + font-style: normal; + } + +@font-face { + font-family: "Means Web"; + src: url("Means-MediumItalic-Web.woff2") format("woff2"), + url("Means-MediumItalic-Web.woff") format("woff"); + font-weight: 500; + font-style: italic; + } + +@font-face { + font-family: "Means Web"; + src: url("Means-Bold-Web.woff2") format("woff2"), + url("Means-Bold-Web.woff") format("woff"); + font-weight: 700; + font-style: normal; + } + +@font-face { + font-family: "Means Web"; + src: url("Means-BoldItalic-Web.woff2") format("woff2"), + url("Means-BoldItalic-Web.woff") format("woff"); + font-weight: 700; + font-style: italic; + } \ No newline at end of file diff --git a/admin/v2/assets/fonts/Roboto/LICENSE.txt b/admin/v2/assets/fonts/Roboto/LICENSE.txt new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/admin/v2/assets/fonts/Roboto/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/admin/v2/assets/fonts/Roboto/Roboto-Black.ttf b/admin/v2/assets/fonts/Roboto/Roboto-Black.ttf new file mode 100644 index 00000000..0112e7da Binary files /dev/null and b/admin/v2/assets/fonts/Roboto/Roboto-Black.ttf differ diff --git a/admin/v2/assets/fonts/Roboto/Roboto-BlackItalic.ttf b/admin/v2/assets/fonts/Roboto/Roboto-BlackItalic.ttf new file mode 100644 index 00000000..b2c6aca5 Binary files /dev/null and b/admin/v2/assets/fonts/Roboto/Roboto-BlackItalic.ttf differ diff --git a/admin/v2/assets/fonts/Roboto/Roboto-Bold.ttf b/admin/v2/assets/fonts/Roboto/Roboto-Bold.ttf new file mode 100644 index 00000000..43da14d8 Binary files /dev/null and b/admin/v2/assets/fonts/Roboto/Roboto-Bold.ttf differ diff --git a/admin/v2/assets/fonts/Roboto/Roboto-BoldItalic.ttf b/admin/v2/assets/fonts/Roboto/Roboto-BoldItalic.ttf new file mode 100644 index 00000000..bcfdab43 Binary files /dev/null and b/admin/v2/assets/fonts/Roboto/Roboto-BoldItalic.ttf differ diff --git a/admin/v2/assets/fonts/Roboto/Roboto-Italic.ttf b/admin/v2/assets/fonts/Roboto/Roboto-Italic.ttf new file mode 100644 index 00000000..1b5eaa36 Binary files /dev/null and b/admin/v2/assets/fonts/Roboto/Roboto-Italic.ttf differ diff --git a/admin/v2/assets/fonts/Roboto/Roboto-Light.ttf b/admin/v2/assets/fonts/Roboto/Roboto-Light.ttf new file mode 100644 index 00000000..e7307e72 Binary files /dev/null and b/admin/v2/assets/fonts/Roboto/Roboto-Light.ttf differ diff --git a/admin/v2/assets/fonts/Roboto/Roboto-LightItalic.ttf b/admin/v2/assets/fonts/Roboto/Roboto-LightItalic.ttf new file mode 100644 index 00000000..2d277afb Binary files /dev/null and b/admin/v2/assets/fonts/Roboto/Roboto-LightItalic.ttf differ diff --git a/admin/v2/assets/fonts/Roboto/Roboto-Medium.ttf b/admin/v2/assets/fonts/Roboto/Roboto-Medium.ttf new file mode 100644 index 00000000..ac0f908b Binary files /dev/null and b/admin/v2/assets/fonts/Roboto/Roboto-Medium.ttf differ diff --git a/admin/v2/assets/fonts/Roboto/Roboto-MediumItalic.ttf b/admin/v2/assets/fonts/Roboto/Roboto-MediumItalic.ttf new file mode 100644 index 00000000..fc36a478 Binary files /dev/null and b/admin/v2/assets/fonts/Roboto/Roboto-MediumItalic.ttf differ diff --git a/admin/v2/assets/fonts/Roboto/Roboto-Regular.ttf b/admin/v2/assets/fonts/Roboto/Roboto-Regular.ttf new file mode 100644 index 00000000..ddf4bfac Binary files /dev/null and b/admin/v2/assets/fonts/Roboto/Roboto-Regular.ttf differ diff --git a/admin/v2/assets/fonts/Roboto/Roboto-Thin.ttf b/admin/v2/assets/fonts/Roboto/Roboto-Thin.ttf new file mode 100644 index 00000000..2e0dee6a Binary files /dev/null and b/admin/v2/assets/fonts/Roboto/Roboto-Thin.ttf differ diff --git a/admin/v2/assets/fonts/Roboto/Roboto-ThinItalic.ttf b/admin/v2/assets/fonts/Roboto/Roboto-ThinItalic.ttf new file mode 100644 index 00000000..084f9c0f Binary files /dev/null and b/admin/v2/assets/fonts/Roboto/Roboto-ThinItalic.ttf differ diff --git a/admin/v2/assets/fonts/SF_Pro_Text/SFProText-Regular.ttf b/admin/v2/assets/fonts/SF_Pro_Text/SFProText-Regular.ttf new file mode 100644 index 00000000..b63615e9 Binary files /dev/null and b/admin/v2/assets/fonts/SF_Pro_Text/SFProText-Regular.ttf differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-Black-Web.woff b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Black-Web.woff new file mode 100644 index 00000000..63e0e3a9 Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Black-Web.woff differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-Black-Web.woff2 b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Black-Web.woff2 new file mode 100644 index 00000000..105e7988 Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Black-Web.woff2 differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-BlackItalic-Web.woff b/admin/v2/assets/fonts/graphik/GraphikMailchimp-BlackItalic-Web.woff new file mode 100644 index 00000000..d9ec814e Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-BlackItalic-Web.woff differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-BlackItalic-Web.woff2 b/admin/v2/assets/fonts/graphik/GraphikMailchimp-BlackItalic-Web.woff2 new file mode 100644 index 00000000..eebf6ade Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-BlackItalic-Web.woff2 differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-Bold-Web.woff b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Bold-Web.woff new file mode 100644 index 00000000..0e533dfc Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Bold-Web.woff differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-Bold-Web.woff2 b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Bold-Web.woff2 new file mode 100644 index 00000000..cf7f3d61 Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Bold-Web.woff2 differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-BoldItalic-Web.woff b/admin/v2/assets/fonts/graphik/GraphikMailchimp-BoldItalic-Web.woff new file mode 100644 index 00000000..8e83d85c Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-BoldItalic-Web.woff differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-BoldItalic-Web.woff2 b/admin/v2/assets/fonts/graphik/GraphikMailchimp-BoldItalic-Web.woff2 new file mode 100644 index 00000000..6638fbb3 Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-BoldItalic-Web.woff2 differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-Extralight-Web.woff b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Extralight-Web.woff new file mode 100644 index 00000000..2afd56b9 Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Extralight-Web.woff differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-Extralight-Web.woff2 b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Extralight-Web.woff2 new file mode 100644 index 00000000..0e40a651 Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Extralight-Web.woff2 differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-ExtralightItalic-Web.woff b/admin/v2/assets/fonts/graphik/GraphikMailchimp-ExtralightItalic-Web.woff new file mode 100644 index 00000000..25a30354 Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-ExtralightItalic-Web.woff differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-ExtralightItalic-Web.woff2 b/admin/v2/assets/fonts/graphik/GraphikMailchimp-ExtralightItalic-Web.woff2 new file mode 100644 index 00000000..246811a4 Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-ExtralightItalic-Web.woff2 differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-Light-Web.woff b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Light-Web.woff new file mode 100644 index 00000000..e84dba0b Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Light-Web.woff differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-Light-Web.woff2 b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Light-Web.woff2 new file mode 100644 index 00000000..81da2179 Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Light-Web.woff2 differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-LightItalic-Web.woff b/admin/v2/assets/fonts/graphik/GraphikMailchimp-LightItalic-Web.woff new file mode 100644 index 00000000..bfbdc38d Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-LightItalic-Web.woff differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-LightItalic-Web.woff2 b/admin/v2/assets/fonts/graphik/GraphikMailchimp-LightItalic-Web.woff2 new file mode 100644 index 00000000..3dc64c4a Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-LightItalic-Web.woff2 differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-Medium-Web.woff b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Medium-Web.woff new file mode 100644 index 00000000..9363ba5e Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Medium-Web.woff differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-Medium-Web.woff2 b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Medium-Web.woff2 new file mode 100644 index 00000000..b5ca2006 Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Medium-Web.woff2 differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-MediumItalic-Web.woff b/admin/v2/assets/fonts/graphik/GraphikMailchimp-MediumItalic-Web.woff new file mode 100644 index 00000000..1a4462e9 Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-MediumItalic-Web.woff differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-MediumItalic-Web.woff2 b/admin/v2/assets/fonts/graphik/GraphikMailchimp-MediumItalic-Web.woff2 new file mode 100644 index 00000000..66589007 Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-MediumItalic-Web.woff2 differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-Regular-Web.woff b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Regular-Web.woff new file mode 100644 index 00000000..267a260c Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Regular-Web.woff differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-Regular-Web.woff2 b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Regular-Web.woff2 new file mode 100644 index 00000000..6d43b112 Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Regular-Web.woff2 differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-RegularItalic-Web.woff b/admin/v2/assets/fonts/graphik/GraphikMailchimp-RegularItalic-Web.woff new file mode 100644 index 00000000..f117e284 Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-RegularItalic-Web.woff differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-RegularItalic-Web.woff2 b/admin/v2/assets/fonts/graphik/GraphikMailchimp-RegularItalic-Web.woff2 new file mode 100644 index 00000000..1fdcc90c Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-RegularItalic-Web.woff2 differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-Semibold-Web.woff b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Semibold-Web.woff new file mode 100644 index 00000000..7956bfab Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Semibold-Web.woff differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-Semibold-Web.woff2 b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Semibold-Web.woff2 new file mode 100644 index 00000000..7b5fa1a4 Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Semibold-Web.woff2 differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-SemiboldItalic-Web.woff b/admin/v2/assets/fonts/graphik/GraphikMailchimp-SemiboldItalic-Web.woff new file mode 100644 index 00000000..8867ee4e Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-SemiboldItalic-Web.woff differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-SemiboldItalic-Web.woff2 b/admin/v2/assets/fonts/graphik/GraphikMailchimp-SemiboldItalic-Web.woff2 new file mode 100644 index 00000000..24dc12ad Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-SemiboldItalic-Web.woff2 differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-Super-Web.woff b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Super-Web.woff new file mode 100644 index 00000000..6e4f942b Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Super-Web.woff differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-Super-Web.woff2 b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Super-Web.woff2 new file mode 100644 index 00000000..287f2960 Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Super-Web.woff2 differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-SuperItalic-Web.woff b/admin/v2/assets/fonts/graphik/GraphikMailchimp-SuperItalic-Web.woff new file mode 100644 index 00000000..10c69a34 Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-SuperItalic-Web.woff differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-SuperItalic-Web.woff2 b/admin/v2/assets/fonts/graphik/GraphikMailchimp-SuperItalic-Web.woff2 new file mode 100644 index 00000000..27452877 Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-SuperItalic-Web.woff2 differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-Thin-Web.woff b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Thin-Web.woff new file mode 100644 index 00000000..640e38b0 Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Thin-Web.woff differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-Thin-Web.woff2 b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Thin-Web.woff2 new file mode 100644 index 00000000..95e34ddc Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-Thin-Web.woff2 differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-ThinItalic-Web.woff b/admin/v2/assets/fonts/graphik/GraphikMailchimp-ThinItalic-Web.woff new file mode 100644 index 00000000..b233822d Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-ThinItalic-Web.woff differ diff --git a/admin/v2/assets/fonts/graphik/GraphikMailchimp-ThinItalic-Web.woff2 b/admin/v2/assets/fonts/graphik/GraphikMailchimp-ThinItalic-Web.woff2 new file mode 100644 index 00000000..260441d1 Binary files /dev/null and b/admin/v2/assets/fonts/graphik/GraphikMailchimp-ThinItalic-Web.woff2 differ diff --git a/admin/v2/assets/fonts/graphik/fonts.css b/admin/v2/assets/fonts/graphik/fonts.css new file mode 100644 index 00000000..6a6d564f --- /dev/null +++ b/admin/v2/assets/fonts/graphik/fonts.css @@ -0,0 +1,263 @@ +/* + This font software is the property of Commercial Type. + + You may not modify the font software, use it on another website, or install it on a computer. + + License information is available at http://commercialtype.com/eula + For more information please visit Commercial Type at http://commercialtype.com or email us at info[at]commercialtype.com + + Copyright (C) 2016 Schwartzco Inc. + +*/ + +.GraphikMailchimp-Thin-Web { + font-family: 'Graphik Mailchimp Web'; + font-weight: 100; + font-style: normal; + } + +.GraphikMailchimp-ThinItalic-Web { + font-family: 'Graphik Mailchimp Web'; + font-weight: 100; + font-style: italic; + } + +.GraphikMailchimp-Extralight-Web { + font-family: 'Graphik Mailchimp Web'; + font-weight: 200; + font-style: normal; + } + +.GraphikMailchimp-ExtralightItalic-Web { + font-family: 'Graphik Mailchimp Web'; + font-weight: 200; + font-style: italic; + } + +.GraphikMailchimp-Light-Web { + font-family: 'Graphik Mailchimp Web'; + font-weight: 300; + font-style: normal; + } + +.GraphikMailchimp-LightItalic-Web { + font-family: 'Graphik Mailchimp Web'; + font-weight: 300; + font-style: italic; + } + +.GraphikMailchimp-Regular-Web { + font-family: 'Graphik Mailchimp Web'; + font-weight: 400; + font-style: normal; + } + +.GraphikMailchimp-RegularItalic-Web { + font-family: 'Graphik Mailchimp Web'; + font-weight: 400; + font-style: italic; + } + +.GraphikMailchimp-Medium-Web { + font-family: 'Graphik Mailchimp Web'; + font-weight: 500; + font-style: normal; + } + +.GraphikMailchimp-MediumItalic-Web { + font-family: 'Graphik Mailchimp Web'; + font-weight: 500; + font-style: italic; + } + +.GraphikMailchimp-Semibold-Web { + font-family: 'Graphik Mailchimp Web'; + font-weight: 600; + font-style: normal; + } + +.GraphikMailchimp-SemiboldItalic-Web { + font-family: 'Graphik Mailchimp Web'; + font-weight: 600; + font-style: italic; + } + +.GraphikMailchimp-Bold-Web { + font-family: 'Graphik Mailchimp Web'; + font-weight: 700; + font-style: normal; + } + +.GraphikMailchimp-BoldItalic-Web { + font-family: 'Graphik Mailchimp Web'; + font-weight: 700; + font-style: italic; + } + +.GraphikMailchimp-Black-Web { + font-family: 'Graphik Mailchimp Web'; + font-weight: 800; + font-style: normal; + } + +.GraphikMailchimp-BlackItalic-Web { + font-family: 'Graphik Mailchimp Web'; + font-weight: 800; + font-style: italic; + } + +.GraphikMailchimp-Super-Web { + font-family: 'Graphik Mailchimp Web'; + font-weight: 900; + font-style: normal; + } + +.GraphikMailchimp-SuperItalic-Web { + font-family: 'Graphik Mailchimp Web'; + font-weight: 900; + font-style: italic; + } + +@font-face { + font-family: 'Graphik Mailchimp Web'; + src: url('GraphikMailchimp-Thin-Web.woff2') format('woff2'), + url('GraphikMailchimp-Thin-Web.woff') format('woff'); + font-weight: 100; + font-style: normal; + } + +@font-face { + font-family: 'Graphik Mailchimp Web'; + src: url('GraphikMailchimp-ThinItalic-Web.woff2') format('woff2'), + url('GraphikMailchimp-ThinItalic-Web.woff') format('woff'); + font-weight: 100; + font-style: italic; + } + +@font-face { + font-family: 'Graphik Mailchimp Web'; + src: url('GraphikMailchimp-Extralight-Web.woff2') format('woff2'), + url('GraphikMailchimp-Extralight-Web.woff') format('woff'); + font-weight: 200; + font-style: normal; + } + +@font-face { + font-family: 'Graphik Mailchimp Web'; + src: url('GraphikMailchimp-ExtralightItalic-Web.woff2') format('woff2'), + url('GraphikMailchimp-ExtralightItalic-Web.woff') format('woff'); + font-weight: 200; + font-style: italic; + } + +@font-face { + font-family: 'Graphik Mailchimp Web'; + src: url('GraphikMailchimp-Light-Web.woff2') format('woff2'), + url('GraphikMailchimp-Light-Web.woff') format('woff'); + font-weight: 300; + font-style: normal; + } + +@font-face { + font-family: 'Graphik Mailchimp Web'; + src: url('GraphikMailchimp-LightItalic-Web.woff2') format('woff2'), + url('GraphikMailchimp-LightItalic-Web.woff') format('woff'); + font-weight: 300; + font-style: italic; + } + +@font-face { + font-family: 'Graphik Mailchimp Web'; + src: url('GraphikMailchimp-Regular-Web.woff2') format('woff2'), + url('GraphikMailchimp-Regular-Web.woff') format('woff'); + font-weight: 400; + font-style: normal; + } + +@font-face { + font-family: 'Graphik Mailchimp Web'; + src: url('GraphikMailchimp-RegularItalic-Web.woff2') format('woff2'), + url('GraphikMailchimp-RegularItalic-Web.woff') format('woff'); + font-weight: 400; + font-style: italic; + } + +@font-face { + font-family: 'Graphik Mailchimp Web'; + src: url('GraphikMailchimp-Medium-Web.woff2') format('woff2'), + url('GraphikMailchimp-Medium-Web.woff') format('woff'); + font-weight: 500; + font-style: normal; + } + +@font-face { + font-family: 'Graphik Mailchimp Web'; + src: url('GraphikMailchimp-MediumItalic-Web.woff2') format('woff2'), + url('GraphikMailchimp-MediumItalic-Web.woff') format('woff'); + font-weight: 500; + font-style: italic; + } + +@font-face { + font-family: 'Graphik Mailchimp Web'; + src: url('GraphikMailchimp-Semibold-Web.woff2') format('woff2'), + url('GraphikMailchimp-Semibold-Web.woff') format('woff'); + font-weight: 600; + font-style: normal; + } + +@font-face { + font-family: 'Graphik Mailchimp Web'; + src: url('GraphikMailchimp-SemiboldItalic-Web.woff2') format('woff2'), + url('GraphikMailchimp-SemiboldItalic-Web.woff') format('woff'); + font-weight: 600; + font-style: italic; + } + +@font-face { + font-family: 'Graphik Mailchimp Web'; + src: url('GraphikMailchimp-Bold-Web.woff2') format('woff2'), + url('GraphikMailchimp-Bold-Web.woff') format('woff'); + font-weight: 700; + font-style: normal; + } + +@font-face { + font-family: 'Graphik Mailchimp Web'; + src: url('GraphikMailchimp-BoldItalic-Web.woff2') format('woff2'), + url('GraphikMailchimp-BoldItalic-Web.woff') format('woff'); + font-weight: 700; + font-style: italic; + } + +@font-face { + font-family: 'Graphik Mailchimp Web'; + src: url('GraphikMailchimp-Black-Web.woff2') format('woff2'), + url('GraphikMailchimp-Black-Web.woff') format('woff'); + font-weight: 800; + font-style: normal; + } + +@font-face { + font-family: 'Graphik Mailchimp Web'; + src: url('GraphikMailchimp-BlackItalic-Web.woff2') format('woff2'), + url('GraphikMailchimp-BlackItalic-Web.woff') format('woff'); + font-weight: 800; + font-style: italic; + } + +@font-face { + font-family: 'Graphik Mailchimp Web'; + src: url('GraphikMailchimp-Super-Web.woff2') format('woff2'), + url('GraphikMailchimp-Super-Web.woff') format('woff'); + font-weight: 900; + font-style: normal; + } + +@font-face { + font-family: 'Graphik Mailchimp Web'; + src: url('GraphikMailchimp-SuperItalic-Web.woff2') format('woff2'), + url('GraphikMailchimp-SuperItalic-Web.woff') format('woff'); + font-weight: 900; + font-style: italic; + } diff --git a/admin/v2/assets/images/3dotpurple.gif b/admin/v2/assets/images/3dotpurple.gif new file mode 100644 index 00000000..3487e40a Binary files /dev/null and b/admin/v2/assets/images/3dotpurple.gif differ diff --git a/admin/v2/assets/images/Chevron-Down.svg b/admin/v2/assets/images/Chevron-Down.svg new file mode 100644 index 00000000..360e557b --- /dev/null +++ b/admin/v2/assets/images/Chevron-Down.svg @@ -0,0 +1 @@ + diff --git a/admin/v2/assets/images/Connect.png b/admin/v2/assets/images/Connect.png new file mode 100644 index 00000000..8dc85f70 Binary files /dev/null and b/admin/v2/assets/images/Connect.png differ diff --git a/admin/v2/assets/images/Mailchimp-Woocommerce.png b/admin/v2/assets/images/Mailchimp-Woocommerce.png new file mode 100644 index 00000000..090d887e Binary files /dev/null and b/admin/v2/assets/images/Mailchimp-Woocommerce.png differ diff --git a/admin/v2/assets/images/Mailchimp-image.png b/admin/v2/assets/images/Mailchimp-image.png new file mode 100644 index 00000000..498e1c96 Binary files /dev/null and b/admin/v2/assets/images/Mailchimp-image.png differ diff --git a/admin/v2/assets/images/blog-image-1.png b/admin/v2/assets/images/blog-image-1.png new file mode 100644 index 00000000..d2c1f715 Binary files /dev/null and b/admin/v2/assets/images/blog-image-1.png differ diff --git a/admin/v2/assets/images/blog-image-2.png b/admin/v2/assets/images/blog-image-2.png new file mode 100644 index 00000000..0ecb67ee Binary files /dev/null and b/admin/v2/assets/images/blog-image-2.png differ diff --git a/admin/v2/assets/images/blog-image-3.png b/admin/v2/assets/images/blog-image-3.png new file mode 100644 index 00000000..11da060f Binary files /dev/null and b/admin/v2/assets/images/blog-image-3.png differ diff --git a/admin/v2/assets/images/icon-delete.svg b/admin/v2/assets/images/icon-delete.svg new file mode 100644 index 00000000..3899197a --- /dev/null +++ b/admin/v2/assets/images/icon-delete.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/admin/v2/assets/images/tick-small.svg b/admin/v2/assets/images/tick-small.svg new file mode 100644 index 00000000..a492583a --- /dev/null +++ b/admin/v2/assets/images/tick-small.svg @@ -0,0 +1,3 @@ + + + diff --git a/admin/v2/assets/js/scripts.js b/admin/v2/assets/js/scripts.js new file mode 100644 index 00000000..9c92aa05 --- /dev/null +++ b/admin/v2/assets/js/scripts.js @@ -0,0 +1,157 @@ +(function( $ ) { + 'use strict'; + + $(window).on('load', function() { + + function debounce(func, timeout = 300){ + let timer; + return (...args) => { + clearTimeout(timer); + timer = setTimeout(() => { func.apply(this, args); }, timeout); + }; + } + + // Tags + $('.mc-wc-tag-list .mc-wc-input').keypress(function(event) { + var charCode = event.which || event.keyCode; + var charStr = String.fromCharCode(charCode); + if (/^[a-zA-Z0-9\s-_]*$/.test(charStr)) { + return true; // Allow input + } else { + return false; // Prevent input + } + }); + + $('.mc-wc-tag-list .mc-wc-input').keydown(function(event) { + if (event.key === 'Enter') { + event.preventDefault(); + } + }); + + $('.mc-wc-tag-list .btn-add').click(function() { + const tag_list_current = $(this).parent().parent(); + const tag_input = tag_list_current.find('.mc-wc-input'); + const input_tag_value = $.trim(tag_input.val()); + if (input_tag_value) { + addNewTag(tag_list_current, input_tag_value); + tag_input.val(''); + } + }); + + function addNewTag(tag_list_ele, tag) { + // const tags_hidden = tag_list_ele.find('#mailchimp-woocommerce-user-tags'); + const tags_hidden = $('#mailchimp-woocommerce-user-tags'); + const show_tagged = $('.mc-wc-tag-show-tagged'); + + let tags_hidden_vals = tags_hidden.val(); + let tags_vals_array = []; + let tag_vals_str = String(tag); + + if (tags_hidden_vals) { + tags_vals_array = tags_hidden_vals.split(', '); + + // Check if the tag is in the tag list + if ($.inArray(tag, tags_vals_array) !== -1) { + return; + } + + tags_vals_array.push(tag); + tag_vals_str = tags_vals_array.join(', '); + } + + let eleTagged = '
' + tag + '
' + if (show_tagged.html().trim() === '') { + show_tagged.html(eleTagged); + } else { + show_tagged.append(eleTagged); + } + + tags_hidden.val(tag_vals_str); + + if ($('#mailchimp_woocommerce_options .mc-wc-tab-content').length) { + saveSettings(); + } + } + + $('.mc-wc-tag-list').on('click', '.mc-wc-tag-icon-del', function() { + const tag_remove = $(this).data('value'); + const tag_list_current = $(this).parent().parent().parent(); + const tag_parent_ele = $(this).parent(); + + removeTag(tag_list_current, tag_parent_ele, tag_remove); + }); + + // when the audience is selected + // $('#mailchimp_list_selector').change(function (e) { + // const label = $('#mailchimp_list_selector option:selected').text(); + // $('.selected_audience_name').text(label); + // }); + + function removeTag(tag_list_ele, parent_ele, tag_remove) { + const tags_hidden = tag_list_ele.find('#mailchimp-woocommerce-user-tags'); + let tags_hidden_vals = tags_hidden.val(); + let tags_vals_array = tags_hidden_vals.split(', '); + var tag_remove_index = tags_vals_array.indexOf(String(tag_remove)); + if (tag_remove_index !== -1) { + tags_vals_array.splice(tag_remove_index, 1); + let tag_vals_str = tags_vals_array.join(', '); + tags_hidden.val(tag_vals_str); + parent_ele.remove(); + + if ($('#mailchimp_woocommerce_options .mc-wc-tab-content').length) { + saveSettings(); + } + } + } + + $('#mailchimp_woocommerce_options .mc-wc-tab-content input:not(.mc-wc-tag-list .mc-wc-input):not(#tower_box_switch):not(#comm_box_switch), #mailchimp_woocommerce_options .mc-wc-tab-content select:not(#log_file):not(#mailchimp-log-pref)').change(function(e) { + e.preventDefault(); + + saveSettings(); + }); + + // auto save after 1.5 seconds. + $('.opt-in-checkbox-text').keyup(debounce(function() { + saveSettings(); + }, 1500)); + + function saveSettings() { + let formData = new FormData($('#mailchimp_woocommerce_options')[0]); + let notice = $('.mc-wc-notice'); + let notice_content = $('#mc_notice_text'); + let content = $('.mc-wc-tab-content'); + + //content.addClass('loading'); + + notice.removeClass('error success'); + notice_content.text(''); + + $.ajax({ + method: 'POST', + url: phpVars.ajax_url_option, + data: formData, + processData: false, + contentType: false, + success: function() { + // put the notice text in the right spot. + notice_content.text(phpVars.l10n.option_update_success); + notice + .addClass('success') + //.text(phpVars.l10n.option_update_success) + .fadeIn(); + }, + error: function () { + notice_content.text(phpVars.l10n.option_update_error); + notice + .addClass('error') + //.text(phpVars.l10n.option_update_error) + .fadeIn(); + }, + complete: function() { + content.removeClass('loading'); + } + }); + } + }); +})( jQuery ); + diff --git a/admin/v2/helpers/helper.php b/admin/v2/helpers/helper.php new file mode 100644 index 00000000..34bd17b2 --- /dev/null +++ b/admin/v2/helpers/helper.php @@ -0,0 +1,13 @@ + +
+
+
+
+
    +
  • + +
  • +
  • + +
  • +
  • + +
  • +
  • + +
  • +
  • + +
  • +
+
+ +
+ +
+ +
+
+
+ + +
+
+ +
+
+
+
\ No newline at end of file diff --git a/admin/v2/templates/confirmation/header.php b/admin/v2/templates/confirmation/header.php new file mode 100644 index 00000000..755f3d25 --- /dev/null +++ b/admin/v2/templates/confirmation/header.php @@ -0,0 +1,37 @@ + + +startSync(); +} +$store_id = mailchimp_get_store_id(); +$mailchimp_api = mailchimp_get_api(); +$store = $mailchimp_api ? $mailchimp_api->getStoreIfAvailable( $store_id ) : null; +$admin_email = mailchimp_get_option( 'admin_email', get_option( 'admin_email' ) ); +?> +
+
+
+

+
+
+
+ <?php esc_html_e( 'Mailchimp Woocommerce', 'mailchimp-for-woocommerce' ); ?> +
+
+
+ +
\ No newline at end of file diff --git a/admin/v2/templates/confirmation/tabs/advanced.php b/admin/v2/templates/confirmation/tabs/advanced.php new file mode 100644 index 00000000..73d676e4 --- /dev/null +++ b/admin/v2/templates/confirmation/tabs/advanced.php @@ -0,0 +1,68 @@ + + + + +
+
+
+

+
+
+
+
+
+ +
+
+
+ +
+
+
+
+
+ +
+
+
+ +
+
+
+
+ +
+
+

+
+
+ +
+
+ + +
+
+
\ No newline at end of file diff --git a/admin/v2/templates/confirmation/tabs/audience.php b/admin/v2/templates/confirmation/tabs/audience.php new file mode 100644 index 00000000..acab2be4 --- /dev/null +++ b/admin/v2/templates/confirmation/tabs/audience.php @@ -0,0 +1,137 @@ + + + +
+
+
+

+
+
+
+
+ + + + + +
+ +

+ Abandoned Cart automations, choose the option to track carts for all customers and select the checkbox to sync new non-subscribed contacts.', 'mailchimp-for-woocommerce' ), + esc_url( 'https://mailchimp.com/help/create-abandoned-cart-customer-journey/' ) + ); + ?> +

+
+
+
+ +
+
+

+
+
+ +
+ +
+
+ +
+
+ +
+
+ +
+
+
+ +
+
+

+
+
+ +
+
+
+
+ +
+
+
+ non-subscribed contacts transactional emails (such as Abandoned Cart automations) and target them with ads.', 'mailchimp-for-woocommerce' ), + esc_url( 'https://mailchimp.com/help/about-non-subscribed-contacts/'), + esc_url( 'https://mailchimp.com/help/create-abandoned-cart-customer-journey/') + ); + ?> +
+
+
+
+
+ +
+
+

+
+
+ +
+ +
+
+ + + + + + + + +
+
+ +
+ + +
+ +
+
+
+
\ No newline at end of file diff --git a/admin/v2/templates/confirmation/tabs/logs.php b/admin/v2/templates/confirmation/tabs/logs.php new file mode 100644 index 00000000..9be0505a --- /dev/null +++ b/admin/v2/templates/confirmation/tabs/logs.php @@ -0,0 +1,138 @@ + + $value ) { + if ( ! in_array( $value, array( '.', '..' ), true ) ) { + if ( ! is_dir( $value ) && mailchimp_string_contains( $value, 'mailchimp_woocommerce' ) ) { + $logs[ sanitize_title( $value ) ] = $value; + } + } + } +} + +$requested_log_file = get_site_transient( 'mailchimp-woocommerce-view-log-file' ); +delete_site_transient( 'mailchimp-woocommerce-view-log-file' ); + +if ( empty( $requested_log_file ) ) { + $requested_log_file = ! empty( $_REQUEST['log_file'] ) && check_admin_referer( 'mailchimp_woocommerce_options', 'mailchimp_woocommerce_nonce' ) ? esc_attr( sanitize_text_field( wp_unslash( $_REQUEST['log_file'] ) ) ) : false; +} +if ( ! empty( $requested_log_file ) && isset( $logs[ sanitize_title( $requested_log_file ) ] ) ) { + $viewed_log = $logs[ sanitize_title( $requested_log_file ) ]; +} elseif ( ! empty( $logs ) ) { + $viewed_log = current( $logs ); +} else { + $viewed_log = null; +} +$handle = ! empty( $viewed_log ) ? substr( $viewed_log, 0, strlen( $viewed_log ) > 37 ? strlen( $viewed_log ) - 37 : strlen( $viewed_log ) - 4 ) : ''; + +?> + +
+
+
+

+
+
+ +
+
+

+ +

+
+ +
+
+
+ +
+
+

+
+
+
+
+ +
+ +
+ +
+
+ +
+ + + +
+

+ +

+
+ +
+
+
+
+
\ No newline at end of file diff --git a/admin/v2/templates/confirmation/tabs/overview.php b/admin/v2/templates/confirmation/tabs/overview.php new file mode 100644 index 00000000..3ed534b4 --- /dev/null +++ b/admin/v2/templates/confirmation/tabs/overview.php @@ -0,0 +1,294 @@ + + +isSyncing(); + $account_details = $handler->getAccountDetails(); + $mailchimp_list_name = $handler->getListName(); + if ( $account_details ) { + $account_name = $account_details['account_name']; + } + try { + $promo_rules = $mailchimp_api->getPromoRules( $store_id, 1, 1, 1 ); + $mailchimp_total_promo_rules = $promo_rules['total_items']; + } catch ( Exception $e ) { + $mailchimp_total_promo_rules = 0; + } + try { + $mailchimp_total_products = $mailchimp_api->getProductCount($store_id); + } catch ( Exception $e ) { + $mailchimp_total_products = 0; + } + try { + $mailchimp_total_orders = $mailchimp_api->getOrderCount($store_id); + } catch ( Exception $e ) { + $mailchimp_total_orders = 0; + } + try { + $mailchimp_total_customers = $mailchimp_api->getCustomerCount($store_id); + } catch (Exception $e) { + + } + // try { +// $mailchimp_total_subscribers = $mailchimp_api->getSubscribedCount( $store->getListId() ); +// } catch ( Exception $e ) { +// $mailchimp_total_subscribers = 0; } +// try { +// $mailchimp_total_transactional = $mailchimp_api->getTransactionalCount( $store->getListId() ); +// } catch ( Exception $e ) { +// $mailchimp_total_transactional = 0; +// } +} + +?> + + +
+
+
+

+
+ + + + + Leave us a review!', 'mailchimp-for-woocommerce' ), + array( + 'a' => array( + 'href' => array(), + 'target' => '_blank', + ), + ) + ), + esc_url( 'https://wordpress.org/support/plugin/mailchimp-for-woocommerce/reviews/' ) + ); + ?> + +
+
+
+
+
+
+ "> + + + + + + " src=""/> +
+
+
+
+ + + + + + +
+
"> + + + + + format('m/d/y')?> + + + + + + + + + format('g:ia T')?> + + + +
+
+
+
+
+
+ + + +
+
+ +
+ + + +
WooCommerce customers sync to Mailchimp as new contacts.
+
+
+
+
+
+ + + +
+
+ +
+ + + +
WooCommerce orders sync to Mailchimp so you can segment and automate based on your contacts’ past purchase behavior.
+
+
+
+
+
+ + + +
+
+ +
+ + + +
WooCommerce discount codes sync to Mailchimp so you can use promo code content blocks in your Mailchimp campaigns.
+
+
+
+
+
+ + + +
+
+ +
+ + + +
WooCommerce products sync to Mailchimp so you can use the product and product recommendation content blocks in your Mailchimp campaigns.
+
+
+
+
+
+ +
+
+
+

+
+
+
+
+

+

+ + Automate your follow-up with a special welcome offer or discount.', 'mailchimp-for-woocommerce' ), + array( + 'a' => array( + 'href' => array(), + 'target' => '_blank', + ), + ) + ), + esc_url( 'https://mailchimp.com/features/automated-welcome-email/' ) + ); + ?> +

+ +
+
+ +
+
+
+
+

+

+ +

+ + +
+
+ +
+
+
+
+

+

+ +

+ +
+
+ +
+
+
+
+
\ No newline at end of file diff --git a/admin/v2/templates/confirmation/tabs/store-info.php b/admin/v2/templates/confirmation/tabs/store-info.php new file mode 100644 index 00000000..e247f857 --- /dev/null +++ b/admin/v2/templates/confirmation/tabs/store-info.php @@ -0,0 +1,164 @@ + + + + + +
+
+
+

+
+
+ tag open %4$s - tag close*/ + __( 'We\'ve detected that your WooCommerce store\'s currency is %1$s (%3$schange%4$s), and the WordPress timezone is a %2$s (%5$schange%4$s). Please apply your locale settings. If you\'re unsure about these, use the defaults.', 'mailchimp-for-woocommerce' ), + esc_attr( isset( $current_currency_data ) ? $current_currency . ' | ' . $current_currency_data['name'] : $current_currency ), + mailchimp_get_timezone( true ) , + '', + '', + '' + )); + ?> +
+
+ +
+ +
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+

+
+
+ checkout page.', 'mailchimp-for-woocommerce' ), + get_the_permalink($checkout_page_id) + ); + else: + echo sprintf( + __( 'Your checkout page is using WooCommerce the Classic Checkout Shortcode. To change the opt-in checkbox at checkout, input one of the available WooCommerce form actions.', 'mailchimp-for-woocommerce' ), + esc_url( 'https://woocommerce.com/document/tutorial-customising-checkout-fields-using-actions-and-filters/') + ); + endif; + ?> +
+ +
+ +

+
+ +
+ +
+
+ +
+
+ +
+
+ +
+
+
+ +
+

+ +

+ and
', 'mailchimp-for-woocommerce' ) ); ?>
+ +

+
+ +
+ +
+
+

+
+
+ +
+
+ +
+
+
\ No newline at end of file diff --git a/admin/v2/templates/connect-accounts/button-actions.php b/admin/v2/templates/connect-accounts/button-actions.php new file mode 100644 index 00000000..189e364f --- /dev/null +++ b/admin/v2/templates/connect-accounts/button-actions.php @@ -0,0 +1,27 @@ + + +
+ + + + +
+ + +
+ + + +

+

+

+

+ +
+ \ No newline at end of file diff --git a/admin/v2/templates/connect-accounts/create-account-popup.php b/admin/v2/templates/connect-accounts/create-account-popup.php new file mode 100644 index 00000000..ed03a1b7 --- /dev/null +++ b/admin/v2/templates/connect-accounts/create-account-popup.php @@ -0,0 +1,198 @@ + + +
+
+
+ + + + + + + + +
+
+
\ No newline at end of file diff --git a/admin/v2/templates/connect-accounts/header.php b/admin/v2/templates/connect-accounts/header.php new file mode 100644 index 00000000..deaebe0f --- /dev/null +++ b/admin/v2/templates/connect-accounts/header.php @@ -0,0 +1,30 @@ + \ No newline at end of file diff --git a/admin/v2/templates/mailchimp-woocommerce-admin-pages.php b/admin/v2/templates/mailchimp-woocommerce-admin-pages.php new file mode 100644 index 00000000..2924ca5a --- /dev/null +++ b/admin/v2/templates/mailchimp-woocommerce-admin-pages.php @@ -0,0 +1,206 @@ +plugin_name, array() ); + +/** Verify that the nonce is correct for the GET and POST variables. */ + +$active_breadcrumb = isset( $_GET['breadcrumb'] ) ? + esc_attr( sanitize_key( $_GET['breadcrumb'] ) ) : + ( isset( $options['breadcrumb'] ) ? esc_attr( wp_unslash( $options['breadcrumb'] ) ) : '' ); + +// Active tab for confirmation breadcrumb +$active_tab = isset( $_GET['tab'] ) ? + esc_attr( sanitize_key( $_GET['tab'] ) ) : + ( isset( $options['active_tab'] ) ? esc_attr( wp_unslash( $options['active_tab'] ) ) : 'api_key' ); + +$mc_configured = mailchimp_is_configured(); +$is_mailchimp_post = isset( $_POST['mailchimp_woocommerce_settings_hidden'] ) && check_admin_referer( 'mailchimp_woocommerce_options', 'mailchimp_woocommerce_nonce' ) && strtolower( esc_attr( sanitize_key( $_POST['mailchimp_woocommerce_settings_hidden'] ) ) ) === 'y'; +$is_confirmation = isset( $_GET['resync'] ) ? ( esc_attr( sanitize_key( $_GET['resync'] ) ) === '1' ) : false; +/** If we have a transient set to start the sync on this page view, initiate it now that the values have been saved. */ + +if ($mc_configured && ! $is_confirmation && (bool) get_site_transient( 'mailchimp_woocommerce_start_sync' ) ) { + $is_confirmation = true; +} + +$has_valid_api_key = false; +$allow_new_list = true; +$only_one_list = false; +$clicked_sync_button = $mc_configured && $is_mailchimp_post && MC_WC_OVERVIEW_TAB === $active_tab; +$has_api_error = isset( $options['api_ping_error'] ) && ! empty( $options['api_ping_error'] ) ? $options['api_ping_error'] : null; +$audience_name = $handler->getListName() ? $handler->getListName() : ''; +$account_name = $handler->getAccountName(); +$store_name = get_option( 'blogname' ); + +// only do this if we haven't selected an audience. +if ( isset( $options['mailchimp_api_key'] ) ) { + try { + if ( $handler->hasValidApiKey( null, true ) ) { + $has_valid_api_key = true; + + /** If we don't have a valid api key we need to redirect back to the 'api_key' tab. */ + $mailchimp_lists = $handler->getMailChimpLists(); + + if ( is_array( $mailchimp_lists ) ) { + $allow_new_list = false; + $only_one_list = count( $mailchimp_lists ) === 1; + if (empty($audience_name)) { + $audience_name = $only_one_list ? reset($mailchimp_lists) : ''; + } + } + + /** Only display this button if the data is not syncing and we have a valid api key */ + if ( (bool) $this->getData( 'sync.started_at', false ) ) { + $is_confirmation = true; + } + + if (!$active_breadcrumb) { + if ($is_confirmation ) { + $active_breadcrumb = MC_WC_CONFIRMATION; + } else { + $active_breadcrumb = MC_WC_REVIEW_SYNC_SETTINGS; + } + } + } + } catch ( Exception $e ) { + if (mailchimp_string_contains($e->getMessage(), array('API key', 'User Disabled'))) { + $active_breadcrumb = MC_WC_CONNECT_ACCOUNTS; + $active_tab = 'api_key'; + $is_confirmation = false; + $has_api_error = "This Mailchimp API key has been disabled, please flush any object caches you may be using and re-connect."; + } else { + $has_api_error = $e->getMessage() . ' on ' . $e->getLine() . ' in ' . $e->getFile(); + } + } +} else { + $active_breadcrumb = MC_WC_CONNECT_ACCOUNTS; +} + +if (MC_WC_REVIEW_SYNC_SETTINGS === $active_breadcrumb && ! $has_valid_api_key){ + $active_breadcrumb = MC_WC_CONNECT_ACCOUNTS; +} + +if ((MC_WC_CONFIRMATION === $active_breadcrumb && ! $is_confirmation)) { + if ($has_valid_api_key && MC_WC_CONNECT_ACCOUNTS !== $active_breadcrumb) { + $active_breadcrumb = MC_WC_REVIEW_SYNC_SETTINGS; + } +} +?> + +
+

+ +

+
+ +
+ +
+
    +
  • + + + + + +
  • +
  • + + + + + +
  • +
  • + + + + + +
  • +
+
+ + + + + + + + + + + + +
+ + + +
+ +
+ + + +
+

+
+ + +
+

+ + +

+
+ +
+ + plugin_name ); + do_settings_sections( $this->plugin_name ); + include 'tabs/notices.php'; + } + ?> +
+ + + + + + +
+ + + + + + +
+ + + + +
+
diff --git a/admin/v2/templates/review-sync-settings/content.php b/admin/v2/templates/review-sync-settings/content.php new file mode 100644 index 00000000..507fc8e9 --- /dev/null +++ b/admin/v2/templates/review-sync-settings/content.php @@ -0,0 +1,176 @@ +validateApiKey() || ( ! isset( $mailchimp_lists ) ) ) { + $mailchimp_lists = $handler->getMailChimpLists(); + if ( false === $mailchimp_lists ) { + wp_safe_redirect( 'admin.php?page=mailchimp-woocommerce&tab=api_key&error_notice=missing_api_key' ); + exit; + } +} + +$list_is_configured = isset( $options['mailchimp_list'] ) && ( ! empty( $options['mailchimp_list'] ) ) && array_key_exists( $options['mailchimp_list'], ( isset( $mailchimp_lists ) ? $mailchimp_lists : array() ) ); + +if ( ! isset( $options ) ) { + $options = array(); +} +$newsletter_settings_error = $this->getData( 'errors.mailchimp_list', false ); + +$checkout_page_id = get_option('woocommerce_checkout_page_id'); +$mailchimp_customer_count = mailchimp_get_customer_count(); +$initial_sync_subscribe = ( array_key_exists( 'mailchimp_auto_subscribe', $options ) && ! is_null( $options['mailchimp_auto_subscribe'] ) ) ? (string) $options['mailchimp_auto_subscribe'] : '1'; +$ongoing_sync_subscribe = ( array_key_exists( 'mailchimp_ongoing_sync_status', $options ) && ! is_null( $options['mailchimp_ongoing_sync_status'] ) ) ? (string) $options['mailchimp_ongoing_sync_status'] : '1'; +?> + +
+

+
+ + +
+
+
+
+

+
+ +
+
+

+ + . +

+
+
+
+

+

+ +

+
+
+
+
+ +
+
+
+ +
+
+
+
+
+ +
+
+
+ +
+
+
+
+
+ +
+
+
+ +
+
+
+

+ +

+
+
+

+
+
+
+
+ +
+
+
+ +
+
+
+
+
+
+ +

+

+ +

+
+
+ + + + + + + + +
+
+ +
+ + +
+ +
+
+
+
+
\ No newline at end of file diff --git a/admin/v2/templates/review-sync-settings/header.php b/admin/v2/templates/review-sync-settings/header.php new file mode 100644 index 00000000..24c11352 --- /dev/null +++ b/admin/v2/templates/review-sync-settings/header.php @@ -0,0 +1,70 @@ + + +
+
+
+

+
+
+
+ <?php esc_html_e( 'Mailchimp Woocommerce', 'mailchimp-for-woocommerce' ); ?> +
+
+
+ + +
\ No newline at end of file diff --git a/admin/v2/templates/tabs/notices.php b/admin/v2/templates/tabs/notices.php new file mode 100644 index 00000000..4545796b --- /dev/null +++ b/admin/v2/templates/tabs/notices.php @@ -0,0 +1,43 @@ + + +
+ +
+ + + +
+ +
+ diff --git a/blocks/newsletter.php b/blocks/newsletter.php index 2b3f7269..1941f346 100644 --- a/blocks/newsletter.php +++ b/blocks/newsletter.php @@ -4,6 +4,7 @@ add_action( 'woocommerce_blocks_loaded', function() { if (class_exists( '\Automattic\WooCommerce\Blocks\Package' ) && + class_exists('\Automattic\WooCommerce\StoreApi\StoreApi') && interface_exists('\Automattic\WooCommerce\Blocks\Integrations\IntegrationInterface')) { require_once dirname( __FILE__ ) . '/woocommerce-blocks-integration.php'; require_once dirname( __FILE__ ) . '/woocommerce-blocks-extend-store-endpoint.php'; diff --git a/blocks/package-lock.json b/blocks/package-lock.json index 2b2845eb..3f92d3c2 100644 --- a/blocks/package-lock.json +++ b/blocks/package-lock.json @@ -8003,13 +8003,13 @@ "dev": true }, "node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", "dev": true, "dependencies": { "bytes": "3.1.2", - "content-type": "~1.0.4", + "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", @@ -8017,7 +8017,7 @@ "iconv-lite": "0.4.24", "on-finished": "2.4.1", "qs": "6.11.0", - "raw-body": "2.5.1", + "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" }, @@ -8920,9 +8920,9 @@ "dev": true }, "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", "dev": true, "engines": { "node": ">= 0.6" @@ -11152,17 +11152,17 @@ "dev": true }, "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", "dev": true, "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.1", + "body-parser": "1.20.2", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.5.0", + "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -11642,9 +11642,9 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", - "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "dev": true, "funding": [ { @@ -18662,9 +18662,9 @@ } }, "node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "dev": true, "dependencies": { "bytes": "3.1.2", @@ -22113,9 +22113,9 @@ } }, "node_modules/webpack-dev-middleware": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz", - "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==", + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", + "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", "dev": true, "dependencies": { "colorette": "^2.0.10", diff --git a/bootstrap.php b/bootstrap.php index 43c67fdb..a8e1d46e 100644 --- a/bootstrap.php +++ b/bootstrap.php @@ -96,7 +96,7 @@ function mailchimp_environment_variables() { return (object) array( 'repo' => 'master', 'environment' => 'production', // staging or production - 'version' => '3.7', + 'version' => '4.0', 'php_version' => phpversion(), 'wp_version' => (empty($wp_version) ? 'Unknown' : $wp_version), 'wc_version' => function_exists('WC') ? WC()->version : null, @@ -242,6 +242,13 @@ function mailchimp_submit_subscribed_only() { return ! (bool) mailchimp_get_option('mailchimp_ongoing_sync_status', '1'); } +/** + * @return bool + */ +function mailchimp_sync_existing_contacts_only() { + return mailchimp_get_option('mailchimp_auto_subscribe', '1') === '2'; +} + /** * @return bool */ @@ -830,6 +837,19 @@ function mailchimp_get_order_count() { return $total; } +function mailchimp_get_customer_count() { + global $wpdb; + $query = "SELECT COUNT(DISTINCT meta_value) FROM {$wpdb->postmeta} WHERE meta_key = '_billing_email'"; + $emails = $wpdb->get_var($query); + $users_query = new WP_User_Query( + array( + 'fields' => array( 'ID' ), + 'role' => 'customer', + ) + ); + return $users_query->get_total() + (int) $emails; +} + /** * @param $type * @return array|null|object @@ -1168,6 +1188,9 @@ function mailchimp_delete_as_jobs() { } function mailchimp_flush_sync_pointers() { // clean up the initial sync pointers + delete_option( 'mailchimp-woocommerce-resource-last-updated' ); + delete_option( 'mailchimp-woocommerce-sync.started_at' ); + delete_option( 'mailchimp-woocommerce-sync.completed_at' ); foreach (array('orders', 'products', 'coupons') as $resource_type) { delete_option("mailchimp-woocommerce-sync.{$resource_type}.started_at"); delete_option("mailchimp-woocommerce-sync.{$resource_type}.completed_at"); @@ -1197,9 +1220,9 @@ function mailchimp_clean_database() { * @return bool */ function mailchimp_has_started_syncing() { - $sync_started_at = get_option('mailchimp-woocommerce-sync.started_at'); - $sync_completed_at = get_option('mailchimp-woocommerce-sync.completed_at'); - return ($sync_completed_at < $sync_started_at); + return (bool) get_option('mailchimp-woocommerce-sync.started_at'); +// $sync_completed_at = get_option('mailchimp-woocommerce-sync.completed_at'); +// return ($sync_completed_at < $sync_started_at); } /** diff --git a/includes/api/class-mailchimp-api.php b/includes/api/class-mailchimp-api.php index e5585ff6..d4da1877 100644 --- a/includes/api/class-mailchimp-api.php +++ b/includes/api/class-mailchimp-api.php @@ -1640,7 +1640,7 @@ public function getPromoRules( $store_id, $page = 1, $count = 10, $return_origin */ public function getPromoCodesForRule( $store_id, $rule_id, $page = 1, $count = 10, $return_original = false ) { $result = $this->get( - "ecommerce/stores/{$store_id}/promo-rules/{$rule_id}/promo_codes", + "ecommerce/stores/{$store_id}/promo-rules/{$rule_id}/promo-codes", array( 'start' => $page, 'count' => $count, @@ -1653,7 +1653,7 @@ public function getPromoCodesForRule( $store_id, $rule_id, $page = 1, $count = 1 } $rules = array(); - foreach ( $result as $rule_data ) { + foreach ( $result['promo_codes'] as $rule_data ) { $rule = new MailChimp_WooCommerce_PromoCode(); $rule->fromArray( $rule_data ); $rules[] = $rule; @@ -1690,7 +1690,7 @@ public function getPromoRuleWithCodes( $store_id, $rule_id ) { $rule = new MailChimp_WooCommerce_PromoCode(); $rule = $rule->fromArray( $this->get( "ecommerce/stores/{$store_id}/promo-rules/{$rule_id}" ) ); try { - $promo_codes = $this->getPromoCodesForRule( $store_id, $rule->getId(), 1, 100 ); + $promo_codes = $this->getPromoCodesForRule( $store_id, $rule_id, 1, 100 ); $codes = array(); foreach ( $promo_codes as $item ) { $codes[] = $item->toArray(); diff --git a/includes/api/class-mailchimp-woocommerce-tower.php b/includes/api/class-mailchimp-woocommerce-tower.php index cfc10a40..f4990988 100644 --- a/includes/api/class-mailchimp-woocommerce-tower.php +++ b/includes/api/class-mailchimp-woocommerce-tower.php @@ -738,6 +738,7 @@ public function toggle( $enable = true ) { 'name' => ! empty( $plugin_options ) && isset( $plugin_options['store_name'] ) ? $plugin_options['store_name'] : get_option( 'blogname' ), 'support_token' => $support_token, 'domain' => get_option( 'siteurl' ), + 'validate' => (bool) $enable, 'data' => $data, ) ), diff --git a/includes/class-mailchimp-woocommerce-rest-api.php b/includes/class-mailchimp-woocommerce-rest-api.php index ebe454ac..415dbf0c 100644 --- a/includes/class-mailchimp-woocommerce-rest-api.php +++ b/includes/class-mailchimp-woocommerce-rest-api.php @@ -58,6 +58,13 @@ public function register_routes() 'permission_callback' => '__return_true', )); + // Tower verify connectivity + register_rest_route(static::$namespace, "/tower/verify", array( + 'methods' => 'POST', + 'callback' => array($this, 'verify_tower_connection'), + 'permission_callback' => '__return_true', + )); + // Tower report register_rest_route(static::$namespace, "/tower/report", array( 'methods' => 'POST', @@ -98,7 +105,7 @@ public function register_routes() public function permission_callback() { $cap = mailchimp_get_allowed_capability(); - return ($cap === 'manage_woocommerce' || $cap === 'manage_options' ); + return ($cap === 'manage_woocommerce' || $cap === 'manage_options' || $cap === 'administrator'); } /** @@ -111,6 +118,17 @@ public function ping(WP_REST_Request $request) return $this->mailchimp_rest_response(array('success' => true)); } + /** + * @param WP_REST_Request $request + * + * @return WP_REST_Response + */ + public function verify_tower_connection(WP_REST_Request $request) + { + $this->authorize('tower.token', $request); + return $this->mailchimp_rest_response(array('success' => true)); + } + /** * @param WP_REST_Request $request * @@ -150,34 +168,40 @@ public function get_sync_stats(WP_REST_Request $request) $store_id = mailchimp_get_store_id(); - $complete = array( - 'coupons' => get_option('mailchimp-woocommerce-sync.coupons.completed_at'), - 'products' => get_option('mailchimp-woocommerce-sync.products.completed_at'), - 'orders' => get_option('mailchimp-woocommerce-sync.orders.completed_at') - ); +// $complete = array( +// 'coupons' => get_option('mailchimp-woocommerce-sync.coupons.completed_at'), +// 'products' => get_option('mailchimp-woocommerce-sync.products.completed_at'), +// 'orders' => get_option('mailchimp-woocommerce-sync.orders.completed_at') +// ); $promo_rules_count = mailchimp_get_coupons_count(); $product_count = mailchimp_get_product_count(); $order_count = mailchimp_get_order_count(); + $customer_count = mailchimp_get_customer_count(); + +// $mailchimp_total_promo_rules = $complete['coupons'] ? $promo_rules_count - mailchimp_get_remaining_jobs_count('MailChimp_WooCommerce_SingleCoupon') : 0; +// $mailchimp_total_products = $complete['products'] ? $product_count - mailchimp_get_remaining_jobs_count('MailChimp_WooCommerce_Single_Product') : 0; +// $mailchimp_total_orders = $complete['orders'] ? $order_count - mailchimp_get_remaining_jobs_count('MailChimp_WooCommerce_Single_Order') : 0; +// $mailchimp_total_customers = ''; + + try { + $promo_rules = $api->getPromoRules($store_id, 1, 1, 1); + $mailchimp_total_promo_rules = $promo_rules['total_items']; + if (isset($promo_rules_count['publish']) && $mailchimp_total_promo_rules > $promo_rules_count['publish']) $mailchimp_total_promo_rules = $promo_rules_count['publish']; + } catch (Exception $e) { $mailchimp_total_promo_rules = 0; } + try { + $mailchimp_total_products = $api->getProductCount($store_id); + if ($mailchimp_total_products > $product_count) $mailchimp_total_products = $product_count; + } catch (Exception $e) { $mailchimp_total_products = 0; } + try { + $mailchimp_total_orders = $api->getOrderCount($store_id); + if ($mailchimp_total_orders > $order_count) $mailchimp_total_orders = $order_count; + } catch (Exception $e) { $mailchimp_total_orders = 0; } - $mailchimp_total_promo_rules = $complete['coupons'] ? $promo_rules_count - mailchimp_get_remaining_jobs_count('MailChimp_WooCommerce_SingleCoupon') : 0; - $mailchimp_total_products = $complete['products'] ? $product_count - mailchimp_get_remaining_jobs_count('MailChimp_WooCommerce_Single_Product') : 0; - $mailchimp_total_orders = $complete['orders'] ? $order_count - mailchimp_get_remaining_jobs_count('MailChimp_WooCommerce_Single_Order') : 0; - // try { - // $promo_rules = $api->getPromoRules($store_id, 1, 1, 1); - // $mailchimp_total_promo_rules = $promo_rules['total_items']; - // if (isset($promo_rules_count['publish']) && $mailchimp_total_promo_rules > $promo_rules_count['publish']) $mailchimp_total_promo_rules = $promo_rules_count['publish']; - // } catch (Exception $e) { $mailchimp_total_promo_rules = 0; } - // try { - // $products = $api->products($store_id, 1, 1); - // $mailchimp_total_products = $products['total_items']; - // if ($mailchimp_total_products > $product_count) $mailchimp_total_products = $product_count; - // } catch (Exception $e) { $mailchimp_total_products = 0; } - // try { - // $orders = $api->orders($store_id, 1, 1); - // $mailchimp_total_orders = $orders['total_items']; - // if ($mailchimp_total_orders > $order_count) $mailchimp_total_orders = $order_count; - // } catch (Exception $e) { $mailchimp_total_orders = 0; } + try { + $mailchimp_total_customers = $api->getCustomerCount($store_id); + if ($mailchimp_total_customers > $customer_count) $mailchimp_total_customers = $customer_count; + } catch (Exception $e) { $mailchimp_total_customers = 0; } $date = mailchimp_date_local('now'); // but we need to do it just in case. @@ -191,14 +215,19 @@ public function get_sync_stats(WP_REST_Request $request) 'orders_in_store' => $order_count, 'orders_in_mailchimp' => $mailchimp_total_orders, + + 'customers_in_store' => $customer_count, + 'customers_in_mailchimp' => $mailchimp_total_customers, // 'promo_rules_page' => get_option('mailchimp-woocommerce-sync.coupons.current_page'), // 'products_page' => get_option('mailchimp-woocommerce-sync.products.current_page'), // 'orders_page' => get_option('mailchimp-woocommerce-sync.orders.current_page'), 'date' => $date ? $date->format( __('D, M j, Y g:i A', 'mailchimp-for-woocommerce')) : '', - 'has_started' => mailchimp_has_started_syncing() || ($order_count != $mailchimp_total_orders), - 'has_finished' => mailchimp_is_done_syncing() && ($order_count == $mailchimp_total_orders), +// 'has_started' => mailchimp_has_started_syncing() || ($order_count != $mailchimp_total_orders), +// 'has_finished' => mailchimp_is_done_syncing() && ($order_count == $mailchimp_total_orders), + 'has_started' => mailchimp_has_started_syncing(), + 'has_finished' => mailchimp_is_done_syncing(), 'last_loop_at' => mailchimp_get_data('sync.last_loop_at'), )); } @@ -571,7 +600,8 @@ public function get_tower_resource(WP_REST_Request $request) } break; case 'promo_code': - $platform = new WC_Coupon($body['resource_id']); + case 'promo-code': + $platform = wc_get_coupon_code_by_id($body['resource_id']); $mc = mailchimp_get_api()->getPromoRuleWithCodes($store_id, $body['resource_id']); break; } diff --git a/includes/class-mailchimp-woocommerce-service.php b/includes/class-mailchimp-woocommerce-service.php index 282eed9c..75718581 100644 --- a/includes/class-mailchimp-woocommerce-service.php +++ b/includes/class-mailchimp-woocommerce-service.php @@ -478,6 +478,9 @@ public function handleProductCreated($post_ID, WP_Post $post, $is_existing_post) */ public function handleDeleteProductVariation($variation_id) { try { + if (!mailchimp_is_configured()) { + return; + } $deleted = mailchimp_get_api()->deleteStoreProduct(mailchimp_get_store_id(), $variation_id); if ($deleted) mailchimp_log('product.deleted', "deleted product variation {$variation_id}"); else mailchimp_log('product.delete_fail', "Unable to deleted product variation {$variation_id}"); diff --git a/includes/class-mailchimp-woocommerce.php b/includes/class-mailchimp-woocommerce.php index d6e2d803..d488460c 100644 --- a/includes/class-mailchimp-woocommerce.php +++ b/includes/class-mailchimp-woocommerce.php @@ -230,10 +230,10 @@ private function define_admin_hooks() { $this->loader->add_action('admin_enqueue_scripts', $plugin_admin, 'enqueue_scripts'); // Add menu item - $this->loader->add_action('admin_menu', $plugin_admin, 'add_plugin_admin_menu', 71); + $this->loader->add_action('admin_menu', $plugin_admin, 'add_plugin_admin_menu_2', 71); // Add WooCommerce Navigation Bar - $this->loader->add_action('admin_menu', $plugin_admin, 'add_woocommerce_navigation_bar'); + // $this->loader->add_action('admin_menu', $plugin_admin, 'add_woocommerce_navigation_bar'); // Add Settings link to the plugin $plugin_basename = plugin_basename( plugin_dir_path( __DIR__ ) . $this->plugin_name . '.php'); diff --git a/includes/processes/class-mailchimp-woocommerce-single-order.php b/includes/processes/class-mailchimp-woocommerce-single-order.php index 431ac268..cc3c55f8 100644 --- a/includes/processes/class-mailchimp-woocommerce-single-order.php +++ b/includes/processes/class-mailchimp-woocommerce-single-order.php @@ -187,11 +187,44 @@ public function process() $current_status = null; $pulled_member = false; + // see if this store has the auto subscribe setting enabled on initial sync + $plugin_options = get_option('mailchimp-woocommerce'); + $subscribe_setting = (string) $plugin_options['mailchimp_auto_subscribe']; + $sync_as_non_subscribed = $subscribe_setting === '0'; + $should_auto_subscribe = $subscribe_setting === '1'; + $only_sync_existing = $subscribe_setting === '2'; + + // during the initial sync, we need to apply different logic for subscriber statuses. + if ($this->is_full_sync) { + if ($should_auto_subscribe) { + // if they selected auto subscribe, we do that. + $order->getCustomer()->setOptInStatus(true); + $status = true; + } else if ($sync_as_non_subscribed) { + // if they said "transactional only", we apply this status of false. + $order->getCustomer()->setOptInStatus(false); + $status = false; + } else if ($only_sync_existing) { + // if they said only sync existing, we need to make sure they're already on the Mailchimp list + // otherwise we block it. + try { + $subscriber = $api->member(mailchimp_get_list_id(), $email); + mailchimp_set_transient($transient_key, $current_status = $subscriber['status']); + $pulled_member = true; + } catch (Exception $e) { + mailchimp_set_transient($transient_key, $current_status); + mailchimp_debug('filter', "#{$woo_order_number} was blocked due to only submitting existing members on initial sync."); + return false; + } + } + } + // if the customer did not actually check the box, this will always be false. // we needed to use this flag because when using double opt in, the status gets // overwritten to allow us to submit a pending status to the list member endpoint // which fires the double opt in. - if (!$original_status && mailchimp_submit_subscribed_only()) { + // this will not fire during the initial sync. + if (!$this->is_full_sync && (!$original_status && mailchimp_submit_subscribed_only())) { try { $subscriber = $api->member(mailchimp_get_list_id(), $email); $current_status = $subscriber['status']; @@ -209,10 +242,6 @@ public function process() } if ($this->is_full_sync) { - // see if this store has the auto subscribe setting enabled on initial sync - $plugin_options = get_option('mailchimp-woocommerce'); - $should_auto_subscribe = (bool) $plugin_options['mailchimp_auto_subscribe']; - // since we're syncing the customer for the first time, this is where we need to add the override // for subscriber status. We don't get the checkbox until this plugin is actually installed and working! if (!$status) { diff --git a/languages/mailchimp-for-woocommerce.pot b/languages/mailchimp-for-woocommerce.pot index ceb6222f..c2337334 100644 --- a/languages/mailchimp-for-woocommerce.pot +++ b/languages/mailchimp-for-woocommerce.pot @@ -813,7 +813,7 @@ msgid "Resync request in progress" msgstr "" #: admin/partials/tabs/store-sync.php:122 -msgid "Running" +msgid "Syncing" msgstr "" #: admin/class-mailchimp-woocommerce-admin.php:1932 diff --git a/mailchimp-woocommerce.php b/mailchimp-woocommerce.php index 68e35c86..cc110d47 100644 --- a/mailchimp-woocommerce.php +++ b/mailchimp-woocommerce.php @@ -16,7 +16,7 @@ * Plugin Name: Mailchimp for WooCommerce * Plugin URI: https://mailchimp.com/connect-your-store/ * Description: Connects WooCommerce to Mailchimp to sync your store data, send targeted campaigns to your customers, and sell more stuff. - * Version: 3.7 + * Version: 4.0 * Author: Mailchimp * Author URI: https://mailchimp.com * License: GPL-2.0+ @@ -26,7 +26,7 @@ * Requires at least: 4.9 * Tested up to: 6.5 * WC requires at least: 4.2 - * WC tested up to: 8.7 + * WC tested up to: 8.8 */ // If this file is called directly, abort.