File "class-mailchimp-woocommerce-tower.php"
Full Path: /home/vantageo/public_html/cache/cache/cache/cache/.wp-cli/wp-content/plugins/mailchimp-for-woocommerce_bk/includes/api/class-mailchimp-woocommerce-tower.php
File size: 22.88 KB
MIME-type: text/x-php
Charset: utf-8
<?php
class MailChimp_WooCommerce_Tower extends Mailchimp_Woocommerce_Job {
protected $store_id;
protected $with_shop_sales = true;
protected $with_log_file = null;
protected $with_log_search = null;
/**
* OrderCreatedHook constructor.
*
* @param $store_id
*/
public function __construct( $store_id ) {
$this->store_id = $store_id;
}
public function withoutShopSales() {
$this->with_shop_sales = false;
return $this;
}
public function withShopSales() {
$this->with_shop_sales = true;
return $this;
}
public function withLogFile( $file ) {
$this->with_log_file = $file;
return $this;
}
public function withLogSearch( $search ) {
$this->with_log_search = $search;
return $this;
}
/**
* @return array
* @throws MailChimp_WooCommerce_Error
* @throws MailChimp_WooCommerce_ServerError
*/
public function handle() {
return $this->getData();
}
/**
* @return array
* @throws MailChimp_WooCommerce_Error
* @throws MailChimp_WooCommerce_RateLimitError
* @throws MailChimp_WooCommerce_ServerError
*/
public function getData() {
$product_count = $customer_count = $order_count = $mc_product_count = $mc_customer_count = $mc_order_count = 0;
$api = mailchimp_get_api();
$store_id = mailchimp_get_store_id();
$authenticated = mailchimp_is_configured();
$list_id = mailchimp_get_list_id();
$url = get_option( 'siteurl' );
$options = (array) get_option( 'mailchimp-woocommerce' );
$last_sync_at = mailchimp_get_data('sync.last_loop_at');
try {
$product_count = mailchimp_get_product_count();
$customer_count = 0;
$order_count = mailchimp_get_order_count();
$plan = $plan_name = 'Woo';
$store_active = true;
} catch ( Throwable $e ) {
$store_active = false;
$plan = null;
}
$has_mailchimp_script = false;
$has_old_integration = false;
$duplicate_store_problem = false;
$store_attached = false;
$syncing_mc = false;
$list_is_valid = false;
$account_info = array();
$shop = null;
$akamai_block = false;
if ( $authenticated ) {
try {
$account_info = $api->getProfile();
} catch ( Exception $e ) {
$account_info = array();
if ( $e->getCode() === 503 ) {
$akamai_block = true;
}
}
if ( is_array( $account_info ) ) {
// don't need these
unset( $account_info['_links'] );
}
$stores = $api->stores();
$compare_url = $this->baseDomain( $url );
$list_name = $list_id ? $api->getList( $list_id )['name'] : null;
if ( is_array( $stores ) && ! empty( $stores ) ) {
foreach ( $stores as $mc_store ) {
/** @var MailChimp_WooCommerce_Store $mc_store */
$store_url = $this->baseDomain( $mc_store->getDomain() );
$public_key_matched = $mc_store->getId() === $store_id;
// make sure the current store in context is inside the Mailchimp array of stores.
if ( $public_key_matched ) {
$shop = $mc_store;
$syncing_mc = (bool) mailchimp_get_data('sync.syncing' );
$store_attached = true;
$list_is_valid = $mc_store->getListId() === $list_id;
$has_mailchimp_script = (bool) $mc_store->getConnectedSiteScriptFragment();
// if the store is not syncing locally, but is still marked as syncing on Mailchimp,
// clean it up by toggling to false.
if ( !$syncing_mc && $mc_store->isSyncing() ) {
if ( $api->flagStoreSync($store_id, false) ) {
mailchimp_log('tower', 'Toggled Mailchimp store to not syncing historical data');
}
}
}
if ( $store_url === $compare_url ) {
if ( ! $public_key_matched && $mc_store->getPlatform() === 'Woocommerce' ) {
$duplicate_store_problem = true;
}
}
}
}
try {
if ( $store_attached ) {
$mc_product_count = $api->getProductCount( $store_id );
$mc_customer_count = $api->getCustomerCount( $store_id );
$mc_order_count = $api->getOrderCount( $store_id );
}
} catch ( Throwable $e ) {
if ( $e->getCode() === 503 ) {
$akamai_block = true;
}
}
$automations = array();
$merge_fields = array();
$journeys = array();
try {
foreach ( $api->getAutomations( $list_id ) as $automation ) {
$created = new DateTime( $automation['create_time'] );
$started = new DateTime( $automation['start_time'] );
$automations[] = array(
'created_at' => $created->format( 'Y-m-d H:i:s' ),
'start_at' => $started->format( 'Y-m-d H:i:s' ),
'status' => $automation['status'],
'name' => $automation['settings']['title'],
'type' => $automation['trigger_settings']['workflow_title'],
'stats' => $automation['report_summary'],
);
}
$merge_fields = $api->mergeFields( $list_id );
$merge_fields = $merge_fields['merge_fields'];
$journeys = $api->getJourneys();
} catch ( Throwable $e ) {
if ( $e->getCode() === 503 ) {
$akamai_block = true;
}
}
}
$time = new DateTime( 'now' );
return array(
'store' => (object) array(
'public_key' => $store_id,
'domain' => $url,
'secure_url' => $url,
'user' => (object) array(
'email' => isset( $options['admin_email'] ) ? $options['admin_email'] : null,
),
'average_monthly_sales' => $this->getShopSales(),
'address' => (object) array(
'street' => isset( $options['store_street'] ) && $options['store_street'] ? $options['store_street'] : '',
'city' => isset( $options['store_street'] ) && $options['store_street'] ? $options['store_street'] : '',
'state' => isset( $options['store_state'] ) && $options['store_state'] ? $options['store_state'] : '',
'country' => isset( $options['store_country'] ) && $options['store_country'] ? $options['store_country'] : '',
'zip' => isset( $options['store_postal_code'] ) && $options['store_postal_code'] ? $options['store_postal_code'] : '',
'phone' => isset( $options['store_phone'] ) && $options['store_phone'] ? $options['store_phone'] : '',
),
'metrics' => array_values(
array(
'shopify_hooks' => (object) array(
'key' => 'shopify_hooks',
'value' => $this->hasWebhookInstalled(),
),
'shop.products' => (object) array(
'key' => 'shop.products',
'value' => $product_count,
),
'shop.customers' => (object) array(
'key' => 'shop.customers',
'value' => $customer_count,
),
'shop.orders' => (object) array(
'key' => 'shop.orders',
'value' => $order_count,
),
'mc.products' => (object) array(
'key' => 'mc.products',
'value' => $mc_product_count,
),
'mc.orders' => (object) array(
'key' => 'mc.orders',
'value' => $mc_order_count,
),
'mc.has_chimpstatic' => (object) array(
'key' => 'mc.has_chimpstatic',
'value' => true,
),
'mc.has_duplicate_store' => (object) array(
'key' => 'mc.has_duplicate_store',
'value' => $duplicate_store_problem,
),
'mc.store_attached' => (object) array(
'key' => 'mc.store_attached',
'value' => $store_attached,
),
'mc.is_syncing' => (object) array(
'key' => 'mc.is_syncing',
'value' => $syncing_mc,
),
'mailchimp_api_connected' => (object) array(
'key' => 'mailchimp_api_connected',
'value' => (bool) $account_info,
),
'mc_list_id' => (object) array(
'key' => 'mc_list_id',
'value' => (bool) $list_id && $list_is_valid,
),
'mc_list_valid' => (object) array(
'key' => 'mc_list_valid',
'value' => $list_is_valid,
),
'mc.has_legacy_integration' => (object) array(
'key' => 'mc.has_legacy_integration',
'value' => $has_old_integration,
),
'admin.updated_at' => (object) array(
'key' => 'admin.updated_at',
'value' => $time->format( 'Y-m-d H:i:s' ),
),
'product_sync_started' => (object) array(
'key' => 'product_sync_started',
'value' => get_option( 'mailchimp-woocommerce-sync.products.started_at' ),
),
'product_sync_completed' => (object) array(
'key' => 'product_sync_completed',
'value' => get_option( 'mailchimp-woocommerce-sync.products.completed_at' ),
),
'customer_sync_started' => (object) array(
'key' => 'customer_sync_started',
'value' => get_option( 'mailchimp-woocommerce-sync.customers.started_at' ),
),
'customer_sync_completed' => (object) array(
'key' => 'customer_sync_completed',
'value' => get_option( 'mailchimp-woocommerce-sync.customers.completed_at' ),
),
'order_sync_started' => (object) array(
'key' => 'order_sync_started',
'value' => get_option( 'mailchimp-woocommerce-sync.orders.started_at' ),
),
'order_sync_completed' => (object) array(
'key' => 'order_sync_completed',
'value' => get_option( 'mailchimp-woocommerce-sync.orders.completed_at' ),
),
'last_loop_at' => (object) array(
'key' => 'last_loop_at',
'value' => $last_sync_at,
),
)
),
'meta' => $this->getMeta(),
),
'meta' => array(
'timestamp' => $time->format( 'Y-m-d H:i:s' ),
'platform' => array(
'active' => $store_active,
'plan' => $plan,
'store_name' => get_option( 'blogname' ),
'domain' => $url,
'secure_url' => $url,
'user_email' => isset( $options['admin_email'] ) ? $options['admin_email'] : null,
'is_syncing' => $syncing_mc,
'sync_started_at' => get_option( 'mailchimp-woocommerce-sync.started_at' ),
'sync_completed_at' => get_option( 'mailchimp-woocommerce-sync.completed_at' ),
'subscribed_to_hooks' => true,
'uses_custom_rules' => false,
'wp_cron_enabled' => $this->hasWPCronEnabled(),
'ecomm_stats' => array(
'products' => $product_count,
'customers' => $customer_count,
'orders' => $order_count,
),
'shop' => array(
'phone' => isset( $options['store_phone'] ) && $options['store_phone'] ? $options['store_phone'] : '',
),
),
'mailchimp' => array(
'shop' => $shop ? $shop->toArray() : false,
'chimpstatic_installed' => $has_mailchimp_script,
'force_disconnect' => false,
'duplicate_store_problem' => $duplicate_store_problem,
'has_old_integration' => $has_old_integration,
'store_attached' => $store_attached,
'akamai_block' => $akamai_block,
'ecomm_stats' => array(
'products' => $mc_product_count,
'customers' => $mc_customer_count,
'orders' => $mc_order_count,
),
'list' => array(
'id' => $list_id,
'name' => isset( $list_name ) ? $list_name : null,
'double_opt_in' => $this->hasDoubleOptInEnabled(),
'valid' => $list_is_valid,
),
'account_info' => $account_info,
'automations' => isset( $automations ) ? $automations : null,
'journeys' => isset( $journeys ) ? $journeys : null,
'merge_fields' => isset( $merge_fields ) ? (object) $merge_fields : null,
),
'merge_tags' => array(),
),
'logs' => static::logs( $this->with_log_file, $this->with_log_search ),
'system_report' => $this->getSystemReport(),
);
}
/**
* @return bool
*/
public function hasDoubleOptInEnabled() {
try {
return mailchimp_list_has_double_optin();
} catch ( Exception $e ) {
return false;
}
}
/**
* @return bool
*/
protected function hasWebhookInstalled() {
if ( ! mailchimp_is_configured() || ! mailchimp_get_data( 'webhook.token' ) ) {
return false;
}
try {
return (bool) mailchimp_get_api()->hasWebhook( mailchimp_get_list_id(), mailchimp_get_webhook_url() );
} catch ( Throwable $e ) {
mailchimp_log( 'tower', 'could not get webhook URL', array( 'message' => $e->getMessage() ) );
return false;
}
}
/**
* @param $domain
* @return string|string[]
*/
protected function baseDomain( $domain ) {
return str_replace(
array( 'http://', 'https://', 'www.' ),
'',
rtrim( strtolower( trim( $domain ) ), '/' )
);
}
/**
* @param null $file
* @param null $search
*
* @return array
*/
public function logs( $file = null, $search = null ) {
try {
$logs = new MailChimp_WooCommerce_Logs();
$logs->limit( 200 );
$logs->withView( ! is_null( $file ) ? $file : $this->with_log_file );
$logs->searching( ! is_null( $search ) ? $search : $this->with_log_search );
return $logs->handle();
} catch ( Exception $e ) {
mailchimp_error( 'tower', $e->getMessage() );
return array();
}
}
public function getShopSales() {
try {
global $woocommerce, $wpdb;
include_once $woocommerce->plugin_path() . '/includes/admin/reports/class-wc-admin-report.php';
// WooCommerce Admin Report
$wc_report = new WC_Admin_Report();
// Set date parameters for the current month
$start_date = strtotime( date( 'Y-m', current_time( 'timestamp' ) ) . '-01 midnight' );
$end_date = strtotime( '+1month', $start_date ) - 86400;
$wc_report->start_date = $start_date;
$wc_report->end_date = $end_date;
// Avoid max join size error
$wpdb->query( 'SET SQL_BIG_SELECTS=1' );
// Get data for current month sold products
$sold_products = $wc_report->get_order_report_data(
array(
'data' => array(
'_product_id' => array(
'type' => 'order_item_meta',
'order_item_type' => 'line_item',
'function' => '',
'name' => 'product_id',
),
'_qty' => array(
'type' => 'order_item_meta',
'order_item_type' => 'line_item',
'function' => 'SUM',
'name' => 'quantity',
),
'_line_subtotal' => array(
'type' => 'order_item_meta',
'order_item_type' => 'line_item',
'function' => 'SUM',
'name' => 'gross',
),
'_line_total' => array(
'type' => 'order_item_meta',
'order_item_type' => 'line_item',
'function' => 'SUM',
'name' => 'gross_after_discount',
),
),
'query_type' => 'get_results',
'group_by' => 'product_id',
'where_meta' => '',
'order_by' => 'quantity DESC',
'order_types' => wc_get_order_types( 'order_count' ),
'filter_range' => true,
'order_status' => array( 'completed', 'complete' ),
)
);
$total = 0;
foreach ( $sold_products as $product ) {
$total += $product->gross;
}
return $total;
} catch ( Throwable $e ) {
mailchimp_log( 'tower', $e->getMessage() );
return 0;
}
}
public function getSystemReport() {
global $wp_version;
$actions = $this->getLastActions();
$theme = wp_get_theme();
return array(
array(
'key' => 'PhpVersion',
'value' => phpversion(),
),
array(
'key' => 'Memory Limit',
'value' => ini_get( 'memory_limit' ),
),
array(
'key' => 'WP CRON Enabled',
'value' => $this->hasWPCronEnabled(),
),
array(
'key' => 'WP CLI Enabled',
'value' => defined('WP_CLI') && WP_CLI,
),
array(
'key' => 'Curl Enabled',
'value' => function_exists( 'curl_init' ),
),
array(
'key' => 'Curl Version',
'value' => $this->getCurlVersion(),
),
array(
'key' => 'Wordpress Version',
'value' => $wp_version,
),
array(
'key' => 'WooCommerce Version',
'value' => defined( 'WC_VERSION' ) ? WC_VERSION : null,
),
array(
'key' => 'Action Scheduler Version',
'value' => $this->getActionSchedulerVersion(),
),
array(
'key' => 'Theme Name',
'value' => esc_html( $theme->get( 'Name' ) ),
),
array(
'key' => 'Theme URL',
'value' => esc_html( $theme->get( 'ThemeURI' ) ),
),
array(
'key' => 'Outbound IP Address',
'value' => mailchimp_get_outbound_ip(),
),
array(
'key' => 'Active Plugins',
'value' => $this->getActivePlugins(),
),
array(
'key' => 'Actions',
'value' => $actions,
),
);
}
/**
* @return bool
*/
public function hasWPCronEnabled() {
return ! defined( 'DISABLE_WP_CRON' ) ||
( defined( 'DISABLE_WP_CRON' ) && ! DISABLE_WP_CRON );
}
/**
* @return mixed|null
*/
public function getCurlVersion() {
$version = function_exists( 'curl_version' ) ? curl_version() : null;
return is_array( $version ) ? $version['version'] : null;
}
/**
* @return string
*/
public function getActionSchedulerVersion() {
// do a query to make sure this exists.
if ( !class_exists('ActionScheduler_Versions') ) {
return 'none';
}
if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
return 'Not Initialized In REST API';
}
return (string) ActionScheduler_Versions::instance()->latest_version();
}
public function getActivePlugins() {
$active_plugins = '<ul>';
$plugins = wp_get_active_and_valid_plugins();
foreach ( $plugins as $plugin ) {
$plugin_data = get_plugin_data( $plugin );
$active_plugins .= '<li><span class="font-bold">' . $plugin_data['Name'] . '</span>: ' . $plugin_data['Version'] . '</li>';
}
$active_plugins .= '</ul>';
return print_r( $active_plugins, true );
}
public function getLastActions() {
global $wpdb;
if ( ! class_exists( 'ActionScheduler' ) || ! ActionScheduler::is_initialized( 'store' ) ) {
return array();
}
if ( ! ActionScheduler::store() ) {
return array();
}
$oldest_and_newest = '<ul>';
foreach ( array_keys( ActionScheduler::store()->get_status_labels() ) as $status ) {
if ( 'in-progress' === $status ) {
continue;
}
$newest = $this->get_action_status_date( $status, 'newest' );
$status = ucfirst( $status );
$oldest_and_newest .= "<li><span class='font-bold'>{$status}</span>: {$newest}</li>";
}
$oldest_and_newest .= '</ul>';
return $oldest_and_newest;
}
/**
* @return array|object|null
*/
public function getMeta() {
global $wpdb;
$results = $wpdb->get_results( "SELECT * FROM $wpdb->options WHERE option_name LIKE 'mailchimp-woocommerce-%'" );
$response = array();
$date = new DateTime( 'now' );
foreach ( $results as $result ) {
$response[] = array(
'key' => str_replace( 'mailchimp-woocommerce-', '', $result->option_name ),
'value' => $result->option_value,
'updated_at' => $date->format( 'Y-m-d H:i:s' ),
);
}
return $response;
}
/**
* This is where we need to hook into tower from the store owner's support request.
* We can enable and disable this feature which will generate an API token specific to
* tower which will be used for authentication coming from our server to this specific store.
*
* @param bool $enable
*
* @return array|mixed|object|null
*/
public function toggle( $enable = true ) {
$command = (bool) $enable ? 'enable' : 'disable';
$store_id = mailchimp_get_store_id();
$key = mailchimp_get_api_key();
$list_id = mailchimp_get_list_id();
$is_connected = mailchimp_is_configured();
$post_url = "https://tower.vextras.com/admin-api/woocommerce/{$command}/{$store_id}";
$plugin_options = (array) get_option( 'mailchimp-woocommerce' );
$akamai_block = false;
if ( (bool) $enable ) {
mailchimp_set_data( 'tower.token', $support_token = wp_generate_password() );
} else {
$support_token = mailchimp_get_data( 'tower.token' );
delete_option( 'mailchimp-woocommerce-tower.support_token' );
}
if ( $enable ) {
$data = array(
'list_id' => $list_id,
'php_version' => phpversion(),
'curl_enabled' => function_exists( 'curl_init' ),
'is_connected' => $is_connected,
'sync_complete' => mailchimp_is_done_syncing(),
'rest_url' => MailChimp_WooCommerce_Rest_Api::url( '' ),
);
if ( $is_connected ) {
try {
$api = mailchimp_get_api();
$account_info = $api->getProfile();
$list_info = ! empty( $list_id ) ? $api->getList( $list_id ) : null;
$mc_store = $api->getStore( $store_id );
$syncing_mc = $mc_store ? $mc_store->isSyncing() : false;
if ( is_array( $list_info ) ) {
unset( $list_info['_links'] );
}
if ( is_array( $account_info ) ) {
unset( $account_info['_links'] );
}
$job = new MailChimp_WooCommerce_Fix_Duplicate_Store( $store_id, false, false );
$job->handle();
$dup_store = (bool) $job->hasDuplicateStoreProblem();
} catch ( Throwable $e ) {
$list_info = false;
$syncing_mc = false;
$account_info = false;
if ( $e->getCode() === 503 ) {
$akamai_block = true;
}
if ( ! isset( $dup_store ) ) {
$dup_store = false;
}
}
$data['list_info'] = $list_info;
$data['is_syncing'] = $syncing_mc;
$data['account_info'] = $account_info;
$data['duplicate_mailchimp_store'] = $dup_store;
$data['akamai_block'] = $akamai_block;
}
} else {
$data = array();
}
try {
$payload = array(
'headers' => array(
'Content-type' => 'application/json',
'Accept' => 'application/json',
'X-Store-Platform' => 'woocommerce',
'X-List-Id' => $list_id,
'X-Store-Key' => base64_encode( "{$store_id}:{$key}" ),
),
'body' => json_encode(
array(
'name' => ! empty( $plugin_options ) && isset( $plugin_options['store_name'] ) ? $plugin_options['store_name'] : get_option( 'blogname' ),
'support_token' => $support_token,
'domain' => get_option( 'siteurl' ),
'data' => $data,
)
),
'timeout' => 30,
);
$response = wp_remote_post( $post_url, $payload );
return json_decode( $response['body'] );
} catch ( Throwable $e ) {
return null;
}
}
/**
* @param $status
* @param string $date_type
*
* @return string
*/
protected function get_action_status_date( $status, $date_type = 'oldest' ) {
$order = 'oldest' === $date_type ? 'ASC' : 'DESC';
$store = ActionScheduler::store();
$action = $store->query_actions(
array(
'claimed' => false,
'status' => $status,
'per_page' => 1,
'order' => $order,
)
);
if ( ! empty( $action ) ) {
$date_object = $store->get_date( $action[0] );
$action_date = $date_object->format( 'Y-m-d H:i:s O' );
} else {
$action_date = '–';
}
return $action_date;
}
}