Viewing File: /usr/local/cpanel/base/3rdparty/roundcube/plugins/mixpanel_analytics/mixpanel_analytics.php
<?php
/**
* This plugin adds Mixpanel analytics to Roundcube.
**/
class mixpanel_analytics extends rcube_plugin
{
function enabledGlobally() {
return file_exists('/var/cpanel/feature_toggles/analytics_ui_includes');
}
function versionCheck() {
$version = file_get_contents('/usr/local/cpanel/version');
$pieces = explode( ".", $version );
if ( $pieces[1] >= 117 ) {
return true;
}
return false;
}
function getEnvDetails() {
$cpnatStat = @stat('/var/cpanel/cpnat');
$isNat = ( $cpnatStat && $cpnatStat[7] );
$isPrivate = false;
$mainIp = file_get_contents('/var/cpanel/mainip');
if ( preg_match( '/^10\./', $mainIp) ) {
$isPrivate = true;
}
$companyId = readlink('/var/cpanel/companyid.fast');
$envDetails = [
"mainIp" => $mainIp,
"companyId" => $companyId,
"isDevEnvironment" => false,
];
if ( file_exists('/var/cpanel/dev_sandbox') || !$isNat && $isPrivate ) {
$envDetails['isDevEnvironment'] = true;
}
return $envDetails;
}
function init()
{
if ( $this->enabledGlobally() && $this->versionCheck() ) {
$this->include_script('mixpanel_analytics_include.js');
$this->add_hook('render_page', array($this, 'addConfigurationJS'));
}
}
// Query Leika via perl to see if consent is required.
// Returns true if consent is required, false if Leika indicates we can skip consent.
// On any error we default to requiring consent (true).
private function leika_consent_required() {
// If disabled at the server level we return true (caller aborts earlier anyway).
if ( !$this->enabledGlobally() ) { return true; }
$perl = '/usr/local/cpanel/3rdparty/bin/perl';
$cmd = "$perl -MCpanel::Analytics -e 'print Cpanel::Analytics::is_user_analytics_consent_required_by_leika()' 2>/dev/null";
$out = @shell_exec($cmd);
$out = trim((string)$out);
if ( $out === '0' ) { return false; }
return true;
}
function addConfigurationJS() {
$envDetailsJSON = json_encode($this->getEnvDetails());
$leikaConsentRequired = $this->leika_consent_required();
$leikaConsentRequiredJSON = $leikaConsentRequired ? 'true' : 'false';
# Examples:
# Webmail-Roundcube-Mail
# Webmail-Roundcube-Mail-Compose
# Webmail-Roundcube-Addressbook
$event = 'Webmail-Roundcube';
if (array_key_exists('_task', $_GET)) {
$event .= '-' . ucfirst($_GET['_task']);
if (array_key_exists('_action', $_GET)) {
$event .= '-' . ucfirst($_GET['_action']);
}
}
$eventJSON = json_encode($event);
$debug = false;
if (array_key_exists('debug', $_GET) && $_GET['debug']) {
$debug = true;
}
$debugJSON = json_encode($debug);
$js = <<<EOF
<script type="text/javascript">
var envDetails = $envDetailsJSON; // envDetails value interpolated from mixpanel_analytics.php
var event = $eventJSON;
var debugMode = $debugJSON;
var leikaConsentRequired = $leikaConsentRequiredJSON;
var mixpanelToken = envDetails.isDevEnvironment ? 'c7c6f1b1bc8e7b3d8254ebe545861955' : '2cca34424fe0e8ad6897d354b9591c45';
var loadedFunc = function(mixp) {
if (!mixp.has_opted_in_tracking() && !leikaConsentRequired) {
mixp.opt_in_tracking();
}
if (!leikaConsentRequired || mixp.has_opted_in_tracking()) {
// Add these two properties that are among the most important of the super properties added by mixpanel-utils.service.ts,
// but without having access to the full data normally gathered by Cpanel/Template/Plugin/UIAnalytics.pm
mixp.register(
{
"server_main_ip": envDetails.mainIp,
"company_id": [envDetails.companyId], // array wrapper matches what's done elsewhere
}
);
mixp.track(event);
}
};
window.addEventListener('DOMContentLoaded', function() {
if (window.mixpanel) {
window.mixpanel.init(
mixpanelToken,
{
debug: debugMode,
persistence: "localStorage",
opt_out_of_tracking_by_default: leikaConsentRequired,
track_pageview: false,
property_blacklist: [
"\$initial_referrer",
"\$referrer",
"\$current_url",
"url",
],
ip: false,
autotrack: false,
api_host: "https://mixpanel-proxy.cpanel.net",
loaded: loadedFunc,
}
);
// On the Compose page, track when the Send button is clicked.
// Note that there are 2 different send buttons, depending on
// the window width.
var sendButtonClicked = false;
var sendTimerId = null;
function trackSendEvent(button) {
button.addEventListener("click", function(e) {
if (!leikaConsentRequired || window.mixpanel && window.mixpanel.has_opted_in_tracking()) {
sendButtonClicked = true;
// Clear any existing timer
if (sendTimerId) {
clearTimeout(sendTimerId);
}
// Set a 5-second timer to clear the flag if no page unload occurs
sendTimerId = setTimeout(function() {
sendButtonClicked = false;
sendTimerId = null;
}, 5000);
}
});
}
// Track successful send when page unloads (indicating redirect/success)
window.addEventListener('beforeunload', function() {
if (sendButtonClicked && window.mixpanel && window.mixpanel.has_opted_in_tracking()) {
// Clear the timer since we're tracking the event now
if (sendTimerId) {
clearTimeout(sendTimerId);
sendTimerId = null;
}
// Use mixpanel's track method with transport: 'sendBeacon' for reliable delivery
window.mixpanel.track(event + "-Send", {
"send_method": "page_unload"
}, {
transport: 'sendBeacon'
});
}
});
var composeContent = document.getElementById("compose-content");
if (composeContent) {
var sendButtonWide = composeContent.getElementsByClassName("btn send");
if (sendButtonWide[0]) {
trackSendEvent(sendButtonWide[0]);
}
}
var sendButtonNarrow = document.getElementsByClassName("send button");
if (sendButtonNarrow[0]) {
trackSendEvent(sendButtonNarrow[0]);
}
}
});
</script>
EOF;
rcube::get_instance()->output->add_footer($js);
}
}
?>
Back to Directory
File Manager