HEX
Server: Apache
System: Linux d5123.usc1.stableserver.net 5.14.0-570.17.1.el9_6.x86_64 #1 SMP PREEMPT_DYNAMIC Sat May 24 12:53:17 EDT 2025 x86_64
User: d5123 (1001)
PHP: 8.4.21
Disabled: NONE
Upload Files
File: /home/d5123/myboofola_com/wp-content/plugins/squarewoosync/squarewoosync.php
<?php

/**
 * Plugin Name:     Square Sync for WooCommerce
 * Requires Plugins: woocommerce
 * Plugin URI:      https://squaresyncforwoo.com
 * Description:     Easily Sync your WooCommerce Square data in real-time with the SquareSync for Woo. Stock, titles, descriptions, orders and more. 
 * Author:          SquareSync for Woo
 * Author URI:      https://squaresyncforwoo.com
 * Text Domain:     squarewoosync
 * License:         GPLv2 or later
 * License URI:     http://www.gnu.org/licenses/gpl-2.0.html
 * Domain Path:     /languages
 * Version:         6.1.2
 * Requires at least: 5.4
 * Requires PHP:      7.4
 * Tested up to:    7.0.0
 *
 * @package         SquareWooSync
 */

if (!defined('ABSPATH')) {
  exit; // Exit if accessed directly
}

use Pixeldev\SquareWooSync\Logger\Logger;
use Pixeldev\SquareWooSync\Payments\Blocks\WC_SquareSync_Gateway_Blocks_Support;
use Pixeldev\SquareWooSync\Security\SquareTokenManager;


final class SquareWooSync
{
  const VERSION = '6.1.2';
  const SLUG = 'squarewoosync';

  private $container = [];

  private function __construct()
  {
    require_once __DIR__ . '/vendor/autoload.php';

    $this->define_constants();

    register_activation_hook(__FILE__, [$this, 'activate']);
    register_deactivation_hook(__FILE__, [$this, 'deactivate']);

    add_action('plugins_loaded', [$this, 'init_plugin']);
    add_action('plugins_loaded', [$this, 'load_textdomain']);
  }

  public static function init()
  {
    static $instance = false;

    if (!$instance) {
      $instance = new SquareWooSync();
    }

    return $instance;
  }

  public function __get($prop)
  {
    if (array_key_exists($prop, $this->container)) {
      return $this->container[$prop];
    }

    return $this->{$prop};
  }

  public function __isset($prop)
  {
    return isset($this->{$prop}) || isset($this->container[$prop]);
  }

  public function define_constants()
  {
    define('SQUAREWOOSYNC_VERSION', self::VERSION);
    define('SQUAREWOOSYNC_SLUG', self::SLUG);
    define('SQUAREWOOSYNC_FILE', __FILE__);
    define('SQUAREWOOSYNC_DIR', __DIR__);
    define('SQUAREWOOSYNC_PATH', dirname(SQUAREWOOSYNC_FILE));
    define('SQUAREWOOSYNC_INCLUDES', SQUAREWOOSYNC_PATH . '/includes');
    define('SQUAREWOOSYNC_TEMPLATE_PATH', SQUAREWOOSYNC_PATH . '/templates');
    define('SQUAREWOOSYNC_URL', plugins_url('', SQUAREWOOSYNC_FILE));
    define('SQUAREWOOSYNC_BUILD', SQUAREWOOSYNC_URL . '/build');
    define('SQUAREWOOSYNC_ASSETS', SQUAREWOOSYNC_URL . '/assets');
  }

  public function init_plugin()
  {
    if (!class_exists('WooCommerce')) {
      add_action('admin_notices', [$this, 'woocommerce_missing_notice']);
      return;
    }

    $this->includes();
    $this->init_hooks();
    $this->maybe_register_auth_notice();

    add_filter('woocommerce_payment_gateways', [$this, 'add_gateway'], 5);
    add_action('woocommerce_blocks_payment_method_type_registration', array($this, 'register_payment_method_block_integrations'), 5, 1);

    do_action('SQUARE_WOO_SYNC_loaded');
  }

  public function load_textdomain()
  {
    load_plugin_textdomain('squarewoosync', false, dirname(plugin_basename(__FILE__)) . '/languages');
  }


  public function activate()
  {
    $this->install();
  }

  public function deactivate() {}

  public function woocommerce_missing_notice()
  {
    echo '<div class="notice notice-error"><p>';
    echo esc_html__('SquareWooSync requires WooCommerce to be installed and activated.', 'squarewoosync');
    echo '</p></div>';
  }

  public function remove_woocommerce_notice()
  {
    remove_action('admin_notices', [$this, 'woocommerce_missing_notice']);
  }

  private function install()
  {
    $installer = new \Pixeldev\SquareWooSync\Setup\Installer();
    $installer->run();
  }

  public function includes()
  {
    if ($this->is_request('admin')) {
      $this->container['admin_menu'] = new Pixeldev\SquareWooSync\Admin\Menu();
    }

    Logger::init();
    \Pixeldev\SquareWooSync\Logger\DebugLogger::init();

    $this->container['assets'] = new Pixeldev\SquareWooSync\Assets\Manager();
    $this->container['rest_api'] = new Pixeldev\SquareWooSync\REST\Api();

    // Background job: bulk-match simple products by SKU.
    \Pixeldev\SquareWooSync\Admin\Helpers\BulkMatchProductsJob::register();
    $this->container['sync_product'] = new Pixeldev\SquareWooSync\Woo\SyncProduct();
    $this->container['square_import'] = new Pixeldev\SquareWooSync\Square\SquareImport();
    $this->container['woo_validator'] = new Pixeldev\SquareWooSync\Woo\ValidateWooProduct();
    $this->container['woo_validator']->init();
    $this->container['woo_import'] = new Pixeldev\SquareWooSync\Woo\WooImport();
    $this->container['token_manager'] = new Pixeldev\SquareWooSync\Security\SquareTokenManager();
    $this->container['token_manager']->init();
    $this->container['woo_import']->init();

    add_action('sws_reset_is_fetching', ['Pixeldev\SquareWooSync\REST\SquareController', 'reset_is_fetching_failsafe']);
  }

  public function init_hooks()
  {
    add_filter('plugin_action_links_' . plugin_basename(__FILE__), [$this, 'plugin_action_links']);

    $settings = new \Pixeldev\SquareWooSync\REST\SettingsController();
    add_action('export_products_to_square', [$settings, 'handle_export_to_square']);


    $square = new \Pixeldev\SquareWooSync\REST\SquareController();
    add_action('update_square_inventory_cron',  [$square, 'update_square_inventory_function']);

    $woo = $this->container['sync_product'];
    add_action('wp_trash_post',  [$woo, 'delete_square_product']);

    $wooOrders = new \Pixeldev\SquareWooSync\Orders\WooOrder();
    $wooOrders::init_hooks();

    // WP-Cron tester (Tools page) — fires the test hook so the React poller can confirm WP-Cron is healthy.
    add_action('sws_cron_health_check', ['\Pixeldev\SquareWooSync\REST\ToolsController', 'cron_test_fire']);
  }

  public function add_gateway($gateways)
  {
    // Initialize the gateway if it's not already set
    if (empty($this->container['gateway'])) {
      $this->container['gateway'] = new \Pixeldev\SquareWooSync\Payments\WC_SquareSync_Gateway(
        'squaresync_credit',
        'Square Payments by SquareSync for Woo',
        'Allow customers to use Square to securely pay with their credit cards, GooglePay, and ApplePay'
      );
    }

    // Add the gateway to WooCommerce gateways if it's not already added
    if (!in_array($this->container['gateway'], $gateways, true)) {
      $gateways[] = $this->container['gateway'];
    }

    // Add Cash App Pay gateway if enabled
    $gateway_settings = get_option('woocommerce_squaresync_credit_settings', array());
    $cashapp_enabled = isset($gateway_settings['enable_cash_app_pay']) && $gateway_settings['enable_cash_app_pay'] === 'yes';

    if ($cashapp_enabled) {
      if (empty($this->container['cashapp_gateway'])) {
        $this->container['cashapp_gateway'] = new \Pixeldev\SquareWooSync\Payments\WC_SquareSync_CashApp_Gateway();
      }

      if (!in_array($this->container['cashapp_gateway'], $gateways, true)) {
        $gateways[] = $this->container['cashapp_gateway'];
      }
    }

    return $gateways;
  }

  /**
   * Render a dismissible warning if we do NOT have a stored access token.
   *
   * @return void
   */
  public function show_auth_notice_if_needed(): void
  {
    // If a token exists we’re already connected → nothing to do.
    if (SquareTokenManager::get()) {
      return;
    }

    $settings_url = esc_url(
      admin_url('admin.php?page=squarewoosync#/')
    );

    printf(
      '<div class="notice notice-error is-dismissible">
                <p>%1$s<br/>
                <a href="%2$s" class="button button-primary">%3$s</a>
                </p>
             </div>',
      esc_html__(
        'SquareSync for Woo is not yet connected to your Square account. Connect now to start syncing products and accepting payments',
        'squarewoosync'
      ),
      $settings_url,
      esc_html__('Connect Square', 'squarewoosync')
    );
  }

  /**
   * Hook point – runs in init_plugin().
   *
   * Registers the notice only in the admin area and
   * only for users that can manage the shop.
   *
   * @return void
   */
  private function maybe_register_auth_notice(): void
  {
    if ($this->is_request('admin') && current_user_can('manage_woocommerce')) {
      add_action('admin_notices', [$this, 'show_auth_notice_if_needed']);
    }
  }

  /**
   * Register the Square Credit Card checkout block integration class
   *
   * @since 2.5.0
   */
  public function register_payment_method_block_integrations($payment_method_registry)
  {
    if (class_exists('\Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType')) {
      // Register main Square gateway blocks support
      $blocks = new WC_SquareSync_Gateway_Blocks_Support;
      $payment_method_registry->register($blocks);

      // Register Cash App Pay blocks support if enabled
      $gateway_settings = get_option('woocommerce_squaresync_credit_settings', array());
      $cashapp_enabled = isset($gateway_settings['enable_cash_app_pay']) && $gateway_settings['enable_cash_app_pay'] === 'yes';

      if ($cashapp_enabled) {
        $cashapp_blocks = new \Pixeldev\SquareWooSync\Payments\Blocks\WC_SquareSync_CashApp_Gateway_Blocks_Support;
        $payment_method_registry->register($cashapp_blocks);
      }
    }
  }

  private function is_request($type)
  {
    switch ($type) {
      case 'admin':
        return is_admin();

      case 'ajax':
        return defined('DOING_AJAX');

      case 'rest':
        return defined('REST_REQUEST');

      case 'cron':
        return defined('DOING_CRON');

      case 'frontend':
        return (!is_admin() || defined('DOING_AJAX')) && !defined('DOING_CRON');
    }
  }

  public function plugin_action_links($links)
  {
    $settings_link = '<a href="' . esc_url(admin_url('admin.php?page=squarewoosync#/settings/general')) . '">' . esc_html__('Settings', 'squarewoosync') . '</a>';
    $documentation_link = '<a href="' . esc_url('https://squaresyncforwoo.com/docs') . '" target="_blank">' . esc_html__('Documentation', 'squarewoosync') . '</a>';
    $upgrade_link = '<a href="' . esc_url('https://squaresyncforwoo.com') . '" target="_blank" style="color: #2e7d32; font-weight: bold;">' . esc_html__('Upgrade to Pro', 'squarewoosync') . '</a>';

    $links[] = $settings_link;
    $links[] = $documentation_link;
    $links[] = $upgrade_link;

    return $links;
  }

  static function square_woo_sync_uninstall()
  {
    global $wpdb;

    $wpdb->query("DROP TABLE IF EXISTS {$wpdb->prefix}square_woo_sync_logs");
    delete_option('square-woo-sync_settings');
    delete_option('square-woo-sync_installed');
    delete_option('square-woo-sync_version');
  }
}

function squarewoosync_init()
{
  return SquareWooSync::init();
}


if (class_exists('SquareWooSync')) {
  squarewoosync_init();
  register_uninstall_hook(__FILE__, 'SquareWooSync::square_woo_sync_uninstall');
}


add_action('restrict_manage_posts', 'filter_products_by_square_product_id');
function filter_products_by_square_product_id()
{
  global $typenow;
  if ($typenow == 'product') {
    $value = isset($_GET['square_product_id']) ? $_GET['square_product_id'] : '';
    ?>
    <select name="square_product_id">
      <option value=""><?php _e('Filter by Square Product ID', 'woocommerce'); ?></option>
      <option value="no_square_id" <?php selected($value, 'no_square_id'); ?>><?php _e('No Square Product ID', 'woocommerce'); ?></option>
    </select>
  <?php
  }
}

add_filter('pre_get_posts', 'filter_products_by_square_product_id_query');
function filter_products_by_square_product_id_query($query)
{
  global $typenow, $pagenow;
  if ($typenow == 'product' && is_admin() && $pagenow == 'edit.php' && isset($_GET['square_product_id']) && $_GET['square_product_id'] == 'no_square_id') {
    $query->set('meta_query', array(
      array(
        'key' => 'square_product_id',
        'compare' => 'NOT EXISTS'
      )
    ));
  }
}

// Add a new section to the user profile page
function squarewoosync_display_additional_user_roles($user)
{
  // Get all roles
  $squarewoosync_all_roles = wp_roles()->roles;
  $squarewoosync_user_roles = get_user_meta($user->ID, 'wp_capabilities', true);

  // Filter out the primary role
  $squarewoosync_primary_role = '';
  if (isset($squarewoosync_user_roles) && is_array($squarewoosync_user_roles)) {
    foreach ($squarewoosync_user_roles as $squarewoosync_role => $squarewoosync_capabilities) {
      if ($squarewoosync_capabilities === true) {
        $squarewoosync_primary_role = sanitize_text_field($squarewoosync_role);
        unset($squarewoosync_user_roles[$squarewoosync_role]);
        break;
      }
    }
  }

  // Display the additional roles with checkboxes
  echo '<h2>' . esc_html__('Additional Roles', 'squarewoosync') . '</h2>';
  echo '<table class="form-table">';
  echo '<tr>';
  echo '<th><label for="squarewoosync_additional_roles">' . esc_html__('Roles', 'squarewoosync') . '</label></th>';
  echo '<td>';
  foreach ($squarewoosync_all_roles as $squarewoosync_role_key => $squarewoosync_role) {
    if ($squarewoosync_role_key !== $squarewoosync_primary_role) {
      $squarewoosync_checked = isset($squarewoosync_user_roles[$squarewoosync_role_key]) && $squarewoosync_user_roles[$squarewoosync_role_key] ? 'checked="checked"' : '';
      echo '<label>';
      echo '<input type="checkbox" name="squarewoosync_additional_roles[]" value="' . esc_attr($squarewoosync_role_key) . '" ' . esc_attr($squarewoosync_checked) . ' />';
      echo esc_html($squarewoosync_role['name']);
      echo '</label><br />';
    }
  }
  echo '</td>';
  echo '</tr>';
  echo '</table>';
}

// Save the additional roles when the user profile is updated
function squarewoosync_save_additional_user_roles($squarewoosync_user_id)
{
  // Check for nonce and permission
  if (!current_user_can('edit_user', $squarewoosync_user_id)) {
    return false;
  }

  // Get current roles
  $squarewoosync_user_roles = get_user_meta($squarewoosync_user_id, 'wp_capabilities', true);
  if (!is_array($squarewoosync_user_roles)) {
    $squarewoosync_user_roles = [];
  }

  // Filter out the primary role
  $squarewoosync_primary_role = '';
  foreach ($squarewoosync_user_roles as $squarewoosync_role => $squarewoosync_capabilities) {
    if ($squarewoosync_capabilities === true) {
      $squarewoosync_primary_role = sanitize_text_field($squarewoosync_role);
      unset($squarewoosync_user_roles[$squarewoosync_role]);
      break;
    }
  }

  // Get additional roles from the form
  $squarewoosync_additional_roles = isset($_POST['squarewoosync_additional_roles']) ? (array) $_POST['squarewoosync_additional_roles'] : [];
  $squarewoosync_additional_roles = array_map('sanitize_text_field', $squarewoosync_additional_roles);

  // Update roles
  $squarewoosync_new_roles = [];
  foreach ($squarewoosync_additional_roles as $squarewoosync_role) {
    if (isset(wp_roles()->roles[$squarewoosync_role])) {
      $squarewoosync_new_roles[$squarewoosync_role] = true;
    }
  }

  // Merge primary role back
  if ($squarewoosync_primary_role) {
    $squarewoosync_new_roles[$squarewoosync_primary_role] = true;
  }

  // Update user meta
  update_user_meta($squarewoosync_user_id, 'wp_capabilities', $squarewoosync_new_roles);
}

// Hook the functions to the appropriate actions
add_action('show_user_profile', 'squarewoosync_display_additional_user_roles');
add_action('edit_user_profile', 'squarewoosync_display_additional_user_roles');
add_action('personal_options_update', 'squarewoosync_save_additional_user_roles');
add_action('edit_user_profile_update', 'squarewoosync_save_additional_user_roles');

// Register the SquareWooSync page in the Tools menu
add_action('admin_menu', 'register_squarewoosync_tools_page');

function register_squarewoosync_tools_page()
{
  add_management_page(
    __('SquareSync for Woo', 'woocommerce'), // Page title
    __('SquareSync for Woo', 'woocommerce'), // Menu title
    'manage_options', // Capability required
    'squarewoosync-tools', // Menu slug
    'display_squarewoosync_tools_page' // Callback function
  );
}

/**
 * Display the Tools page for SquareWooSync.
 *
 * This page includes:
 *  - A setting to display line-item metadata
 *  - A button to remove all Square customer metadata
 *  - A button to remove all Square product-related metadata (square_product_id, square_variation_id, square_locations)
 *
 * @return void
 */
function display_squarewoosync_tools_page()
{
  ?>
  <div class="wrap">
    <h1><?php esc_html_e('SquareSync for Woo', 'woocommerce'); ?></h1>
    <form method="post" action="">
      <?php
      wp_nonce_field('squarewoosync_tools_nonce', 'squarewoosync_nonce');

      // -- Handle form submissions --

      // 1) Remove Square customer metadata
      if (isset($_POST['remove_metadata'])) {
        if (isset($_POST['squarewoosync_nonce']) && wp_verify_nonce($_POST['squarewoosync_nonce'], 'squarewoosync_tools_nonce')) {
          remove_square_customer_id_metadata();
          echo '<div class="updated"><p>' . __('All Square customer metadata has been removed.', 'woocommerce') . '</p></div>';
        } else {
          echo '<div class="error"><p>' . __('Invalid nonce. Please try again.', 'woocommerce') . '</p></div>';
        }
      }

      // 2) Remove all Square product metadata (square_product_id, square_variation_id, square_locations)
      if (isset($_POST['remove_product_metadata'])) {
        if (isset($_POST['squarewoosync_nonce']) && wp_verify_nonce($_POST['squarewoosync_nonce'], 'squarewoosync_tools_nonce')) {
          remove_square_product_metadata();
          echo '<div class="updated"><p>' . __('All Square product metadata has been removed.', 'woocommerce') . '</p></div>';
        } else {
          echo '<div class="error"><p>' . __('Invalid nonce. Please try again.', 'woocommerce') . '</p></div>';
        }
      }

      // 3) Save the checkbox setting
      if (isset($_POST['submit'])) {
        update_squarewoosync_tools_settings();
        echo '<div class="updated"><p>' . __('Settings saved.', 'woocommerce') . '</p></div>';
      }

      // Display the checkbox for "Display line item metadata"
      $display_metadata = get_option('squarewoosync_display_metadata', 'no');
      ?>
      <label>
        <input type="checkbox" name="squarewoosync_display_metadata" value="yes" <?php checked($display_metadata, 'yes'); ?>>
        <?php esc_html_e('Display line item metadata', 'woocommerce'); ?>
      </label>
      <?php submit_button(__('Save Settings', 'woocommerce')); ?>

      <hr />

      <h2><?php esc_html_e('Remove Square Customer Metadata', 'woocommerce'); ?></h2>
      <p><?php esc_html_e('Click the button below to remove all users\' Square customer metadata (square_customer_id).', 'woocommerce'); ?></p>
      <button type="submit" name="remove_metadata" class="button button-secondary"><?php esc_html_e('Remove Customer Metadata', 'woocommerce'); ?></button>

      <hr />

      <h2><?php esc_html_e('Remove Square Product Metadata', 'woocommerce'); ?></h2>
      <p>
        <?php esc_html_e('Click the button below to remove the following meta fields from ALL WooCommerce products:', 'woocommerce'); ?>
      <ul style="margin-left: 20px; list-style: disc;">
        <li><strong>square_product_id</strong></li>
        <li><strong>square_variation_id</strong></li>
        <li><strong>square_locations</strong></li>
      </ul>
      </p>
      <button type="submit" name="remove_product_metadata" class="button button-secondary"><?php esc_html_e('Remove Product Metadata', 'woocommerce'); ?></button>
    </form>
  </div>
<?php
}

// Save or update the SquareWooSync display metadata setting
function update_squarewoosync_tools_settings()
{
  $display_metadata = isset($_POST['squarewoosync_display_metadata']) ? 'yes' : 'no';
  update_option('squarewoosync_display_metadata', $display_metadata);
}


/**
 * Remove all Square product metadata from all WooCommerce products.
 *
 * This deletes:
 *   - square_product_id
 *   - square_variation_id
 *   - square_locations
 *
 * @return void
 */
function remove_square_product_metadata()
{
  global $wpdb;

  // Only target posts of type 'product'
  $meta_keys = [
    'square_product_id',
    'square_variation_id',
    'square_locations',
  ];

  $meta_keys_in = "'" . implode("','", array_map('esc_sql', $meta_keys)) . "'";

  // Use a subselect for product IDs
  $product_ids_subselect = "
        SELECT ID
        FROM {$wpdb->posts}
        WHERE post_type = 'product'
    ";

  // Execute the DELETE
  $wpdb->query("
        DELETE pm
        FROM {$wpdb->postmeta} pm
        WHERE pm.meta_key IN ({$meta_keys_in})
        AND pm.post_id IN ({$product_ids_subselect})
    ");
}

function remove_square_customer_id_metadata()
{
  // Fetch all WP_User objects
  $users = get_users([
    'number' => -1,
    // no 'fields' => … so you get full WP_User objects
  ]);

  error_log("zero_out_square_customer_id_meta: found " . count($users) . " users");

  $success = $fail = 0;

  foreach ($users as $user) {
    // $user is a WP_User, so $user->ID is always an int
    $user_id   = (int) $user->ID;
    $old_value = get_user_meta($user_id, 'square_customer_id', true);
    $res       = update_user_meta($user_id, 'square_customer_id', '');

    if (false === $res) {
      $fail++;
      error_log("zero_out_square_customer_id_meta: FAILED for user_id={$user_id} | old_value=" . var_export($old_value, true));
    } else {
      $success++;
      error_log("zero_out_square_customer_id_meta: OK for user_id={$user_id} | old_value=" . var_export($old_value, true));
    }
  }

  error_log("zero_out_square_customer_id_meta: DONE — {$success} succeeded, {$fail} failed");
}


// Hook to display all line item metadata on the WooCommerce admin order page if the checkbox is checked
add_action('woocommerce_before_order_itemmeta', 'display_raw_admin_order_item_meta', 10, 3);
function display_raw_admin_order_item_meta($item_id, $item, $order)
{
  if (get_option('squarewoosync_display_metadata') === 'yes') {
    // Retrieve all metadata for the line item
    $meta_data = $item->get_meta_data();

    // Display metadata directly
    if (!empty($meta_data)) {
      echo '<div class="admin-order-item-meta" style="margin-top:10px; background: #f9f9f9; padding: 10px;">';
      echo '<h4>Item Meta (Development):</h4>';
      echo '<table style="width: 100%; border-collapse: collapse;">';
      echo '<thead>';
      echo '<tr>';
      echo '<th style="border: 1px solid #ddd; padding: 8px; text-align: left;">Key</th>';
      echo '<th style="border: 1px solid #ddd; padding: 8px; text-align: left;">Value</th>';
      echo '</tr>';
      echo '</thead>';
      echo '<tbody>';

      // Loop through each meta entry and display the raw key and value in a table row
      foreach ($meta_data as $meta) {
        echo '<tr>';
        echo '<td style="border: 1px solid #ddd; padding: 8px;">' . esc_html($meta->key) . '</td>';
        echo '<td style="border: 1px solid #ddd; padding: 8px;"><pre style="margin:0;">' . esc_html(print_r($meta->value, true)) . '</pre></td>';
        echo '</tr>';
      }

      echo '</tbody>';
      echo '</table>';
      echo '</div>';
    }
  }
}



/**
 * Add a custom field for Square Customer ID in the WordPress user profile.
 */

// Add the Square Customer ID field to the user profile page
function add_square_customer_id_field($user)
{
  // Only display the field for users who can edit users
  if (!current_user_can('edit_users')) {
    return;
  }

  $square_customer_id = get_user_meta($user->ID, 'square_customer_id', true);
?>
  <h3><?php esc_html_e('Square Customer Information', 'text-domain'); ?></h3>
  <table class="form-table">
    <tr>
      <th><label for="square_customer_id"><?php esc_html_e('Square Customer ID', 'text-domain'); ?></label></th>
      <td>
        <input type="text" name="square_customer_id" id="square_customer_id" value="<?php echo esc_attr($square_customer_id); ?>" class="regular-text" />
        <p class="description"><?php esc_html_e('Edit or update the Square Customer ID associated with this user.', 'text-domain'); ?></p>
      </td>
    </tr>
  </table>
<?php
}
add_action('show_user_profile', 'add_square_customer_id_field');
add_action('edit_user_profile', 'add_square_customer_id_field');

// Save the Square Customer ID field
function save_square_customer_id_field($user_id)
{
  // Verify if the current user has permission to edit users
  if (!current_user_can('edit_user', $user_id)) {
    return false;
  }

  // Update the square_customer_id meta field
  if (isset($_POST['square_customer_id'])) {
    update_user_meta($user_id, 'square_customer_id', sanitize_text_field($_POST['square_customer_id']));
  }
}
add_action('personal_options_update', 'save_square_customer_id_field');
add_action('edit_user_profile_update', 'save_square_customer_id_field');


function my_plugin_install_tables()
{
  global $wpdb;

  $table_name = $wpdb->prefix . 'square_inventory';

  // 1. Drop the table if it exists
  $wpdb->query("DROP TABLE IF EXISTS $table_name");

  // 2. Create the table
  $charset_collate = $wpdb->get_charset_collate();
  $sql = "CREATE TABLE $table_name (
      id INT NOT NULL AUTO_INCREMENT,
      product_id VARCHAR(255) NOT NULL,
      product_data JSON NOT NULL,
      PRIMARY KEY (id),
      UNIQUE KEY (product_id)
  ) $charset_collate;";

  require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
  dbDelta($sql);
}

add_action('upgrader_process_complete', 'my_plugin_after_update', 10, 2);
function my_plugin_after_update($upgrader_object, $options)
{
  // Only run if this was a plugin update:
  if ($options['type'] === 'plugin' && !empty($options['plugins'])) {
    // Loop through the updated plugins
    foreach ($options['plugins'] as $plugin) {
      // Check if our plugin slug/file is in the list
      if (strpos($plugin, 'squarewoosync.php') !== false) {
        // If it matches your main plugin file
        my_plugin_install_tables(); // Drop/recreate
      }
    }
  }
}