- 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>
438 lines
13 KiB
PHP
Executable File
438 lines
13 KiB
PHP
Executable File
<?php
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit; // Exit if accessed directly
|
|
}
|
|
|
|
/**
|
|
* Class BWFAN_DB_Update
|
|
*
|
|
* @package Autonami
|
|
*
|
|
* @since 3.0.0
|
|
*/
|
|
#[AllowDynamicProperties]
|
|
class BWFAN_DB_Update {
|
|
private static $ins = null;
|
|
|
|
public $db_changes = [];
|
|
|
|
/**
|
|
* 0 - Null | nothing to do
|
|
* 1 - DB update can start
|
|
* 2 - DB update started
|
|
* 3 - DB update complete
|
|
*/
|
|
|
|
/**
|
|
* Class constructor
|
|
*/
|
|
public function __construct() {
|
|
add_action( 'admin_init', [ $this, 'db_update' ], 11 );
|
|
add_action( 'bwfan_db_update_2_11', array( $this, 'db_update_2_11_cb' ) );
|
|
add_action( 'bwfan_reindex_cart_conversions_base_total', array( $this, 'reindex_cart_conversion_base_total' ) );
|
|
|
|
$this->db_changes = array(
|
|
'2.11' => '2_11',
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Return the object of current class
|
|
*
|
|
* @return null|BWFAN_DB_Update
|
|
*/
|
|
public static function get_instance() {
|
|
if ( null === self::$ins ) {
|
|
self::$ins = new self();
|
|
}
|
|
|
|
return self::$ins;
|
|
}
|
|
|
|
/**
|
|
* Update pro db function for setting value
|
|
*/
|
|
public function db_update() {
|
|
$db_status = $this->get_saved_data( 'status' );
|
|
$db_version = $this->get_saved_data() ?? false;
|
|
$db_version = ( false === $db_version ) ? '2.8.4' : $db_version;
|
|
|
|
/** Status 1 = ready for run, 2 = in progress, 3 = complete */
|
|
if ( in_array( $db_status, [ 1, 2, 3 ] ) ) {
|
|
return;
|
|
}
|
|
|
|
foreach ( $this->db_changes as $version => $version_value ) {
|
|
if ( version_compare( $db_version, $version, '<' ) ) {
|
|
$value = [ $version => 1 ];
|
|
|
|
/** Should run or not */
|
|
if ( method_exists( $this, 'should_run_' . $version_value ) && false === call_user_func( [ $this, 'should_run_' . $version_value ] ) ) {
|
|
$value = [ $version => 0 ];
|
|
}
|
|
|
|
update_option( 'bwfan_db_update', $value, true );
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Return version or status from the DB saved value
|
|
*
|
|
* @param string $type
|
|
*
|
|
* @return false|int|mixed|string|null
|
|
*/
|
|
public function get_saved_data( $type = 'version' ) {
|
|
$data = get_option( 'bwfan_db_update', [] );
|
|
|
|
if ( ! is_array( $data ) ) {
|
|
return ( 'version' === $type ) ? false : 0;
|
|
}
|
|
|
|
/** Return version */
|
|
if ( 'version' === $type ) {
|
|
return key( $data );
|
|
}
|
|
|
|
$status = (int) current( $data );
|
|
|
|
/** If status is 2 (in processing) then check if action is scheduled */
|
|
if ( 2 === $status ) {
|
|
$this->is_action_scheduled( $data );
|
|
}
|
|
|
|
/** Return status */
|
|
return $status;
|
|
}
|
|
|
|
/**
|
|
* Schedule DB update action
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function start_db_update() {
|
|
/** Status */
|
|
$status = $this->get_saved_data( 'status' );
|
|
if ( 0 === $status ) {
|
|
return false;
|
|
}
|
|
|
|
/** Check if already scheduled */
|
|
if ( in_array( $status, [ 2, 3 ] ) ) {
|
|
return true;
|
|
}
|
|
|
|
/** Version */
|
|
$version = $this->get_saved_data();
|
|
|
|
/** Schedule recurring action */
|
|
$this->schedule_action( $version );
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Set the DB update current version value to 0
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function dismiss_db_update() {
|
|
/** Version */
|
|
$version = $this->get_saved_data();
|
|
if ( false === $version ) {
|
|
return false;
|
|
}
|
|
|
|
return update_option( 'bwfan_db_update', [ $version => 0 ], true );
|
|
}
|
|
|
|
/**
|
|
* Mark version complete and check for next DB update.
|
|
* If available then start it
|
|
*
|
|
* @param $version_no
|
|
*/
|
|
protected function mark_complete( $version_no ) {
|
|
$version_name = str_replace( ".", "_", $version_no );
|
|
BWFAN_Core()->logger->log( 'mark complete: ' . $version_no, 'db_update_' . $version_name );
|
|
|
|
/** Mark complete */
|
|
update_option( 'bwfan_db_update', [ $version_no => 3 ], true );
|
|
|
|
/** Un-schedule action */
|
|
$version_name = str_replace( ".", "_", $version_no );
|
|
bwf_unschedule_actions( 'bwfan_db_update_' . $version_name );
|
|
|
|
/** Maybe schedule next version */
|
|
if ( ! is_array( $this->db_changes ) || 0 === count( $this->db_changes ) ) {
|
|
return;
|
|
}
|
|
foreach ( $this->db_changes as $version => $version_value ) {
|
|
if ( version_compare( $version_no, $version, '<' ) ) {
|
|
/** Schedule recurring action */
|
|
$this->schedule_action( $version );
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Schedule recurring action
|
|
*
|
|
* @param $version
|
|
*/
|
|
protected function schedule_action( $version ) {
|
|
if ( empty( $version ) ) {
|
|
return false;
|
|
}
|
|
|
|
/** Mark DB update started */
|
|
update_option( 'bwfan_db_update', [ $version => 2 ], true );
|
|
|
|
$version_name = str_replace( ".", "_", $version );
|
|
$action = 'bwfan_db_update_' . $version_name;
|
|
$args = array( 'datetime' => current_time( 'mysql', 1 ) );
|
|
|
|
/** Check if action is already scheduled */
|
|
if ( ! bwf_has_action_scheduled( $action, $args, 'bwf_update' ) ) {
|
|
bwf_schedule_recurring_action( time(), 60, $action, $args, 'bwf_update' );
|
|
|
|
BWFAN_Core()->logger->log( 'scheduling action: ' . $version, 'db_update_' . $version_name );
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Check if time limit or memory passed
|
|
*
|
|
* @param $time
|
|
*
|
|
* @return bool
|
|
*/
|
|
protected function should_run( $time ) {
|
|
/** If time exceeds */
|
|
if ( ( time() - $time ) > $this->get_threshold_time() ) {
|
|
return false;
|
|
}
|
|
|
|
/** If memory exceeds */
|
|
return ! BWFAN_Common::memory_exceeded();
|
|
}
|
|
|
|
/**
|
|
* Return call duration time in seconds
|
|
*
|
|
* @return mixed|void
|
|
*/
|
|
protected function get_threshold_time() {
|
|
return apply_filters( 'bwfan_db_update_call_duration', 20 );
|
|
}
|
|
|
|
public function db_update_2_11_cb() {
|
|
|
|
global $wpdb;
|
|
$start_time = time();
|
|
$key = 'bwfan_db_update_2_11_cb';
|
|
BWFAN_Core()->logger->log( 'call starts for: 2.11', 'db_update_2_11' );
|
|
|
|
$post_statuses = apply_filters( 'bwfan_recovered_cart_excluded_statuses', array(
|
|
'wc-pending',
|
|
'wc-failed',
|
|
'wc-cancelled',
|
|
'wc-refunded',
|
|
'trash',
|
|
'draft'
|
|
) );
|
|
$post_statuses = implode( "','", $post_statuses );
|
|
|
|
/** Get if conversion table is empty */
|
|
$is_conversion_empty = bwf_options_get( 'is_conversion_empty' );
|
|
if ( empty( $is_conversion_empty ) ) {
|
|
$is_conversion_empty = BWFAN_Common::is_conversion_empty();
|
|
bwf_options_update( 'is_conversion_empty', $is_conversion_empty );
|
|
}
|
|
|
|
do {
|
|
$last_order_id = bwf_options_get( 'last_index_order' );
|
|
$last_order = intval( $last_order_id ) > 0 ? " AND p.`id` > $last_order_id " : "";
|
|
|
|
if ( BWF_WC_Compatibility::is_hpos_enabled() ) {
|
|
$query = "SELECT p.id AS id FROM {$wpdb->prefix}wc_orders as p LEFT JOIN {$wpdb->prefix}wc_orders_meta as m ON p.id = m.order_id WHERE p.type = 'shop_order' AND p.status NOT IN ('$post_statuses') AND m.meta_key = '_bwfan_ab_cart_recovered_a_id' $last_order ORDER BY p.`id` ASC LIMIT 10";
|
|
} else {
|
|
$query = "SELECT p.ID as id FROM {$wpdb->prefix}posts as p LEFT JOIN {$wpdb->prefix}postmeta as m ON p.ID = m.post_id WHERE p.post_type = 'shop_order' AND p.post_status NOT IN ('$post_statuses') AND m.meta_key = '_bwfan_ab_cart_recovered_a_id' $last_order ORDER BY p.`id` ASC LIMIT 10";
|
|
}
|
|
|
|
$order_ids = $wpdb->get_col( $query ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
|
|
if ( ! is_array( $order_ids ) || 0 === count( $order_ids ) ) {
|
|
bwf_options_delete( 'last_index_order' );
|
|
bwf_options_delete( 'is_conversion_empty' );
|
|
delete_option( $key );
|
|
$this->mark_complete( '2.11' );
|
|
|
|
return;
|
|
}
|
|
$order_id = 0;
|
|
foreach ( $order_ids as $order_id ) {
|
|
$order = wc_get_order( $order_id );
|
|
if ( ! $order instanceof WC_Order ) {
|
|
continue;
|
|
}
|
|
|
|
/** Check order is already exists in table if table is not empty */
|
|
if ( ! $is_conversion_empty ) {
|
|
$already_exists = BWFAN_Model_Conversions::get_specific_rows( 'wcid', $order_id );
|
|
if ( ! empty( $already_exists ) ) {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
$cid = BWF_WC_Compatibility::get_order_meta( $order, '_woofunnel_cid' );
|
|
$oid = BWF_WC_Compatibility::get_order_meta( $order, '_bwfan_ab_cart_recovered_a_id' );
|
|
|
|
$data = array(
|
|
'wcid' => intval( $order_id ),
|
|
'cid' => intval( $cid ),
|
|
'oid' => intval( $oid ),
|
|
'otype' => 1,
|
|
'wctotal' => $order->get_total(),
|
|
'date' => $order->get_date_created()->date( 'Y-m-d H:i:s' )
|
|
);
|
|
BWFAN_Model_Conversions::insert( $data );
|
|
}
|
|
/** Save last order id to fetch next orders ids */
|
|
bwf_options_update( 'last_index_order', $order_id );
|
|
BWFAN_Core()->logger->log( 'updated: ' . implode( ', ', $order_ids ), 'db_update_2_11' );
|
|
} while ( $this->should_run( $start_time ) ); // keep going until we run out of time, or memory
|
|
|
|
}
|
|
|
|
/**
|
|
* Check DB upgrade action scheduler is scheduled or not
|
|
*
|
|
* @return void
|
|
*/
|
|
public function is_action_scheduled( $versions ) {
|
|
if ( empty( $versions ) ) {
|
|
return;
|
|
}
|
|
|
|
foreach ( $versions as $version => $status ) {
|
|
if ( 2 !== intval( $status ) ) {
|
|
continue;
|
|
}
|
|
|
|
if ( ! in_array( $version, $this->db_changes, true ) ) {
|
|
delete_option( 'bwfan_db_update' );
|
|
break;
|
|
}
|
|
|
|
$version_name = str_replace( ".", "_", $version );
|
|
$action = 'bwfan_db_update_' . $version_name;
|
|
|
|
/** Check if action is already scheduled */
|
|
if ( ! bwf_has_action_scheduled( $action ) ) {
|
|
$args = array( 'datetime' => current_time( 'mysql', 1 ) );
|
|
bwf_schedule_recurring_action( time(), 60, $action, $args, 'bwf_update' );
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Re-index cart and conversion table base total
|
|
*
|
|
* @return void
|
|
*/
|
|
public function reindex_cart_conversion_base_total() {
|
|
global $wpdb;
|
|
$start_time = time();
|
|
|
|
do {
|
|
$data_type = bwf_options_get( 're_index_data_type' );
|
|
$last_processed_id = bwf_options_get( 'last_index_id' );
|
|
|
|
/** Fetch rows from conversion table */
|
|
if ( 'conversion' === $data_type ) {
|
|
$last_id = intval( $last_processed_id ) > 0 ? " AND `ID` > $last_processed_id " : "";
|
|
$query = "SELECT `ID`, `wctotal` AS total, `wcid` FROM `{$wpdb->prefix}bwfan_conversions` WHERE 1=1 $last_id ORDER BY `ID` ASC LIMIT 0,30";
|
|
|
|
$result = $wpdb->get_results( $query, ARRAY_A ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
|
|
if ( is_array( $result ) && count( $result ) > 0 ) {
|
|
$last_id = 0;
|
|
foreach ( $result as $data ) {
|
|
$order_id = isset( $data['wcid'] ) ? $data['wcid'] : 0;
|
|
if ( empty( $order_id ) ) {
|
|
continue;
|
|
}
|
|
$id = $data['ID'];
|
|
$saved_price = isset( $data['total'] ) ? $data['total'] : 0;
|
|
$order = wc_get_order( $order_id );
|
|
$order_total = $order instanceof WC_Order ? $order->get_total() : 0;
|
|
if ( empty( $order_total ) && empty( $saved_price ) ) {
|
|
$last_id = $id;
|
|
continue;
|
|
}
|
|
|
|
$currency = $order instanceof WC_Order ? $order->get_currency() : '';
|
|
if ( ! empty( $currency ) && ! empty( $order_total ) ) {
|
|
$order_total = BWF_Plugin_Compatibilities::get_fixed_currency_price_reverse( $order_total, $currency );
|
|
}
|
|
|
|
$wpdb->update( $wpdb->prefix . 'bwfan_conversions', [ 'wctotal' => $order_total ], array( 'ID' => $id ) ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
|
|
$last_id = $id;
|
|
}
|
|
|
|
bwf_options_update( 'last_index_id', $last_id );
|
|
continue;
|
|
} else {
|
|
/** cart table will process now */
|
|
$last_processed_id = 0;
|
|
bwf_options_update( 'last_index_id', 0 );
|
|
bwf_options_update( 're_index_data_type', 'cart' );
|
|
}
|
|
}
|
|
|
|
/** No conversion rows are left, fetch rows from cart table */
|
|
$last_id = intval( $last_processed_id ) > 0 ? " AND `ID` > $last_processed_id " : "";
|
|
$query = "SELECT `ID`, `total`, `currency` FROM `{$wpdb->prefix}bwfan_abandonedcarts` WHERE 1=1 $last_id ORDER BY `ID` ASC LIMIT 0,30";
|
|
|
|
$result = $wpdb->get_results( $query, ARRAY_A ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
|
|
if ( is_array( $result ) && count( $result ) > 0 ) {
|
|
$last_id = 0;
|
|
foreach ( $result as $data ) {
|
|
$id = $data['ID'];
|
|
$saved_price = isset( $data['total'] ) ? $data['total'] : 0;
|
|
if ( empty( $saved_price ) ) {
|
|
$last_id = $id;
|
|
continue;
|
|
}
|
|
$currency = isset( $data['currency'] ) ? $data['currency'] : '';
|
|
$order_total = 0;
|
|
if ( ! empty( $currency ) ) {
|
|
$order_total = BWF_Plugin_Compatibilities::get_fixed_currency_price_reverse( $saved_price, $currency );
|
|
}
|
|
|
|
$wpdb->update( $wpdb->prefix . 'bwfan_abandonedcarts', [ 'total_base' => $order_total ], array( 'ID' => $id ) ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
|
|
$last_id = $id;
|
|
}
|
|
|
|
bwf_options_update( 'last_index_id', $last_id );
|
|
continue;
|
|
}
|
|
|
|
/** No cart rows to process */
|
|
bwf_options_delete( 're_index_data_type' );
|
|
bwf_options_delete( 'last_index_id' );
|
|
|
|
bwf_unschedule_actions( 'bwfan_reindex_cart_conversions_base_total' );
|
|
break;
|
|
} while ( $this->should_run( $start_time ) ); // keep going until we run out of time, or memory
|
|
}
|
|
}
|
|
|
|
BWFAN_DB_Update::get_instance();
|