From 0afb2c0046b55c123eafb4ab9ee77efa68d12463 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Sat, 06 Jun 2026 17:15:31 +0000
Subject: [PATCH] =Starting the Favourites.js setup, converting previous Northeh stuff to new Registrar, fixing up Square.php integration to match

---
 inc/managers/InvitationsManager.php |  146 ++++++++++++++++++++++++++++++++++++------------
 1 files changed, 110 insertions(+), 36 deletions(-)

diff --git a/inc/managers/InvitationsManager.php b/inc/managers/InvitationsManager.php
index ebf3c92..c8d17a2 100644
--- a/inc/managers/InvitationsManager.php
+++ b/inc/managers/InvitationsManager.php
@@ -4,7 +4,8 @@
 use Exception;
 use JVBase\managers\queue\executors\InvitationExecutor;
 use JVBase\managers\queue\TypeConfig;
-use JVBase\utility\Features;
+use JVBase\registrar\Registrar;
+use JVBase\base\Site;
 use WP_Error;
 
 if (!defined('ABSPATH')) {
@@ -16,10 +17,15 @@
 	protected array $inviteConfig;
 	protected CustomTable $table;
 	protected int $expiryDays = 14;
+	protected Cache $cache;
 	public function __construct()
 	{
+		$this->defineTable();
+		if (!isset($this->table)) {
+			return;
+		}
 		$this->setInviteConfig();
-		$this->table = CustomTable::for('invitations');
+		$this->cache = Cache::for('invitations')->user();
 		add_action('init', [$this, 'registerInvitationExecutors'], 5);
 
 		add_action('user_register', [$this, 'checkInvitation']);
@@ -28,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', [
@@ -86,46 +147,58 @@
 	 */
 	protected function buildInviteTypes(): array
 	{
-		$types = [];
+		$invitable = $this->cache->remember(
+			'invitableTypes',
+			function () {
+				$types = [];
 
-		// Global invitations from JVB_MEMBERSHIP
-		if (!empty(JVB_MEMBERSHIP['can_invite'])) {
-			foreach (JVB_MEMBERSHIP['can_invite'] as $role => $canInvite) {
-				$types[$role] = [
-					'can_invite' => $canInvite,
-					'to_terms' => []
-				];
-			}
-		}
+				// Global invitations from JVB_MEMBERSHIP
+				if (!empty(JVB_MEMBERSHIP['can_invite'])) {
+					foreach (JVB_MEMBERSHIP['can_invite'] as $role => $canInvite) {
+						$types[$role] = [
+							'can_invite' => $canInvite,
+							'to_terms' => []
+						];
+					}
+				}
 
-		// Term invitations from invitable content taxonomies
-		foreach (JVB_TAXONOMY as $taxonomy => $config) {
-			if (Features::forTaxonomy($taxonomy)->has('invitable') &&
-				Features::forTaxonomy($taxonomy)->has('is_content') &&
-				Features::forTaxonomy($taxonomy)->has('is_ownable')) {
+				// Term invitations from invitable content taxonomies
+				$invitable = Registrar::getFeatured('invitable', 'term');
+				$content = Registrar::getFeatured('is_content', 'term');
+				$ownable = Registrar::getFeatured('is_ownable', 'term');
+				$taxonomies = array_intersect($invitable, $content, $ownable);
+				if (!empty($taxonomies)) {
+					$users = Registrar::getRegistered('user');
+				}
+				foreach ($taxonomies as $taxonomy) {
+					$registrar = Registrar::getInstance($taxonomy);
 
-				$forContent = $config['for_content'] ?? [];
-				foreach ($forContent as $content) {
-					// Find which user roles can create this content
-					foreach (JVB_USER as $role => $userConfig) {
-						$creatable = Features::forUser($role)->getCreatableContent();
-						if (in_array($content, $creatable)) {
-							if (!isset($types[$role])) {
-								$types[$role] = [
-									'can_invite' => [],
-									'to_terms' => []
-								];
-							}
-							if (!in_array($taxonomy, $types[$role]['to_terms'])) {
-								$types[$role]['to_terms'][] = $taxonomy;
+					foreach ($registrar->registrar->for as $content) {
+						// Find which user roles can create this content
+						foreach ($users as $user) {
+							$userRegistrar = Registrar::getInstance($user);
+
+							$creatable = $userRegistrar->getCreatable();
+							if (in_array($content, $creatable)) {
+								if (!isset($types[$role])) {
+									$types[$role] = [
+										'can_invite' => [],
+										'to_terms' => []
+									];
+								}
+								if (!in_array($taxonomy, $types[$role]['to_terms'])) {
+									$types[$role]['to_terms'][] = $taxonomy;
+								}
 							}
 						}
 					}
 				}
-			}
-		}
 
-		return $types;
+				return $types;
+			}
+		);
+		return $invitable;
+
 	}
 
 	/******************************************************************
@@ -467,8 +540,9 @@
 
 			$term = get_term($termID, BASE . $taxonomy);
 			if ($term && !is_wp_error($term)) {
-				$config = JVB_TAXONOMY[$taxonomy] ?? [];
-				$singular = $config['singular'] ?? $taxonomy;
+				$registrar = Registrar::getInstance($taxonomy);
+
+				$singular = $registrar ? $registrar->getSingular() : $taxonomy;
 
 				$termContent[] = sprintf(
 					"<p>%s has also invited you to join %s. You'll be automatically added to this %s when you register.</p>",

--
Gitblit v1.10.0