PluginProbe ʕ •ᴥ•ʔ
Microsoft Clarity / 0.10.29
Microsoft Clarity v0.10.29
0.10.29 0.10.28 0.10.27 0.10.26 0.10.25 0.10.24 0.8.0 0.9.0 0.9.1 0.9.2 0.9.3 0.9.4 trunk 0.10.0 0.10.1 0.10.10 0.10.11 0.10.12 0.10.13 0.10.14 0.10.15 0.10.16 0.10.17 0.10.18 0.10.19 0.10.2 0.10.20 0.10.21 0.10.22 0.10.23 0.10.3 0.10.4 0.10.5 0.10.6 0.10.7 0.10.8 0.10.9 0.2 0.4 0.5 0.6 0.6.1 0.7 0.7.1 0.7.2 0.7.3 0.7.4 0.7.5
microsoft-clarity / clarity-collect-storage.php
microsoft-clarity Last commit date
includes 3 days ago js 1 week ago LICENSE.txt 5 years ago clarity-collect-batch.php 6 months ago clarity-collect-storage.php 6 months ago clarity-hooks.php 6 months ago clarity-page.php 1 week ago clarity-server-analytics.php 2 months ago clarity.php 3 days ago index.php 5 years ago readme.txt 3 days ago
clarity-collect-storage.php
168 lines
1 <?php
2
3 // Storage helpers for collect event batching.
4
5 const CLARITY_COLLECT_TABLE_NAME = 'clarity_collect_events';
6
7 /**
8 * Creates the collect events table.
9 */
10 function clarity_create_collect_events_table()
11 {
12 global $wpdb;
13
14 if (!$wpdb->ready) {
15 return;
16 }
17
18 $table = clarity_get_collect_events_table_name();
19 $charset_collate = $wpdb->get_charset_collate();
20
21 $sql = "CREATE TABLE $table (
22 id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
23 payload longtext NOT NULL,
24 created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
25 PRIMARY KEY (id)
26 ) ENGINE=InnoDB $charset_collate;";
27
28 require_once ABSPATH . 'wp-admin/includes/upgrade.php';
29 dbDelta($sql);
30 }
31
32 /**
33 * Drops the collect events table.
34 */
35 function clarity_drop_collect_events_table()
36 {
37 global $wpdb;
38
39 if (!$wpdb->ready) {
40 return;
41 }
42
43 $table = clarity_get_collect_events_table_name();
44 $wpdb->query("DROP TABLE IF EXISTS $table");
45 }
46
47 /**
48 * Inserts a collect event payload.
49 *
50 * @param array $event The event payload to store.
51 * @return bool True when stored successfully.
52 */
53 function clarity_insert_collect_event($event)
54 {
55 global $wpdb;
56
57 if (!$wpdb->ready) {
58 return false;
59 }
60
61 if (!clarity_collect_events_table_exists()) {
62 clarity_create_collect_events_table();
63 }
64
65 clarity_maybe_schedule_collect_recurring();
66
67 $payload = wp_json_encode($event);
68 if ($payload === false) { // wp_json_encode returns false on failure
69 return false;
70 }
71
72 $table = clarity_get_collect_events_table_name();
73 $result = $wpdb->insert(
74 $table,
75 array(
76 'payload' => $payload,
77 ),
78 array('%s') // payload is a JSON string
79 );
80
81 return $result !== false;
82 }
83
84 /**
85 * Fetches and deletes pending events in one transaction.
86 *
87 * @return array Rows fetched for processing.
88 */
89 function clarity_fetch_and_delete_pending_events_transactionally()
90 {
91 global $wpdb;
92
93 $table = clarity_get_collect_events_table_name();
94 $committed = false;
95
96 try {
97 // Uses READ COMMITTED isolation and row locks to avoid concurrent processing
98 // of the same rows while allowing concurrent inserts.
99 $wpdb->query('SET TRANSACTION ISOLATION LEVEL READ COMMITTED');
100 $wpdb->query('START TRANSACTION');
101
102 $rows = $wpdb->get_results(
103 "SELECT id, payload FROM $table ORDER BY id ASC FOR UPDATE",
104 ARRAY_A // Return as associative array so columns (like 'payload') can be accessed by name
105 );
106
107 if (!is_array($rows) || empty($rows)) {
108 return array();
109 }
110
111 $rows_count = count($rows);
112 $max_id = $rows[$rows_count - 1]['id'];
113 $deleted = $wpdb->query(
114 $wpdb->prepare(
115 "DELETE FROM $table WHERE id <= %d",
116 $max_id
117 )
118 );
119
120 if ($deleted === false || $deleted !== $rows_count) {
121 return array();
122 }
123
124 $wpdb->query('COMMIT');
125 $committed = true;
126 return $rows;
127 } finally {
128 // Rollback if unexpected error thrown or any issue before committing.
129 if (!$committed) {
130 $wpdb->query('ROLLBACK');
131 }
132 }
133 }
134
135 /**
136 * Returns the collect events table name for the current site.
137 *
138 * @return string Table name.
139 */
140 function clarity_get_collect_events_table_name()
141 {
142 global $wpdb;
143
144 return $wpdb->prefix . CLARITY_COLLECT_TABLE_NAME;
145 }
146
147 /**
148 * Checks whether the collect events table exists.
149 *
150 * @return bool True when the table exists.
151 */
152 function clarity_collect_events_table_exists($force_refresh = false)
153 {
154 static $table_exists = null;
155
156 if (!$force_refresh && $table_exists !== null) {
157 return $table_exists;
158 }
159
160 global $wpdb;
161 $table = clarity_get_collect_events_table_name();
162 $like = $wpdb->esc_like($table);
163 $table_exists = ($wpdb->get_var($wpdb->prepare('SHOW TABLES LIKE %s', $like)) === $table);
164
165 return $table_exists;
166 }
167
168