Jake Vanderwerf
2026-07-09 c68aefb847b09daa0697de7684d3451e2e68ce1e
inc/integrations/Helcim.php
@@ -2,6 +2,7 @@
namespace JVBase\integrations;
use Exception;
use JVBase\meta\Meta;
use WP_Error;
use WP_Post;
use JVBase\ui\Checkout;
@@ -25,6 +26,7 @@
 */
class Helcim extends Integrations
{
   protected static string $syncCustomer = 'helcim_sync_customer';
   protected string $service_name = 'helcim';
   protected string|array $apiBase = 'https://api.helcim.com/v2';
@@ -40,7 +42,17 @@
      'per_hour'   => 1000
   ];
   public function __construct(?int $userID = null)
   protected static array $instances = [];
   public static function getInstance(?int $userID = null):self
   {
      $key = is_null($userID) ? 'base' : $userID;
      if (!array_key_exists($key, self::$instances)) {
         self::$instances[$key] = new self($userID);
      }
      return self::$instances[$key];
   }
   protected function __construct(?int $userID = null)
   {
      $this->title = 'Helcim';
      $this->icon  = 'credit-card';
@@ -170,11 +182,30 @@
      }
   }
   public function getAdditionalFields(?string $content_type = null):array
   {
      if ($content_type === 'customer') {
         $array = $this->getCustomerFields();
         return array_combine(
            array_map(fn($k) => '_square_' . $k, array_keys($array)),
            $array
         );
      }
      return array_combine(
         array_map(fn($k) => 'hc_' . $k, array_keys($this->getHelcimMeta($content_type))),
         $this->getHelcimMeta($content_type)
      );
   }
   protected function getCustomerFields():array
   {
      return [];
   }
   /**
    * Get Helcim product meta fields by type.
    *
    * Used by FieldRegistry when 'use_helcim' => true is set
    * in a JVB_CONTENT definition.
    * Used by Registrar.php  when helcim is configured
    */
   public function getHelcimMeta(?string $type = null): array
   {
@@ -682,9 +713,6 @@
         return $desc;
      }, 10, 2);
      // Register queue operation types with IntegrationExecutor
      $this->registerQueueTypes();
      // Register webhook endpoint (handled by parent)
      $this->registerWebhookEndpoint();
   }
@@ -731,38 +759,16 @@
   }
   protected function registerQueueTypes(): void
   protected function registerAdditionalQueueTypes(IntegrationExecutor $executor): void
   {
      $queue    = JVB()->queue();
      $executor = new IntegrationExecutor();
      $queue->registry()->register('helcim_sync_to', new TypeConfig(
         executor:  $executor,
         chunkKey:  'items',
         chunkSize: 10,
         maxRetries: 3
      ));
      $queue->registry()->register('helcim_sync_from', new TypeConfig(
         executor:  $executor,
         chunkKey:  'items',
         chunkSize: 10,
         maxRetries: 3
      ));
      $queue->registry()->register('helcim_delete_from', new TypeConfig(
         executor:  $executor,
         chunkKey:  'external_ids',
         chunkSize: 20,
         maxRetries: 2
      ));
      $queue->registry()->register('helcim_import', new TypeConfig(
      $queue->registry()->register(self::$import, new TypeConfig(
         executor:   $executor,
         maxRetries: 3
      ));
      $queue->registry()->register('helcim_sync_customer', new TypeConfig(
      $queue->registry()->register(self::$syncCustomer, new TypeConfig(
         executor:   $executor,
         maxRetries: 2
      ));
@@ -999,22 +1005,34 @@
   protected function handleTheSavePost(int $postID, \WP_Post $post, bool $update, array $settings): void
   {
      $fields = $this->getSyncFields($postID, 'post', ['share_to_helcim', 'schedule_helcim']);
      if (empty($fields['share_to_helcim'])) {
         return;
      }
      // Uses IntegrationExecutor via TypeRegistry instead of FilteredExecutor
      $this->queueOperation('sync_to', [
      error_log('==== [Helcim]::handleTheSavePost ====');
      $this->queueOperation(self::$syncTo, [
         'items'   => [$postID],
         'user_id' => $this->userID,
         'user'      => user_can($post->post_author, 'manage_options') ? null : $post->post_author
      ], [
         'priority' => 'high',
         'delay'    => 30,
      ]);
      Meta::forPost($postID)->set('_'.$this->service_name.'_sync_status', 'queued');
   }
   /**
    * Handle post deletion
    */
   public function handleDeletePost(int $postID): void
   {
      $item_id = Meta::forPost($postID)->get("_{$this->service_name}_item_id");
      update_post_meta($postID, BASE . '_helcim_sync_status', 'queued');
      if (empty($item_id)) {
         return;
      }
      $this->queueOperation(self::$deleteFrom, [
         'external_ids' => [$item_id],
         'post_id'      => $postID,
      ], [
         'priority' => 'high',
      ]);
   }
   protected function handleImportFromHelcim(): array