Jake Vanderwerf
2026-05-01 48721c85ebcfa973ee81719d2467ca80e4253dc9
inc/managers/InvitationsManager.php
@@ -5,7 +5,7 @@
use JVBase\managers\queue\executors\InvitationExecutor;
use JVBase\managers\queue\TypeConfig;
use JVBase\registrar\Registrar;
use JVBase\utility\Features;
use JVBase\base\Site;
use WP_Error;
if (!defined('ABSPATH')) {
@@ -20,9 +20,12 @@
   protected Cache $cache;
   public function __construct()
   {
      $this->defineTable();
      if (!isset($this->table)) {
         return;
      }
      $this->setInviteConfig();
      $this->cache = Cache::for('invitations');
      $this->table = CustomTable::for('invitations');
      add_action('init', [$this, 'registerInvitationExecutors'], 5);
      add_action('user_register', [$this, 'checkInvitation']);
@@ -31,6 +34,61 @@
      add_filter(BASE . 'handle_bulk_operation', [$this, 'processOperation'], 10, 3);
   }
   public function defineTable():void
   {
      $terms = Registrar::getFeatured('invitable', 'term');
      $membership = Site::membership();
      $roles = ($membership) ? Site::membership()->has('can_invite') :[];
      if (empty($terms) && empty($roles)) {
         return;
      }
      $table = CustomTable::for('invitations');
      $columns = [
         'id'           => 'bigint(20) unsigned NOT NULL AUTO_INCREMENT',
         'name'            => 'varchar(255) NOT NULL',
         'email'           => 'varchar(255) NOT NULL',
         'invitation_token'   => 'varchar(255) NOT NULL',
         'invited_role'    => 'varchar(50) NOT NULL',    //Role being invited to
         'status'       => "ENUM('pending','accepted','rejected','expired','revoked') DEFAULT 'pending'",
         'inviters'        => 'JSON NOT NULL',        // Array of {user_id, invited_at}
         'new_user_id'     => $table->getUserIDType().' DEFAULT NULL',
         'expires_at'      => 'datetime NOT NULL',
         'accepted_at'     => 'datetime DEFAULT NULL',
         'created_at'      => 'datetime NOT NULL DEFAULT CURRENT_TIMESTAMP',
         'updated_at'      => 'datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'
      ];
      foreach ($terms as $tax) {
         $columns["to_{$tax}"] = $table->getTermIDType().' DEFAULT NULL';
      }
      $table->setColumns($columns);
      $table->setKeys([
         ['key' => 'PRIMARY', 'value' => '(`id`)'],
         ['key' => 'UNIQUE', 'value' => '`unique_email_role` (`email`, `invited_role`)'],
         '`token_lookup` (`invitation_token`)',
         '`status_expiry` (`status`, `expires_at`)',
         '`role_status` (`invited_role`, `status`)',
         '`email_status` (`email`, `status`)'
      ]);
      $constraints = [];
      $base = BASE;
      global $wpdb;
      foreach ($terms as $tax) {
         $constraints[] = "CONSTRAINT `{$base}invitations_{$tax}_fk` FOREIGN KEY (`to_{$tax}`) REFERENCES `{$wpdb->terms}` (`term_id`)
            ON DELETE SET NULL";
      }
      $constraints[] = "CONSTRAINT `{$base}invitations_user_fk`  FOREIGN KEY (`new_user_id`) REFERENCES `{$table->getUserTable()}` (`ID`)
        ON DELETE SET NULL";
      $table->setConstraints($constraints);
      $table->defineTable();
      $this->table = $table;
   }
   protected function setInviteConfig():void
   {
      $this->inviteConfig = get_option(BASE.'invitation_config', [