Jake Vanderwerf
2026-04-15 c4aa5cdb5e90ad4b420e22772797d16980232a2b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
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_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.'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
        ));
    }
}