From 48721c85ebcfa973ee81719d2467ca80e4253dc9 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Fri, 01 May 2026 17:30:03 +0000
Subject: [PATCH] =Edmonton Ink hard test begins! Real testing of the managers and reset routes will commence. So far, just ensuring our classes are all loaded correctly: Site() and its sub-classes Membership, Login, etc. Care should be taken to load conditionally on 'init', as we finish defining most settings by 'plugins_loaded' at priority 5

---
 inc/registrar/helpers/MakeTrackChanges.php |  121 ++++++++++++++++++++++++++++++++++++++++
 1 files changed, 121 insertions(+), 0 deletions(-)

diff --git a/inc/registrar/helpers/MakeTrackChanges.php b/inc/registrar/helpers/MakeTrackChanges.php
index 4019f1f..6e4d57a 100644
--- a/inc/registrar/helpers/MakeTrackChanges.php
+++ b/inc/registrar/helpers/MakeTrackChanges.php
@@ -1,10 +1,131 @@
 <?php
 namespace JVBase\registrar\helpers;
 
+use JVBase\managers\CustomTable;
+
 if (!defined('ABSPATH')) {
 	exit;
 }
 
 class MakeTrackChanges {
+	protected string $slug;
+	protected string $based;
+	protected CustomTable $table;
+	public function __construct(string $slug) {
+		$this->slug = $slug;
+		$this->based = jvbCheckBase($slug);
+		$this->defineTables();
 
+		add_action('set_object_terms', [$this, 'trackHistory'], 10, 6);
+	}
+	public function defineTables():void
+	{
+		$table = CustomTable::for('history_'.$this->slug);
+
+		$table->setColumns([
+			'id'			=> 'bigint(20) unsigned NOT NULL AUTO_INCREMENT',
+			'user_id'		=> "{$table->getUserIDType()} NOT NULL",
+			'profile_id'	=> "{$table->getPostIDType()} NOT NULL",
+			'role'			=> 'varchar(255) NOT NULL',
+			'term_id'		=> "{$table->getTermIDType()} NOT NULL",
+			'start_date'	=> 'date DEFAULT NULL',
+			'end_date'		=> 'date DEFAULT NULL',
+			'locked'		=> 'tinyint(1) NOT NULL DEFAULT 0',
+			'created_at'	=> 'timestamp DEFAULT CURRENT_TIMESTAMP',
+			'updated_at'	=> 'timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP',
+		]);
+
+		$table->setKeys([
+			['key' => 'PRIMARY', 'value' => '(`id`)'],
+			['key' => 'UNIQUE', 'value' => 'profile_term_date (`profile_id`, `term_id`, `start_date`)'],
+			'content_role (`term_id`, `role`)',
+			'user_id (`user_id`)',
+			'profile_id (`profile_id`)',
+			'term_id (`term_id`)',
+		]);
+
+		$base = BASE;
+		$table->setConstraints([
+			"CONSTRAINT `{$base}{$this->slug}_history_user` FOREIGN KEY (`user_id`)
+			REFERENCES `{$table->getUserTable()}` (`ID`) ON DELETE CASCADE",
+			"CONSTRAINT `{$base}{$this->slug}_history_profile` FOREIGN KEY (`profile_id`)
+			REFERENCES `{$table->getPostTable()}` (`ID`) ON DELETE CASCADE"
+		]);
+
+		$table->defineTable();
+		$this->table = $table;
+	}
+
+	public function trackHistory(int $object_id, array $terms, array $tt_ids, string $taxonomy, bool $append, array $old_tt_ids):void
+	{
+		if ($taxonomy !== $this->based) {
+			return;
+		}
+
+		$user = get_post_meta($object_id, BASE.'profile_link', true);
+		if (empty($author)) {
+			$user = get_post($object_id)->post_author??false;
+			if (!$user) {
+				return;
+			}
+		}
+		$userObj = get_userdata($user);
+		if (!$userObj) {return;}
+
+		$role = jvbUserRole($user);
+
+		$new = array_diff($tt_ids, $old_tt_ids);
+		$old = array_diff($old_tt_ids, $new);
+
+		$this->table->transaction(
+			function() use ($new, $old, $role, $user, $object_id) {
+				foreach ($new as $newTerm) {
+					$termID = $this->getTermIDFromTTID($newTerm);
+
+					$this->table->findOrCreate([
+						'user_id'	=> $user,
+						'profile_id'=> $object_id,
+						'role'		=> $role,
+						'term_id'	=> $termID,
+						'locked'	=> 0
+					], [
+						'start_date'	=> date('Y-m-d')
+					]);
+				}
+
+				foreach ($old as $oldTerm) {
+					$termID = $this->getTermIDFromTTID($oldTerm);
+
+					$this->table->update(
+						[
+							'end_date'	=> date('Y-m-d'),
+							'locked'	=> 1
+						],
+						[
+							'user_id'	=> $user,
+							'profile_id'=> $object_id,
+							'term_id'	=> $termID,
+							'locked'	=> 0
+						]);
+				}
+			}
+		);
+
+
+	}
+
+	/**
+	 * Helper function to get term_id from term_taxonomy_id
+	 * @param int $tt_id
+	 *
+	 * @return int
+	 */
+	private function getTermIDFromTTID(int $tt_id):int
+	{
+		global $wpdb;
+		return $wpdb->get_var($wpdb->prepare(
+			"SELECT term_id FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id = %d",
+			$tt_id
+		));
+	}
 }

--
Gitblit v1.10.0