Commit inicial - WordPress Análisis de Precios Unitarios

- WordPress core y plugins
- Tema Twenty Twenty-Four configurado
- Plugin allow-unfiltered-html.php simplificado
- .gitignore configurado para excluir wp-config.php y uploads

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
root
2025-11-03 21:04:30 -06:00
commit a22573bf0b
24068 changed files with 4993111 additions and 0 deletions

View File

@@ -0,0 +1,134 @@
<?php
/**
* Contact Controller Class
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'BWF_Contacts' ) ) {
/**
* Class BWF_Contacts
*
*/
#[AllowDynamicProperties]
class BWF_Contacts {
/**
* @var static instance
*/
private static $ins;
/**
* public db_operations $db_operations
*/
public $db_operations;
public $child_entities;
public $cached_contact_obj;
/**
* Get the contact details for the email passed if this uid exits other create a new contact with this email
*
* @param $email
*/
public function __construct() {
$this->db_operations = WooFunnels_DB_Operations::get_instance();
$this->get_registerd_child_entities();
$this->cached_contact_obj = [
'cid' => [],
'uid' => [],
'email' => [],
'wp_id' => [],
'phone' => [],
];
}
/**
* @return mixed|void
*/
public static function get_registerd_child_entities() {
$entities = apply_filters( 'bwf_child_entities', array( 'customer' => 'WooFunnels_Customer' ) );
return $entities;
}
/**
* @return BWF_Contacts
*/
public static function get_instance() {
if ( null === self::$ins ) {
self::$ins = new self;
}
return self::$ins;
}
/**
* Get contacts based on different criteria
*/
public function get_contacts( $args = array() ) {
$default_args = array(
'min_creation_date' => '',
'max_creation_date' => '',
);
$args = wp_parse_args( $args, $default_args );
if ( ! empty( $args['min_creation_date'] ) ) {
$args['min_creation_date'] = strtotime( 'midnight', strtotime( sanitize_text_field( $args['min_creation_date'] ) ) );
}
if ( ! empty( $args['max_creation_date'] ) ) {
$args['max_creation_date'] = strtotime( 'midnight', strtotime( sanitize_text_field( $args['max_creation_date'] ) ) );
}
$customers = $this->db_operations->get_contacts( $args );
return $customers;
}
/**
* get contact by given field
*/
public function get_contact_by( $field, $value ) {
if ( 'id' === $field ) {
return new WooFunnels_Contact( '', '', '', $value );
}
if ( 'wpid' === $field ) {
return new WooFunnels_Contact( $value );
}
if ( 'email' === $field ) {
return new WooFunnels_Contact( '', $value );
}
if ( 'phone' === $field ) {
return new WooFunnels_Contact( '', '', $value );
}
if ( 'uid' === $field ) {
return new WooFunnels_Contact( '', '', '', '', $value );
}
}
/**
* Getting date range
*
* @param $range
*
*/
public function get_date_range( $range ) {
$result = array();
$result['start_date'] = max( strtotime( '-20 years' ), strtotime( sanitize_text_field( $range['start_date'] ) ) );
$result['end_date'] = strtotime( 'midnight', current_time( 'timestamp' ) );
if ( ! empty( $range['end_date'] ) ) {
$result['end_date'] = strtotime( 'midnight', strtotime( sanitize_text_field( $range['end_date'] ) ) );
}
return $result;
}
}
}

View File

@@ -0,0 +1,114 @@
<?php
/**
* Customer Controller Class
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'BWF_Customers' ) ) {
/**
* Class BWF_Customers
*/
#[AllowDynamicProperties]
class BWF_Customers {
/**
* public db_operations $db_operations
*/
public $db_operations;
/**
* Get the customer details for the email passed if this email exits other create a new customer with this email
* BWF_Customers constructor.
*/
public function __construct() {
$this->db_operations = WooFunnels_DB_Operations::get_instance();
}
/**
* Get customers based on different criteria
*
* @param array $args
*
* @return array|object|null
*/
public function get_customers( $args = array() ) {
$default_args = array(
'min_order_count' => 0,
'max_order_count' => 999999,
'min_order_value' => 0,
'max_order_value' => 999999999,
'customer_limit' => - 1,
'min_last_order_date' => '',
'max_last_order_date' => '',
'min_creation_date' => '',
'max_creation_date' => '',
);
$args = wp_parse_args( $args, $default_args );
if ( ! empty( $args['min_last_order_date'] ) ) {
$args['min_last_order_date'] = strtotime( 'midnight', strtotime( sanitize_text_field( $args['min_last_order_date'] ) ) );
}
if ( ! empty( $args['max_last_order_date'] ) ) {
$args['max_last_order_date'] = strtotime( 'midnight', strtotime( sanitize_text_field( $args['max_last_order_date'] ) ) );
}
if ( ! empty( $args['min_creation_date'] ) ) {
$args['min_creation_date'] = strtotime( 'midnight', strtotime( sanitize_text_field( $args['min_creation_date'] ) ) );
}
if ( ! empty( $args['max_creation_date'] ) ) {
$args['max_creation_date'] = strtotime( 'midnight', strtotime( sanitize_text_field( $args['max_creation_date'] ) ) );
}
$customers = $this->db_operations->get_customers( $args );
return $customers;
}
/**
* Get customer by given field
*
* @param $field
* @param $value
*
* @return WooFunnels_Customer
*/
public function get_customer_by( $field, $value ) {
$customer = new stdClass();
if ( 'id' === $field ) {
$customer = $this->db_operations->get_customer_by_customer_id( $value );
}
if ( 'cid' === $field ) {
$customer = $this->db_operations->get_customer_by_cid( $value );
}
$cid = $customer->cid;
return bwf_get_customer( $cid );
}
/**
* Getting date range
*
* @param $range
*
* @return array
*/
public function get_date_range( $range ) {
$result = array();
$result['start_date'] = max( strtotime( '-20 years' ), strtotime( sanitize_text_field( $range['start_date'] ) ) );
$result['end_date'] = strtotime( 'midnight', current_time( 'timestamp' ) );
if ( ! empty( $range['end_date'] ) ) {
$result['end_date'] = strtotime( 'midnight', strtotime( sanitize_text_field( $range['end_date'] ) ) );
}
return $result;
}
}
}

View File

@@ -0,0 +1,426 @@
<?php
/**
* Background Updater
*
* @version 1.7.4
*/
defined( 'ABSPATH' ) || exit;
if ( ! class_exists( 'WP_Async_Request', false ) ) {
include_once dirname( dirname( __FILE__ ) ) . '/libraries/wp-async-request.php';
}
if ( ! class_exists( 'WP_Background_Process', false ) ) {
include_once dirname( dirname( __FILE__ ) ) . '/libraries/wp-background-process.php';
}
if ( ! class_exists( 'WooFunnels_Background_Updater' ) ) {
/**
* WooFunnels_Background_Updater Class.
* Based on WC_Background_Updater concept
*/
#[AllowDynamicProperties]
class WooFunnels_Background_Updater extends WP_Background_Process {
const MAX_SAME_OFFSET_THRESHOLD = 5;
protected $prefix = 'bwf_1';
protected $action = 'updater';
/**
* Initiate new background process.
*
* WooFunnels_Background_Updater constructor.
*/
public function __construct() {
parent::__construct();
}
/**
* Schedule cron healthcheck.
*
* @param array $schedules Schedules.
*
* @return array
*/
public function schedule_cron_healthcheck( $schedules ) {
$interval = apply_filters( $this->identifier . '_cron_interval', 5 );
if ( property_exists( $this, 'cron_interval' ) ) {
$interval = apply_filters( $this->identifier . '_cron_interval', $this->cron_interval );
}
// Adds every 5 minutes to the existing schedules.
$schedules[ $this->identifier . '_cron_interval' ] = array(
'interval' => MINUTE_IN_SECONDS * $interval,
/* translators: %d: interval */
'display' => sprintf( __( 'Every %d minutes', 'woocommerce' ), $interval ), // phpcs:ignore WordPress.WP.I18n.TextDomainMismatch
);
return $schedules;
}
/**
* Handle cron healthcheck
*
* Restart the background process if not already running
* and data exists in the queue.
*/
public function handle_cron_healthcheck() {
if ( $this->is_process_running() ) {
// Background process already running.
return;
}
if ( $this->is_queue_empty() ) {
// No data to process.
$this->clear_scheduled_event();
BWF_Logger::get_instance()->log( 'Scheduled event cleared as queue is empty.', 'woofunnels_indexing' );
return;
}
/**
* We are saving the last 5 offset value, due to any specific reason if last 5 offsets are same then it might be the time to kill the process.
*/
$offsets = $this->get_last_offsets();
if ( self::MAX_SAME_OFFSET_THRESHOLD === count( $offsets ) ) {
$unique = array_unique( $offsets );
if ( 1 === count( $unique ) ) {
$this->kill_process();
BWF_Logger::get_instance()->log( sprintf( 'Offset is stuck from last %d cron jobs, terminating the process.', self::MAX_SAME_OFFSET_THRESHOLD ), 'woofunnels_indexing' );
return;
}
}
$this->manage_last_offsets();
BWF_Logger::get_instance()->log( 'Cron started again!!', 'woofunnels_indexing' );
/**
* Everything looks good, lets roll the indexing
*/
$this->handle();
}
/**
* Overriding parent protected function publically to use outside this class
* @return bool
*/
public function is_process_running() {
return parent::is_process_running();
}
/**
* Is queue empty.
*
* @return bool
*/
protected function is_queue_empty() {
global $wpdb;
$table = $wpdb->options;
$column = 'option_name';
if ( is_multisite() ) {
$table = $wpdb->sitemeta;
$column = 'meta_key';
}
$key = $wpdb->esc_like( $this->identifier . '_batch_' ) . '%';
$count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$table} WHERE {$column} LIKE %s", $key ) ); // @codingStandardsIgnoreLine.
return ! ( $count > 0 );
}
public function get_last_offsets() {
return get_option( '_bwf_last_offsets', array() );
}
/**
* Kill process.
*
* Stop processing queue items, clear cronjob and delete all batches.
*/
public function kill_process() {
$this->kill_process_safe();
WooFunnels_Dashboard::$classes['WooFunnels_DB_Updater']->set_upgrade_state( '1' );
}
public function kill_process_safe() {
if ( ! $this->is_queue_empty() ) {
$this->delete_all_batches();
wp_clear_scheduled_hook( $this->cron_hook_identifier );
}
}
/**
* Delete all batches.
*
* @return WooFunnels_Background_Updater
*/
public function delete_all_batches() {
global $wpdb;
$table = $wpdb->options;
$column = 'option_name';
if ( is_multisite() ) {
$table = $wpdb->sitemeta;
$column = 'meta_key';
}
$key = $wpdb->esc_like( $this->identifier . '_batch_' ) . '%';
$wpdb->query( $wpdb->prepare( "DELETE FROM {$table} WHERE {$column} LIKE %s", $key ) ); // @codingStandardsIgnoreLine.
return $this;
}
/**
* Manage last 5 offsets
*/
public function manage_last_offsets() {
$offsets = $this->get_last_offsets();
$current_offset = get_option( '_bwf_offset', 0 );
if ( self::MAX_SAME_OFFSET_THRESHOLD === count( $offsets ) ) {
$offsets = array_map( function ( $key ) use ( $offsets ) {
return isset( $offsets[ $key + 1 ] ) ? $offsets[ $key + 1 ] : 0;
}, array_keys( $offsets ) );
$offsets[ self::MAX_SAME_OFFSET_THRESHOLD - 1 ] = $current_offset;
} else {
$offsets[ count( $offsets ) ] = $current_offset;
}
$this->update_last_offsets( $offsets );
}
public function update_last_offsets( $offsets ) {
update_option( '_bwf_last_offsets', $offsets );
}
/**
* Handle.
*
* Pass each queue item to the task handler, while remaining
* within server memory and time limit constraints.
*/
protected function handle() {
$this->lock_process();
do {
$batch = $this->get_batch();
foreach ( $batch->data as $key => $value ) {
$task = $this->task( $value );
if ( false !== $task ) {
$batch->data[ $key ] = $task;
} else {
unset( $batch->data[ $key ] );
}
if ( $this->batch_limit_exceeded() ) {
// Batch limits reached.
break;
}
}
// Update or delete current batch.
if ( ! empty( $batch->data ) ) {
$this->update( $batch->key, $batch->data );
} else {
$this->delete( $batch->key );
}
} while ( ! $this->batch_limit_exceeded() && ! $this->is_queue_empty() );
$this->unlock_process();
// Start next batch or complete process.
if ( ! $this->is_queue_empty() ) {
$this->dispatch();
} else {
$this->complete();
}
}
/**
* Get batch.
*
* @return stdClass Return the first batch from the queue.
*/
protected function get_batch() {
global $wpdb;
$table = $wpdb->options;
$column = 'option_name';
$key_column = 'option_id';
$value_column = 'option_value';
if ( is_multisite() ) {
$table = $wpdb->sitemeta;
$column = 'meta_key';
$key_column = 'meta_id';
$value_column = 'meta_value';
}
$key = $wpdb->esc_like( $this->identifier . '_batch_' ) . '%';
$query = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$table} WHERE {$column} LIKE %s ORDER BY {$key_column} ASC LIMIT 1", $key ) ); // @codingStandardsIgnoreLine.
$batch = new stdClass();
$batch->key = $query->$column;
$batch->data = array_filter( (array) maybe_unserialize( $query->$value_column ) );
return $batch;
}
/**
* Task
*
* Override this method to perform any actions required on each
* queue item. Return the modified item for further processing
* in the next pass through. Or, return false to remove the
* item from the queue.
*
* @param string $callback Update callback function.
*
* @return string|bool
* @SuppressWarnings(PHPMD.DevelopmentCodeFragment)
* @SuppressWarnings(PHPMD.ElseExpression)
*/
protected function task( $callback ) {
$result = false;
if ( is_callable( $callback ) ) {
BWF_Logger::get_instance()->log( 'Running the callback: ' . print_r( $callback, true ), 'woofunnels_indexing' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
$result = (bool) call_user_func( $callback );
if ( $result ) {
/**sleep( 5 );*/
BWF_Logger::get_instance()->log( "Result: $result Need to run again the callback: " . print_r( $callback, true ), 'woofunnels_indexing' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
} else {
BWF_Logger::get_instance()->log( "Result: $result Finished running the callback: " . print_r( $callback, true ), 'woofunnels_indexing' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
}
} else {
BWF_Logger::get_instance()->log( "Result: $result Could not find the callback: " . print_r( $callback, true ), 'woofunnels_indexing' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
}
return $result ? $callback : false;
}
/**
* See if the batch limit has been exceeded.
*
* @return bool
*/
protected function batch_limit_exceeded() {
return $this->time_exceeded() || $this->memory_exceeded();
}
/**
* Memory exceeded
*
* Ensures the batch process never exceeds 90%
* of the maximum WordPress memory.
*
* @return bool
*/
protected function memory_exceeded() {
$memory_limit = $this->get_memory_limit() * 0.9; // 90% of max memory
$current_memory = memory_get_usage( true );
$return = false;
if ( $current_memory >= $memory_limit ) {
$return = true;
}
return apply_filters( $this->identifier . '_memory_exceeded', $return );
}
/**
* Get memory limit.
*
* @return int
*/
protected function get_memory_limit() {
if ( function_exists( 'ini_get' ) ) {
$memory_limit = ini_get( 'memory_limit' );
} else {
// Sensible default.
$memory_limit = '128M';
}
if ( ! $memory_limit || - 1 === intval( $memory_limit ) ) {
// Unlimited, set to 32GB.
$memory_limit = '32G';
}
return wp_convert_hr_to_bytes( $memory_limit );
}
/**
* Complete
*
* Override if applicable, but ensure that the below actions are
* performed, or, call parent::complete().
*/
protected function complete() {
update_option( '_bwf_offset', 0 );
BWF_Logger::get_instance()->log( 'Background scanning completed for indexing order and creating updating contacts and customers.', 'woofunnels_indexing' );
do_action( 'bwf_order_index_completed' );
parent::complete();
}
/**
* Is the updater running?
*
* @return boolean
*/
public function is_updating() {
return false === $this->is_queue_empty();
}
public function maybe_re_dispatch_background_process() {
if ( 3 !== absint( WooFunnels_Dashboard::$classes['WooFunnels_DB_Updater']->get_upgrade_state() ) ) {
return;
}
if ( $this->is_queue_empty() ) {
return;
}
if ( $this->is_process_running() ) {
return;
}
/**
* We are saving the last 5 offset value, due to any specific reason if last 5 offsets are same then it might be the time to kill the process.
*/
$offsets = $this->get_last_offsets();
if ( self::MAX_SAME_OFFSET_THRESHOLD === count( $offsets ) ) {
$unique = array_unique( $offsets );
if ( 1 === count( $unique ) ) {
$this->kill_process();
BWF_Logger::get_instance()->log( sprintf( 'Offset is stuck from last %d attempts, terminating the process.', self::MAX_SAME_OFFSET_THRESHOLD ), 'woofunnels_indexing' );
return;
}
}
$this->manage_last_offsets();
$this->dispatch();
}
/**
* Schedule fallback event.
*/
protected function schedule_event() {
if ( ! wp_next_scheduled( $this->cron_hook_identifier ) ) {
wp_schedule_event( time() + 10, $this->cron_interval_identifier, $this->cron_hook_identifier );
}
}
}
}

View File

@@ -0,0 +1,971 @@
<?php
/**
* Contact Class
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'WooFunnels_Contact' ) ) {
/**
* Class WooFunnels_Contact
*
*
*/
#[AllowDynamicProperties]
class WooFunnels_Contact {
/**
* @var WooFunnels_DB_Operations
*/
public $db_operations;
/**
* public id $id
*/
public $id;
/**
* public ud $uid
*/
public $uid;
/**
* public email $email
*/
public $email;
/**
* public wp_id $wp_id
*/
public $wp_id;
/**
* public meta $meta
*/
public $meta;
/**
* public customer $customer
*/
public $children;
/**
* @var mixed $db_contact
*/
public $db_contact;
/**
* @var bool $blank_values_update
*/
public $blank_values_update = false;
public $is_subscribed = false;
/**
* Get the contact details for the email passed if this email exits other create a new contact with this email
*
* @param string|int $wp_id WordPress User ID
* @param string $email email
* @param string $phone contact number
* @param string|int $cid contact id,
* @param string $uid Unique ID
*/
public function __construct( $wp_id = '', $email = '', $phone = '', $cid = '', $uid = '' ) {
/** Set blank properties */
$this->set_blank_props();
$this->email = $email;
$this->wp_id = $wp_id;
/** If CID given */
if ( ! empty( $cid ) && absint( $cid ) > 0 ) {
$this->db_contact = $this->get_contact_by_id( absint( $cid ) );
$db_obj = $this->validate_and_set_obj( $this->db_contact );
if ( false !== $db_obj ) {
return;
}
}
/** If WP ID given */
if ( ! empty( $wp_id ) && absint( $wp_id ) > 0 ) {
$this->db_contact = $this->get_contact_by_wpid( absint( $wp_id ) );
$db_obj = $this->validate_and_set_obj( $this->db_contact );
if ( false !== $db_obj ) {
return;
}
}
/** If EMAIL given */
if ( ! empty( $email ) && is_email( $email ) ) {
$this->db_contact = $this->get_contact_by_email( trim( $email ) );
$db_obj = $this->validate_and_set_obj( $this->db_contact );
if ( false !== $db_obj ) {
return;
}
}
/** If PHONE given */
if ( ! empty( $phone ) ) {
$this->db_contact = $this->get_contact_by_phone( trim( $phone ) );
$db_obj = $this->validate_and_set_obj( $this->db_contact );
if ( false !== $db_obj ) {
return;
}
}
/** If UID given */
if ( ! empty( $uid ) ) {
$this->db_contact = $this->get_contact_by_uid( trim( $uid ) );
$this->validate_and_set_obj( $this->db_contact );
}
}
public function set_blank_props() {
$this->db_operations = WooFunnels_DB_Operations::get_instance();
if ( ! isset( $this->children ) ) {
$this->children = new stdClass();
}
if ( ! isset( $this->meta ) ) {
$this->meta = new stdClass();
}
$this->db_contact = new stdClass();
}
/**
* Get contact by id i.e. cid
*
* @param $cid
*
* @return mixed
*/
public function get_contact_by_id( $cid ) {
$cached_obj = $this->get_cache_obj( 'cid', $cid );
if ( false !== $cached_obj ) {
return $cached_obj;
}
$output = $this->db_operations->get_contact_by_contact_id( $cid );
$this->set_cache_object( 'cid', $cid, $output );
return $output;
}
/**
* Get contact cache object
*
* @param $type
* @param $value
*
* @return false|mixed
*/
public function get_cache_obj( $type, $value ) {
$obj = BWF_Contacts::get_instance();
$value = sanitize_key( $value );
if ( isset( $obj->cached_contact_obj[ $type ] ) && isset( $obj->cached_contact_obj[ $type ][ $value ] ) ) {
return $obj->cached_contact_obj[ $type ][ $value ];
}
return false;
}
/**
* Set contact cache object
*
* @param $type
* @param $value
* @param $output
*/
public function set_cache_object( $type, $value, $output ) {
$obj = BWF_Contacts::get_instance();
$value = sanitize_key( $value );
if ( ! isset( $obj->cached_contact_obj[ $type ] ) ) {
$obj->cached_contact_obj[ $type ] = [];
}
$obj->cached_contact_obj[ $type ][ $value ] = $output;
}
public function validate_and_set_obj( $obj ) {
if ( ! is_object( $obj ) || ! isset( $obj->id ) ) {
return false;
}
$this->id = $obj->id;
$this->email = $this->db_contact->email;
$this->wp_id = $this->db_contact->wpid;
$this->set_obj_meta();
return true;
}
public function set_obj_meta() {
if ( ! isset( $this->id ) || empty( $this->id ) ) {
return;
}
$contact_meta = $this->db_operations->get_contact_metadata( $this->id );
foreach ( is_array( $contact_meta ) ? $contact_meta : array() as $meta ) {
$this->meta->{$meta->meta_key} = maybe_unserialize( $meta->meta_value );
}
}
/**
* Get contact by wp_id
*
* @param $wp_id
*
* @return mixed
*/
public function get_contact_by_wpid( $wp_id ) {
$cached_obj = $this->get_cache_obj( 'wp_id', $wp_id );
if ( false !== $cached_obj ) {
return $cached_obj;
}
$output = $this->db_operations->get_contact_by_wpid( $wp_id );
$this->set_cache_object( 'wp_id', $wp_id, $output );
return $output;
}
/**
* Get contact by email
*
* @param $email
*
* @return mixed
*/
public function get_contact_by_email( $email ) {
$cached_obj = $this->get_cache_obj( 'email', $email );
if ( false !== $cached_obj ) {
return $cached_obj;
}
$output = $this->db_operations->get_contact_by_email( $email );
$this->set_cache_object( 'email', $email, $output );
return $output;
}
/**
* Get contact by phone
*
* @param $phone
*
* @return mixed
*/
public function get_contact_by_phone( $phone ) {
$cached_obj = $this->get_cache_obj( 'phone', $phone );
if ( false !== $cached_obj ) {
return $cached_obj;
}
$output = $this->db_operations->get_contact_by_phone( $phone );
$this->set_cache_object( 'phone', $phone, $output );
return $output;
}
public function get_contact_by_uid( $uid ) {
$cached_obj = $this->get_cache_obj( 'uid', $uid );
if ( false !== $cached_obj ) {
return $cached_obj;
}
$output = $this->db_operations->get_contact( $uid );
$this->set_cache_object( 'uid', $uid, $output );
return $output;
}
/**
* Implementing magic function for calling other contact's actor(like customer) functions
*
* @param $name
* @param $args
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*
* @return mixed
*/
public function __call( $name, $args ) {
$keys_arr = explode( '_', $name );
$action = ( is_array( $keys_arr ) && count( $keys_arr ) > 0 ) ? $keys_arr[0] : '';
$child = ( is_array( $keys_arr ) && count( $keys_arr ) > 1 ) ? $keys_arr[1] : '';
$function = str_replace( $child . '_', '', $name );
$child_entities = BWF_Contacts::get_registerd_child_entities();
if ( 'set_child' === $function && ! isset( $this->children->{$child} ) ) {
if ( isset( $child_entities[ $child ] ) ) {
$object_child = $child_entities[ $child ];
$this->children->{$child} = new $object_child( $this );
}
} elseif ( isset( $this->children ) && ! empty( $this->children ) && ! empty( $child ) && isset( $this->children->{$child} ) && 'set_child' !== $function ) {
$result = '';
if ( is_array( $args ) && count( $args ) > 0 ) {
$result = $this->children->{$child}->{$function}( $args[0] );
}
if ( ! is_array( $args ) || ( is_array( $args ) && 0 === count( $args ) ) ) {
$result = $this->children->{$child}->{$function}();
}
if ( 'get' === $action ) {
return $result;
}
} elseif ( ! isset( $this->children->{$child} ) ) {
BWF_Logger::get_instance()->log( "Magic Function $name is not defined for child function: $function", 'woofunnels_indexing' );
}
}
/**
* Get marketing status
*/
public function get_marketing_status() {
return $this->get_status();
}
/**
* Get marketing status
*/
public function get_status() {
$status = ( isset( $this->status ) && '' !== $this->status ) ? $this->status : '';
$db_status = ( isset( $this->db_contact->status ) && '' !== $this->db_contact->status ) ? $this->db_contact->status : '';
return '' !== $status ? $status : $db_status;
}
/**
* Get meta value for a given meta key from current contact object
*
* @param string $meta_key meta key to get value against
* @param bool $is_primary_column_check whether to check primary properties or not
*
* @return mixed|string
*/
public function get_meta( $meta_key, $is_primary_column_check = true ) {
if ( $is_primary_column_check ) {
$primary_columns = $this->get_primary_properties();
if ( in_array( $meta_key, $primary_columns, true ) ) {
return call_user_func( array( $this, 'get_' . $meta_key ) );
}
}
if ( isset( $this->meta->{$meta_key} ) ) {
return maybe_unserialize( $this->meta->{$meta_key} );
}
return '';
}
/**
* @param $meta_key
* @param $meta_value
*/
public function set_meta( $meta_key, $meta_value ) {
$this->meta->{$meta_key} = $meta_value;
}
/**
* @param $meta_key
*/
public function unset_meta( $meta_key ) {
if ( isset( $this->meta ) && isset( $this->meta->{$meta_key} ) ) {
unset( $this->meta->{$meta_key} );
}
}
public function get_primary_properties() {
return array(
'id',
'email',
'wpid',
'uid',
'email',
'f_name',
'l_name',
'creation_date',
'contact_no',
'country',
'state',
'timezone',
'type',
'source',
'points',
'last_modified',
'status',
'tags',
'lists'
);
}
/**
* Set contact first name
*
* @param $f_name
*/
public function set_f_name( $f_name ) {
if ( true === $this->blank_values_update ) {
$this->f_name = $f_name;
if ( ! empty( $this->f_name ) ) {
$this->f_name = trim( $this->f_name );
}
return;
}
$this->f_name = empty( $f_name ) ? $this->get_f_name() : $f_name;
if ( ! empty( $this->f_name ) ) {
$this->f_name = trim( $this->f_name );
}
}
/**
* Get contact first name
*/
public function get_f_name() {
$f_name = ( isset( $this->f_name ) ) ? $this->f_name : null;
if ( ! empty( $f_name ) ) {
$f_name = trim( $f_name );
}
$db_f_name = ( isset( $this->db_contact->f_name ) ) ? $this->db_contact->f_name : '';
if ( ! empty( $db_f_name ) ) {
$db_f_name = trim( $db_f_name );
}
return is_null( $f_name ) ? $db_f_name : $f_name;
}
/**
* Set contact last name
*
* @param $l_name
*/
public function set_l_name( $l_name ) {
if ( true === $this->blank_values_update ) {
$this->l_name = $l_name;
if ( ! empty( $this->l_name ) ) {
$this->l_name = trim( $this->l_name );
}
return;
}
$this->l_name = empty( $l_name ) ? $this->get_l_name() : $l_name;
if ( ! empty( $this->l_name ) ) {
$this->l_name = trim( $this->l_name );
}
}
/**
* Get contact last name
*/
public function get_l_name() {
$l_name = ( isset( $this->l_name ) ) ? $this->l_name : null;
if ( ! empty( $l_name ) ) {
$l_name = trim( $l_name );
}
$db_l_name = ( isset( $this->db_contact->l_name ) ) ? $this->db_contact->l_name : '';
if ( ! empty( $db_l_name ) ) {
$db_l_name = trim( $db_l_name );
}
return is_null( $l_name ) ? $db_l_name : $l_name;
}
/**
* Set contact tags
*
* @param string[] $tags
*/
public function set_tags( $tags ) {
if ( ! is_array( $tags ) ) {
return;
}
$this->tags = wp_json_encode( array_map( 'strval', $tags ) );
}
/**
* Get contact tags
*/
public function get_tags() {
$tags = ( isset( $this->tags ) && ! empty( $this->tags ) ) ? json_decode( $this->tags, true ) : null;
$db_tags = ( isset( $this->db_contact->tags ) && ! empty( $this->db_contact->tags ) ) ? json_decode( $this->db_contact->tags, true ) : null;
$db_tags = ! is_array( $db_tags ) ? [] : $db_tags;
return ! is_array( $tags ) ? $db_tags : $tags;
}
/**
* Set contact lists
*
* @param string[] $lists
*/
public function set_lists( $lists ) {
if ( ! is_array( $lists ) ) {
return;
}
$this->lists = wp_json_encode( array_map( 'strval', $lists ) );
}
/**
* Get contact lists
*/
public function get_lists() {
$lists = ( isset( $this->lists ) && ! empty( $this->lists ) ) ? json_decode( $this->lists, true ) : null;
$db_lists = ( isset( $this->db_contact->lists ) && ! empty( $this->db_contact->lists ) ) ? json_decode( $this->db_contact->lists, true ) : null;
$db_lists = ! is_array( $db_lists ) ? [] : $db_lists;
return ! is_array( $lists ) ? $db_lists : $lists;
}
/**
* Set contact created date
*
* @param $date
*/
public function set_last_modified( $date ) {
$this->last_modified = empty( $date ) ? $this->get_last_modified() : $date;
}
/**
* Get contact fname
*/
public function get_last_modified() {
$last_mod = ( isset( $this->last_modified ) && ! empty( $this->last_modified ) ) ? $this->last_modified : '';
$db_last_modified = ( isset( $this->db_contact->last_modified ) && ! empty( $this->db_contact->last_modified ) ) ? $this->db_contact->last_modified : '';
return empty( $last_mod ) ? $db_last_modified : $last_mod;
}
/**
* Set contact created date
*
* @param $date
*/
public function set_creation_date( $date ) {
$this->creation_date = empty( $date ) ? $this->get_creation_date() : $date;
}
/**
* Get contact created date
*/
public function get_creation_date() {
$creation_date = ( isset( $this->creation_date ) && ! empty( $this->creation_date ) ) ? $this->creation_date : '';
$db_creation_date = ( isset( $this->db_contact->creation_date ) && ! empty( $this->db_contact->creation_date ) ) ? $this->db_contact->creation_date : current_time( 'mysql' );
return empty( $creation_date ) ? $db_creation_date : $creation_date;
}
public function set_type( $type ) {
$this->type = empty( $type ) ? $this->get_type() : $type;
}
/**
* Get type the contact belongs to
* @return string
*/
public function get_type() {
$type = ( isset( $this->type ) && ! empty( $this->type ) ) ? $this->type : '';
$db_type = ( isset( $this->db_contact->type ) && ! empty( $this->db_contact->type ) ) ? $this->db_contact->type : '';
return empty( $type ) ? $db_type : $type;
}
public function set_source( $source ) {
$this->source = empty( $source ) ? $this->get_source() : $source;
}
/**
* Get source the contact generated from
* @return string
*/
public function get_source() {
$source = ( isset( $this->source ) && ! empty( $this->source ) ) ? $this->source : '';
$db_source = ( isset( $this->db_contact->source ) && ! empty( $this->db_contact->source ) ) ? $this->db_contact->source : '';
return empty( $source ) ? $db_source : $source;
}
public function set_points( $points ) {
$this->points = empty( $points ) ? 0 : $points;
}
/**
* Get points the contact have
* @return integer
*/
public function get_points() {
return ( isset( $this->points ) && intval( $this->points ) > 0 ) ? intval( $this->points ) : 0;
}
/**
* Saves the data in the properties.
* This method is responsible for any db operation inside the contact table and sibling tables
* Updating contact table with set data
*
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.DevelopmentCodeFragment)
*
*/
public function save() {
$contact = array();
$get_primary_properties = $this->get_primary_properties();
foreach ( $get_primary_properties as $property ) {
$contact[ $property ] = call_user_func( array( $this, 'get_' . $property ) );
if ( 'tags' === $property || 'lists' === $property ) {
$contact[ $property ] = wp_json_encode( $contact[ $property ] );
}
}
$contact['last_modified'] = current_time( 'mysql' );
if ( $this->get_id() > 0 ) {
/** Existing contact */
$contact['id'] = $this->get_id();
/** Check if UID empty */
if ( empty( $this->get_uid() ) ) {
$contact['uid'] = md5( $this->email . $this->wp_id . time() );
$this->set_uid( $contact['uid'] );
}
$this->db_operations->update_contact( $contact );
} elseif ( empty( $this->get_id() ) ) {
$contact['uid'] = md5( $this->email . $this->wp_id . time() );
$contact['wpid'] = $this->get_wpid() > 0 ? $this->get_wpid() : 0;
$this->set_uid( $contact['uid'] );
$contact_id = $this->db_operations->insert_contact( $contact );
$this->id = $contact_id;
}
/** Run subscribe action */
if ( true === $this->is_subscribed ) {
do_action( 'bwfcrm_after_contact_subscribed', $this );
$this->is_subscribed = false;
}
/** Purge Cache */
$this->purge_contact_from_cache();
if ( isset( $this->children ) && ! empty( $this->children ) ) {
foreach ( $this->children as $child_actor ) {
$child_actor->set_cid( $this->get_id() );
$child_actor->save();
}
}
}
/**
* Get contact id
* @SuppressWarnings(PHPMD.ShortVariable)
*/
public function get_id() {
$id = ( isset( $this->id ) && $this->id > 0 ) ? $this->id : 0;
$db_id = ( isset( $this->db_contact->id ) && ( $this->db_contact->id > 0 ) ) ? $this->db_contact->id : 0;
return ( $id > 0 ) ? $id : $db_id;
}
/**
* Set contact id
*
* @param $id
*/
public function set_id( $id ) {
$this->id = empty( $id ) ? $this->get_id() : $id;
}
/**
* Get contact wp_id
*/
public function get_wpid() {
return ( isset( $this->wp_id ) && intval( $this->wp_id ) > 0 ) ? intval( $this->wp_id ) : 0;
}
/**
* Set contact wp id
*
* @param $wp_id
*/
public function set_wpid( $wp_id ) {
$this->wp_id = intval( $wp_id );
}
/**
* Purge contact sql object from cache
*/
public function purge_contact_from_cache() {
$obj = BWF_Contacts::get_instance();
$cid = sanitize_key( $this->get_id() );
$email = sanitize_key( $this->get_email() );
$phone = sanitize_key( $this->get_contact_no() );
$wp_id = sanitize_key( $this->get_wpid() );
$uid = sanitize_key( $this->get_uid() );
/** cid */
if ( isset( $obj->cached_contact_obj['cid'] ) && isset( $obj->cached_contact_obj['cid'][ $cid ] ) ) {
unset( $obj->cached_contact_obj['cid'][ $cid ] );
}
/** email */
if ( isset( $obj->cached_contact_obj['email'] ) && isset( $obj->cached_contact_obj['email'][ $email ] ) ) {
unset( $obj->cached_contact_obj['email'][ $email ] );
}
/** phone */
if ( isset( $obj->cached_contact_obj['phone'] ) && isset( $obj->cached_contact_obj['phone'][ $phone ] ) ) {
unset( $obj->cached_contact_obj['phone'][ $phone ] );
}
/** wp id */
if ( isset( $obj->cached_contact_obj['wp_id'] ) && isset( $obj->cached_contact_obj['wp_id'][ $wp_id ] ) ) {
unset( $obj->cached_contact_obj['wp_id'][ $wp_id ] );
}
/** uid */
if ( isset( $obj->cached_contact_obj['uid'] ) && isset( $obj->cached_contact_obj['uid'][ $uid ] ) ) {
unset( $obj->cached_contact_obj['uid'][ $uid ] );
}
}
/**
* Get contact email
*/
public function get_email() {
$email = ( isset( $this->email ) && ! empty( $this->email ) ) ? $this->email : '';
if ( ! empty( $email ) ) {
$email = trim( $email );
}
$db_email = ( isset( $this->db_contact->email ) && ! empty( $this->db_contact->email ) ) ? $this->db_contact->email : '';
if ( ! empty( $db_email ) ) {
$db_email = trim( $db_email );
}
return empty( $email ) ? $db_email : $email;
}
/**
* Set contact email
*
* @param $email
*/
public function set_email( $email ) {
$this->email = empty( $email ) ? $this->get_email() : $email;
if ( ! empty( $this->email ) ) {
$this->email = trim( $this->email );
}
}
public function get_contact_no() {
$contact_no = ( isset( $this->contact_no ) ) ? $this->contact_no : null;
$db_contact_no = ( isset( $this->db_contact->contact_no ) ) ? $this->db_contact->contact_no : '';
return is_null( $contact_no ) ? $db_contact_no : $contact_no;
}
/**
* Get contact uid
*/
public function get_uid() {
$uid = ( isset( $this->uid ) && ! empty( $this->uid ) ) ? $this->uid : '';
$db_uid = ( isset( $this->db_contact->uid ) && ! empty( $this->db_contact->uid ) ) ? $this->db_contact->uid : '';
return empty( $uid ) ? $db_uid : $uid;
}
/**
* Set contact uid
*
* @param $uid
*/
public function set_uid( $uid ) {
$this->uid = empty( $uid ) ? $this->get_uid() : $uid;
}
/**
* Get meta value for a given meta key from DB
*/
public function get_contact_meta( $meta_key ) {
return $this->db_operations->get_contact_meta_value( $this->get_id(), $meta_key );
}
/**
* Set meta value for a given meta key
*
* @param $meta_key
* @param $meta_value
*
* @return mixed
*/
public function update_meta( $meta_key, $meta_value ) {
return $this->db_operations->update_contact_meta( $this->get_id(), $meta_key, $meta_value );
}
/**
* Updating contact meta table with set data
*/
public function save_meta() {
$this->db_operations->save_contact_meta( $this->id, $this->meta );
$contact = [];
$contact['id'] = $this->get_id();
$contact['last_modified'] = current_time( 'mysql' );
$this->db_operations->update_contact( $contact );
}
/**
* Set marketing status
*
* @param $status
*/
public function set_marketing_status( $status ) {
$this->set_status( $status );
}
/**
* Set marketing status
*
* @param $status
*/
public function set_status( $status ) {
/** If cid 0 */
if ( 0 === absint( $this->get_id() ) ) {
/** New contact */
/** Check if status is subscribed */
if ( 1 === absint( $status ) ) {
/** run do action contact subscribed */
$this->is_subscribed = true;
}
} else {
$old_status = $this->get_status();
if ( 1 !== absint( $old_status ) && 1 === absint( $status ) ) {
/** run do action contact subscribed */
$this->is_subscribed = true;
}
}
$this->status = ( '' === $status ) ? $this->get_status() : $status;
}
/**
* Set contact country
*
* @param $country
*/
public function set_country( $country ) {
if ( true === $this->blank_values_update ) {
$this->country = $country;
return;
}
$this->country = empty( $country ) ? $this->get_country() : $country;
}
/**
* Get contact country
*/
public function get_country() {
$country = ( isset( $this->country ) ) ? $this->country : null;
$db_country = ( isset( $this->db_contact->country ) ) ? $this->db_contact->country : '';
return is_null( $country ) ? $db_country : $country;
}
/**
* Set contact timezone
*
* @param $timezone
*/
public function set_timezone( $timezone ) {
if ( true === $this->blank_values_update ) {
$this->timezone = $timezone;
return;
}
$this->timezone = empty( $timezone ) ? $this->get_timezone() : $timezone;
}
/**
* Get contact timezone
*
* @return string
*/
public function get_timezone() {
$timezone = ( isset( $this->timezone ) ) ? $this->timezone : null;
$db_timezone = ( isset( $this->db_contact->timezone ) ) ? $this->db_contact->timezone : '';
return is_null( $timezone ) ? $db_timezone : $timezone;
}
/**
* Set contact number
*
* @param $contact_no
*/
public function set_contact_no( $contact_no ) {
if ( true === $this->blank_values_update ) {
$this->contact_no = $contact_no;
return;
}
$this->contact_no = empty( $contact_no ) ? $this->get_contact_no() : $contact_no;
}
/**
* Set contact state
*
* @param $state
*/
public function set_state( $state ) {
if ( true === $this->blank_values_update ) {
$this->state = $state;
return;
}
$this->state = empty( $state ) ? $this->get_state() : $state;
}
/**
* Get contact state
*/
public function get_state() {
$state = ( isset( $this->state ) ) ? $this->state : null;
$db_state = ( isset( $this->db_contact->state ) ) ? $this->db_contact->state : '';
return is_null( $state ) ? $db_state : $state;
}
/**
* Deleting a meta key from contact meta table
*
* @param $meta_key
*/
public function delete_meta( $meta_key ) {
$this->db_operations->delete_contact_meta( $this->id, $meta_key );
}
}
}

View File

@@ -0,0 +1,428 @@
<?php
/**
* WooFunnels Contacts Background Updater
*
* @version 1.7.4
*/
defined( 'ABSPATH' ) || exit;
if ( ! class_exists( 'WP_Async_Request', false ) ) {
include_once dirname( dirname( __FILE__ ) ) . '/libraries/wp-async-request.php';
}
if ( ! class_exists( 'WP_Background_Process', false ) ) {
include_once dirname( dirname( __FILE__ ) ) . '/libraries/wp-background-process.php';
}
if ( ! class_exists( 'WooFunnels_Contacts_Background_Updater' ) ) {
/**
* WooFunnels_Background_Updater Class.
* Based on WC_Background_Updater concept
*/
#[AllowDynamicProperties]
class WooFunnels_Contacts_Background_Updater extends WP_Background_Process {
const MAX_SAME_OFFSET_THRESHOLD = 5;
/**
* Initiate new background process.
*
* WooFunnels_Background_Updater constructor.
*/
public function __construct() {
// Uses unique prefix per blog so each blog has separate queue.
$this->prefix = 'bwf_' . get_current_blog_id();
$this->action = 'contact_updater';
parent::__construct();
}
/**
* Schedule cron healthcheck.
*
* @param array $schedules Schedules.
*
* @return array
*/
public function schedule_cron_healthcheck( $schedules ) {
$interval = apply_filters( $this->identifier . '_cron_interval', 5 );
if ( property_exists( $this, 'cron_interval' ) ) {
$interval = apply_filters( $this->identifier . '_cron_interval', $this->cron_interval );
}
// Adds every 5 minutes to the existing schedules.
$schedules[ $this->identifier . '_cron_interval' ] = array(
'interval' => MINUTE_IN_SECONDS * $interval,
/* translators: %d: interval */
'display' => sprintf( __( 'Every %d minutes', 'woocommerce' ), $interval ), // phpcs:ignore WordPress.WP.I18n.TextDomainMismatch
);
return $schedules;
}
/**
* Handle cron healthcheck
*
* Restart the background process if not already running
* and data exists in the queue.
*/
public function handle_cron_healthcheck() {
if ( $this->is_process_running() ) {
// Background process already running.
return;
}
if ( $this->is_queue_empty() ) {
// No data to process.
$this->clear_scheduled_event();
BWF_Logger::get_instance()->log( 'Scheduled event cleared as queue is empty.', 'woofunnels_contacts_indexing' );
return;
}
/**
* We are saving the last 5 offset value, due to any specific reason if last 5 offsets are same then it might be the time to kill the process.
*/
$offsets = $this->get_last_offsets();
if ( self::MAX_SAME_OFFSET_THRESHOLD === count( $offsets ) ) {
$unique = array_unique( $offsets );
if ( 1 === count( $unique ) ) {
$this->kill_process();
BWF_Logger::get_instance()->log( sprintf( 'Offset is stuck from last %d cron jobs, terminating the process.', self::MAX_SAME_OFFSET_THRESHOLD ), 'woofunnels_contacts_indexing' );
return;
}
}
$this->manage_last_offsets();
BWF_Logger::get_instance()->log( 'Cron started again!!', 'woofunnels_contacts_indexing' );
/**
* Everything looks good, lets roll the indexing
*/
$this->handle();
}
/**
* Overriding parent protected function publically to use outside this class
* @return bool
*/
public function is_process_running() {
return parent::is_process_running();
}
/**
* Is queue empty.
*
* @return bool
*/
protected function is_queue_empty() {
global $wpdb;
$table = $wpdb->options;
$column = 'option_name';
if ( is_multisite() ) {
$table = $wpdb->sitemeta;
$column = 'meta_key';
}
$key = $wpdb->esc_like( $this->identifier . '_batch_' ) . '%';
$count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$table} WHERE {$column} LIKE %s", $key ) ); // @codingStandardsIgnoreLine.
return ! ( $count > 0 );
}
public function get_last_offsets() {
return get_option( '_bwf_contacts_last_offsets', array() );
}
/**
* Kill process.
*
* Stop processing queue items, clear cronjob and delete all batches.
*/
public function kill_process() {
$this->kill_process_safe();
WooFunnels_Dashboard::$classes['WooFunnels_DB_Updater']->set_upgrade_state( '1' );
}
public function kill_process_safe() {
if ( ! $this->is_queue_empty() ) {
$this->delete_all_batches();
wp_clear_scheduled_hook( $this->cron_hook_identifier );
}
}
/**
* Delete all batches.
*
* @return WooFunnels_Contacts_Background_Updater
*/
public function delete_all_batches() {
global $wpdb;
$table = $wpdb->options;
$column = 'option_name';
if ( is_multisite() ) {
$table = $wpdb->sitemeta;
$column = 'meta_key';
}
$key = $wpdb->esc_like( $this->identifier . '_batch_' ) . '%';
$wpdb->query( $wpdb->prepare( "DELETE FROM {$table} WHERE {$column} LIKE %s", $key ) ); // @codingStandardsIgnoreLine.
return $this;
}
/**
* Manage last 5 offsets
*/
public function manage_last_offsets() {
$offsets = $this->get_last_offsets();
$current_offset = get_option( '_bwf_contacts_offset', 0 );
if ( self::MAX_SAME_OFFSET_THRESHOLD === count( $offsets ) ) {
$offsets = array_map( function ( $key ) use ( $offsets ) {
return isset( $offsets[ $key + 1 ] ) ? $offsets[ $key + 1 ] : 0;
}, array_keys( $offsets ) );
$offsets[ self::MAX_SAME_OFFSET_THRESHOLD - 1 ] = $current_offset;
} else {
$offsets[ count( $offsets ) ] = $current_offset;
}
$this->update_last_offsets( $offsets );
}
public function update_last_offsets( $offsets ) {
update_option( '_bwf_contacts_last_offsets', $offsets );
}
/**
* Handle.
*
* Pass each queue item to the task handler, while remaining
* within server memory and time limit constraints.
*/
protected function handle() {
$this->lock_process();
do {
$batch = $this->get_batch();
foreach ( $batch->data as $key => $value ) {
$task = $this->task( $value );
if ( false !== $task ) {
$batch->data[ $key ] = $task;
} else {
unset( $batch->data[ $key ] );
}
if ( $this->batch_limit_exceeded() ) {
// Batch limits reached.
break;
}
}
// Update or delete current batch.
if ( ! empty( $batch->data ) ) {
$this->update( $batch->key, $batch->data );
} else {
$this->delete( $batch->key );
}
} while ( ! $this->batch_limit_exceeded() && ! $this->is_queue_empty() );
$this->unlock_process();
// Start next batch or complete process.
if ( ! $this->is_queue_empty() ) {
$this->dispatch();
} else {
$this->complete();
}
}
/**
* Get batch.
*
* @return stdClass Return the first batch from the queue.
*/
protected function get_batch() {
global $wpdb;
$table = $wpdb->options;
$column = 'option_name';
$key_column = 'option_id';
$value_column = 'option_value';
if ( is_multisite() ) {
$table = $wpdb->sitemeta;
$column = 'meta_key';
$key_column = 'meta_id';
$value_column = 'meta_value';
}
$key = $wpdb->esc_like( $this->identifier . '_batch_' ) . '%';
$query = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$table} WHERE {$column} LIKE %s ORDER BY {$key_column} ASC LIMIT 1", $key ) ); // @codingStandardsIgnoreLine.
$batch = new stdClass();
$batch->key = $query->$column;
$batch->data = array_filter( (array) maybe_unserialize( $query->$value_column ) );
return $batch;
}
/**
* Task
*
* Override this method to perform any actions required on each
* queue item. Return the modified item for further processing
* in the next pass through. Or, return false to remove the
* item from the queue.
*
* @param string $callback Update callback function.
*
* @return string|bool
* @SuppressWarnings(PHPMD.DevelopmentCodeFragment)
* @SuppressWarnings(PHPMD.ElseExpression)
*/
protected function task( $callback ) {
$result = false;
if ( is_callable( $callback ) ) {
BWF_Logger::get_instance()->log( 'Running the callback: ' . print_r( $callback, true ), 'woofunnels_contacts_indexing' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
$result = (bool) call_user_func( $callback );
if ( $result ) {
/**sleep( 5 );*/
BWF_Logger::get_instance()->log( "Result: $result Need to run again the callback: " . print_r( $callback, true ), 'woofunnels_contacts_indexing' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
} else {
BWF_Logger::get_instance()->log( "Result: $result Finished running the callback: " . print_r( $callback, true ), 'woofunnels_contacts_indexing' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
}
} else {
BWF_Logger::get_instance()->log( "Result: $result Could not find the callback: " . print_r( $callback, true ), 'woofunnels_contacts_indexing' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
}
return $result ? $callback : false;
}
/**
* See if the batch limit has been exceeded.
*
* @return bool
*/
protected function batch_limit_exceeded() {
return $this->time_exceeded() || $this->memory_exceeded();
}
/**
* Memory exceeded
*
* Ensures the batch process never exceeds 90%
* of the maximum WordPress memory.
*
* @return bool
*/
protected function memory_exceeded() {
$memory_limit = $this->get_memory_limit() * 0.9; // 90% of max memory
$current_memory = memory_get_usage( true );
$return = false;
if ( $current_memory >= $memory_limit ) {
$return = true;
}
return apply_filters( $this->identifier . '_memory_exceeded', $return );
}
/**
* Get memory limit.
*
* @return int
*/
protected function get_memory_limit() {
if ( function_exists( 'ini_get' ) ) {
$memory_limit = ini_get( 'memory_limit' );
} else {
// Sensible default.
$memory_limit = '128M';
}
if ( ! $memory_limit || - 1 === intval( $memory_limit ) ) {
// Unlimited, set to 32GB.
$memory_limit = '32G';
}
return wp_convert_hr_to_bytes( $memory_limit );
}
/**
* Complete
*
* Override if applicable, but ensure that the below actions are
* performed, or, call parent::complete().
*/
protected function complete() {
update_option( '_bwf_contacts_offset', 0 );
BWF_Logger::get_instance()->log( 'Background scanning completed for indexing contacts and creating updating contacts and customers.', 'woofunnels_contacts_indexing' );
delete_option( '_bwf_last_offsets' );
do_action( 'bwf_contacts_index_completed' );
parent::complete();
}
/**
* Is the updater running?
*
* @return boolean
*/
public function is_updating() {
return false === $this->is_queue_empty();
}
public function maybe_re_dispatch_background_process() {
if ( 3 !== absint( WooFunnels_Dashboard::$classes['WooFunnels_DB_Updater']->get_upgrade_state() ) ) {
return;
}
if ( $this->is_queue_empty() ) {
return;
}
if ( $this->is_process_running() ) {
return;
}
/**
* We are saving the last 5 offset value, due to any specific reason if last 5 offsets are same then it might be the time to kill the process.
*/
$offsets = $this->get_last_offsets();
if ( self::MAX_SAME_OFFSET_THRESHOLD === count( $offsets ) ) {
$unique = array_unique( $offsets );
if ( 1 === count( $unique ) ) {
$this->kill_process();
BWF_Logger::get_instance()->log( sprintf( 'Offset is stuck from last %d attempts, terminating the process.', self::MAX_SAME_OFFSET_THRESHOLD ), 'woofunnels_contacts_indexing' );
return;
}
}
$this->manage_last_offsets();
$this->dispatch();
}
/**
* Schedule fallback event.
*/
protected function schedule_event() {
if ( ! wp_next_scheduled( $this->cron_hook_identifier ) ) {
wp_schedule_event( time() + 10, $this->cron_interval_identifier, $this->cron_hook_identifier );
}
}
}
}

View File

@@ -0,0 +1,116 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class WooFunnels_Create_DB_Tables
*/
if ( ! class_exists( 'WooFunnels_Create_DB_Tables' ) ) {
#[AllowDynamicProperties]
class WooFunnels_Create_DB_Tables {
/**
* instance of class
* @var null
*/
private static $ins = null;
/**
* Charector collation
*
* @since 2.0
*
* @var string
*/
protected $charset_collate;
/**
* @var bool
*/
protected $last_created_table = array();
/**
* WooFunnels_DB_Tables constructor.
*/
public function __construct() {
global $wpdb;
if ( $wpdb->has_cap( 'collation' ) ) {
$this->charset_collate = $wpdb->get_charset_collate();
}
}
/**
* @return WooFunnels_Create_DB_Tables|null
*/
public static function get_instance() {
if ( null === self::$ins ) {
self::$ins = new self;
}
return self::$ins;
}
/**
* @hooked over `admin_head`
* This method create new tables in database except core table
*/
public function create() {
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
$current_table_list = get_option( '_bwf_db_table_list', array( 'tables' => array(), 'version' => '0.0.0' ) );
$tables = apply_filters( 'bwf_add_db_table_schema', array(), $current_table_list );
global $wpdb;
if ( is_array( $tables ) && count( $tables ) > 0 ) {
foreach ( $tables as $table ) {
$schema = $table['schema'];
$schema = str_replace( array( '{table_prefix}', '{table_collate}' ), array( $wpdb->prefix, $this->charset_collate ), $schema );
dbDelta( $schema );
/**
* Handle unique key error
* if table exists and try re-attempt to create table
*/
$table_name = $wpdb->prefix . $table['name'];
$esc_unique_key = "ALTER TABLE {$table_name} ADD UNIQUE KEY";
if ( ! empty( $wpdb->last_error ) && ( strpos( $wpdb->last_query, $esc_unique_key ) === false ) ) {
BWF_Logger::get_instance()->log( "bwf failed create table {$table['name']}: " . print_r( $wpdb->last_error, true ), 'woofunnel-failed-actions', 'buildwoofunnels', true ); //phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
} else {
$this->last_created_table[] = $table['name'];
$current_table_list['tables'][] = $table['name'];
}
}
$current_table_list['version'] = BWF_DB_VERSION;
if ( isset( $current_table_list['tables'] ) && is_array( $current_table_list['tables'] ) ) {
$current_table_list['tables'] = array_values( array_unique( $current_table_list['tables'] ) );
}
update_option( '_bwf_db_table_list', $current_table_list, true );
} else {
if ( isset( $current_table_list['tables'] ) && is_array( $current_table_list['tables'] ) ) {
/**
* Check if array of table has duplicate values
*/
$current = array_values( array_unique( $current_table_list['tables'] ) );
if ( sizeof( $current ) !== sizeof( $current_table_list['tables'] ) ) {
$current_table_list['tables'] = $current;
update_option( '_bwf_db_table_list', $current_table_list, true );
}
}
}
}
/**
* get tables list which is created in current version
* @return array|bool
*/
public function maybe_table_created_current_version() {
return $this->last_created_table;
}
}
}

View File

@@ -0,0 +1,400 @@
<?php
/**
* Customer Class
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'WooFunnels_Customer' ) ) {
/**
* Class WooFunnels_Customer
*/
#[AllowDynamicProperties]
class WooFunnels_Customer {
/**
* public db_operations $db_operations
*/
public $db_operations;
/**
* public id $id
*/
public $id;
/**
* public cid $cid
*/
public $cid;
/**
* public contact $contact
*/
public $contact;
/**
* @var $db_customer
*/
public $db_customer;
/**
* Get the customer details for the contact object passed if this contact id exits otherwise create a new customer
* WooFunnels_Customer constructor.
*
* @param $cid
*
*/
public function __construct( $contact ) {
$this->db_operations = WooFunnels_DB_Operations::get_instance();
$this->cid = $contact->get_id();
$this->contact = $contact;
if ( empty( $this->cid ) || ( $this->cid < 1 ) ) {
return;
}
$this->db_customer = $this->get_customer_by_cid( $this->cid );
if ( isset( $this->db_customer->id ) && $this->db_customer->id > 0 ) {
$this->id = $this->db_customer->id;
}
}
/**
* Get customer by cid
*
* @param $wpid
*
* @return mixed
*/
public function get_customer_by_cid( $cid ) {
return $this->db_operations->get_customer_by_cid( $cid );
}
/**
* Get customer created date
*/
public function get_creation_date() {
$creation_date = ( isset( $this->creation_date ) && ! empty( $this->creation_date ) ) ? $this->creation_date : '';
$db_creation_date = ( isset( $this->db_customer->creation_date ) && ( $this->db_customer->creation_date > 0 ) ) ? $this->db_customer->creation_date : current_time( 'mysql' );
return empty( $creation_date ) ? $db_creation_date : $creation_date;
}
/**
* Set customer last order date
*
* @param $date
*/
public function set_l_order_date( $date ) {
$this->l_order_date = empty( $date ) ? $this->get_l_order_date() : $date;
}
/**
* Get customer last order date
*/
public function get_l_order_date() {
$order_date = ( isset( $this->l_order_date ) && ! empty( $this->l_order_date ) ) ? $this->l_order_date : '';
$db_data = ( isset( $this->db_customer->l_order_date ) && ! empty( $this->db_customer->l_order_date ) ) ? $this->db_customer->l_order_date : '0000-00-00';
return empty( $order_date ) ? $db_data : $order_date;
}
/**
* Set customer last order date
*
* @param $date
*/
public function set_f_order_date( $date ) {
$this->f_order_date = empty( $date ) ? $this->get_f_order_date() : $date;
}
/**
* Get customer last order date
*/
public function get_f_order_date() {
$order_date = ( isset( $this->f_order_date ) && ! empty( $this->f_order_date ) ) ? $this->f_order_date : '';
$db_data = ( isset( $this->db_customer->f_order_date ) && ! empty( $this->db_customer->f_order_date ) ) ? $this->db_customer->f_order_date : '0000-00-00';
return empty( $order_date ) ? $db_data : $order_date;
}
/**
* Set total order count
*
* @param $count
*/
public function set_total_order_count( $count ) {
$this->total_order_count = ( $count >= 0 ) ? $count : $this->get_total_order_count();
}
/**
* Get total order count
*/
public function get_total_order_count() {
$total_order = ( isset( $this->total_order_count ) && ! empty( $this->total_order_count ) ) ? $this->total_order_count : 0;
$db_data = ( isset( $this->db_customer->total_order_count ) && ! empty( $this->db_customer->total_order_count ) ) ? $this->db_customer->total_order_count : 0;
return empty( $total_order ) ? $db_data : $total_order;
}
/**
* Set total order value
*
* @param $value
*/
public function set_total_order_value( $value ) {
$this->total_order_value = ( $value >= 0 ) ? $value : $this->get_total_order_value();
}
/**
* Get total order value
*/
public function get_total_order_value() {
$total_order_value = ( isset( $this->total_order_value ) && $this->total_order_value >= 0 ) ? $this->total_order_value : false;
$db_data = ( isset( $this->db_customer->total_order_value ) && ! empty( $this->db_customer->total_order_value ) ) ? $this->db_customer->total_order_value : 0;
return false !== $total_order_value ? $total_order_value : $db_data;
}
/**
* Set customer AOV
*
* @param $value
*/
public function set_aov( $value ) {
$this->aov = $value;
}
/**
* Get customer AOV
*
* @return int
*/
public function get_aov() {
$aov = ( isset( $this->aov ) && ! empty( $this->aov ) ) ? $this->aov : 0;
$db_data = ( isset( $this->db_customer->aov ) && ! empty( $this->db_customer->aov ) ) ? $this->db_customer->aov : 0;
return empty( $aov ) ? $db_data : $aov;
}
/**
* Set purchased products
*
* @param $products
*/
public function set_purchased_products( $products ) {
$this->purchased_products = empty( $products ) ? $this->get_purchased_products() : $products;
}
/**
* Get purchased products
*
*/
public function get_purchased_products() {
$products = ( isset( $this->purchased_products ) && ! empty( $this->purchased_products ) ) ? $this->purchased_products : array();
$db_products = isset( $this->db_customer->purchased_products ) ? $this->db_customer->purchased_products : array();
if ( ! empty( $db_products ) && ! is_array( $db_products ) ) {
$db_products = json_decode( $db_products, true );
}
if ( ! empty( $products ) && ! is_array( $products ) ) {
$products = json_decode( $products, true );
}
$arr = empty( $products ) ? $db_products : $products;
if ( is_array( $arr ) && count( $arr ) > 0 ) {
$arr = array_map( 'intval', $arr );
}
return $arr;
}
/**
* Set purchased product categories
*
* @param $cats
*/
public function set_purchased_products_cats( $cats ) {
$this->purchased_products_cats = empty( $cats ) ? $this->get_purchased_products_cats() : $cats;
}
/**
* Get purchased product categories
*
*/
public function get_purchased_products_cats() {
$purchased_products_cats = ( isset( $this->purchased_products_cats ) && ! empty( $this->purchased_products_cats ) ) ? $this->purchased_products_cats : array();
$db_purchased_products_cats = isset( $this->db_customer->purchased_products_cats ) ? $this->db_customer->purchased_products_cats : array();
if ( ! empty( $db_purchased_products_cats ) && ! is_array( $db_purchased_products_cats ) ) {
$db_purchased_products_cats = json_decode( $db_purchased_products_cats, true );
}
if ( ! empty( $purchased_products_cats ) && ! is_array( $purchased_products_cats ) ) {
$purchased_products_cats = json_decode( $purchased_products_cats, true );
}
$arr = empty( $purchased_products_cats ) ? $db_purchased_products_cats : $purchased_products_cats;
if ( is_array( $arr ) && count( $arr ) > 0 ) {
$arr = array_map( 'intval', $arr );
}
return $arr;
}
/**
* Set purchased product tags
*
* @param $tags
*/
public function set_purchased_products_tags( $tags ) {
$this->purchased_products_tags = empty( $tags ) ? $this->get_purchased_products_tags() : $tags;
}
/**
* Get purchased product tags
*
*/
public function get_purchased_products_tags() {
$purchased_products_tags = ( isset( $this->purchased_products_tags ) && ! empty( $this->purchased_products_tags ) ) ? $this->purchased_products_tags : array();
$db_purchased_products_tags = isset( $this->db_customer->purchased_products_tags ) ? $this->db_customer->purchased_products_tags : array();
if ( ! empty( $db_purchased_products_tags ) && ! is_array( $db_purchased_products_tags ) ) {
$db_purchased_products_tags = json_decode( $db_purchased_products_tags, true );
}
if ( ! empty( $purchased_products_tags ) && ! is_array( $purchased_products_tags ) ) {
$purchased_products_tags = json_decode( $purchased_products_tags, true );
}
$arr = empty( $purchased_products_tags ) ? $db_purchased_products_tags : $purchased_products_tags;
if ( is_array( $arr ) && count( $arr ) > 0 ) {
$arr = array_map( 'intval', $arr );
}
return $arr;
}
/**
* Set used coupons
*
* @param $state
*/
public function set_used_coupons( $coupons ) {
$this->used_coupons = empty( $coupons ) ? $this->get_used_coupons() : $coupons;
}
/**
* Get customer used coupons
*/
public function get_used_coupons() {
$coupons = isset( $this->used_coupons ) ? $this->used_coupons : array();
$db_coupons = isset( $this->db_customer->used_coupons ) ? $this->db_customer->used_coupons : array();
if ( ! empty( $coupons ) && ! is_array( $coupons ) ) {
$coupons = json_decode( $coupons, true );
}
if ( ! empty( $db_coupons ) && ! is_array( $db_coupons ) ) {
$db_coupons = json_decode( $db_coupons, true );
}
return ! empty( $coupons ) ? $coupons : $db_coupons;
}
/**
* Set customer created date
*
* @param $date
*/
public function set_creation_date( $date ) {
$this->creation_date = $date;
}
/**
* Updating customer table with set data
* @SuppressWarnings(PHPMD.BooleanArgumentFlag)
*/
public function save() {
$customer = array();
$customer['l_order_date'] = $this->get_l_order_date();
$customer['f_order_date'] = $this->get_f_order_date();
$customer['total_order_count'] = $this->get_total_order_count();
$customer['total_order_value'] = $this->get_total_order_value();
$customer['aov'] = ( $customer['total_order_value'] > 0 ) ? $customer['total_order_value'] / absint( $customer['total_order_count'] ) : $customer['total_order_value'];
$purchased_products = $this->get_purchased_products();
$purchased_products = array_map( 'strval', $purchased_products );
$customer['purchased_products'] = wp_json_encode( $purchased_products );
$purchased_products_cats = $this->get_purchased_products_cats();
$purchased_products_cats = array_map( 'strval', $purchased_products_cats );
$customer['purchased_products_cats'] = wp_json_encode( $purchased_products_cats );
$purchased_products_tags = $this->get_purchased_products_tags();
$purchased_products_tags = array_map( 'strval', $purchased_products_tags );
$customer['purchased_products_tags'] = wp_json_encode( $purchased_products_tags );
$customer['used_coupons'] = wp_json_encode( $this->get_used_coupons() );
if ( ( $this->get_id() > 0 ) ) {
$customer['id'] = $this->get_id();
$this->db_operations->update_customer( $customer );
} elseif ( empty( $this->get_id() ) ) {
$customer['cid'] = $this->get_cid();
$this->id = $this->db_operations->insert_customer( $customer );
}
}
/**
* Get customer id
*/
public function get_id() {
$id = ( isset( $this->id ) && $this->id > 0 ) ? $this->id : 0;
$db_id = ( isset( $this->db_customer->id ) && ( $this->db_customer->id > 0 ) ) ? $this->db_customer->id : 0;
return ( $id > 0 ) ? $id : $db_id;
}
/**
* Set customer last order date
*
* @param $date
*/
public function set_id( $id ) {
$this->id = empty( $id ) ? $this->id : $id;
}
/**
* Get customer cid
*/
public function get_cid() {
$cid = ( isset( $this->cid ) && ! empty( $this->cid ) ) ? $this->cid : '';
$db_cid = ( isset( $this->db_customer->cid ) && ( $this->db_customer->cid > 0 ) ) ? $this->db_customer->cid : 0;
return empty( $cid ) ? $db_cid : $cid;
}
/**
* Set customer last order date
*
* @param $date
*/
public function set_cid( $cid ) {
$this->cid = empty( $cid ) ? $this->get_cid() : $cid;
}
/**
* Get customer by id
*
* @param $customer_id
*
* @return mixed
*/
public function get_customer_by_customer_id( $customer_id ) {
return $this->db_operations->get_customer_by_customer_id( $customer_id );
}
}
}

View File

@@ -0,0 +1,544 @@
<?php
/**
* WooFunnels customer and contact DB operations
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'WooFunnels_DB_Operations' ) ) {
/**
* Class WooFunnels_DB_Operations
*/
#[AllowDynamicProperties]
class WooFunnels_DB_Operations {
/**
* @var $ins
*/
public static $ins;
/**
* @var $contact_tbl
*/
public $contact_tbl;
/**
* @var $customer_tbl
*/
public $customer_tbl;
public $cache_query = [];
public $cache_meta_query = false;
public $cache_field_query = false;
/**
* WooFunnels_DB_Operations constructor.
*/
public function __construct() {
global $wpdb;
$this->contact_tbl = $wpdb->prefix . 'bwf_contact';
$this->contact_meta_tbl = $wpdb->prefix . 'bwf_contact_meta';
$this->customer_tbl = $wpdb->prefix . 'bwf_wc_customers';
}
/**
* @return WooFunnels_DB_Operations
*/
public static function get_instance() {
if ( null === self::$ins ) {
self::$ins = new self;
}
return self::$ins;
}
/**
* Inserting a new row in bwf_contact table
*
* @param $customer
*
* @return int
* @SuppressWarnings(PHPMD.DevelopmentCodeFragment)
*/
public function insert_contact( $contact ) {
if ( isset( $contact['id'] ) ) {
unset( $contact['id'] );
}
global $wpdb;
$inserted = $wpdb->insert( $this->contact_tbl, $contact ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
$lastId = 0;
if ( $inserted ) {
$lastId = $wpdb->insert_id;
}
if ( $wpdb->last_error !== '' ) {
BWF_Logger::get_instance()->log( 'Get last error in insert_contact: ' . print_r( $wpdb->last_error, true ), 'woofunnels_indexing' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
}
return $lastId;
}
/**
* Updating a contact
*
* @param $contact
*
* @return array|object|null
* @SuppressWarnings(PHPMD.DevelopmentCodeFragment)
*/
public function update_contact( $contact ) {
global $wpdb;
$update_data = array();
foreach ( is_array( $contact ) ? $contact : array() as $key => $value ) {
$update_data[ $key ] = $value;
}
$wpdb->update( $this->contact_tbl, $update_data, array( 'id' => $contact['id'] ) ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
if ( $wpdb->last_error !== '' ) {
BWF_Logger::get_instance()->log( "Get last error in update_customer for cid: {$contact['id']} " . print_r( $wpdb->last_error, true ), 'woofunnels_indexing' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
}
}
/**
* Getting contacts
*
* @return array|object|null
*/
public function get_all_contacts_count() {
global $wpdb;
$sql = "SELECT COUNT(id) FROM `$this->contact_tbl`";
return $wpdb->get_var( $sql ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
}
/**
* Getting contacts based on given criteria
*
* @param $args
*
* @return array|object|null
*/
public function get_contacts( $args ) {
global $wpdb;
$query = array();
$query['select'] = 'SELECT * ';
$query['from'] = "FROM {$this->contact_tbl} AS contact";
$query['where'] = ' WHERE 1=1 ';
if ( ! empty( $args['min_creation_date'] ) ) {
$query['where'] .= "AND contact.creation_date >= '" . gmdate( 'Y-m-d H:i:s', $args['min_creation_date'] ) . "'"; //phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
}
if ( ! empty( $args['max_creation_date'] ) ) {
$query['where'] .= "AND contact.creation_date < '" . gmdate( 'Y-m-d H:i:s', $args['max_creation_date'] ) . "'"; //phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
}
if ( - 1 !== $args['contact_limit'] ) {
$query['limit'] = "LIMIT {$args['contact_limit']}";
}
$query = implode( ' ', $query );
return $wpdb->get_results( $query ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
}
protected function get_set_cached_response( $sql, $get = 'row' ) {
global $wpdb;
if ( 'row' === $get ) {
$result = $wpdb->get_row( $sql ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
} elseif ( 'var' === $get ) {
$result = $wpdb->get_var( $sql ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
} elseif ( 'col' === $get ) {
$result = $wpdb->get_col( $sql ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
} else {
$result = $wpdb->get_results( $sql ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
}
return $result;
}
/**
* Get contact for given uid id if it exists
*/
public function get_contact( $uid ) {
global $wpdb;
$sql = "SELECT * FROM `$this->contact_tbl` WHERE `uid` = %s";
$sql = $wpdb->prepare( $sql, $uid );
return $this->get_set_cached_response( $sql );
}
/**
* Get contact for given wpid id if it exists
*/
public function get_contact_by_wpid( $wp_id ) {
global $wpdb;
$sql = "SELECT * FROM `$this->contact_tbl` WHERE `wpid` = %d";
$sql = $wpdb->prepare( $sql, $wp_id );
return $this->get_set_cached_response( $sql );
}
/**
* Get contact for given email id if it exists
*/
public function get_contact_by_email( $email ) {
global $wpdb;
$sql = "SELECT * FROM `$this->contact_tbl` WHERE `email` = %s";
$sql = $wpdb->prepare( $sql, $email );
return $this->get_set_cached_response( $sql );
}
/**
* Get contact by given phone number
*
* @param $phone
*
* @return array|object|void|null
*/
public function get_contact_by_phone( $phone ) {
global $wpdb;
$sql = "SELECT * FROM `$this->contact_tbl` WHERE `contact_no` = %s";
$sql = $wpdb->prepare( $sql, $phone );
return $this->get_set_cached_response( $sql );
}
/**
* Get contact for given contact id if it exists
*/
public function get_contact_by_contact_id( $contact_id ) {
global $wpdb;
$sql = "SELECT * FROM `$this->contact_tbl` WHERE `id` = %d";
$sql = $wpdb->prepare( $sql, $contact_id );
return $this->get_set_cached_response( $sql );
}
/**
* Get all contact meta key value for a given contact id
*
* @param $contact_id
*
* @return array|object|null
*/
public function get_contact_metadata( $contact_id ) {
global $wpdb;
$sql = "SELECT `meta_key`, `meta_value` FROM `$this->contact_meta_tbl` WHERE `contact_id` = %d";
$sql = $wpdb->prepare( $sql, $contact_id );
if ( true === $this->cache_meta_query ) {
// extra caching when variable is set, used in actions like FKA broadcast
if ( isset( $this->cache_query['meta'] ) && isset( $this->cache_query['meta'][ $contact_id ] ) ) {
return $this->cache_query['meta'][ $contact_id ];
}
if ( ! isset( $this->cache_query['meta'] ) ) {
$this->cache_query['meta'] = [];
}
$this->cache_query['meta'][ $contact_id ] = $this->get_set_cached_response( $sql, 'results' );
return $this->cache_query['meta'][ $contact_id ];
}
return $this->get_set_cached_response( $sql, 'results' );
}
/**
* @param $contact_id
* @param $contact_meta
*/
public function save_contact_meta( $contact_id, $contact_meta ) {
global $wpdb;
foreach ( is_object( $contact_meta ) ? $contact_meta : array() as $meta_key => $meta_value ) {
$meta_exists = false;
$meta_value = ( is_array( $meta_value ) ) ? maybe_serialize( $meta_value ) : $meta_value;
if ( $this->meta_id_exists( $contact_id, $meta_key ) ) {
$meta_exists = true;
//phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
$wpdb->update( $this->contact_meta_tbl, array(
'meta_value' => $meta_value, //phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value
), array(
'meta_key' => $meta_key, //phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
'contact_id' => $contact_id,
), array(
'%s', // meta_value
), array( '%s', '%s' ) );
}
if ( ! $meta_exists ) {
$contact_meta = array(
'contact_id' => $contact_id,
'meta_key' => $meta_key, //phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
'meta_value' => $meta_value, //phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value
);
$wpdb->insert( $this->contact_meta_tbl, $contact_meta ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
}
}
}
/**
* @param $contact_id
* @param $meta_key
*/
public function meta_id_exists( $contact_id, $meta_key ) {
global $wpdb;
$sql = "SELECT `meta_id` FROM `$this->contact_meta_tbl` WHERE `contact_id` = '$contact_id' AND `meta_key` = '$meta_key'";
$meta_id = $wpdb->get_var( $sql ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
return ( ! empty( $meta_id ) && $meta_id > 0 ) ? true : false;
}
/**
* @param $contact_id
* @param $meta_key
* @param $meta_value
*
* @return int
*/
public function update_contact_meta( $contact_id, $meta_key, $meta_value ) {
global $wpdb;
$db_meta_value = $this->get_contact_meta_value( $contact_id, $meta_key );
if ( is_array( $meta_value ) || is_object( $meta_value ) ) {
$meta_value_ids = empty( $db_meta_value ) ? array() : json_decode( $db_meta_value, true );
if ( false === is_array( $meta_value_ids ) ) {
$meta_value_ids = [];
}
if ( false === is_array( $meta_value ) ) {
$meta_value = [];
}
$meta_value = wp_json_encode( array_unique( array_merge( $meta_value_ids, $meta_value ) ) );
}
$meta_exists = false;
if ( $this->meta_id_exists( $contact_id, $meta_key ) ) {
$meta_exists = true;
//phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
$wpdb->update( $this->contact_meta_tbl, array(
'meta_value' => $meta_value, //phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value
), array(
'meta_key' => $meta_key, //phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
'contact_id' => $contact_id,
), array(
'%s', // meta_value
), array( '%s', '%s' ) );
}
if ( ! $meta_exists ) {
$contact_meta = array(
'contact_id' => $contact_id,
'meta_key' => $meta_key, //phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
'meta_value' => $meta_value, //phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value
);
$inserted = $wpdb->insert( $this->contact_meta_tbl, $contact_meta );//phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
$last_id = 0;
if ( $inserted ) {
$last_id = $wpdb->insert_id;
}
return $last_id;
}
}
/**
* Get contact meta for a given contact id and meta key
*
* @param $contact_id
*
* @return string|null
*/
public function get_contact_meta_value( $contact_id, $meta_key ) {
global $wpdb;
$sql = "SELECT `meta_value` FROM `$this->contact_meta_tbl` WHERE `contact_id` = %d AND `meta_key` = %s";
$sql = $wpdb->prepare( $sql, $contact_id, $meta_key );
return $this->get_set_cached_response( $sql, 'var' );
}
/**
* Inserting a new row in bwf_customer table
*
* @param $customer
*
* @return int
* @SuppressWarnings(PHPMD.DevelopmentCodeFragment)
*/
public function insert_customer( $customer ) {
global $wpdb;
$customer_data = array(
'cid' => $customer['cid'],
'l_order_date' => $customer['l_order_date'],
'f_order_date' => $customer['f_order_date'],
'total_order_count' => $customer['total_order_count'],
'total_order_value' => $customer['total_order_value'],
'aov' => $customer['aov'],
'purchased_products' => $customer['purchased_products'],
'purchased_products_cats' => $customer['purchased_products_cats'],
'purchased_products_tags' => $customer['purchased_products_tags'],
'used_coupons' => $customer['used_coupons'],
);
$inserted = $wpdb->insert( $this->customer_tbl, $customer_data ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
$lastId = 0;
if ( $inserted ) {
$lastId = $wpdb->insert_id;
}
if ( $wpdb->last_error !== '' ) {
BWF_Logger::get_instance()->log( 'Get last error in insert_customer: ' . print_r( $wpdb->last_error, true ), 'woofunnels_indexing' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
}
return $lastId;
}
/**
* Updating a customer
*
* @param $customer
*
* @return array|object|null
* @SuppressWarnings(PHPMD.DevelopmentCodeFragment)
*/
public function update_customer( $customer ) {
global $wpdb;
$update_data = array();
foreach ( is_array( $customer ) ? $customer : array() as $key => $value ) {
$update_data[ $key ] = $value;
}
$wpdb->update( $this->customer_tbl, $update_data, array( 'id' => $customer['id'] ) ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
if ( $wpdb->last_error !== '' ) {
BWF_Logger::get_instance()->log( "Get last error in update_customer for cid: {$customer['cid']} " . print_r( $wpdb->last_error, true ), 'woofunnels_indexing' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
}
}
/**
* Getting customers based on given criteria
*
* @param $args
*
* @return array|object|null
*/
public function get_customers( $args ) {
global $wpdb;
$query = array();
$query['select'] = 'SELECT * ';
$query['from'] = "FROM {$this->customer_tbl} AS customer";
$query['where'] = '';
$query['where'] = ' WHERE 1=1 ';
$query['where'] .= '
AND customer.total_order_count >= ' . $args['min_order_count'] . '
AND customer.total_order_count < ' . $args['max_order_count'] . '
AND customer.total_order_value >= ' . $args['min_order_value'] . '
AND customer.total_order_value < ' . $args['max_order_value'] . '
';
if ( ! empty( $args['min_last_order_date'] ) ) {
$query['where'] .= "
AND customer.l_order_date >= '" . gmdate( 'Y-m-d H:i:s', $args['min_last_order_date'] ) . "'
";
}
if ( ! empty( $args['max_last_order_date'] ) ) {
$query['where'] .= "
AND customer.l_order_date < '" . gmdate( 'Y-m-d H:i:s', $args['max_last_order_date'] ) . "'
";
}
if ( ! empty( $args['min_creation_date'] ) ) {
$query['where'] .= "
AND customer.creation_date >= '" . gmdate( 'Y-m-d H:i:s', $args['min_creation_date'] ) . "'";
}
if ( ! empty( $args['max_creation_date'] ) ) {
$query['where'] .= "
AND customer.creation_date < '" . gmdate( 'Y-m-d H:i:s', $args['max_creation_date'] ) . "'";
}
if ( - 1 !== $args['customer_limit'] ) {
$query['limit'] = "LIMIT {$args['customer_limit']}";
}
$query = implode( ' ', $query );
$customers = $wpdb->get_results( $query ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
return $customers;
}
/**
* Get customer for given uid id if it exists
*/
public function get_customer( $uid ) {
global $wpdb;
$sql = "SELECT * FROM `$this->customer_tbl` WHERE `uid` = %s";
$sql = $wpdb->prepare( $sql, $uid );
return $this->get_set_cached_response( $sql );
}
/**
* Get customer for given cid id if it exists
*/
public function get_customer_by_cid( $cid ) {
global $wpdb;
$sql = "SELECT * FROM `$this->customer_tbl` WHERE `cid` = %d";
$sql = $wpdb->prepare( $sql, $cid );
return $this->get_set_cached_response( $sql );
}
/**
* Get customer for given customer id if it exists
*/
public function get_customer_by_customer_id( $customer_id ) {
global $wpdb;
$sql = "SELECT * FROM `$this->customer_tbl` WHERE `id` = %d";
$sql = $wpdb->prepare( $sql, $customer_id );
return $this->get_set_cached_response( $sql );
}
/**
* Deleting a meta key from contact meta table
*
* @param $cid
* @param $meta_key
*/
public function delete_contact_meta( $cid, $meta_key ) {
global $wpdb;
if ( $this->meta_id_exists( $cid, $meta_key ) ) {
//phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
$wpdb->delete( $this->contact_meta_tbl, array(
'contact_id' => $cid,
'meta_key' => $meta_key, //phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
) );
}
}
}
WooFunnels_DB_Operations::get_instance();
}

View File

@@ -0,0 +1,135 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'WooFunnels_DB_Tables' ) ) {
/**
* Class WooFunnels_DB_Tables
*/
#[AllowDynamicProperties]
class WooFunnels_DB_Tables {
/**
* instance of class
* @var null
*/
private static $ins = null;
/**
* WooFunnels_DB_Tables constructor.
*/
public function __construct() {
add_filter( 'bwf_add_db_table_schema', array( $this, 'create_db_tables' ), 10, 2 );
}
/**
* @return WooFunnels_DB_Tables|null
*/
public static function get_instance() {
if ( null === self::$ins ) {
self::$ins = new self;
}
return self::$ins;
}
/**
* Add bwf_contact table
*
* Warning: check if it exists first, which could cause SQL errors.
*/
public function create_db_tables( $args, $tables ) {
if ( $tables['version'] !== BWF_DB_VERSION || ! in_array( 'bwf_contact', $tables['tables'], true ) ) {
$args[] = [
'name' => 'bwf_contact',
'schema' => "CREATE TABLE `{table_prefix}bwf_contact` (
`id` int(12) unsigned NOT NULL AUTO_INCREMENT,
`wpid` int(12) NOT NULL,
`uid` varchar(35) NOT NULL DEFAULT '',
`email` varchar(100) NOT NULL,
`f_name` varchar(100),
`l_name` varchar(100),
`contact_no` varchar(20),
`country` char(2),
`state` varchar(100),
`timezone` varchar(50) DEFAULT '',
`type` varchar(20) DEFAULT 'lead',
`source` varchar(100) DEFAULT '',
`points` bigint(20) unsigned NOT NULL DEFAULT '0',
`tags` longtext,
`lists` longtext,
`last_modified` DateTime NOT NULL,
`creation_date` DateTime NOT NULL,
`status` tinyint unsigned NOT NULL DEFAULT 1,
PRIMARY KEY (`id`),
KEY `id` (`id`),
KEY `wpid` (`wpid`),
KEY `uid` (`uid`),
KEY `contact_no` (`contact_no`),
KEY `last_modified` (`last_modified`),
KEY `creation_date` (`creation_date`),
KEY `status` (`status`),
UNIQUE KEY `email` (`email`)
) {table_collate};",
];
}
if ( $tables['version'] !== BWF_DB_VERSION || ! in_array( 'bwf_contact_meta', $tables['tables'], true ) ) {
$args[] = [
'name' => 'bwf_contact_meta',
'schema' => "CREATE TABLE `{table_prefix}bwf_contact_meta` (
`meta_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`contact_id` bigint(20) unsigned NOT NULL DEFAULT '0',
`meta_key` varchar(50) DEFAULT NULL,
`meta_value` longtext,
PRIMARY KEY (`meta_id`)
) {table_collate};",
];
}
if ( $tables['version'] !== BWF_DB_VERSION || ! in_array( 'bwf_wc_customers', $tables['tables'], true ) ) {
$args[] = [
'name' => 'bwf_wc_customers',
'schema' => "CREATE TABLE `{table_prefix}bwf_wc_customers` (
`id` int(12) unsigned NOT NULL AUTO_INCREMENT,
`cid` int(12) NOT NULL,
`l_order_date` DateTime NOT NULL,
`f_order_date` DateTime NOT NULL,
`total_order_count` int(7) unsigned NOT NULL,
`total_order_value` double NOT NULL,
`aov` double NOT NULL,
`purchased_products` longtext,
`purchased_products_cats` longtext,
`purchased_products_tags` longtext,
`used_coupons` longtext,
PRIMARY KEY (`id`),
KEY `id` (`id`),
UNIQUE KEY `cid` (`cid`)
) {table_collate};",
];
}
if ( $tables['version'] !== BWF_DB_VERSION || ! in_array( 'wfco_report_views', $tables['tables'], true ) ) {
$args[] = [
'name' => 'wfco_report_views',
'schema' => "CREATE TABLE `{table_prefix}wfco_report_views` (
id bigint(20) unsigned NOT NULL auto_increment,
date date NOT NULL,
no_of_sessions int(11) NOT NULL DEFAULT '1',
object_id bigint(20) DEFAULT '0',
type tinyint(2) NOT NULL COMMENT '1 - Abandonment 2 - Landing visited 3 - Landing converted 4 - Aero visited 5- Thank you visited 6 - NextMove 7 - Funnel session 8-Optin visited 9-Optin converted 10- Optin thank you visited 11- Optin thank you converted' DEFAULT '1',
PRIMARY KEY (id),
KEY date (date),
KEY object_id (object_id),
KEY type (type)
) {table_collate};",
];
}
return $args;
}
}
WooFunnels_DB_Tables::get_instance();
}

View File

@@ -0,0 +1,251 @@
{
"AF": "Afghanistan",
"AX": "\u00c5land Islands",
"AL": "Albania",
"DZ": "Algeria",
"AS": "American Samoa",
"AD": "Andorra",
"AO": "Angola",
"AI": "Anguilla",
"AQ": "Antarctica",
"AG": "Antigua and Barbuda",
"AR": "Argentina",
"AM": "Armenia",
"AW": "Aruba",
"AU": "Australia",
"AT": "Austria",
"AZ": "Azerbaijan",
"BS": "Bahamas",
"BH": "Bahrain",
"BD": "Bangladesh",
"BB": "Barbados",
"BY": "Belarus",
"PW": "Belau",
"BE": "Belgium",
"BZ": "Belize",
"BJ": "Benin",
"BM": "Bermuda",
"BT": "Bhutan",
"BO": "Bolivia",
"BQ": "Bonaire, Saint Eustatius and Saba",
"BA": "Bosnia and Herzegovina",
"BW": "Botswana",
"BV": "Bouvet Island",
"BR": "Brazil",
"IO": "British Indian Ocean Territory",
"BN": "Brunei",
"BG": "Bulgaria",
"BF": "Burkina Faso",
"BI": "Burundi",
"KH": "Cambodia",
"CM": "Cameroon",
"CA": "Canada",
"CV": "Cape Verde",
"KY": "Cayman Islands",
"CF": "Central African Republic",
"TD": "Chad",
"CL": "Chile",
"CN": "China",
"CX": "Christmas Island",
"CC": "Cocos (Keeling) Islands",
"CO": "Colombia",
"KM": "Comoros",
"CG": "Congo (Brazzaville)",
"CD": "Congo (Kinshasa)",
"CK": "Cook Islands",
"CR": "Costa Rica",
"HR": "Croatia",
"CU": "Cuba",
"CW": "Cura\u00e7ao",
"CY": "Cyprus",
"CZ": "Czech Republic",
"DK": "Denmark",
"DJ": "Djibouti",
"DM": "Dominica",
"DO": "Dominican Republic",
"EC": "Ecuador",
"EG": "Egypt",
"SV": "El Salvador",
"GQ": "Equatorial Guinea",
"ER": "Eritrea",
"EE": "Estonia",
"ET": "Ethiopia",
"FK": "Falkland Islands",
"FO": "Faroe Islands",
"FJ": "Fiji",
"FI": "Finland",
"FR": "France",
"GF": "French Guiana",
"PF": "French Polynesia",
"TF": "French Southern Territories",
"GA": "Gabon",
"GM": "Gambia",
"GE": "Georgia",
"DE": "Germany",
"GH": "Ghana",
"GI": "Gibraltar",
"GR": "Greece",
"GL": "Greenland",
"GD": "Grenada",
"GP": "Guadeloupe",
"GU": "Guam",
"GT": "Guatemala",
"GG": "Guernsey",
"GN": "Guinea",
"GW": "Guinea-Bissau",
"GY": "Guyana",
"HT": "Haiti",
"HM": "Heard Island and McDonald Islands",
"HN": "Honduras",
"HK": "Hong Kong",
"HU": "Hungary",
"IS": "Iceland",
"IN": "India",
"ID": "Indonesia",
"IR": "Iran",
"IQ": "Iraq",
"IE": "Ireland",
"IM": "Isle of Man",
"IL": "Israel",
"IT": "Italy",
"CI": "Ivory Coast",
"JM": "Jamaica",
"JP": "Japan",
"JE": "Jersey",
"JO": "Jordan",
"KZ": "Kazakhstan",
"KE": "Kenya",
"KI": "Kiribati",
"KW": "Kuwait",
"KG": "Kyrgyzstan",
"LA": "Laos",
"LV": "Latvia",
"LB": "Lebanon",
"LS": "Lesotho",
"LR": "Liberia",
"LY": "Libya",
"LI": "Liechtenstein",
"LT": "Lithuania",
"LU": "Luxembourg",
"MO": "Macao",
"MG": "Madagascar",
"MW": "Malawi",
"MY": "Malaysia",
"MV": "Maldives",
"ML": "Mali",
"MT": "Malta",
"MH": "Marshall Islands",
"MQ": "Martinique",
"MR": "Mauritania",
"MU": "Mauritius",
"YT": "Mayotte",
"MX": "Mexico",
"FM": "Micronesia",
"MD": "Moldova",
"MC": "Monaco",
"MN": "Mongolia",
"ME": "Montenegro",
"MS": "Montserrat",
"MA": "Morocco",
"MZ": "Mozambique",
"MM": "Myanmar",
"NA": "Namibia",
"NR": "Nauru",
"NP": "Nepal",
"NL": "Netherlands",
"NC": "New Caledonia",
"NZ": "New Zealand",
"NI": "Nicaragua",
"NE": "Niger",
"NG": "Nigeria",
"NU": "Niue",
"NF": "Norfolk Island",
"KP": "North Korea",
"MK": "North Macedonia",
"MP": "Northern Mariana Islands",
"NO": "Norway",
"OM": "Oman",
"PK": "Pakistan",
"PS": "Palestinian Territory",
"PA": "Panama",
"PG": "Papua New Guinea",
"PY": "Paraguay",
"PE": "Peru",
"PH": "Philippines",
"PN": "Pitcairn",
"PL": "Poland",
"PT": "Portugal",
"PR": "Puerto Rico",
"QA": "Qatar",
"RE": "Reunion",
"RO": "Romania",
"RU": "Russia",
"RW": "Rwanda",
"ST": "S\u00e3o Tom\u00e9 and Pr\u00edncipe",
"BL": "Saint Barth\u00e9lemy",
"SH": "Saint Helena",
"KN": "Saint Kitts and Nevis",
"LC": "Saint Lucia",
"SX": "Saint Martin (Dutch part)",
"MF": "Saint Martin (French part)",
"PM": "Saint Pierre and Miquelon",
"VC": "Saint Vincent and the Grenadines",
"WS": "Samoa",
"SM": "San Marino",
"SA": "Saudi Arabia",
"SN": "Senegal",
"RS": "Serbia",
"SC": "Seychelles",
"SL": "Sierra Leone",
"SG": "Singapore",
"SK": "Slovakia",
"SI": "Slovenia",
"SB": "Solomon Islands",
"SO": "Somalia",
"ZA": "South Africa",
"GS": "South Georgia\/Sandwich Islands",
"KR": "South Korea",
"SS": "South Sudan",
"ES": "Spain",
"LK": "Sri Lanka",
"SD": "Sudan",
"SR": "Suriname",
"SJ": "Svalbard and Jan Mayen",
"SZ": "Swaziland",
"SE": "Sweden",
"CH": "Switzerland",
"SY": "Syria",
"TW": "Taiwan",
"TJ": "Tajikistan",
"TZ": "Tanzania",
"TH": "Thailand",
"TL": "Timor-Leste",
"TG": "Togo",
"TK": "Tokelau",
"TO": "Tonga",
"TT": "Trinidad and Tobago",
"TN": "Tunisia",
"TR": "Turkey",
"TM": "Turkmenistan",
"TC": "Turks and Caicos Islands",
"TV": "Tuvalu",
"UG": "Uganda",
"UA": "Ukraine",
"AE": "United Arab Emirates",
"GB": "United Kingdom",
"US": "United States",
"UM": "United States (US) Minor Outlying Islands",
"UY": "Uruguay",
"UZ": "Uzbekistan",
"VU": "Vanuatu",
"VA": "Vatican",
"VE": "Venezuela",
"VN": "Vietnam",
"VG": "Virgin Islands (British)",
"VI": "Virgin Islands (US)",
"WF": "Wallis and Futuna",
"EH": "Western Sahara",
"YE": "Yemen",
"ZM": "Zambia",
"ZW": "Zimbabwe"
}

View File

@@ -0,0 +1,278 @@
<?php
/**
* Contact functions
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Providing a contact object
*
* @param $email
* @param $wp_id
*
* @return WooFunnels_Contact|WooFunnels_Customer
*/
if ( ! function_exists( 'bwf_get_contact' ) ) {
function bwf_get_contact( $wp_id, $email ) {
return new WooFunnels_Contact( $wp_id, $email );
}
}
if ( ! function_exists( 'bwf_create_update_contact' ) ) {
/**
* Creating updating contact and customer table
* On offer accepted, on order status change and on order indexing
*
* @param $order_id
* @param $products
* @param $total
* @param false $force
*
* @return int|void
*/
function bwf_create_update_contact( $order_id, $products, $total, $force = false ) {
$order = wc_get_order( $order_id );
if ( ! $order instanceof WC_Order ) {
return;
}
$wp_id = $order->get_customer_id();
$wp_email = '';
if ( $wp_id > 0 ) {
$wp_user = get_user_by( 'id', $wp_id );
$wp_email = ( $wp_user instanceof WP_User ) ? $wp_user->user_email : '';
}
$email = empty( $wp_email ) ? $order->get_billing_email() : $wp_email;
if ( empty( $email ) ) {
return;
}
$bwf_contact = bwf_get_contact( $wp_id, $email );
$bwf_email = isset( $bwf_contact->db_contact->email ) ? $bwf_contact->db_contact->email : '';
$bwf_wpid = isset( $bwf_contact->db_contact->wpid ) ? $bwf_contact->db_contact->wpid : 0;
if ( $wp_id > 0 && ( $bwf_wpid !== $wp_id ) ) {
$bwf_contact->set_wpid( $wp_id );
}
if ( ( empty( $bwf_email ) && ! empty( $email ) ) || ( ! empty( $wp_email ) && ( $bwf_email !== $email ) ) ) {
$bwf_contact->set_email( $email );
}
if ( true === $force ) {
bwf_create_update_contact_object( $bwf_contact, $order );
}
bwf_contact_maybe_update_creation_date( $bwf_contact, $order );
bwf_create_update_customer( $bwf_contact, $order, $order_id, $products, $total );
if ( true === $force ) {
do_action( 'bwf_normalize_contact_meta_before_save', $bwf_contact, $order_id, $order );
}
$bwf_contact->save();
if ( true === $force ) {
do_action( 'bwf_normalize_contact_meta_after_save', $bwf_contact, $order_id, $order );
}
$cid = $bwf_contact->get_id();
$order->update_meta_data( '_woofunnel_cid', $cid );
$order->save_meta_data();
return $cid;
}
}
/**
* @param WooFunnels_Contact $bwf_contact
* @param WC_order $order
*/
if ( ! function_exists( 'bwf_contact_maybe_update_creation_date' ) ) {
function bwf_contact_maybe_update_creation_date( $bwf_contact, $order ) {
$get_creation_date = $bwf_contact->get_creation_date();
if ( empty( $get_creation_date ) || $get_creation_date === '0000-00-00' || ( ! empty( $get_creation_date ) && $order->get_date_created() instanceof DateTime && ( strtotime( $get_creation_date ) > $order->get_date_created()->getTimestamp() ) ) ) {
$bwf_contact->set_creation_date( $order->get_date_created()->format( 'Y-m-d H:i:s' ) );
}
}
}
if ( ! function_exists( 'bwf_create_update_contact_object' ) ) {
/**
* Called on login, & checkout order processed
*
* @param $bwf_contact WooFunnels_Contact
* @param $order WC_Order
*
* @return mixed
*/
function bwf_create_update_contact_object( $bwf_contact, $order ) {
$wp_id = $order->get_customer_id();
/** If false then update the fields only when empty */
$force = ( true === WooFunnels_DB_Updater::$indexing ) ? false : true;
$wp_f_name = '';
$wp_l_name = '';
if ( $wp_id > 0 ) {
$wp_user = get_user_by( 'id', $wp_id );
$wp_f_name = ( $wp_user instanceof WP_User ) ? $wp_user->user_firstname : '';
$wp_l_name = ( $wp_user instanceof WP_User ) ? $wp_user->user_lastname : '';
}
$f_name = $order->get_billing_first_name();
$l_name = $order->get_billing_last_name();
$f_name = empty( $f_name ) ? $wp_f_name : $f_name;
$l_name = empty( $l_name ) ? $wp_l_name : $l_name;
$update_name = apply_filters( 'bwf_update_contact_name', true, $bwf_contact );
if ( ! empty( $f_name ) ) {
$should_skip_update = ( false === $force || false === $update_name ) && ! empty( $bwf_contact->get_f_name() );
if ( ! $should_skip_update ) {
$bwf_contact->set_f_name( $f_name );
}
}
if ( ! empty( $l_name ) ) {
$should_skip_update = ( false === $force || false === $update_name ) && ! empty( $bwf_contact->get_l_name() );
if ( ! $should_skip_update ) {
$bwf_contact->set_l_name( $l_name );
}
}
/** New contact */
if ( '' === $bwf_contact->get_status() ) {
if ( class_exists( 'BWFAN_Core' ) ) {
/** Check if consent value is 1 */
$marketing_status = $order->get_meta( 'marketing_status' );
if ( 1 === intval( $marketing_status ) ) {
$bwf_contact->set_status( 1 );
} else {
$bwf_contact->set_status( 0 );
}
} else {
$bwf_contact->set_status( 1 );
}
}
$order_country = $order->get_billing_country();
if ( ! empty( $order_country ) && 2 === strlen( $order_country ) ) {
$order_country = ( false === $force && ! empty( $bwf_contact->get_country() ) ) ? '' : $order_country;
$bwf_contact->set_country( $order_country );
}
$order_state = $order->get_billing_state();
if ( ! empty( $order_country ) && ! empty( $order_state ) ) {
$state = bwf_get_states( $order_country, $order_state );
$state = ( false === $force && ! empty( $bwf_contact->get_state() ) ) ? '' : $state;
$bwf_contact->set_state( $state );
}
$bwf_contact->set_type( 'customer' );
$contact_no = $order->get_billing_phone();
if ( empty( $contact_no ) && method_exists( $order, 'get_shipping_phone' ) ) {
$contact_no = $order->get_shipping_phone();
}
$timezone = bwf_get_timezone_from_order( $order );
if ( ! empty( $contact_no ) ) {
$contact_no = ( false === $force && ! empty( $bwf_contact->get_contact_no() ) ) ? '' : $contact_no;
/** Appending country code in phone number if not added */
if ( class_exists( 'BWFAN_Phone_Numbers' ) && ! empty( $contact_no ) && ! empty( $bwf_contact->get_country() ) ) {
$contact_no = BWFAN_Phone_Numbers::add_country_code( $contact_no, $bwf_contact->get_country() );
}
$bwf_contact->set_contact_no( $contact_no );
}
if ( ! empty( $timezone ) ) {
$timezone = ( false === $force && ! empty( $bwf_contact->get_timezone() ) ) ? '' : $timezone;
$bwf_contact->set_timezone( $timezone );
}
if ( empty( $bwf_contact->get_source() ) ) {
$bwf_contact->set_source( 'wc_order' );
}
return $bwf_contact;
}
}
if ( ! function_exists( 'bwf_get_timezone_from_order' ) ) {
/**
* @param $order WC_Order
*
* @return array|mixed|string
*/
function bwf_get_timezone_from_order( $order ) {
if ( ! $order instanceof WC_Order ) {
return '';
}
$may_be_timezone = BWF_WC_Compatibility::get_order_data( $order, '_wfacp_timezone' );
/** If set in order meta */
if ( ! empty( $may_be_timezone ) && true === bwf_if_valid_timezone( $may_be_timezone ) ) {
return $may_be_timezone;
}
/** Check for country */
$country = $order->get_billing_country();
ob_start();
include dirname( __DIR__ ) . '/contact/data/contries-timzone.json'; //phpcs:ignore WordPressVIPMinimum.Files.IncludingNonPHPFile.IncludingNonPHPFile
$list = ob_get_clean();
$list = json_decode( $list, true );
if ( ! is_array( $list ) || ! array_key_exists( $country, $list ) ) {
return '';
}
if ( ! isset( $list[ $country ] ) || ! isset( $list[ $country ]['timezone'] ) || count( $list[ $country ]['timezone'] ) === 0 ) {
return '';
}
return $list[ $country ]['timezone'][0];
}
}
if ( ! function_exists( 'bwf_if_valid_timezone' ) ) {
/**
* @param $timezone
*
* @return bool
*/
function bwf_if_valid_timezone( $timezone ) {
if ( empty( $timezone ) ) {
return false;
}
$zones = timezone_identifiers_list();
return in_array( $timezone, $zones, true );
}
}
if ( ! function_exists( 'bwf_get_countries_data' ) ) {
/** countries data
* @return mixed|null
*/
function bwf_get_countries_data() {
ob_start();
include dirname( __DIR__ ) . '/contact/data/countries.json'; //phpcs:ignore WordPressVIPMinimum.Files.IncludingNonPHPFile.IncludingNonPHPFile
$countries_data = ob_get_clean();
$countries = json_decode( $countries_data, true );
return $countries;
}
}

View File

@@ -0,0 +1,408 @@
<?php
/**
* Customer functions
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Providing a new customer object
*
* @param $contact
*
* @return WooFunnels_Customer
*/
function bwf_get_customer( $contact ) {
return new WooFunnels_Customer( $contact );
}
/**
* @param $bwf_contact
* @param $order WC_Order
* @param $order_id
* @param $products - only in case of upstroke upsell orders
* @param $total
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
if ( ! function_exists( 'bwf_create_update_customer' ) ) {
function bwf_create_update_customer( $bwf_contact, $order, $order_id, $products, $total ) {
if ( ! $order instanceof WC_Order ) {
return;
}
/** Registering customer as child entities to contact for using its object */
$bwf_contact->set_customer_child();
$indexed = BWF_WC_Compatibility::get_order_meta( $order, '_woofunnel_custid' );
if ( ! $indexed && ( ! is_array( $products ) || ( is_array( $products ) && count( $products ) < 1 ) ) ) { //Non-batching un-indexed order
$bwf_contact->set_customer_total_order_count( $bwf_contact->get_customer_total_order_count() + 1 );
}
$total_change = false;
$new_total = 0;
if ( ( $total > 0 && $indexed ) ) {
/** Offer accepted and parent order already indexed and batching is on */
$new_total = $total - $order->get_total_refunded();
$total_change = true;
} elseif ( ! $indexed ) {
/** new order checkout, payment status paid */
$new_total = $order->get_total() - $order->get_total_refunded();
$total_change = true;
}
if ( $total_change && $new_total >= 0 ) {
/** Convert to base currency */
$fixed_order_spent = BWF_Plugin_Compatibilities::get_fixed_currency_price_reverse( $new_total, BWF_WC_Compatibility::get_order_currency( $order ) );
$db_total_order_spent = $bwf_contact->get_customer_total_order_value();
$fixed_order_spent = $fixed_order_spent + $db_total_order_spent;
$bwf_contact->set_customer_total_order_value( $fixed_order_spent );
}
/**BWF_Logger::get_instance()->log( "Order id: $order_id, Indexed: $indexed, New Total: $new_total, TotalChange: $total_change, Total: $total, OrderTotal: {$order->get_total()}, DatePaid: {$order->get_date_paid()}", "customer_batch" );*/
$product_ids = $cat_ids = $tag_ids = array();
$subscription_renewal = BWF_WC_Compatibility::get_order_meta( $order, '_subscription_renewal' );
if ( empty( $subscription_renewal ) ) { //Don't scan a subscription renewal order for products, cats and tags
$is_batching = false;
$db_products = $bwf_contact->get_customer_purchased_products();
$db_cats = $bwf_contact->get_customer_purchased_products_cats();
$db_tags = $bwf_contact->get_customer_purchased_products_tags();
$cat_ids = $db_cats;
$tag_ids = $db_tags;
if ( is_array( $products ) && count( $products ) > 0 ) { //batching on current offer package products and parent order is already been indexed
$is_batching = true;
foreach ( $products as $product_id ) {
if ( ! in_array( $product_id, $db_products, true ) && ! in_array( $product_id, $product_ids, true ) && $product_id > 0 ) {
array_push( $product_ids, $product_id );
}
$product = wc_get_product( $product_id );
if ( $product->is_type( 'variation' ) ) {
$product_id = $product->get_parent_id();
if ( ! in_array( $product_id, $product_ids, true ) && ! in_array( $product_id, $db_products, true ) && $product_id > 0 ) {
array_push( $product_ids, $product_id );
}
}
$updated_tags_cats = bwf_update_cats_and_tags( $product_id, $cat_ids, $tag_ids );
$cat_ids = $updated_tags_cats['cats'];
$tag_ids = $updated_tags_cats['tags'];
}
}
if ( false === $is_batching ) {
foreach ( $order->get_items() as $item ) {
$product = $item->get_product();
if ( $product instanceof WC_Product ) {
$product_id = $product->get_id();
if ( ! in_array( $product_id, $product_ids, true ) && ! in_array( $product_id, $db_products, true ) && $product_id > 0 ) {
array_push( $product_ids, $product_id );
}
if ( $product->is_type( 'variation' ) ) {
$product_id = $product->get_parent_id();
if ( ! in_array( $product_id, $product_ids, true ) && ! in_array( $product_id, $db_products, true ) && $product_id > 0 ) {
array_push( $product_ids, $product_id );
}
}
$updated_tags_cats = bwf_update_cats_and_tags( $product_id, $cat_ids, $tag_ids );
$cat_ids = $updated_tags_cats['cats'];
$tag_ids = $updated_tags_cats['tags'];
}
}
$db_used_coupons = $bwf_contact->get_customer_used_coupons();
$order_coupons = BWF_WC_Compatibility::get_used_coupons( $order );
if ( count( $order_coupons ) > 0 && ( count( array_diff( $order_coupons, $db_used_coupons ) ) > 0 || count( $db_used_coupons ) < 1 ) ) {
$final_coupons = array_unique( array_merge( $db_used_coupons, $order_coupons ) );
sort( $final_coupons );
$bwf_contact->set_customer_used_coupons( $final_coupons );
}
}
if ( is_array( $product_ids ) && count( $product_ids ) > 0 && ( count( array_diff( $product_ids, $db_products ) ) > 0 || count( $db_products ) < 1 ) ) {
$final_products = bwf_get_array_unique_integers( $db_products, $product_ids );
$bwf_contact->set_customer_purchased_products( $final_products );
}
if ( count( $cat_ids ) > 0 && ( count( array_diff( $cat_ids, $db_cats ) ) > 0 || count( $db_cats ) < 1 ) ) {
$final_cats = bwf_get_array_unique_integers( $db_cats, $cat_ids );
$bwf_contact->set_customer_purchased_products_cats( $final_cats );
}
if ( count( $tag_ids ) > 0 && ( count( array_diff( $tag_ids, $db_tags ) ) > 0 || count( $db_tags ) < 1 ) ) {
$final_tags = bwf_get_array_unique_integers( $db_tags, $tag_ids );
$bwf_contact->set_customer_purchased_products_tags( $final_tags );
}
}
$bwf_l_order_date = $bwf_contact->get_customer_l_order_date();
$bwf_f_order_date = $bwf_contact->get_customer_f_order_date();
$order_created_date = $order->get_date_created()->date( 'Y-m-d H:i:s' );
if ( empty( $bwf_l_order_date ) || $bwf_l_order_date < $order_created_date ) {
$bwf_contact->set_customer_l_order_date( $order_created_date );
}
if ( empty( $bwf_f_order_date ) || $bwf_f_order_date === '0000-00-00' || $bwf_f_order_date === '0000-00-00 00:00:00' || $bwf_f_order_date > $order_created_date ) {
$bwf_contact->set_customer_f_order_date( $order_created_date );
}
$cid = $bwf_contact->get_id();
$bwf_contact->set_customer_cid( $cid );
$order->update_meta_data( '_woofunnel_custid', $cid );
$order->save_meta_data();
}
}
/**
* Setting category ids and tag ids
*
* @param $product_ids
* @param $product_id
*/
if ( ! function_exists( 'bwf_update_cats_and_tags' ) ) {
function bwf_update_cats_and_tags( $product_id, $cat_ids, $tag_ids ) {
$product_obj = wc_get_product( $product_id );
if ( ! $product_obj instanceof WC_Product ) {
return array(
'cats' => [],
'tags' => [],
);
}
/** Terms */
$product_cats = $product_obj->get_category_ids();
$product_tags = $product_obj->get_tag_ids();
$cat_ids = ( is_array( $product_cats ) ) ? array_merge( $cat_ids, $product_cats ) : [];
$tag_ids = ( is_array( $product_tags ) ) ? array_merge( $tag_ids, $product_tags ) : [];
$cat_ids = ( is_array( $cat_ids ) ) ? array_unique( $cat_ids ) : [];
$tag_ids = ( is_array( $tag_ids ) ) ? array_unique( $tag_ids ) : [];
return array(
'cats' => $cat_ids,
'tags' => $tag_ids,
);
}
}
/**
* Updating refunded amount in customer meta
*
* @param $order_id
* @param $amount
*/
if ( ! function_exists( 'bwf_update_customer_refunded' ) ) {
function bwf_update_customer_refunded( $order_id, $refund_amount ) {
$order = wc_get_order( $order_id );
$custid = BWF_WC_Compatibility::get_order_meta( $order, '_woofunnel_custid' );
if ( empty( $custid ) || 0 === $custid ) {
return;
}
$cid = BWF_WC_Compatibility::get_order_meta( $order, '_woofunnel_cid' );
$meta_key = '_bwf_customer_refunded';
$bwf_refunded = BWF_WC_Compatibility::get_order_meta( $order, $meta_key );
$bwf_refunded = empty( $bwf_refunded ) ? 0 : $bwf_refunded;
$bwf_contacts = BWF_Contacts::get_instance();
$bwf_contact = $bwf_contacts->get_contact_by( 'id', $cid );
$bwf_contact->set_customer_child();
$customer_total = $bwf_contact->get_customer_total_order_value();
$order_total = $order->get_total();
BWF_Logger::get_instance()->log( "Processing a refund for amount $refund_amount and order id: $order_id Order Total: $order_total, cid: $cid BWF Refunded: $bwf_refunded", 'woofunnels_indexing' );
if ( $refund_amount <= ( $order_total - $bwf_refunded ) ) {
/** Convert to base currency */
$refund_amount = BWF_Plugin_Compatibilities::get_fixed_currency_price_reverse( $refund_amount, BWF_WC_Compatibility::get_order_currency( $order ) );
$customer_total -= $refund_amount;
if ( $customer_total < 0 ) {
$customer_total = 0;
}
$bwf_contact->set_customer_total_order_value( $customer_total );
bwf_contact_maybe_update_creation_date( $bwf_contact, $order );
$bwf_contact->save();
$bwf_refunded += $refund_amount;
BWF_Logger::get_instance()->log( "Refund amount $refund_amount is reduced from customer meta 'total_value' for contact id: $cid Reduced total is: $customer_total ", 'woofunnels_indexing' );
}
$order->update_meta_data( $meta_key, $bwf_refunded );
$order->save_meta_data();
}
}
/**
* Reducing customer total spent on order cancelled
*
* @param $order_id
*/
if ( ! function_exists( 'bwf_reduce_customer_total_on_cancel' ) ) {
function bwf_reduce_customer_total_on_cancel( $order_id ) {
$order = wc_get_order( $order_id );
$custid = BWF_WC_Compatibility::get_order_meta( $order, '_woofunnel_custid' );
if ( empty( $custid ) ) {
return;
}
$cid = BWF_WC_Compatibility::get_order_meta( $order, '_woofunnel_cid' );
$meta_key = '_bwf_customer_refunded';
$bwf_refunded = BWF_WC_Compatibility::get_order_meta( $order, $meta_key );
$bwf_refunded = empty( $bwf_refunded ) ? 0 : $bwf_refunded;
$bwf_contacts = BWF_Contacts::get_instance();
$bwf_contact = $bwf_contacts->get_contact_by( 'id', $cid );
$order_total = $order->get_total();
$bwf_contact->set_customer_child();
$customer_total = $bwf_contact->get_customer_total_order_value();
$remaining_total = $order_total - $bwf_refunded;
BWF_Logger::get_instance()->log( "Processing a cancellation for order_id: $order_id, BWF Refunded: $bwf_refunded, Order Total: $order_total, Remaining order total: $remaining_total, Customer total: $customer_total", 'woofunnels_indexing' );
/** Convert to base currency */
$remaining_total = BWF_Plugin_Compatibilities::get_fixed_currency_price_reverse( $remaining_total, BWF_WC_Compatibility::get_order_currency( $order ) );
$customer_total -= $remaining_total;
if ( $customer_total < 0 ) {
$customer_total = 0;
}
$bwf_contact->set_customer_total_order_value( $customer_total );
bwf_contact_maybe_update_creation_date( $bwf_contact, $order );
$bwf_contact->save();
$order->update_meta_data( $meta_key, $order_total );
$order->save_meta_data();
BWF_Logger::get_instance()->log( "Order $order_id is cancelled for contact id: $cid. Reduced total is: $customer_total ", 'woofunnels_indexing' );
}
}
/**
* Return the total order amount
*
* @param $order WC_Order
*
* @return int
*/
if ( ! function_exists( 'bwf_get_order_total' ) ) {
function bwf_get_order_total( $order ) {
$total = 0;
if ( ! $order instanceof WC_Order ) {
return $total;
}
$total = $order->get_total() - $order->get_total_refunded();
$total = BWF_Plugin_Compatibilities::get_fixed_currency_price_reverse( $total, BWF_WC_Compatibility::get_order_currency( $order ) );
return $total;
}
}
/**
* Return the Order product items ids
*
* @param $order WC_Order
*
* @return array
*/
if ( ! function_exists( 'bwf_get_order_product_ids' ) ) {
function bwf_get_order_product_ids( $order ) {
$product_ids = [];
if ( ! $order instanceof WC_Order ) {
return $product_ids;
}
$products = $order->get_items();
if ( ! is_array( $products ) || count( $products ) === 0 ) {
return $product_ids;
}
$product_arr = [];
foreach ( $products as $val ) {
if ( ! $val instanceof WC_Order_Item_Product ) {
continue;
}
$product_id = $val->get_product_id();
$variation_id = $val->get_variation_id();
if ( $variation_id > 0 ) {
$product_id = $variation_id;
}
$product_arr[] = $product_id;
}
return $product_arr;
}
}
/**
* Return the Order product items categories and terms ids
*
* @param $order WC_Order
*
* @return array
*/
if ( ! function_exists( 'bwf_get_order_product_terms' ) ) {
function bwf_get_order_product_terms( $order ) {
$product_ids = [];
if ( ! $order instanceof WC_Order ) {
return $product_ids;
}
$products = $order->get_items();
if ( ! is_array( $products ) || ( is_array( $products ) && count( $products ) === 0 ) ) {
return $product_ids;
}
$order_cats = $order_tags = [];
$product_cats = false;
$product_tags = false;
foreach ( $products as $val ) {
if ( ! $val instanceof WC_Order_Item_Product ) {
continue;
}
/** @todo we can save this product obj as object cache so that can be used */
$product_obj = $val->get_product();
if ( ! $product_obj instanceof WC_Product ) {
continue;
}
/** Terms */
$product_cats = $product_obj->get_category_ids();
$product_tags = $product_obj->get_tag_ids();
$order_cats = ( is_array( $product_cats ) ) ? array_merge( $order_cats, $product_cats ) : [];
$order_tags = ( is_array( $product_tags ) ) ? array_merge( $order_tags, $product_tags ) : [];
}
$order_cats = ( is_array( $product_cats ) ) ? array_unique( $order_cats ) : [];
$order_tags = ( is_array( $product_tags ) ) ? array_unique( $order_tags ) : [];
return array(
'cats' => $order_cats,
'tags' => $order_tags,
);
}
}
/**
* Combine 2 arrays and return unique integer array values
*
* @param $arr
*
* @return mixed
*/
if ( ! function_exists( 'bwf_get_array_unique_integers' ) ) {
function bwf_get_array_unique_integers( $array1 = [], $array2 = [] ) {
$arr = array_unique( array_merge( $array1, $array2 ) );
sort( $arr );
$arr = array_map( 'intval', $arr );
return $arr;
}
}

View File

@@ -0,0 +1,129 @@
<?php
//Updating contact and customer tables functions in background
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
define( 'BWF_THRESHOLD_ORDERS', 0 ); //defining it more than 0 means you want the background to run only on "n" orders
define( 'BWF_ORDERS_PER_BATCH', 20 ); //defining it means how many orders to process per batch operation
/*** Updating customer tables ***/
if ( ! function_exists( 'bwf_create_update_contact_customer' ) ) {
/**
*
* @return bool|string
*/
function bwf_create_update_contact_customer() {
global $wpdb;
add_action( 'shutdown', [ WooFunnels_Dashboard::$classes['WooFunnels_DB_Updater'], 'capture_fatal_error' ] );
/**
* get the offset and the threshold of max orders to process
*/
$offset = get_option( '_bwf_offset', 0 );
$get_threshold_order = get_option( '_bwf_order_threshold', BWF_THRESHOLD_ORDERS );
$paid_statuses = implode( ',', array_map( function ( $status ) {
return "'wc-$status'";
}, wc_get_is_paid_statuses() ) );
if ( 0 === $get_threshold_order ) {
if ( ! BWF_WC_Compatibility::is_hpos_enabled() ) {
$query = $wpdb->prepare( "SELECT COUNT(p.ID) FROM {$wpdb->posts} AS p LEFT JOIN {$wpdb->postmeta} AS pm ON ( p.ID = pm.post_id AND pm.meta_key = '_woofunnel_cid') LEFT JOIN {$wpdb->postmeta} AS pm2 ON (p.ID = pm2.post_id) WHERE 1=1 AND pm.post_id IS NULL AND ( pm2.meta_key = '_billing_email' AND pm2.meta_value != '' ) AND p.post_type = %s AND p.post_status IN ({$paid_statuses})
ORDER BY p.post_date DESC", 'shop_order' );
} else {
$order_table = $wpdb->prefix . 'wc_orders';
$order_meta_table = $wpdb->prefix . 'wc_orders_meta';
$query = $wpdb->prepare( "SELECT COUNT(p.id) FROM {$order_table} AS p LEFT JOIN {$order_meta_table} AS pm ON ( p.id = pm.order_id AND pm.meta_key = '_woofunnel_cid') WHERE 1=1 AND pm.order_id IS NULL AND p.billing_email != '' AND
p.type = %s AND p.status IN ({$paid_statuses})
ORDER BY p.date_created_gmt DESC", 'shop_order' );
}
$query_results = $wpdb->get_var( $query ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
$get_threshold_order = $query_results;
update_option( '_bwf_order_threshold', $get_threshold_order );
}
/**************** PROCESS BATCH STARTS ************/
$numberposts = ( ( $offset > 0 ) && ( ( $get_threshold_order / $offset ) < 2 ) && ( ( $get_threshold_order % $offset ) < BWF_ORDERS_PER_BATCH ) ) ? ( $get_threshold_order % $offset ) : BWF_ORDERS_PER_BATCH;
if ( ! BWF_WC_Compatibility::is_hpos_enabled() ) {
$query = $wpdb->prepare( "SELECT p.ID FROM {$wpdb->posts} AS p LEFT JOIN {$wpdb->postmeta} AS pm ON ( p.ID = pm.post_id AND pm.meta_key = '_woofunnel_cid') LEFT JOIN {$wpdb->postmeta} AS pm2 ON (p.ID = pm2.post_id) WHERE 1=1 AND pm.post_id IS NULL AND ( pm2.meta_key = '_billing_email' AND pm2.meta_value != '' ) AND p.post_type = %s AND p.post_status IN ({$paid_statuses})
ORDER BY p.post_date DESC LIMIT 0, %d", 'shop_order', $numberposts );
} else {
$order_table = $wpdb->prefix . 'wc_orders';
$order_meta_table = $wpdb->prefix . 'wc_orders_meta';
$query = $wpdb->prepare( "SELECT p.id as ID FROM {$order_table} AS p LEFT JOIN {$order_meta_table} AS pm ON ( p.id = pm.order_id AND pm.meta_key = '_woofunnel_cid') WHERE 1=1 AND pm.order_id IS NULL AND p.billing_email != '' AND
p.type = %s AND p.status IN ({$paid_statuses})
ORDER BY p.date_created_gmt DESC LIMIT 0, %d", 'shop_order', $numberposts );
}
$query_results = $wpdb->get_results( $query ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
if ( empty( $query_results ) || ! is_array( $query_results ) ) {
return false;
}
$order_ids = array_map( function ( $query_instance ) {
return $query_instance->ID;
}, $query_results );
/**
* IF offset reached the threshold or no unindexed orders found, its time to terminate the batch process.
*/
if ( $offset >= $get_threshold_order || count( $order_ids ) < 1 ) {
BWF_Logger::get_instance()->log( 'Terminated on ' . $get_threshold_order, 'woofunnels_indexing' );
remove_action( 'shutdown', [ WooFunnels_Dashboard::$classes['WooFunnels_DB_Updater'], 'capture_fatal_error' ] );
return false;
}
/**
* @SuppressWarnings(PHPMD.DevelopmentCodeFragment)
*/
$retrieved_count = count( $order_ids );
BWF_Logger::get_instance()->log( "These $retrieved_count orders are retrieved: " . implode( ',', $order_ids ), 'woofunnels_indexing' ); //phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
WooFunnels_DB_Updater::$indexing = true;
remove_all_actions( 'woocommerce_update_order' );
foreach ( $order_ids as $order_id ) {
WooFunnels_Dashboard::$classes['WooFunnels_DB_Updater']->set_order_id_in_process( $order_id );
bwf_create_update_contact( $order_id, array(), 0, true );
$offset ++;
update_option( '_bwf_offset', $offset );
}
WooFunnels_DB_Updater::$indexing = null;
/**************** PROCESS BATCH ENDS ************/
BWF_Logger::get_instance()->log( "bwf_create_update_contact_customer function returned. Offset: $offset, Order Count: $get_threshold_order ", 'woofunnels_indexing' );
remove_action( 'shutdown', [ WooFunnels_Dashboard::$classes['WooFunnels_DB_Updater'], 'capture_fatal_error' ] );
return 'bwf_create_update_contact_customer';
}
}
/*
* CONTACTS DATABASE STARTS
*/
if ( ! function_exists( 'bwf_contacts_v1_0_init_db_setup' ) ) {
function bwf_contacts_v1_0_init_db_setup() {
return 'bwf_contacts_v1_0_init_db_setup';
}
}