Jake Vanderwerf
2026-07-10 f94860aacd6200fb24c9e7431eb379a368cb392d
inc/integrations/CredentialsManager.php
@@ -1,6 +1,8 @@
<?php
namespace JVBase\integrations;
use JVBase\managers\CustomTable;
if (!defined('ABSPATH')) {
   exit;
}
@@ -9,12 +11,39 @@
{
   private static ?CredentialsManager $instance = null;
   private string $encryption_key;
   private string $option_prefix = 'jvb_integration_';
   private string $user_meta_prefix = 'jvb_integration_';
   private CustomTable $table;
   private function __construct()
   {
      $this->encryption_key = $this->getEncryptionKey();
      $this->getEncryptionKey();
      $this->defineTable();
   }
   protected function defineTable():void
   {
      $table = CustomTable::for('integrations');
      $table->setColumns([
         'id'        => 'bigint(20) unsigned NOT NULL AUTO_INCREMENT',
         'user_id'      => $table->getUserIDType().' NOT NULL',
         'integration'  => "ENUM('bluesky','cloudflare','facebook','google-maps','gmb','helcim','instagram','postmark','square','umami') NOT NULL",
         'credentials'  => 'varchar(255) DEFAULT NULL',
         'created_at'   => 'datetime DEFAULT CURRENT_TIMESTAMP',
         'updated_at'   => 'datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'
      ]);
      $table->setKeys([
         ['key' => 'PRIMARY', 'value' => '(`id`)'],
         ['key' => 'UNIQUE', 'value' => '`user_integration` (`user_id`, `integration`)'],
         '`user` (`user_id`)',
      ]);
      $base = BASE;
      $table->setConstraints([
         "CONSTRAINT `{$base}integrations_user` FOREIGN KEY (`user_id`)
         REFERENCES `{$table->getUserTable()}` (`ID`) ON DELETE CASCADE"
      ]);
      $table->defineTable();
      $this->table = $table;
   }
   public static function getInstance(): CredentialsManager
@@ -30,18 +59,11 @@
    */
   public function storeCredentials(string $service, array $credentials, ?int $userID = null): bool
   {
      $credentials['updated_at'] = time();
      if ($userID) {
         return $this->storeUserCredentials($service, $credentials, $userID);
      }
      $encrypted_data = $this->encrypt(json_encode($credentials));
      return update_option($this->option_prefix . $service, $encrypted_data);
   }
   public function storeUserCredentials(string $service, array $credentials, int $userID): bool
   {
      $encrypted_data = $this->encrypt(json_encode($credentials));
      return update_user_meta($userID, $this->user_meta_prefix . $service, $encrypted_data);
      $find = $this->findBy($service, $userID);
      $update = [
         'credentials'  => $this->encrypt(json_encode($credentials))
      ];
      return (bool)$this->table->findOrCreate($find, $update);
   }
   /**
@@ -49,30 +71,13 @@
    */
   public function getCredentials(string $service, ?int $userID = null): array
   {
      if ($userID) {
         return $this->getUserCredentials($service, $userID);
      }
      $encrypted_data = get_option($this->option_prefix . $service, '');
      if (empty($encrypted_data)) {
      $find = $this->findBy($service, $userID);
      $credentials = $this->table->pluck('credentials', $find);
      if (empty($credentials)) {
         return [];
      }
      $decrypted_data = $this->decrypt($encrypted_data);
      return $decrypted_data ? json_decode($decrypted_data, true) : [];
   }
   public function getUserCredentials(string $service, int $userID): array
   {
      $encrypted_data = get_user_meta($userID, $this->user_meta_prefix . $service, true);
      if (empty($encrypted_data)) {
         return [];
      }
      $decrypted_data = $this->decrypt($encrypted_data);
      return $decrypted_data ? json_decode($decrypted_data, true) : [];
      $decrypted_data = $this->decrypt($credentials[0]);
      return empty($decrypted_data) ? [] : json_decode($decrypted_data, true);
   }
   /**
@@ -80,16 +85,16 @@
    */
   public function deleteCredentials(string $service, ?int $userID = null): bool
   {
      if ($userID) {
         return $this->deleteUserCredentials($service, $userID);
      }
      return delete_option($this->option_prefix . $service);
      $find = $this->findBy($service, $userID);
      return $this->table->delete($find);
   }
   public function deleteUserCredentials(string $service, int $userID): bool
   protected function findBy(string $service, ?int $userID = null):array
   {
      return delete_user_meta($userID, $this->user_meta_prefix . $service);
      return [
         'user_id'   => is_null($userID) ? 0 : $userID,
         'integration'=> $service
      ];
   }
   /**
@@ -97,31 +102,15 @@
    */
   public function hasCredentials(string $service, ?int $userID = null): bool
   {
      if ($userID) {
         return $this->hasUserCredentials($service, $userID);
      }
      return !empty(get_option($this->option_prefix . $service, ''));
   }
   public function hasUserCredentials(string $service, int $userID): bool
   {
      $encrypted_data = get_user_meta($userID, $this->user_meta_prefix . $service, true);
      return !empty($encrypted_data);
      return !empty($this->getCredentials($service, $userID));
   }
   /**
    * Get or create encryption key
    */
   private function getEncryptionKey(): string
   private function getEncryptionKey():void
   {
      $key = get_option('jvb_encryption_key');
      if (!$key) {
         $key = base64_encode(random_bytes(32));
         update_option('jvb_encryption_key', $key);
      }
      return base64_decode($key);
      $this->encryption_key = JVB_KEY;
   }
   /**
@@ -151,14 +140,6 @@
    */
   public function getUsersWithCredentials(string $service): array
   {
      global $wpdb;
      $meta_key = $this->user_meta_prefix . $service;
      $results = $wpdb->get_results($wpdb->prepare(
         "SELECT user_id FROM {$wpdb->usermeta} WHERE meta_key = %s",
         $meta_key
      ));
      return wp_list_pluck($results, 'user_id');
      return $this->table->pluck('user_id', ['integration' => $service]);
   }
}