acquia_vwo-1.0.x-dev/src/Service/User/UserControl.php
src/Service/User/UserControl.php
<?php
namespace Drupal\acquia_vwo\Service\User;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Render\Markup;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\user\UserData;
use Drupal\user\UserDataInterface;
// cspell:ignore cfasync nocontrol optout
/**
* User Control class.
*/
class UserControl {
use StringTranslationTrait;
/**
* The current user.
*
* @var \Drupal\Core\Session\AccountProxyInterface
*/
protected $account;
/**
* Data of the user.
*
* @var \Drupal\user\UserDataInterface
*/
protected UserDataInterface $userData;
/**
* The config factory service.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
private $configFactory;
/**
* Constructor for Acquia VWO class.
*
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The config factory service.
* @param \Drupal\Core\Session\AccountProxyInterface $account
* The current user.
* @param \Drupal\user\UserData $userData
* Data of the user.
*/
public function __construct(
ConfigFactoryInterface $config_factory,
AccountProxyInterface $account,
UserData $userData,
) {
$this->configFactory = $config_factory;
$this->account = $account;
$this->userData = $userData;
}
/**
* User form alter.
*
* Adds an extra field to the user profile to allow users to choose
* how to load VWO scripts.
*
* @param array $form
* The user form.
*/
public function userFormAlter(&$form) {
// Check if VWO account ID is configured.
if (!is_numeric($this->getVwoConfigSettings()->get('id'))) {
return;
}
// Check if user control is enabled.
$user_control = $this->getVwoConfigSettings()->get('visibility.user_control');
if ($user_control == 'nocontrol') {
return;
}
$enabled = ($user_control === 'optin') ? 0 : 1;
// User settings stored in user.data.
$user_opt = $this->userData->get('acquia_vwo', $this->account->id(), 'user_opt');
if (isset($user_opt)) {
$enabled = $user_opt;
}
$form['vwo_user'] = [
'#type' => 'details',
'#open' => TRUE,
'#title' => $this->t('VWO'),
];
$form['vwo_user']['user_opt'] = [
'#type' => 'checkbox',
'#title' => $this->t('Include VWO A/B testing'),
'#description' => $this->t('This website may run A/B testing at times. If this box is checked, the javascript required for it to work will be included.'),
'#default_value' => $enabled,
];
$form['actions']['submit']['#submit'][] = 'acquia_vwo_form_user_form_alter_submit';
}
/**
* Saves user data.
*
* @param string $name
* The name of the data key.
* @param string $user_opt
* The user_opt is '0' for disabled and '1' for enabled.
*/
public function saveUserData($name, $user_opt) {
$this->userData->set('acquia_vwo', $this->account->id(), $name, $user_opt);
}
/**
* User opt script.
*
* Add drupal settings to the page, to let the user_opt library set the value
* in the browser's local storage. The value from local storage is used by
* the VWO scripts to let the user decide if they want to opt in/out.
*
* @param array $page
* The page array.
*/
public function addUserOptScript(&$page) {
$user_control = $this->getVwoConfigSettings()->get('visibility.user_control');
$user_opt = NULL;
// Check if user is authenticated.
$uid = $this->account->id();
if ($uid > 0) {
$user_opt = $this->userData->get('acquia_vwo', $this->account->id(), 'user_opt');
}
// Check user preferences to control script visibility using data
// from the local storage.
// The user data is added to the local storage when the page loads.
$script = "const acquiaVwoUserOptOut = function () {
if ('$user_control' == 'optout') {
return (localStorage.getItem('acquia_vwo_user_opt') !== null &&
localStorage.getItem('acquia_vwo_user_opt') == '0');
}
if ('$user_control' == 'optin') {
return (localStorage.getItem('acquia_vwo_user_opt') === null ||
localStorage.getItem('acquia_vwo_user_opt') == '0');
}
return false;
}" . PHP_EOL;
// Create the header script.
$header = [
[
'#tag' => 'script',
'#attributes' => [
'data-cfasync' => 'false',
'type' => 'text/javascript',
],
'#value' => Markup::create($script),
],
'acquia_vwo_user_control',
];
$page['#attached']['drupalSettings']['user']['vwo_user_opt'] = $user_opt;
$page['#attached']['library'][] = 'acquia_vwo/user_opt';
$page['#attached']['html_head'][] = $header;
}
/**
* Get Acquia VWO config settings.
*
* @return \Drupal\Core\Config\Config
* The VWO Config Object.
*/
protected function getVwoConfigSettings() {
return $this->configFactory->get('acquia_vwo.settings');
}
}
