| @@ -33,12 +33,8 @@ | ||
| 33 | 33 | if (!$this->is_configured()) { |
| 34 | 34 | return; |
| 35 | 35 | } |
| 36 | 36 | |
| 37 | - if (get_option(self::OPT_IN_OPTION) === false) { | |
| 38 | - update_option(self::OPT_IN_OPTION, 'yes'); | |
| 39 | - } | |
| 40 | - | |
| 41 | 37 | add_action('admin_enqueue_scripts', array($this, 'enqueue_ga4_script')); |
| 42 | 38 | add_action('admin_head', array($this, 'track_admin_page_view')); |
| 43 | 39 | } |
| 44 | 40 | |
| @@ -52,9 +48,9 @@ | ||
| 52 | 48 | return $this->get_measurement_id() !== null; |
| 53 | 49 | } |
| 54 | 50 | |
| 55 | 51 | public function is_opted_in() { |
| 56 | - return get_option(self::OPT_IN_OPTION, 'yes') === 'yes'; | |
| 52 | + return get_option(self::OPT_IN_OPTION, 'no') === 'yes'; | |
| 57 | 53 | } |
| 58 | 54 | |
| 59 | 55 | private function get_anonymized_user_id() { |
| 60 | 56 | $current_user = wp_get_current_user(); |
| @@ -169,13 +165,10 @@ | ||
| 169 | 165 | array('screen_name' => $screen_name), |
| 170 | 166 | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT |
| 171 | 167 | ); |
| 172 | 168 | |
| 173 | - echo "<script type='text/javascript'> | |
| 174 | - if (typeof gtag !== 'undefined') { | |
| 175 | - gtag('event', 'plugin_admin_accessed', " . $params . "); | |
| 176 | - } | |
| 177 | - </script>"; | |
| 169 | + $inline_tracking = "<script type='text/javascript'>\n if (typeof gtag !== 'undefined') {\n gtag('event', 'plugin_admin_accessed', " . $params . ");\n }\n </script>"; | |
| 170 | + echo $inline_tracking; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- $params is wp_json_encode() output with JSON_HEX_TAG/AMP/APOS/QUOT, safe inside an inline <script> | |
| 178 | 171 | } |
| 179 | 172 | |
| 180 | 173 | /** |
| 181 | 174 | * Track Content Genius article creation/update (server-side) |
| @@ -191,12 +184,32 @@ | ||
| 191 | 184 | if (!$post) { |
| 192 | 185 | return; |
| 193 | 186 | } |
| 194 | 187 | |
| 195 | - $this->send_mp_event('content_genius_article_' . strtolower($action), array( | |
| 196 | - 'content_type' => $post->post_type, | |
| 197 | - 'action' => ucfirst($action), | |
| 198 | - )); | |
| 188 | + // Bulk syncs fire this once per article; roll up to at most one event | |
| 189 | + // per action per hour with accumulated counts so a sync of N articles | |
| 190 | + // stays a single send (same shape as the PostHog rollup). | |
| 191 | + $action = strtolower($action); | |
| 192 | + $key = 'metasync_ga4_cg_' . $action; | |
| 193 | + $state = get_option($key, array()); | |
| 194 | + if (!is_array($state)) { | |
| 195 | + $state = array(); | |
| 196 | + } | |
| 197 | + $counts = isset($state['counts']) && is_array($state['counts']) ? $state['counts'] : array(); | |
| 198 | + $sent_at = (int) ($state['sent_at'] ?? 0); | |
| 199 | + $type = (string) $post->post_type; | |
| 200 | + $counts[$type] = ($counts[$type] ?? 0) + 1; | |
| 201 | + | |
| 202 | + if (time() - $sent_at >= HOUR_IN_SECONDS) { | |
| 203 | + $this->send_mp_event('content_genius_article_' . $action, array( | |
| 204 | + 'content_type' => $type, | |
| 205 | + 'action' => ucfirst($action), | |
| 206 | + 'count' => array_sum($counts), | |
| 207 | + )); | |
| 208 | + update_option($key, array('counts' => array(), 'sent_at' => time()), false); | |
| 209 | + } else { | |
| 210 | + update_option($key, array('counts' => $counts, 'sent_at' => $sent_at), false); | |
| 211 | + } | |
| 199 | 212 | } |
| 200 | 213 | |
| 201 | 214 | /** |
| 202 | 215 | * Track OTTO page optimization (server-side) |