PluginProbe ʕ •ᴥ•ʔ
Reviews Feed – Add Testimonials and Customer Reviews From Google Reviews, Yelp, TripAdvisor, and More / trunk
Reviews Feed – Add Testimonials and Customer Reviews From Google Reviews, Yelp, TripAdvisor, and More vtrunk
2.11.0 2.10.0 2.9.0 2.8.0 2.7.0 2.6.7 2.6.8 2.6.5 2.6.4 2.6.3 2.6.2 2.6.0 2.5.5 2.5.4 2.5.3 2.5.2 trunk 1.0 1.0.1 1.0.2 1.0.3 1.1 1.1.1 1.1.2 1.2.0 2.0 2.1.0 2.1.1 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.5.0 2.5.1
reviews-feed / class / Common / UsageTracking / Config.php
reviews-feed / class / Common / UsageTracking Last commit date
Core 6 days ago Reviews 6 days ago Config.php 6 days ago EventRecorder.php 6 days ago ReporterInterface.php 6 days ago SmashUsageTracking.php 6 days ago
Config.php
180 lines
1 <?php
2
3 /**
4 * Smash Usage Tracking configuration for Reviews Feed.
5 *
6 * API URL and option names.
7 *
8 * @package SmashBalloon\Reviews\Common\UsageTracking
9 * @since 1.0
10 */
11
12 namespace SmashBalloon\Reviews\Common\UsageTracking;
13
14 if (! defined('ABSPATH')) {
15 exit;
16 }
17
18 class Config {
19 /**
20 * Option key: send-state bookkeeping —
21 * {last_send, last_attempt, last_status, consecutive_failures}.
22 * Consent lives in sbr_settings['usagetracking'] (see is_enabled()).
23 */
24 const OPTION_TRACKING = 'sbr_smash_usage_tracking';
25
26 /**
27 * Option key: site token returned by the API.
28 */
29 const OPTION_SITE_TOKEN = 'sbr_smash_usage_tracking_site_token';
30
31 /**
32 * Option key: schedule metadata written by earlier builds of this
33 * feature. No longer written or read — retained only so uninstall and
34 * the opt-out purge can delete it from sites that stored it.
35 */
36 const OPTION_SCHEDULE = 'sbr_smash_usage_tracking_schedule';
37
38 /**
39 * Option key: dates when plugin was active (Y-m-d), for days_active metric.
40 */
41 const OPTION_ACTIVE_DATES = 'sbr_smash_usage_active_dates';
42
43 /**
44 * Option key: last N session durations in seconds, for session_duration metric.
45 */
46 const OPTION_SESSION_DURATIONS = 'sbr_smash_usage_session_durations';
47
48 /**
49 * Cron hook name.
50 */
51 const CRON_HOOK = 'sbr_smash_usage_tracking_cron';
52
53 /**
54 * Max request timeout in seconds for usage report (large payloads).
55 */
56 const REQUEST_TIMEOUT = 30;
57
58 /**
59 * Max payload size in bytes before send is skipped (default 2MB).
60 */
61 const MAX_PAYLOAD_BYTES = 2097152;
62
63 /**
64 * Register-site endpoint path (relative to API base).
65 */
66 const REGISTER_SITE_PATH = '/v1/register-site';
67
68 /**
69 * Usage report endpoint path (relative to API base).
70 */
71 const USAGE_REPORT_PATH = '/v1/usage-report';
72
73 /**
74 * Get the API base URL (filterable, validated).
75 *
76 * The filter is a kill switch (return '' to disable all requests) and a
77 * dev override, but its output is constrained: both outbound requests
78 * carry the full usage payload, so an unvalidated filtered URL would let
79 * any other plugin silently re-route that data, and a cleartext scheme
80 * would expose it in transit. A filtered value must be https on an
81 * allowlisted host or it is discarded in favor of the constant.
82 *
83 * @return string Base URL, or '' when tracking requests are disabled.
84 */
85 public static function get_api_url()
86 {
87 $default = defined('SBR_SMASH_USAGE_TRACKING_API_URL') ? (string) SBR_SMASH_USAGE_TRACKING_API_URL : '';
88 $url = (string) apply_filters('sbr_smash_usage_tracking_api_url', $default);
89
90 if ($url === $default) {
91 return $url;
92 }
93 if ('' === $url) {
94 // Explicit kill switch — callers skip the request entirely.
95 return '';
96 }
97
98 return self::is_allowed_api_url($url) ? $url : $default;
99 }
100
101 /**
102 * Whether a filtered API URL may be used: https, on smashballoon.com or
103 * the host the SBR_SMASH_USAGE_TRACKING_API_URL constant points at.
104 *
105 * @param string $url Candidate URL from the filter.
106 * @return bool
107 */
108 private static function is_allowed_api_url($url)
109 {
110 if ('https' !== wp_parse_url($url, PHP_URL_SCHEME)) {
111 return false;
112 }
113 $host = wp_parse_url($url, PHP_URL_HOST);
114 if (! is_string($host) || '' === $host) {
115 return false;
116 }
117 $host = strtolower($host);
118
119 $allowed = array( 'smashballoon.com' );
120 if (defined('SBR_SMASH_USAGE_TRACKING_API_URL')) {
121 $constant_host = wp_parse_url((string) SBR_SMASH_USAGE_TRACKING_API_URL, PHP_URL_HOST);
122 if (is_string($constant_host) && '' !== $constant_host) {
123 $allowed[] = strtolower($constant_host);
124 }
125 }
126
127 foreach ($allowed as $allowed_host) {
128 if ($host === $allowed_host || substr($host, -(strlen($allowed_host) + 1)) === '.' . $allowed_host) {
129 return true;
130 }
131 }
132 return false;
133 }
134
135 /**
136 * Get full URL for register-site endpoint.
137 *
138 * @return string
139 */
140 public static function get_register_site_url()
141 {
142 return rtrim(self::get_api_url(), '/') . self::REGISTER_SITE_PATH;
143 }
144
145 /**
146 * Get full URL for usage-report endpoint.
147 *
148 * @return string
149 */
150 public static function get_usage_report_url()
151 {
152 return rtrim(self::get_api_url(), '/') . self::USAGE_REPORT_PATH;
153 }
154
155 /**
156 * Check if tracking is enabled.
157 *
158 * Consent is stored in sbr_settings['usagetracking']. When the key is
159 * absent the default is per edition, a deliberate product decision
160 * (SMASH-1130, signed off 2026-08-05):
161 *
162 * - Pro: enabled. The legacy tracker only ever booted on Pro and the
163 * Advanced-tab toggle has always displayed as ON there, so default-on
164 * matches what Pro customers have been shown.
165 * - Free: disabled. Free installs have never transmitted usage data
166 * (the legacy service was registered by the Pro container only), so
167 * they require explicit opt-in via the toggle.
168 *
169 * @return bool
170 */
171 public static function is_enabled()
172 {
173 $settings = get_option('sbr_settings', array());
174 if (is_array($settings) && array_key_exists('usagetracking', $settings)) {
175 return (bool) $settings['usagetracking'];
176 }
177 return \SmashBalloon\Reviews\Common\Util::sbr_is_pro();
178 }
179 }
180