Jake Vanderwerf
2026-02-04 2127b1bdd73ecd2423e443992da4b442f5a3c1a3
inc/integrations/Square.php
@@ -1,8 +1,8 @@
<?php
namespace JVBase\integrations;
use JVBase\meta\MetaForm;
use JVBase\meta\MetaManager;
use JVBase\meta\Form;
use JVBase\meta\Meta;
use Exception;
use JVBase\registry\PostTypeRegistrar;
use WP_Error;
@@ -379,8 +379,6 @@
    */
   protected function exchangeOAuthCode(string $code): ?array
   {
      error_log('Exchanging tokens with credentials: '.print_r($this->credentials, true));
      $this->ensureInitialized();
      // Prepare the request body as an array
@@ -406,7 +404,6 @@
      }
      $data = json_decode(wp_remote_retrieve_body($response), true);
      error_log('OAuth Response: '.print_r($data, true));
      if (isset($data['access_token'])) {
         return [
            'access_token' => $data['access_token'],
@@ -468,7 +465,6 @@
      $data = json_decode(wp_remote_retrieve_body($response), true);
      error_log('RefreshAccessToken Response: '.print_r($data, true));
      if (isset($data['access_token'])) {
         $this->credentials['access_token'] = $data['access_token'];
         $this->credentials['expires_at'] = time() + ($data['expires_in'] ?? 2592000); // 30 days
@@ -491,7 +487,6 @@
   {
      // Skip if we don't have credentials yet (during OAuth flow)
      if (empty($this->credentials['access_token'])) {
         error_log('[Square] Skipping loadLocations - no access token yet');
         return;
      }
      try {
@@ -862,8 +857,7 @@
      if (is_singular(BASE.'dash') || is_post_type_archive(BASE.'dash')) {
         return $actions;
      }
      $meta = new MetaForm();
      $form = '<aside id="cart" class="right">
      $form = '<aside id="cart" class="right main">
         <form id="checkout" data-form-id="checkout" data-save="checkout">';
            $tabs = [
@@ -879,33 +873,33 @@
         'description' => 'Securely checkout with your name, email, and payments processed by Square.',
         'content'   => '<div class="checkout-section">
                        <h3>Customer Information</h3>
                        '.$meta->return('cart_name', null, [
                        '.Form::render('cart_name', null, [
                           'type'      => 'text',
                           'label'     => 'Your Name',
                           'required'  => true,
                           'autocomplete' => 'name'
                        ]).
                        $meta->return('cart_email', null, [
                        Form::render('cart_email', null, [
                           'type'      => 'email',
                           'label'     => 'Your Email',
                           'required'  => true,
                           'autocomplete'=> 'email',
                        ]).
                        $meta->return('cart_phone', null, [
                        Form::render('cart_phone', null, [
                           'type'      => 'tel',
                           'label'     => 'Your Phone',
                           'required'  => true,
                           'autocomplete'=> 'phone'
                        ]).'
                        <h3>Pickup Details</h3>'.
                        $meta->return('pickup_time', null, [
                        Form::render('pickup_time', null, [
                           'type'      => 'datetime',
                           'label'     => 'Pickup Type',
                           'min'    => '11:00',
                           'max'    => '20:00',
                           'required'  => true,
                        ]).
                        $meta->return('special_instructions', null, [
                        Form::render('special_instructions', null, [
                           'type'      => 'textarea',
                           'label'     => 'Special Instructions',
                           'quill'     => true,
@@ -949,11 +943,11 @@
               <label for="quantity"></label>
               <div class="quantity field" data-min="0" data-max="50" data-step="1" data-price="17" data-id="">
                  <button type="button" class="decrease"aria-label="Decrease Add to Order">'.jvbIcon('minus').'</button>
                  <button type="button" class="decrease"aria-label="Decrease Add to Order">'.jvbIcon('minus-square').'</button>
                  <input type="number" id="quantity" name="quantity" value="0" min="0" max="50" step="1" class="quantity-input">
                  <button type="button" class="increase" aria-label="Increase Add to Order">'.jvbIcon('add').'</button>
                  <button type="button" class="increase" aria-label="Increase Add to Order">'.jvbIcon('plus-square').'</button>
               </div>
            </td>
            <td class="price">
@@ -977,7 +971,7 @@
      $actions[] = [
         'button' =>    '<button type="button" class="toggle-cart row" title="Your Cart" data-action="toggle-cart" aria-label="Open Cart" aria-controls="checkout" aria-expanded="false">
               '.jvbIcon('cart').'<span class="abs"></span><span class="abs count"></span>
               '.jvbIcon('shopping-cart').'<span class="abs"></span><span class="abs count"></span>
            </button>',
         'content' =>   $form
      ];
@@ -1083,7 +1077,6 @@
    */
   protected function handleTheSavePost(int $postID, \WP_Post $post, bool $update, array $settings): void
   {
      error_log('Queuing Sync to Square');
      // Queue the sync operation
      $this->queueOperation('sync_to_square', [
         'items' => [$postID],
@@ -1325,7 +1318,7 @@
         return new WP_Error('post_not_found', "Post $postID not found");
      }
      $meta = new MetaManager($postID, 'post');
      $meta = Meta::forPost($postID);
      $post_type = get_post_type($postID);
      // Get existing Square catalog ID if it exists
@@ -1350,10 +1343,10 @@
      }
      // Add variations
      $variations = $meta->getValue('product_variations');
      $variations = $meta->get('product_variations');
      if (empty($variations)) {
         // Create default variation if none exist
         $price = floatval($meta->getValue('price') ?: 0);
         $price = floatval($meta->get('price') ?: 0);
         $catalog_object['item_data']['variations'][] = [
            'type' => 'ITEM_VARIATION',
            'id' => $existing_square_id ? null : '#'.BASE.'menu_item_' . $postID . '_var_default',
@@ -1406,7 +1399,7 @@
      }
      // Add modifiers if they exist
      $modifiers = $meta->getValue('modifiers');
      $modifiers = $meta->get('modifiers');
      if (!empty($modifiers)) {
         $modifier_ids = [];
         foreach ($modifiers as $modifier) {
@@ -1422,7 +1415,7 @@
      }
      // Add tax settings
      $tax_ids = $meta->getValue('tax_ids');
      $tax_ids = $meta->get('tax_ids');
      if (!empty($tax_ids)) {
         $catalog_object['item_data']['tax_ids'] = $tax_ids;
      }
@@ -1849,20 +1842,22 @@
      $message = sprintf(
         "Welcome to %s!\n\n" .
         "Your account has been created. Please click the link below to set your password:\n\n" .
         "Your account has been created. Please click the button below to set your password:\n\n" .
         "%s\n\n" .
         "Once you've set your password, you can log in to:\n" .
         "Or, copy and paste the link below:\n\n".
         "%s\n\n" .
         "Once you've set your password, you can:\n" .
         "- View your order history\n" .
         "- Save your favorite items\n" .
         "- Speed up checkout with saved payment methods\n\n" .
         "If you didn't create this account, please ignore this email.\n\n" .
         "Thanks,\n%s",
         "Thanks,\n",
         $site_name,
         $reset_url,
         $site_name
         JVB()->email()->button('Reset Password', $reset_url),
         JVB()->email()->link($reset_url),
      );
      jvbMail(
      JVB()->email()->sendEmail(
         $user->user_email,
         sprintf('[%s] Welcome! Set Your Password', $site_name),
         $message
@@ -1906,11 +1901,10 @@
      // Send notification
      $user = get_user_by('ID', $user_id);
      if ($user) {
         wp_mail(
         JVB()->email()->sendEmail(
            $user->user_email,
            '['.get_bloginfo('name').'] Security Code',
            'For your security, enter this code to continue accessing your account and saved payment methods.',
            ['Content-Type: text/html; charset=UTF-8']
         );
      }
   }
@@ -2013,7 +2007,7 @@
      if ($wp_order_id) {
         // Update the post meta
         $meta = new MetaManager($wp_order_id, 'post');
         $meta = Meta::forPost($wp_order_id);
         $updates = [
            'status' => $state,
            'updated_at' => current_time('mysql')
@@ -2441,7 +2435,7 @@
    */
   private function mapSquareFieldsToWordPress(int $post_id, array $item): void
   {
      $meta = new MetaManager($post_id, 'post');
      $meta = Meta::forPost($post_id);
      $field_map = $this->getFieldMapping(get_post_type($post_id));
      $values_to_save = [];
@@ -2577,7 +2571,7 @@
         update_user_meta($user->ID, BASE . '_square_customer_updated', current_time('mysql'));
         // Clear cached customer data
         $this->cache->delete('square_customer_' . $user->ID);
         $this->cache->forget('square_customer_' . $user->ID);
      }
      return true;
@@ -2808,7 +2802,6 @@
         // Validate environment setting
         if (isset($credentials['environment'])) {
            error_log('Environment: '.print_r($credentials['environment'], true));
            $validEnvironments = ['sandbox', 'production'];
            if (!in_array($credentials['environment'], $validEnvironments)) {
               $this->logError('Invalid environment setting', [
@@ -3595,10 +3588,9 @@
      }
      // Save all order meta
      $meta = new MetaManager($order_post_id, 'post');
      $meta = Meta::forPost($order_post_id);
      $fields = $this->getSquarePostConfig('_sq_orders')['fields'];
      unset($fields['post_title']);
      $meta->setFieldConfig($fields);
      $meta->setAll([
         'square_order_id' => $order_data['square_order_id'],