File "class-mailchimp-woocommerce-service.php"
Full Path: /home/vantageo/public_html/cache/cache/cache/cache/.wp-cli/wp-content/plugins/mailchimp-for-woocommerce_bk/includes/class-mailchimp-woocommerce-service.php
File size: 40.33 KB
MIME-type: text/x-php
Charset: utf-8
<?php
/**
* Created by MailChimp.
*
* Name: Ryan Hungate
* Email: ryan@vextras.com
* Date: 2/17/16
* Time: 12:03 PM
*/
class MailChimp_Service extends MailChimp_WooCommerce_Options
{
protected $user_email = null;
protected $previous_email = null;
protected $user_language = null;
protected $cart_subscribe = null;
protected $force_cart_post = false;
protected $cart_was_submitted = false;
protected $cart = array();
protected $validated_cart_db = false;
/** @var null|static */
protected static $_instance = null;
/**
* @return MailChimp_Service
*/
public static function instance()
{
if (!empty(static::$_instance)) {
return static::$_instance;
}
$env = mailchimp_environment_variables();
static::$_instance = new MailChimp_Service();
static::$_instance->setVersion($env->version);
return static::$_instance;
}
/**
* hook fired when we know everything is booted
*/
public function wooIsRunning()
{
// make sure the site option for setting the mailchimp_carts has been saved.
$this->validated_cart_db = get_site_option('mailchimp_woocommerce_db_mailchimp_carts');
$this->is_admin = current_user_can('administrator');
}
/**
* @param $r
* @param $url
* @return mixed
*/
public function addHttpRequestArgs( $r, $url ) {
// not sure whether or not we need to implement something like this yet.
//$r['headers']['Authorization'] = 'Basic ' . base64_encode('username:password');
return $r;
}
/**
* @param $key
* @param $default
* @return mixed
*/
protected function cookie($key, $default = null)
{
// if we're not allowed to use cookies, just return the default
if ($this->is_admin || !mailchimp_allowed_to_use_cookie($key)) {
return $default;
}
return isset($_COOKIE[$key]) ? $_COOKIE[$key] : $default;
}
/**
* @param WC_Order $order
*/
public function onNewPayPalOrder($order)
{
$this->onNewOrder($order->get_id());
}
/**
* This should only fire on a web based order so we can do real campaign tracking here.
*
* @param $order_id
* @return void|array
*/
public function onNewOrder($order_id)
{
if (!mailchimp_is_configured()) {
return;
}
// see if we have a session id and a campaign id, also only do this when this user is not the admin.
$campaign_id = $this->getCampaignTrackingID();
if (empty($campaign_id)) {
$campaign_id = get_post_meta($order_id, 'mailchimp_woocommerce_campaign_id', true);
// make sure this campaign ID has a valid format before we submit something
if (!$this->campaignIdMatchesFormat($campaign_id)) {
$campaign = null;
}
}
// grab the landing site cookie if we have one here.
$landing_site = $this->getLandingSiteCookie();
if (empty($landing_site)) {
$landing_site = get_post_meta($order_id, 'mailchimp_woocommerce_landing_site', true);
if (!$landing_site) $campaign = null;
}
// expire the landing site cookie so we can rinse and repeat tracking
$this->expireLandingSiteCookie();
// remove this record from the db.
$this->clearCartData();
return array (
'campaign_id' => $campaign_id,
'landing_site' => $landing_site
);
}
/**
* @param $order_id
* @param $old_status
* @param $new_status
*/
public function handleOrderStatusChanged($order_id, $old_status, $new_status)
{
if (!mailchimp_is_configured()) return;
$tracking = null;
$newOrder = false;
if ("pending" == $old_status && ("processing" == $new_status || "completed" == $new_status)) {
$tracking = $this->onNewOrder($order_id);
$newOrder = true;
}
mailchimp_log('debug', "Order ID {$order_id} was {$old_status} and is now {$new_status}", array('new_order' => $newOrder, 'tracking' => $tracking));
$this->onOrderSave($order_id, $tracking, $newOrder);
}
/**
* @param $order_id
* @param null $tracking
* @param null $newOrder
*/
public function onOrderSave($order_id, $tracking = null, $newOrder = null)
{
if (!mailchimp_is_configured()) return;
// queue up the single order to be processed.
$campaign_id = isset($tracking) && isset($tracking['campaign_id']) ? $tracking['campaign_id'] : null;
$landing_site = isset($tracking) && isset($tracking['landing_site']) ? $tracking['landing_site'] : null;
$language = $newOrder ? substr( get_locale(), 0, 2 ) : null;
$gdpr_fields = isset($_POST['mailchimp_woocommerce_gdpr']) ?
$_POST['mailchimp_woocommerce_gdpr'] : false;
// update the post meta with campaign tracking and landing site details
if (!empty($campaign_id)) {
update_post_meta($order_id, 'mailchimp_woocommerce_campaign_id', $campaign_id);
}
if (!empty($landing_site)) {
update_post_meta($order_id, 'mailchimp_woocommerce_landing_site', $landing_site);
}
// if we have gdpr fields in the post - let's save them to the order
if (!empty($gdpr_fields)) {
update_post_meta($order_id, "mailchimp_woocommerce_gdpr_fields", $gdpr_fields);
}
$handler = new MailChimp_WooCommerce_Single_Order($order_id, null, $campaign_id, $landing_site, $language, $gdpr_fields);
$handler->is_update = $newOrder ? !$newOrder : null;
$handler->is_admin_save = is_admin();
mailchimp_handle_or_queue($handler, 90);
}
/**
* @param $order_id
*/
public function onPartiallyRefunded($order_id)
{
if (!mailchimp_is_configured()) return;
$handler = new MailChimp_WooCommerce_Single_Order($order_id, null, null, null);
$handler->partially_refunded = true;
mailchimp_handle_or_queue($handler);
}
/**
* Clear the card data for a user.
*/
public function clearCartData()
{
if ($user_email = $this->getCurrentUserEmail()) {
$this->deleteCart(mailchimp_hash_trim_lower($user_email));
}
}
/**
* @param null $updated
*
* @return bool|mixed|null
* @throws MailChimp_WooCommerce_Error
* @throws MailChimp_WooCommerce_RateLimitError
* @throws MailChimp_WooCommerce_ServerError
*/
public function handleCartUpdated($updated = null)
{
if (mailchimp_carts_disabled()) {
return $updated;
}
if ($updated === false || $this->is_admin || $this->cart_was_submitted || !mailchimp_is_configured()) {
return !is_null($updated) ? $updated : false;
}
if (empty($this->cart)) {
$this->cart = $this->getCartItems();
}
if (($user_email = $this->getCurrentUserEmail())) {
// let's skip this right here - no need to go any further.
if (mailchimp_email_is_privacy_protected($user_email)) {
return !is_null($updated) ? $updated : false;
}
// if the user chose to send to subscribers only we need to do a quick check
// to see if this email has already subscribed.
if (!$this->cart_subscribe && (mailchimp_carts_subscribers_only() || mailchimp_submit_subscribed_only())) {
$transient_key = mailchimp_hash_trim_lower($user_email).".mc.status";
$cached_status = mailchimp_get_transient($transient_key);
if ($cached_status === null) {
$cached_status = mailchimp_get_subscriber_status($user_email);
mailchimp_set_transient($transient_key, $cached_status ? $cached_status : false, 300);
}
if ($cached_status !== 'subscribed') {
mailchimp_debug('filter', "preventing {$user_email} from submitting cart data due to subscriber settings.");
return $updated;
}
}
$previous = $this->getPreviousEmailFromSession();
$uid = mailchimp_hash_trim_lower($user_email);
$unique_sid = $this->getUniqueStoreID();
// delete the previous records.
if (!empty($previous) && $previous !== $user_email) {
if ($this->api()->deleteCartByID($unique_sid, $previous_email = mailchimp_hash_trim_lower($previous))) {
mailchimp_log('ac.cart_swap', "Deleted cart [$previous] :: ID [$previous_email]");
}
// going to delete the cart because we are switching.
$this->deleteCart($previous_email);
}
// delete the current cart record if there is one
$this->api()->deleteCartByID($unique_sid, $uid);
if ($this->cart && !empty($this->cart)) {
// track the cart locally so we can repopulate things for cross device compatibility.
$this->trackCart($uid, $user_email);
$this->cart_was_submitted = true;
// grab the cookie data that could play important roles in the submission
$campaign = $this->getCampaignTrackingID();
// get user language or default to admin main language
$language = $this->user_language ?: substr(get_locale(), 0, 2);
// fire up the job handler
$handler = new MailChimp_WooCommerce_Cart_Update($uid, $user_email, $campaign, $this->cart, $language);
// if they had the checkbox checked - go ahead and subscribe them if this is the first post.
//$handler->setStatus($this->cart_subscribe);
mailchimp_handle_or_queue($handler);
}
return !is_null($updated) ? $updated : true;
}
return !is_null($updated) ? $updated : false;
}
/**
* @param $post_id
*/
public function handleNewCoupon($post_id)
{
$this->handleCouponSaved($post_id, new WC_Coupon($post_id));
}
/**
* @param $post_id
* @param null $coupon
*/
public function handleCouponSaved($post_id, $coupon = null)
{
if (!mailchimp_is_configured()) return;
if ($coupon instanceof WC_Coupon) {
mailchimp_handle_or_queue(new MailChimp_WooCommerce_SingleCoupon($post_id));
}
}
/**
* @param $post_id
*/
public function handleCouponRestored($post_id)
{
$this->handleCouponSaved($post_id, new WC_Coupon($post_id));
}
/**
* @param WC_Data $object The deleted or trashed object.
* @param WP_REST_Response $response The response data.
* @param WP_REST_Request $request The request sent to the API.
*/
public function handleAPICouponTrashed($object, $response, $request)
{
try {
$deleted = mailchimp_get_api()->deletePromoRule(mailchimp_get_store_id(), $request['id']);
if ($deleted) mailchimp_log('api.promo_code.deleted', "deleted promo code {$request['id']}");
else mailchimp_log('api.promo_code.delete_fail', "Unable to delete promo code {$request['id']}");
} catch (Exception $e) {
mailchimp_error('delete promo code', $e->getMessage());
}
}
/**
* When a product post has been updated, handle or queue syncing when key fields have changed.
*
* @param int $post_ID The ID of the post/product being updated
* @param WP_Post $post_after The post object as it existed before the update
* @param WP_Post $post_before The post object as it exists after the update
* @return void
*/
public function handleProductUpdated( int $post_ID, WP_Post $post_after, WP_Post $post_before )
{
// Only work with products that have certain statuses
if ('product' !== $post_after->post_type
|| in_array($post_after->post_status, array('trash', 'auto-draft', 'draft', 'pending'))
|| ! mailchimp_is_configured()
) {
return;
}
// Check if product title or description has been altered
if ($post_after->post_title !== $post_before->post_title
|| $post_after->post_content !== $post_before->post_content
) {
mailchimp_handle_or_queue( new MailChimp_WooCommerce_Single_Product($post_ID), 5);
}
}
/**
* @param WC_Product $product
* @param $data
*/
public function handleProcessProductMeta($product, $data)
{
if (!is_array($data) || empty($data) || !$product) {
return;
}
$valid_keys = array(
'_thumbnail_id',
'description',
'image_id',
'price',
'sku',
'regular_price',
'sale_price',
'_stock_status',
'stock_quantity',
'_stock',
'stock_status',
'manage_stock',
'gallery_image_ids',
'name',
'status',
'slug',
);
// if there's not a valid prop in the update, just skip this.
if (!array_intersect($valid_keys, $data)) {
return;
}
mailchimp_debug('action', "handleProcessProductMeta {$product->get_id()} update being queued", array(
'data' => $data,
));
mailchimp_handle_or_queue(new MailChimp_WooCommerce_Single_Product($product->get_id()), 5);
}
/**
* When the _stock, _thumbnail_id,
* meta is updated for a product, handle or queue syncing updates.
*
* @param int $meta_id The ID of the post meta entry that was updated
* @param int $object_id The ID of the object the post meta entry is attached to
* @param string $meta_key The key of the meta entry that was updated
* @param mixed $_meta_value The value of the meta entry that was updated
* @return void
*/
public function handleProductMetaUpdated($meta_id, $object_id, $meta_key, $_meta_value)
{
// If we're not working with the meta key used to store stock quantity, bail
if (!in_array($meta_key, array('_thumbnail_id'), true)) {
return;
}
// Confirm that we're working with an object that is a WooCommerce product with a certain status
$product = wc_get_product($object_id);
if ($product instanceof WC_Product &&
!in_array($product->get_status(), array('trash', 'auto-draft', 'draft', 'pending'))
) {
mailchimp_debug('queue', "handling meta update for meta [{$meta_key}] on product {$object_id}");
mailchimp_handle_or_queue(new MailChimp_WooCommerce_Single_Product($object_id), 5);
}
}
/**
* If a product has been updated and isn't an existing post, handle or queue syncing updates.
*
* @param int $post_ID The ID of the post that was updated/created
* @param WP_Post $post The post object that was updated/created
* @param bool $is_existing_post Whether the updated post existed before the update
* @return void
*/
public function handleProductCreated($post_ID, WP_Post $post, $is_existing_post)
{
// Since the handleProductUpdated() function above handles product updates, bail for existing posts/products.
if ($is_existing_post || !mailchimp_is_configured()) {
return;
}
// If the product is of a certain status, process it.
if (!in_array($post->post_status, array('trash', 'auto-draft', 'draft', 'pending'))) {
mailchimp_handle_or_queue(new MailChimp_WooCommerce_Single_Product($post_ID), 5);
}
}
/**
* Fire new order and order save handling/queueing events when a shop_order post is saved.
*
* @param int $post_ID The ID of the order
* @param WP_Post $post The post object of the order
* @param bool $is_existing_post Whether the order existed before the update
* @return void
*/
public function handleOrderSaved( $post_ID, WP_Post $post, $is_existing_post)
{
if (!mailchimp_is_configured()) {
return;
}
if (!in_array($post->post_status, array('trash', 'auto-draft', 'draft', 'pending'))) {
$tracking = $this->onNewOrder($post_ID);
$this->onOrderSave($post_ID, $tracking, !$is_existing_post);
}
}
/**
* @param $post_id
*/
public function handlePostTrashed($post_id)
{
if (!mailchimp_is_configured()) return;
switch (get_post_type($post_id)) {
case 'shop_coupon':
try {
$deleted = mailchimp_get_api()->deletePromoRule(mailchimp_get_store_id(), $post_id);
if ($deleted) mailchimp_log('promo_code.deleted', "deleted promo code {$post_id}");
else mailchimp_log('promo_code.delete_fail', "Unable to delete promo code {$post_id}");
} catch (Exception $e) {
mailchimp_error('delete promo code', $e->getMessage());
}
break;
case 'product':
try {
$deleted = mailchimp_get_api()->deleteStoreProduct(mailchimp_get_store_id(), $post_id);
if ($deleted) mailchimp_log('product.deleted', "deleted product {$post_id}");
else mailchimp_log('product.delete_fail', "Unable to deleted product {$post_id}");
} catch (Exception $e) {
mailchimp_error('delete product', $e->getMessage());
}
break;
}
}
/**
* @param $post_id
* @return void
*/
public function handlePostRestored($post_id)
{
if (!mailchimp_is_configured() || !($post = get_post($post_id))) {
return;
}
// don't handle any of these statuses because they're not ready for the show
if (in_array($post->post_status, array('trash', 'auto-draft', 'draft', 'pending'))) {
return;
}
switch(get_post_type($post_id)) {
case 'shop_coupon':
$this->handleCouponRestored($post_id);
break;
case 'product':
mailchimp_handle_or_queue(new MailChimp_WooCommerce_Single_Product($post_id), 5);
break;
}
}
/**
* @param $user_id
*/
public function handleUserRegistration($user_id)
{
if (!mailchimp_is_configured()) return;
$subscribed = (bool) isset($_POST['mailchimp_woocommerce_newsletter']) && $_POST['mailchimp_woocommerce_newsletter'];
if (isset($_POST['mailchimp_woocommerce_newsletter']) && $_POST['mailchimp_woocommerce_newsletter']) {
$gdpr_fields = isset($_POST['mailchimp_woocommerce_gdpr']) ?
$_POST['mailchimp_woocommerce_gdpr'] : false;
} else {
$gdpr_fields = null;
}
// update the user meta with the 'is_subscribed' form element
update_user_meta($user_id, 'mailchimp_woocommerce_is_subscribed', $subscribed);
if ($subscribed) {
$job = new MailChimp_WooCommerce_User_Submit($user_id, true, null, null, $gdpr_fields);
mailchimp_handle_or_queue($job);
}
}
/**
* @param $user_id
* @param $old_user_data
*/
function handleUserUpdated($user_id, $old_user_data)
{
if (!mailchimp_is_configured()) return;
// only update this person if they were marked as subscribed before
$is_subscribed = get_user_meta($user_id, 'mailchimp_woocommerce_is_subscribed', true);
$gdpr_fields = get_user_meta($user_id, 'mailchimp_woocommerce_gdpr_fields', true);
$job = new MailChimp_WooCommerce_User_Submit(
$user_id,
(bool) $is_subscribed,
$old_user_data,
null,
!empty($gdpr_fields) ? $gdpr_fields : null
);
// only send this update if the user actually has a boolean value.
mailchimp_handle_or_queue($job);
}
/**
* Delete all the options pointing to the pages, and re-start the sync process.
* @param bool $only_products
* @return bool
*/
protected function syncProducts($only_products = false)
{
if (!$this->isAdmin()) return false;
$this->removePointers(true, ($only_products ? false : true));
update_option('mailchimp-woocommerce-sync.orders.prevent', $only_products);
MailChimp_WooCommerce_Process_Products::push();
return true;
}
/**
* Delete all the options pointing to the pages, and re-start the sync process.
* @return bool
*/
protected function syncOrders()
{
if (!$this->isAdmin()) return false;
$this->removePointers(false);
// since the products are all good, let's sync up the orders now.
mailchimp_handle_or_queue(new MailChimp_WooCommerce_Process_Orders());
return true;
}
/**
* @return bool|string
*/
public function getCurrentUserEmail()
{
if (isset($this->user_email) && !empty($this->user_email)) {
return $this->user_email = strtolower($this->user_email);
}
$user = wp_get_current_user();
$email = ($user->ID > 0 && isset($user->user_email)) ? $user->user_email : $this->getEmailFromSession();
return $this->user_email = strtolower($email);
}
/**
* @return bool|array
*/
public function getCartItems()
{
if (!($this->cart = $this->getWooSession('cart', false))) {
$this->cart = !function_exists('WC') ? false : WC()->cart->get_cart();
} else {
$cart_session = array();
foreach ( $this->cart as $key => $values ) {
$cart_session[$key] = $values;
unset($cart_session[$key]['data']); // Unset product object
}
return $this->cart = $cart_session;
}
return is_array($this->cart) ? $this->cart : false;
}
/**
* @throws MailChimp_WooCommerce_Error
* @throws MailChimp_WooCommerce_RateLimitError
* @throws MailChimp_WooCommerce_ServerError
*/
public function handleCampaignTracking()
{
if (!mailchimp_allowed_to_use_cookie('mailchimp_user_email')) {
return;
}
// set the landing site cookie if we don't have one.
$this->setLandingSiteCookie();
$cookie_duration = $this->getCookieDuration();
// if we have a query string of the mc_cart_id in the URL, that means we are sending a campaign from MC
if (isset($_GET['mc_cart_id']) && !isset($_GET['removed_item'])) {
// try to pull the cart from the database.
if (($cart = $this->getCart($_GET['mc_cart_id'])) && !empty($cart)) {
// set the current user email
$this->user_email = trim(str_replace(' ','+', $cart->email));
if (($current_email = $this->getEmailFromSession()) && $current_email !== $this->user_email) {
$this->previous_email = $current_email;
mailchimp_set_cookie('mailchimp_user_previous_email',$this->user_email, $cookie_duration, '/');
}
// cookie the current email
mailchimp_set_cookie('mailchimp_user_email', $this->user_email, $cookie_duration, '/' );
$cart_data = unserialize($cart->cart);
if (!empty($cart_data)) {
// set the cart data.
$this->setWooSession('cart', unserialize($cart->cart));
mailchimp_debug('carts', "manually setting cart data for {$this->user_email}", array(
'cart_id' => $_GET['mc_cart_id'],
'cart' => $cart->cart,
));
}
}
}
if (isset($_GET['mc_cid'])) {
$this->setCampaignTrackingID($_GET['mc_cid'], $cookie_duration);
}
if (isset($_GET['mc_eid'])) {
mailchimp_set_cookie('mailchimp_email_id', trim($_GET['mc_eid']), $cookie_duration, '/' );
}
}
/**
* @return mixed|null
*/
public function getCampaignTrackingID()
{
$cookie = $this->cookie('mailchimp_campaign_id', false);
if (empty($cookie)) {
$cookie = $this->getWooSession('mailchimp_campaign_id', false);
}
// we must follow a pattern at minimum in order to think this is possibly a valid campaign ID.
if (!$this->campaignIdMatchesFormat($cookie)) {
return false;
}
return $cookie;
}
/**
* @param $id
* @param $cookie_duration
*
* @return $this
* @throws MailChimp_WooCommerce_Error
* @throws MailChimp_WooCommerce_RateLimitError
* @throws MailChimp_WooCommerce_ServerError
*/
public function setCampaignTrackingID($id, $cookie_duration)
{
if (!mailchimp_is_configured()) {
return $this;
}
$cid = trim($id);
// we must follow a pattern at minimum in order to think this is possibly a valid campaign ID.
if (!$this->campaignIdMatchesFormat($cid)) {
return $this;
}
// don't throw the error if it's not found.
if (!$this->api()->getCampaign($cid, false)) {
$cid = null;
}
mailchimp_set_cookie('mailchimp_campaign_id', $cid, $cookie_duration, '/' );
$this->setWooSession('mailchimp_campaign_id', $cid);
return $this;
}
/**
* @param $cid
* @return bool
*/
public function campaignIdMatchesFormat($cid)
{
if (!is_string($cid) || empty($cid)) return false;
return (bool) preg_match("/^[a-zA-Z0-9]{10,12}$/", $cid, $matches);
}
/**
* @return mixed|null
*/
public function getLandingSiteCookie()
{
$cookie = $this->cookie('mailchimp_landing_site', false);
if (empty($cookie)) {
$cookie = $this->getWooSession('mailchimp_landing_site', false);
}
return $cookie;
}
/**
* @return $this
*/
public function setLandingSiteCookie()
{
// if we're not allowed to use this cookie, just return
if (!mailchimp_allowed_to_use_cookie('mailchimp_landing_site')) {
return $this;
}
if (isset($_GET['expire_landing_site'])) $this->expireLandingSiteCookie();
// if we already have a cookie here, we need to skip it.
if ($this->getLandingSiteCookie() != false) return $this;
// grab the current landing url since it's a referral.
$landing_site = home_url() . wp_unslash($_SERVER['REQUEST_URI']);
// Catch all possible file requests to avoid false positives
// We need to catch just real pages of the website
// Catching images, videos and fonts file types
preg_match("/^.*\.(ai|bmp|gif|ico|jpeg|jpg|png|ps|psd|svg|tif|tiff|fnt|fon|otf|ttf|3g2|3gp|avi|flv|h264|m4v|mkv|mov|mp4|mpg|mpeg|rm|swf|vob|wmv|aif|cda|mid|midi|mp3|mpa|ogg|wav|wma|wpl)$/i", $landing_site, $matches);
if (!empty($landing_site) && !wp_doing_ajax() && ( count($matches) == 0 ) ) {
mailchimp_set_cookie('mailchimp_landing_site', $landing_site, $this->getCookieDuration(), '/' );
$this->setWooSession('mailchimp_landing_site', $landing_site);
}
return $this;
}
/**
* @return array|bool|string
*/
public function getReferer()
{
if (function_exists('wp_get_referer')) {
return wp_get_referer();
}
if (!empty($_REQUEST['_wp_http_referer'])) {
return wp_unslash($_REQUEST['_wp_http_referer']);
} elseif (!empty($_SERVER['HTTP_REFERER'])) {
return wp_unslash( $_SERVER['HTTP_REFERER']);
}
return false;
}
/**
* @return $this
*/
public function expireLandingSiteCookie()
{
if (!mailchimp_allowed_to_use_cookie('mailchimp_landing_site')) {
return $this;
}
mailchimp_set_cookie('mailchimp_landing_site', false, $this->getCookieDuration(), '/' );
$this->setWooSession('mailchimp_landing_site', false);
return $this;
}
/**
* @return bool
*/
protected function getEmailFromSession()
{
return $this->cookie('mailchimp_user_email', false);
}
/**
* @return bool
*/
protected function getPreviousEmailFromSession()
{
if ($this->previous_email) {
return $this->previous_email = strtolower($this->previous_email);
}
$email = $this->cookie('mailchimp_user_previous_email', false);
return $email ? strtolower($email) : false;
}
/**
* @param $key
* @param null $default
* @return mixed|null
*/
public function getWooSession($key, $default = null)
{
if (!function_exists('WC')) return $default;
if (!($woo = WC()) || empty($woo->session)) {
return $default;
}
// not really sure why this would be the case, but if there is no session we can't get it anyway.
if (!is_object($woo->session) || !method_exists($woo->session, 'get')) {
return $default;
}
return $woo->session->get($key, $default);
}
/**
* @param $key
* @param $value
* @return $this
*/
public function setWooSession($key, $value)
{
if (!function_exists('WC')) return $this;
if (!($woo = WC()) || empty($woo->session)) {
return $this;
}
$woo->session->set($key, $value);
return $this;
}
/**
* @param $key
* @return $this
*/
public function removeWooSession($key)
{
if (!function_exists('WC')) return $this;
if (!($woo = WC()) || empty($woo->session)) {
return $this;
}
$woo->session->__unset($key);
return $this;
}
/**
*
*/
public function get_user_by_hash()
{
if ($this->doingAjax() && isset($_GET['hash'])) {
if (($cart = $this->getCart($_GET['hash']))) {
$this->respondJSON(array('success' => true, 'email' => $cart->email));
}
}
$this->respondJSON(array('success' => false, 'email' => false));
}
/**
* @param $email
*
* @return bool
* @throws MailChimp_WooCommerce_Error
* @throws MailChimp_WooCommerce_RateLimitError
* @throws MailChimp_WooCommerce_ServerError
*/
public function set_user_from_block_checkout($email)
{
if (!mailchimp_allowed_to_use_cookie('mailchimp_user_email')) {
return false;
}
if (!empty($email)) {
$cookie_duration = $this->getCookieDuration();
$this->user_email = trim(str_replace(' ','+', $email));
if (($current_email = $this->getEmailFromSession()) && $current_email !== $this->user_email) {
$this->previous_email = $current_email;
$this->force_cart_post = true;
mailchimp_set_cookie('mailchimp_user_previous_email',$this->user_email, $cookie_duration, '/' );
}
mailchimp_set_cookie('mailchimp_user_email', $this->user_email, $cookie_duration, '/' );
$this->getCartItems();
// if (isset($_GET['mc_language'])) {
// $this->user_language = $_GET['mc_language'];
// }
$this->handleCartUpdated();
return true;
}
return false;
}
/**
* @throws MailChimp_WooCommerce_Error
* @throws MailChimp_WooCommerce_RateLimitError
* @throws MailChimp_WooCommerce_ServerError
*/
public function set_user_by_email()
{
if (mailchimp_carts_disabled()) {
$this->respondJSON(array('success' => false, 'message' => 'filter blocked due to carts being disabled'));
}
if ($this->is_admin) {
$this->respondJSON(array('success' => false, 'message' => 'admin carts are not tracked.'));
}
if (!mailchimp_allowed_to_use_cookie('mailchimp_user_email')) {
$this->respondJSON(array('success' => false, 'email' => false, 'message' => 'filter blocked due to cookie preferences'));
}
if ($this->doingAjax() && isset($_GET['email'])) {
$cookie_duration = $this->getCookieDuration();
$this->user_email = trim(str_replace(' ','+', $_GET['email']));
if (($current_email = $this->getEmailFromSession()) && $current_email !== $this->user_email) {
$this->previous_email = $current_email;
$this->force_cart_post = true;
mailchimp_set_cookie('mailchimp_user_previous_email',$this->user_email, $cookie_duration, '/' );
}
mailchimp_set_cookie('mailchimp_user_email', $this->user_email, $cookie_duration, '/' );
$this->getCartItems();
if (isset($_GET['mc_language'])) {
$this->user_language = $_GET['mc_language'];
}
if (isset($_GET['subscribed'])) {
$this->cart_subscribe = (bool) $_GET['subscribed'];
}
$this->handleCartUpdated();
$this->respondJSON(array(
'success' => true,
'email' => $this->user_email,
'previous' => $this->previous_email,
'cart' => $this->cart,
));
}
$this->respondJSON(array('success' => false, 'email' => false));
}
/**
* @param string $time
* @return int
*/
protected function getCookieDuration($time = 'thirty_days')
{
$durations = array(
'one_day' => 86400, 'seven_days' => 604800, 'fourteen_days' => 1209600, 'thirty_days' => 2419200,
);
if (!array_key_exists($time, $durations)) {
$time = 'thirty_days';
}
return time() + $durations[$time];
}
/**
* @param $key
* @param bool $default
* @return bool
*/
protected function get($key, $default = false)
{
if (!isset($_REQUEST['mailchimp-woocommerce']) || !isset($_REQUEST['mailchimp-woocommerce'][$key])) {
return $default;
}
return $_REQUEST['mailchimp-woocommerce'][$key];
}
/**
* @param $uid
* @return array|bool|null|object|void
*/
protected function getCart($uid)
{
if (!$this->validated_cart_db) return false;
global $wpdb;
$table = "{$wpdb->prefix}mailchimp_carts";
$statement = "SELECT * FROM $table WHERE id = %s";
$sql = $wpdb->prepare($statement, $uid);
if (($saved_cart = $wpdb->get_row($sql)) && !empty($saved_cart)) {
return $saved_cart;
}
return false;
}
/**
* @param $uid
*
* @return bool
*/
protected function deleteCart($uid)
{
if (!$this->validated_cart_db) return false;
global $wpdb;
$table = "{$wpdb->prefix}mailchimp_carts";
$sql = $wpdb->prepare("DELETE FROM $table WHERE id = %s", $uid);
$wpdb->query($sql);
return true;
}
/**
* @param $uid
* @param $email
* @return bool
*/
protected function trackCart($uid, $email)
{
if (!$this->validated_cart_db) return false;
$hash = md5(strtolower($email));
$transient_key = "mailchimp-woocommerce-cart-{$hash}";
// let's set a transient here to block dup inserts
if (get_site_transient($transient_key)) {
return false;
}
// insert the transient
set_site_transient($transient_key, true, 5);
global $wpdb;
// Some people don't want to see these logs when they're in debug mode
$wpdb->suppress_errors();
$table = "{$wpdb->prefix}mailchimp_carts";
$statement = "SELECT * FROM $table WHERE id = %s";
$sql = $wpdb->prepare($statement, $uid);
$user_id = get_current_user_id();
if (($saved_cart = $wpdb->get_row($sql)) && is_object($saved_cart)) {
$statement = "UPDATE {$table} SET `cart` = '%s', `email` = '%s', `user_id` = %s WHERE `id` = '%s'";
$sql = $wpdb->prepare($statement, array(maybe_serialize($this->cart), $email, $user_id, $uid));
try {
$wpdb->query($sql);
delete_site_transient($transient_key);
} catch (Exception $e) {
return false;
}
} else {
try {
$wpdb->insert("{$wpdb->prefix}mailchimp_carts", array(
'id' => $uid,
'email' => $email,
'user_id' => (int) $user_id,
'cart' => maybe_serialize($this->cart),
'created_at' => gmdate('Y-m-d H:i:s', time()),
));
delete_site_transient($transient_key);
} catch (Exception $e) {
return false;
}
}
return true;
}
/**
* @param $data
*/
protected function respondJSON($data)
{
header('Content-Type: application/json');
echo json_encode($data);
exit;
}
/**
* @param null $obj_id
* @return bool
*/
public function mailchimp_process_single_job($obj_id = null) {
try {
// not sure why this is happening - but we need to prepare for it and return false when it does.
if (empty($obj_id)) {
return false;
}
// get job row from db
global $wpdb;
$sql = $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}mailchimp_jobs WHERE obj_id = %s", $obj_id );
$job_row = $wpdb->get_row( $sql );
if (is_null($job_row) || !is_object($job_row)) {
mailchimp_error('action_scheduler.process_job.fail','Job '.current_action().' not found at '.$wpdb->prefix.'_mailchimp_jobs database table :: obj_id '.$obj_id);
return false;
}
// get variables
$job = unserialize($job_row->job);
$job_id =$job_row->id;
// process job
$job->handle();
// delete processed job
$sql = $wpdb->prepare("DELETE FROM {$wpdb->prefix}mailchimp_jobs WHERE id = %s AND obj_id = %s", array($job_id, $obj_id));
$wpdb->query($sql);
return true;
} catch (Exception $e) {
$message = !empty($e->getMessage()) ? ' - ' . $e->getMessage() :'';
mailchimp_debug('action_scheduler.process_job.fail', (isset($job) ? get_class($job) : '') . ' :: obj_id '.$obj_id . ' :: ' .get_class($e) . $message);
}
return false;
}
/**
* @throws MailChimp_WooCommerce_Error
* @throws MailChimp_WooCommerce_RateLimitError
* @throws MailChimp_WooCommerce_ServerError
*/
public function mailchimp_process_sync_manager()
{
$sync_stats_manager = new MailChimp_WooCommerce_Process_Full_Sync_Manager();
$sync_stats_manager->handle();
}
/**
* Display the Mailchimp checkbox on the admin page
* @param $user
*/
public function user_subscribed_profile( $user )
{
$admin = MailChimp_WooCommerce_Admin::instance();
$admin->display_user_profile_info( $user );
}
/**
* Update the user meta from the admin page
* @param $user_id
*/
public function user_update_subscribe_status( $user_id )
{
$subscribed = isset($_POST['mailchimp_woocommerce_is_subscribed_checkbox']) &&
$_POST['mailchimp_woocommerce_is_subscribed_checkbox'] == 'on';
$gdpr_fields = isset($_POST['mailchimp_woocommerce_gdpr']) ? $_POST['mailchimp_woocommerce_gdpr'] : null;
// set a site transient that will prevent overlapping updates from refreshing the page on the admin user view
mailchimp_set_transient("updating_subscriber_status.{$user_id}", true, 300);
mailchimp_log("profile", 'user_update_subscribe_status', array(
'subscribed' => $subscribed,
'user_id' => $user_id,
'gdpr_fields' => $gdpr_fields,
));
$user = get_user_by('id', $user_id);
if ( $user && $user->user_email ) {
$email_hash = md5( strtolower( trim( $user->user_email ) ) );
$list_id = mailchimp_get_list_id();
$transient = "mailchimp-woocommerce-subscribed.{$list_id}.{$email_hash}";
delete_site_transient( $transient );
}
update_user_meta($user_id, 'mailchimp_woocommerce_is_subscribed', $subscribed);
update_user_meta($user_id, 'mailchimp_woocommerce_gdpr_fields', $gdpr_fields);
mailchimp_set_transient("mailchimp_woocommerce_gdpr_fields_{$user_id}", $gdpr_fields, 300);
}
}