added piwik contrib module

This commit is contained in:
2018-04-16 22:25:17 +02:00
parent 7e073fdfa0
commit c0fbcb7706
42 changed files with 3910 additions and 0 deletions
@@ -0,0 +1,43 @@
<?php
namespace Drupal\piwik\Component\Render;
use Drupal\Component\Render\MarkupInterface;
/**
* Formats a string for JavaScript display.
*/
class PiwikJavaScriptSnippet implements MarkupInterface {
/**
* The string to escape.
*
* @var string
*/
protected $string;
/**
* Constructs an HtmlEscapedText object.
*
* @param string $string
* The string to escape. This value will be cast to a string.
*/
public function __construct($string) {
$this->string = (string) $string;
}
/**
* {@inheritdoc}
*/
public function __toString() {
return $this->string;
}
/**
* {@inheritdoc}
*/
public function jsonSerialize() {
return $this->__toString();
}
}
@@ -0,0 +1,717 @@
<?php
namespace Drupal\piwik\Form;
use Drupal\Component\Utility\Unicode;
use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use GuzzleHttp\Exception\RequestException;
/**
* Configure Piwik settings for this site.
*/
class PiwikAdminSettingsForm extends ConfigFormBase {
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'piwik_admin_settings';
}
/**
* {@inheritdoc}
*/
protected function getEditableConfigNames() {
return ['piwik.settings'];
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$config = $this->config('piwik.settings');
$form['general'] = [
'#type' => 'details',
'#title' => $this->t('General settings'),
'#open' => TRUE,
];
$form['general']['piwik_site_id'] = [
'#default_value' => $config->get('site_id'),
'#description' => $this->t('The user account number is unique to the websites domain. Click the <strong>Settings</strong> link in your Piwik account, then the <strong>Websites</strong> tab and enter the appropriate site <strong>ID</strong> into this field.'),
'#maxlength' => 20,
'#required' => TRUE,
'#size' => 15,
'#title' => $this->t('Piwik site ID'),
'#type' => 'textfield',
];
$form['general']['piwik_url_http'] = [
'#default_value' => $config->get('url_http'),
'#description' => $this->t('The URL to your Piwik base directory. Example: "http://www.example.com/piwik/".'),
'#maxlength' => 255,
'#required' => TRUE,
'#size' => 80,
'#title' => $this->t('Piwik HTTP URL'),
'#type' => 'textfield',
];
$form['general']['piwik_url_https'] = [
'#default_value' => $config->get('url_https'),
'#description' => $this->t('The URL to your Piwik base directory with SSL certificate installed. Required if you track a SSL enabled website. Example: "https://www.example.com/piwik/".'),
'#maxlength' => 255,
'#size' => 80,
'#title' => $this->t('Piwik HTTPS URL'),
'#type' => 'textfield',
];
// Required for automated form save testing only.
$form['general']['piwik_url_skiperror'] = [
'#type' => 'hidden',
'#default_value' => FALSE,
];
// Visibility settings.
$form['tracking_scope'] = [
'#type' => 'vertical_tabs',
'#title' => $this->t('Tracking scope'),
'#attached' => [
'library' => [
'piwik/piwik.admin',
],
],
];
$form['tracking']['domain_tracking'] = [
'#type' => 'details',
'#title' => $this->t('Domains'),
'#group' => 'tracking_scope',
];
global $cookie_domain;
$multiple_sub_domains = [];
foreach (['www', 'app', 'shop'] as $subdomain) {
if (count(explode('.', $cookie_domain)) > 2 && !is_numeric(str_replace('.', '', $cookie_domain))) {
$multiple_sub_domains[] = $subdomain . $cookie_domain;
}
// IP addresses or localhost.
else {
$multiple_sub_domains[] = $subdomain . '.example.com';
}
}
$form['tracking']['domain_tracking']['piwik_domain_mode'] = [
'#type' => 'radios',
'#title' => $this->t('What are you tracking?'),
'#options' => [
0 => $this->t('A single domain (default)'),
1 => $this->t('One domain with multiple subdomains'),
],
0 => [
'#description' => $this->t('Domain: @domain', ['@domain' => $_SERVER['HTTP_HOST']]),
],
1 => [
'#description' => $this->t('Examples: @domains', ['@domains' => implode(', ', $multiple_sub_domains)]),
],
'#default_value' => $config->get('domain_mode'),
];
// Page specific visibility configurations.
$account = \Drupal::currentUser();
$php_access = $account->hasPermission('use PHP for piwik tracking visibility');
$visibility_request_path_pages = $config->get('visibility.request_path_pages');
$form['tracking']['page_visibility_settings'] = [
'#type' => 'details',
'#title' => $this->t('Pages'),
'#group' => 'tracking_scope',
];
if ($config->get('visibility.request_path_mode') == 2 && !$php_access) {
// No permission to change PHP snippets, but keep existing settings.
$form['tracking']['page_visibility_settings'] = [];
$form['tracking']['page_visibility_settings']['piwik_visibility_request_path_mode'] = ['#type' => 'value', '#value' => 2];
$form['tracking']['page_visibility_settings']['piwik_visibility_request_path_pages'] = ['#type' => 'value', '#value' => $visibility_request_path_pages];
}
else {
$options = [
t('Every page except the listed pages'),
t('The listed pages only'),
];
$description = t("Specify pages by using their paths. Enter one path per line. The '*' character is a wildcard. Example paths are %blog for the blog page and %blog-wildcard for every personal blog. %front is the front page.", ['%blog' => '/blog', '%blog-wildcard' => '/blog/*', '%front' => '<front>']);
if (\Drupal::moduleHandler()->moduleExists('php') && $php_access) {
$options[] = t('Pages on which this PHP code returns <code>TRUE</code> (experts only)');
$title = t('Pages or PHP code');
$description .= ' ' . t('If the PHP option is chosen, enter PHP code between %php. Note that executing incorrect PHP code can break your Drupal site.', ['%php' => '<?php ?>']);
}
else {
$title = t('Pages');
}
$form['tracking']['page_visibility_settings']['piwik_visibility_request_path_mode'] = [
'#type' => 'radios',
'#title' => $this->t('Add tracking to specific pages'),
'#options' => $options,
'#default_value' => $config->get('visibility.request_path_mode'),
];
$form['tracking']['page_visibility_settings']['piwik_visibility_request_path_pages'] = [
'#type' => 'textarea',
'#title' => $title,
'#title_display' => 'invisible',
'#default_value' => !empty($visibility_request_path_pages) ? $visibility_request_path_pages : '',
'#description' => $description,
'#rows' => 10,
];
}
// Render the role overview.
$visibility_user_role_roles = $config->get('visibility.user_role_roles');
$form['tracking']['role_visibility_settings'] = [
'#type' => 'details',
'#title' => $this->t('Roles'),
'#group' => 'tracking_scope',
];
$form['tracking']['role_visibility_settings']['piwik_visibility_user_role_mode'] = [
'#type' => 'radios',
'#title' => $this->t('Add tracking for specific roles'),
'#options' => [
t('Add to the selected roles only'),
t('Add to every role except the selected ones'),
],
'#default_value' => $config->get('visibility.user_role_mode'),
];
$form['tracking']['role_visibility_settings']['piwik_visibility_user_role_roles'] = [
'#type' => 'checkboxes',
'#title' => $this->t('Roles'),
'#default_value' => !empty($visibility_user_role_roles) ? $visibility_user_role_roles : [],
'#options' => array_map('\Drupal\Component\Utility\Html::escape', user_role_names()),
'#description' => $this->t('If none of the roles are selected, all users will be tracked. If a user has any of the roles checked, that user will be tracked (or excluded, depending on the setting above).'),
];
// Standard tracking configurations.
$visibility_user_account_mode = $config->get('visibility.user_account_mode');
$form['tracking']['user_visibility_settings'] = [
'#type' => 'details',
'#title' => $this->t('Users'),
'#group' => 'tracking_scope',
];
$t_permission = ['%permission' => $this->t('opt-in or out of tracking')];
$form['tracking']['user_visibility_settings']['piwik_visibility_user_account_mode'] = [
'#type' => 'radios',
'#title' => $this->t('Allow users to customize tracking on their account page'),
'#options' => [
t('No customization allowed'),
t('Tracking on by default, users with %permission permission can opt out', $t_permission),
t('Tracking off by default, users with %permission permission can opt in', $t_permission),
],
'#default_value' => !empty($visibility_user_account_mode) ? $visibility_user_account_mode : 0,
];
$form['tracking']['user_visibility_settings']['piwik_trackuserid'] = [
'#type' => 'checkbox',
'#title' => $this->t('Track User ID'),
'#default_value' => $config->get('track.userid'),
'#description' => $this->t('User ID enables the analysis of groups of sessions, across devices, using a unique, persistent, and non-personally identifiable ID string representing a user. <a href=":url">Learn more about the benefits of using User ID</a>.', [':url' => 'http://piwik.org/docs/user-id/']),
];
// Link specific configurations.
$form['tracking']['linktracking'] = [
'#type' => 'details',
'#title' => $this->t('Links and downloads'),
'#group' => 'tracking_scope',
];
$form['tracking']['linktracking']['piwik_trackmailto'] = [
'#type' => 'checkbox',
'#title' => $this->t('Track clicks on mailto links'),
'#default_value' => $config->get('track.mailto'),
];
$form['tracking']['linktracking']['piwik_trackfiles'] = [
'#type' => 'checkbox',
'#title' => $this->t('Track clicks on outbound links and downloads (clicks on file links) for the following extensions'),
'#default_value' => $config->get('track.files'),
];
$form['tracking']['linktracking']['piwik_trackfiles_extensions'] = [
'#title' => $this->t('List of download file extensions'),
'#title_display' => 'invisible',
'#type' => 'textfield',
'#default_value' => $config->get('track.files_extensions'),
'#description' => $this->t('A file extension list separated by the | character that will be tracked as download when clicked. Regular expressions are supported. For example: @extensions', ['@extensions' => PIWIK_TRACKFILES_EXTENSIONS]),
'#maxlength' => 500,
'#states' => [
'enabled' => [
':input[name="piwik_trackfiles"]' => ['checked' => TRUE],
],
// Note: Form required marker is not visible as title is invisible.
'required' => [
':input[name="piwik_trackfiles"]' => ['checked' => TRUE],
],
],
];
$colorbox_dependencies = '<div class="admin-requirements">';
$colorbox_dependencies .= t('Requires: @module-list', ['@module-list' => (\Drupal::moduleHandler()->moduleExists('colorbox') ? t('@module (<span class="admin-enabled">enabled</span>)', ['@module' => 'Colorbox']) : t('@module (<span class="admin-missing">disabled</span>)', ['@module' => 'Colorbox']))]);
$colorbox_dependencies .= '</div>';
$form['tracking']['linktracking']['piwik_trackcolorbox'] = [
'#type' => 'checkbox',
'#title' => t('Track content in colorbox modal dialogs'),
'#description' => t('Enable to track the content shown in colorbox modal windows.') . $colorbox_dependencies,
'#default_value' => $config->get('track.colorbox'),
'#disabled' => (\Drupal::moduleHandler()->moduleExists('colorbox') ? FALSE : TRUE),
];
// Message specific configurations.
$form['tracking']['messagetracking'] = [
'#type' => 'details',
'#title' => $this->t('Messages'),
'#group' => 'tracking_scope',
];
$track_messages = $config->get('track.messages');
$form['tracking']['messagetracking']['piwik_trackmessages'] = [
'#type' => 'checkboxes',
'#title' => $this->t('Track messages of type'),
'#default_value' => !empty($track_messages) ? $track_messages : [],
'#description' => $this->t('This will track the selected message types shown to users. Tracking of form validation errors may help you identifying usability issues in your site. Every message is tracked as one individual event. Messages from excluded pages cannot be tracked.'),
'#options' => [
'status' => $this->t('Status message'),
'warning' => $this->t('Warning message'),
'error' => $this->t('Error message'),
],
];
$form['tracking']['search'] = [
'#type' => 'details',
'#title' => $this->t('Search'),
'#group' => 'tracking_scope',
];
$site_search_dependencies = '<div class="admin-requirements">';
$site_search_dependencies .= t('Requires: @module-list', ['@module-list' => (\Drupal::moduleHandler()->moduleExists('search') ? t('@module (<span class="admin-enabled">enabled</span>)', ['@module' => 'Search']) : t('@module (<span class="admin-missing">disabled</span>)', ['@module' => 'Search']))]);
$site_search_dependencies .= '</div>';
$form['tracking']['search']['piwik_site_search'] = [
'#type' => 'checkbox',
'#title' => $this->t('Track internal search'),
'#description' => $this->t('If checked, internal search keywords are tracked.') . $site_search_dependencies,
'#default_value' => $config->get('track.site_search'),
'#disabled' => (\Drupal::moduleHandler()->moduleExists('search') ? FALSE : TRUE),
];
// Privacy specific configurations.
$form['tracking']['privacy'] = [
'#type' => 'details',
'#title' => $this->t('Privacy'),
'#group' => 'tracking_scope',
];
$form['tracking']['privacy']['piwik_privacy_donottrack'] = [
'#type' => 'checkbox',
'#title' => $this->t('Universal web tracking opt-out'),
'#description' => $this->t('If enabled and your Piwik server receives the <a href="http://donottrack.us/">Do-Not-Track</a> header from the client browser, the Piwik server will not track the user. Compliance with Do Not Track could be purely voluntary, enforced by industry self-regulation, or mandated by state or federal law. Please accept your visitors privacy. If they have opt-out from tracking and advertising, you should accept their personal decision.'),
'#default_value' => $config->get('privacy.donottrack'),
];
// Piwik page title tree view settings.
$form['page_title_hierarchy'] = [
'#type' => 'details',
'#title' => $this->t('Page titles hierarchy'),
'#description' => $this->t('This functionality enables a dynamically expandable tree view of your site page titles in your Piwik statistics. See in Piwik statistics under <em>Actions</em> > <em>Page titles</em>.'),
'#group' => 'page_title_hierarchy',
];
$form['page_title_hierarchy']['piwik_page_title_hierarchy'] = [
'#type' => 'checkbox',
'#title' => $this->t("Show page titles as hierarchy like breadcrumbs"),
'#description' => $this->t('By default Piwik tracks the current page title and shows you a flat list of the most popular titles. This enables a breadcrumbs like tree view.'),
'#default_value' => $config->get('page_title_hierarchy'),
];
$form['page_title_hierarchy']['piwik_page_title_hierarchy_exclude_home'] = [
'#type' => 'checkbox',
'#title' => $this->t('Hide home page from hierarchy'),
'#description' => $this->t('If enabled, the "Home" item will be removed from the hierarchy to flatten the structure in the Piwik statistics. Hits to the home page will still be counted, but for other pages the hierarchy will start at level Home+1.'),
'#default_value' => $config->get('page_title_hierarchy_exclude_home'),
];
// Custom variables.
$form['piwik_custom_var'] = [
'#description' => $this->t('You can add Piwiks <a href=":custom_var_documentation">Custom Variables</a> here. These will be added to every page that Piwik tracking code appears on. Custom variable names and values are limited to 200 characters in length. Keep the names and values as short as possible and expect long values to get trimmed. You may use tokens in custom variable names and values. Global and user tokens are always available; on node pages, node tokens are also available.', [':custom_var_documentation' => 'http://piwik.org/docs/custom-variables/']),
'#title' => $this->t('Custom variables'),
'#tree' => TRUE,
'#type' => 'details',
];
$form['piwik_custom_var']['slots'] = [
'#type' => 'table',
'#header' => [
['data' => $this->t('Slot')],
['data' => $this->t('Name')],
['data' => $this->t('Value')],
['data' => $this->t('Scope')],
],
];
$piwik_custom_vars = $config->get('custom.variable');
// Piwik supports up to 5 custom variables.
for ($i = 1; $i < 6; $i++) {
$form['piwik_custom_var']['slots'][$i]['slot'] = [
'#default_value' => $i,
'#description' => $this->t('Slot number'),
'#disabled' => TRUE,
'#size' => 1,
'#title' => $this->t('Custom variable slot #@slot', ['@slot' => $i]),
'#title_display' => 'invisible',
'#type' => 'textfield',
];
$form['piwik_custom_var']['slots'][$i]['name'] = [
'#default_value' => isset($piwik_custom_vars[$i]['name']) ? $piwik_custom_vars[$i]['name'] : '',
'#description' => $this->t('The custom variable name.'),
'#maxlength' => 100,
'#size' => 20,
'#title' => $this->t('Custom variable name #@slot', ['@slot' => $i]),
'#title_display' => 'invisible',
'#type' => 'textfield',
];
$form['piwik_custom_var']['slots'][$i]['value'] = [
'#default_value' => isset($piwik_custom_vars[$i]['value']) ? $piwik_custom_vars[$i]['value'] : '',
'#description' => $this->t('The custom variable value.'),
'#maxlength' => 255,
'#title' => $this->t('Custom variable value #@slot', ['@slot' => $i]),
'#title_display' => 'invisible',
'#type' => 'textfield',
'#element_validate' => [[get_class($this), 'tokenElementValidate']],
'#token_types' => ['node'],
];
if (\Drupal::moduleHandler()->moduleExists('token')) {
$form['piwik_custom_var']['slots'][$i]['value']['#element_validate'][] = 'token_element_validate';
}
$form['piwik_custom_var']['slots'][$i]['scope'] = [
'#default_value' => isset($piwik_custom_vars[$i]['scope']) ? $piwik_custom_vars[$i]['scope'] : '',
'#description' => $this->t('The scope for the custom variable.'),
'#title' => $this->t('Custom variable slot #@slot', ['@slot' => $i]),
'#title_display' => 'invisible',
'#type' => 'select',
'#options' => [
'visit' => $this->t('Visit'),
'page' => $this->t('Page'),
],
];
}
$form['piwik_custom_var']['piwik_custom_var_description'] = [
'#type' => 'item',
'#description' => $this->t("You can supplement Piwiks' basic IP address tracking of visitors by segmenting users based on custom variables. Make sure you will not associate (or permit any third party to associate) any data gathered from your websites (or such third parties' websites) with any personally identifying information from any source as part of your use (or such third parties' use) of the Piwik' service."),
];
if (\Drupal::moduleHandler()->moduleExists('token')) {
$form['piwik_custom_var']['piwik_custom_var_token_tree'] = [
'#theme' => 'token_tree_link',
'#token_types' => ['node'],
];
}
// Advanced feature configurations.
$form['advanced'] = [
'#type' => 'details',
'#title' => $this->t('Advanced settings'),
'#open' => FALSE,
];
$form['advanced']['piwik_cache'] = [
'#type' => 'checkbox',
'#title' => $this->t('Locally cache tracking code file'),
'#description' => $this->t('If checked, the tracking code file is retrieved from your Piwik site and cached locally. It is updated daily to ensure updates to tracking code are reflected in the local copy.'),
'#default_value' => $config->get('cache'),
];
// Allow for tracking of the originating node when viewing translation sets.
if (\Drupal::moduleHandler()->moduleExists('content_translation')) {
$form['advanced']['piwik_translation_set'] = [
'#type' => 'checkbox',
'#title' => $this->t('Track translation sets as one unit'),
'#description' => $this->t('When a node is part of a translation set, record statistics for the originating node instead. This allows for a translation set to be treated as a single unit.'),
'#default_value' => $config->get('translation_set'),
];
}
$user_access_add_js_snippets = !$this->currentUser()->hasPermission('add JS snippets for piwik');
$user_access_add_js_snippets_permission_warning = $user_access_add_js_snippets ? ' <em>' . $this->t('This field has been disabled because you do not have sufficient permissions to edit it.') . '</em>' : '';
$form['advanced']['codesnippet'] = [
'#type' => 'details',
'#title' => $this->t('Custom JavaScript code'),
'#open' => TRUE,
'#description' => $this->t('You can add custom Piwik <a href=":snippets">code snippets</a> here. These will be added to every page that Piwik appears on. <strong>Do not include the &lt;script&gt; tags</strong>, and always end your code with a semicolon (;).', [':snippets' => 'http://piwik.org/docs/javascript-tracking/']),
];
$form['advanced']['codesnippet']['piwik_codesnippet_before'] = [
'#type' => 'textarea',
'#title' => $this->t('Code snippet (before)'),
'#default_value' => $config->get('codesnippet.before'),
'#disabled' => $user_access_add_js_snippets,
'#rows' => 5,
'#description' => $this->t('Code in this textarea will be added <strong>before</strong> _paq.push(["trackPageView"]).') . $user_access_add_js_snippets_permission_warning,
];
$form['advanced']['codesnippet']['piwik_codesnippet_after'] = [
'#type' => 'textarea',
'#title' => $this->t('Code snippet (after)'),
'#default_value' => $config->get('codesnippet.after'),
'#disabled' => $user_access_add_js_snippets,
'#rows' => 5,
'#description' => $this->t('Code in this textarea will be added <strong>after</strong> _paq.push(["trackPageView"]). This is useful if you\'d like to track a site in two accounts.') . $user_access_add_js_snippets_permission_warning,
];
return parent::buildForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
parent::validateForm($form, $form_state);
// Custom variables validation.
foreach ($form_state->getValue(['piwik_custom_var', 'slots']) as $custom_var) {
$form_state->setValue(['piwik_custom_var', 'slots', $custom_var['slot'], 'name'], trim($custom_var['name']));
$form_state->setValue(['piwik_custom_var', 'slots', $custom_var['slot'], 'value'], trim($custom_var['value']));
// Validate empty names/values.
if (empty($custom_var['name']) && !empty($custom_var['value'])) {
$form_state->setErrorByName("piwik_custom_var][slots][" . $custom_var['slot'] . "][name", t('The custom variable @slot-number requires a <em>Name</em> if a <em>Value</em> has been provided.', ['@slot-number' => $custom_var['slot']]));
}
elseif (!empty($custom_var['name']) && empty($custom_var['value'])) {
$form_state->setErrorByName("piwik_custom_var][slots][" . $custom_var['slot'] . "][value", t('The custom variable @slot-number requires a <em>Value</em> if a <em>Name</em> has been provided.', ['@slot-number' => $custom_var['slot']]));
}
}
$form_state->setValue('piwik_custom_var', $form_state->getValue(['piwik_custom_var', 'slots']));
// Trim some text area values.
$form_state->setValue('piwik_site_id', trim($form_state->getValue('piwik_site_id')));
$form_state->setValue('piwik_visibility_request_path_pages', trim($form_state->getValue('piwik_visibility_request_path_pages')));
$form_state->setValue('piwik_codesnippet_before', trim($form_state->getValue('piwik_codesnippet_before')));
$form_state->setValue('piwik_codesnippet_after', trim($form_state->getValue('piwik_codesnippet_after')));
$form_state->setValue('piwik_visibility_user_role_roles', array_filter($form_state->getValue('piwik_visibility_user_role_roles')));
$form_state->setValue('piwik_trackmessages', array_filter($form_state->getValue('piwik_trackmessages')));
if (!preg_match('/^\d{1,}$/', $form_state->getValue('piwik_site_id'))) {
$form_state->setErrorByName('piwik_site_id', t('A valid Piwik site ID is an integer only.'));
}
$url = $form_state->getValue('piwik_url_http') . 'piwik.php';
try {
$result = \Drupal::httpClient()->get($url);
if ($result->getStatusCode() != 200 && $form_state->getValue('piwik_url_skiperror') == FALSE) {
$form_state->setErrorByName('piwik_url_http', t('The validation of "@url" failed with error "@error" (HTTP code @code).', [
'@url' => UrlHelper::filterBadProtocol($url),
'@error' => $result->getReasonPhrase(),
'@code' => $result->getStatusCode(),
]));
}
}
catch (RequestException $exception) {
$form_state->setErrorByName('piwik_url_http', t('The validation of "@url" failed with an exception "@error" (HTTP code @code).', [
'@url' => UrlHelper::filterBadProtocol($url),
'@error' => $exception->getMessage(),
'@code' => $exception->getCode(),
]));
}
$piwik_url_https = $form_state->getValue('piwik_url_https');
if (!empty($piwik_url_https)) {
$url = $piwik_url_https . 'piwik.php';
try {
$result = \Drupal::httpClient()->get($url);
if ($result->getStatusCode() != 200 && $form_state->getValue('piwik_url_skiperror') == FALSE) {
$form_state->setErrorByName('piwik_url_https', t('The validation of "@url" failed with error "@error" (HTTP code @code).', [
'@url' => UrlHelper::filterBadProtocol($url),
'@error' => $result->getReasonPhrase(),
'@code' => $result->getStatusCode(),
]));
}
}
catch (RequestException $exception) {
$form_state->setErrorByName('piwik_url_https', t('The validation of "@url" failed with an exception "@error" (HTTP code @code).', [
'@url' => UrlHelper::filterBadProtocol($url),
'@error' => $exception->getMessage(),
'@code' => $exception->getCode(),
]));
}
}
// Verify that every path is prefixed with a slash, but don't check PHP
// code snippets.
if ($form_state->getValue('piwik_visibility_request_path_mode') != 2) {
$pages = preg_split('/(\r\n?|\n)/', $form_state->getValue('piwik_visibility_request_path_pages'));
foreach ($pages as $page) {
if (strpos($page, '/') !== 0 && $page !== '<front>') {
$form_state->setErrorByName('piwik_visibility_request_path_pages', t('Path "@page" not prefixed with slash.', ['@page' => $page]));
// Drupal forms show one error only.
break;
}
}
}
// Clear obsolete local cache if cache has been disabled.
if ($form_state->isValueEmpty('piwik_cache') && $form['advanced']['piwik_cache']['#default_value']) {
piwik_clear_js_cache();
}
// This is for the Newbie's who cannot read a text area description.
if (preg_match('/(.*)<\/?script(.*)>(.*)/i', $form_state->getValue('piwik_codesnippet_before'))) {
$form_state->setErrorByName('piwik_codesnippet_before', t('Do not include the &lt;script&gt; tags in the javascript code snippets.'));
}
if (preg_match('/(.*)<\/?script(.*)>(.*)/i', $form_state->getValue('piwik_codesnippet_after'))) {
$form_state->setErrorByName('piwik_codesnippet_after', t('Do not include the &lt;script&gt; tags in the javascript code snippets.'));
}
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$config = $this->config('piwik.settings');
$config
->set('site_id', $form_state->getValue('piwik_site_id'))
->set('url_http', $form_state->getValue('piwik_url_http'))
->set('url_https', $form_state->getValue('piwik_url_https'))
->set('codesnippet.before', $form_state->getValue('piwik_codesnippet_before'))
->set('codesnippet.after', $form_state->getValue('piwik_codesnippet_after'))
->set('custom.variable', $form_state->getValue('piwik_custom_var'))
->set('domain_mode', $form_state->getValue('piwik_domain_mode'))
->set('track.files', $form_state->getValue('piwik_trackfiles'))
->set('track.files_extensions', $form_state->getValue('piwik_trackfiles_extensions'))
->set('track.colorbox', $form_state->getValue('piwik_trackcolorbox'))
->set('track.userid', $form_state->getValue('piwik_trackuserid'))
->set('track.mailto', $form_state->getValue('piwik_trackmailto'))
->set('track.messages', $form_state->getValue('piwik_trackmessages'))
->set('track.site_search', $form_state->getValue('piwik_site_search'))
->set('privacy.donottrack', $form_state->getValue('piwik_privacy_donottrack'))
->set('cache', $form_state->getValue('piwik_cache'))
->set('visibility.request_path_mode', $form_state->getValue('piwik_visibility_request_path_mode'))
->set('visibility.request_path_pages', $form_state->getValue('piwik_visibility_request_path_pages'))
->set('visibility.user_account_mode', $form_state->getValue('piwik_visibility_user_account_mode'))
->set('visibility.user_role_mode', $form_state->getValue('piwik_visibility_user_role_mode'))
->set('visibility.user_role_roles', $form_state->getValue('piwik_visibility_user_role_roles'))
->save();
if ($form_state->hasValue('piwik_translation_set')) {
$config->set('translation_set', $form_state->getValue('piwik_translation_set'))->save();
}
parent::submitForm($form, $form_state);
}
/**
* Validate a form element that should have tokens in it.
*
* For example:
* @code
* $form['my_node_text_element'] = [
* '#type' => 'textfield',
* '#title' => $this->t('Some text to token-ize that has a node context.'),
* '#default_value' => 'The title of this node is [node:title].',
* '#element_validate' => [[get_class($this), 'tokenElementValidate']],
* ];
* @endcode
*/
public static function tokenElementValidate(&$element, FormStateInterface $form_state) {
$value = isset($element['#value']) ? $element['#value'] : $element['#default_value'];
if (!Unicode::strlen($value)) {
// Empty value needs no further validation since the element should depend
// on using the '#required' FAPI property.
return $element;
}
$tokens = \Drupal::token()->scan($value);
$invalid_tokens = static::getForbiddenTokens($tokens);
if ($invalid_tokens) {
$form_state->setError($element, t('The %element-title is using the following forbidden tokens with personal identifying information: @invalid-tokens.', ['%element-title' => $element['#title'], '@invalid-tokens' => implode(', ', $invalid_tokens)]));
}
return $element;
}
/**
* Get an array of all forbidden tokens.
*
* @param array $value
* An array of token values.
*
* @return array
* A unique array of invalid tokens.
*/
protected static function getForbiddenTokens(array $value) {
$invalid_tokens = [];
$value_tokens = is_string($value) ? \Drupal::token()->scan($value) : $value;
foreach ($value_tokens as $tokens) {
if (array_filter($tokens, 'static::containsForbiddenToken')) {
$invalid_tokens = array_merge($invalid_tokens, array_values($tokens));
}
}
array_unique($invalid_tokens);
return $invalid_tokens;
}
/**
* Validate if string contains forbidden tokens not allowed by privacy rules.
*
* @param string $token_string
* A string with one or more tokens to be validated.
*
* @return bool
* TRUE if blacklisted token has been found, otherwise FALSE.
*/
protected static function containsForbiddenToken($token_string) {
// List of strings in tokens with personal identifying information not
// allowed for privacy reasons. See section 8.1 of the Google Analytics
// terms of use for more detailed information.
//
// This list can never ever be complete. For this reason it tries to use a
// regex and may kill a few other valid tokens, but it's the only way to
// protect users as much as possible from admins with illegal ideas.
//
// User tokens are not prefixed with colon to catch 'current-user' and
// 'user'.
//
// TODO: If someone have better ideas, share them, please!
$token_blacklist = [
':account-name]',
':author]',
':author:edit-url]',
':author:url]',
':author:path]',
':current-user]',
':current-user:original]',
':display-name]',
':fid]',
':mail]',
':name]',
':uid]',
':one-time-login-url]',
':owner]',
':owner:cancel-url]',
':owner:edit-url]',
':owner:url]',
':owner:path]',
'user:cancel-url]',
'user:edit-url]',
'user:url]',
'user:path]',
'user:picture]',
// addressfield_tokens.module
':first-name]',
':last-name]',
':name-line]',
':mc-address]',
':thoroughfare]',
':premise]',
// realname.module
':name-raw]',
// token.module
':ip-address]',
];
return preg_match('/' . implode('|', array_map('preg_quote', $token_blacklist)) . '/i', $token_string);
}
}
@@ -0,0 +1,27 @@
<?php
namespace Drupal\piwik\Plugin\migrate\process;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\Row;
/**
* This plugin flattens the custom variables array.
*
* @MigrateProcessPlugin(
* id = "piwik_custom_vars"
* )
*/
class PiwikCustomVars extends ProcessPluginBase {
/**
* Flatten custom vars array.
*/
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
list($piwik_custom_vars) = $value;
return isset($piwik_custom_vars['slots']) ? $piwik_custom_vars['slots'] : [];
}
}
@@ -0,0 +1,30 @@
<?php
namespace Drupal\piwik\Plugin\migrate\process;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\Row;
use Drupal\migrate\MigrateSkipRowException;
/**
* If the source evaluates to empty, we skip the current row.
*
* @MigrateProcessPlugin(
* id = "piwik_skip_row_if_not_set",
* handle_multiples = TRUE
* )
*/
class PiwikSkipRowIfNotSet extends ProcessPluginBase {
/**
* {@inheritdoc}
*/
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
if (!isset($value[$this->configuration['module']][$this->configuration['key']])) {
throw new MigrateSkipRowException();
}
return $value[$this->configuration['module']][$this->configuration['key']];
}
}
@@ -0,0 +1,113 @@
<?php
namespace Drupal\piwik\Plugin\migrate\process;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\MigrateSkipRowException;
use Drupal\migrate\Plugin\MigrateProcessInterface;
use Drupal\migrate\Plugin\MigrationInterface;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\Row;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Prefixes paths with a slash.
*
* @MigrateProcessPlugin(
* id = "piwik_visibility_pages"
* )
*/
class PiwikVisibilityPages extends ProcessPluginBase implements ContainerFactoryPluginInterface {
/**
* The module handler.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* The migration process plugin, configured for lookups in the d6_user_role
* and d7_user_role migrations.
*
* @var \Drupal\migrate\Plugin\MigrateProcessInterface
*/
protected $migrationPlugin;
/**
* Whether or not to skip Piwik that use PHP for visibility. Only applies if
* the PHP module is not enabled.
*
* @var bool
*/
protected $skipPHP = FALSE;
/**
* {@inheritdoc}
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, ModuleHandlerInterface $module_handler, MigrateProcessInterface $migration_plugin) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->moduleHandler = $module_handler;
$this->migrationPlugin = $migration_plugin;
if (isset($configuration['skip_php'])) {
$this->skipPHP = $configuration['skip_php'];
}
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) {
$migration_configuration = [
'migration' => [
'd6_user_role',
'd7_user_role',
],
];
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('module_handler'),
$container->get('plugin.manager.migrate.process')->createInstance('migration', $migration_configuration, $migration)
);
}
/**
* {@inheritdoc}
*/
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
list($old_visibility, $pages) = $value;
$request_path_pages = '';
if ($pages) {
// 2 == BLOCK_VISIBILITY_PHP in Drupal 6 and 7.
if ($old_visibility == 2) {
// If the PHP module is present, migrate the visibility code unaltered.
if ($this->moduleHandler->moduleExists('php')) {
$request_path_pages = $pages;
}
// Skip the row if we're configured to. If not, we don't need to do
// anything else -- the block will simply have no PHP or request_path
// visibility configuration.
elseif ($this->skipPHP) {
throw new MigrateSkipRowException();
}
}
else {
$paths = preg_split("(\r\n?|\n)", $pages);
foreach ($paths as $key => $path) {
$paths[$key] = $path === '<front>' ? $path : '/' . ltrim($path, '/');
}
$request_path_pages = implode("\n", $paths);
}
}
return $request_path_pages;
}
}
@@ -0,0 +1,87 @@
<?php
namespace Drupal\piwik\Plugin\migrate\process;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\Plugin\MigrateProcessInterface;
use Drupal\migrate\Plugin\MigrationInterface;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\Row;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Converts D7 role ids to D8 role names.
*
* @MigrateProcessPlugin(
* id = "piwik_visibility_roles"
* )
*/
class PiwikVisibilityRoles extends ProcessPluginBase implements ContainerFactoryPluginInterface {
/**
* The module handler.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* The migration process plugin, configured for lookups in the d6_user_role
* and d7_user_role migrations.
*
* @var \Drupal\migrate\Plugin\MigrateProcessInterface
*/
protected $migrationPlugin;
/**
* {@inheritdoc}
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, ModuleHandlerInterface $module_handler, MigrateProcessInterface $migration_plugin) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->moduleHandler = $module_handler;
$this->migrationPlugin = $migration_plugin;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) {
$migration_configuration = [
'migration' => [
'd6_user_role',
'd7_user_role',
],
];
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('module_handler'),
$container->get('plugin.manager.migrate.process')->createInstance('migration', $migration_configuration, $migration)
);
}
/**
* {@inheritdoc}
*/
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
list($roles) = $value;
// Remove role IDs disabled in D6/D7.
$roles = array_filter($roles);
$user_role_roles = [];
if ($roles) {
foreach ($roles as $key => $role_id) {
$roles[$key] = $this->migrationPlugin->transform($role_id, $migrate_executable, $row, $destination_property);
}
$user_role_roles = array_combine($roles, $roles);
}
return $user_role_roles;
}
}
@@ -0,0 +1,221 @@
<?php
namespace Drupal\piwik\Tests;
use Drupal\Core\Session\AccountInterface;
use Drupal\simpletest\WebTestBase;
/**
* Test basic functionality of Piwik module.
*
* @group Piwik
*/
class PiwikBasicTest extends WebTestBase {
/**
* User without permissions to use snippets.
*
* @var \Drupal\user\UserInterface
*/
protected $noSnippetUser;
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['piwik'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$permissions = [
'access administration pages',
'administer piwik',
];
// User to set up piwik.
$this->noSnippetUser = $this->drupalCreateUser($permissions);
$permissions[] = 'add JS snippets for piwik';
$this->admin_user = $this->drupalCreateUser($permissions);
$this->drupalLogin($this->admin_user);
}
/**
* Tests if configuration is possible.
*/
public function testPiwikConfiguration() {
// Check for setting page's presence.
$this->drupalGet('admin/config/system/piwik');
$this->assertRaw(t('Piwik site ID'), '[testPiwikConfiguration]: Settings page displayed.');
// Check for account code validation.
$edit['piwik_site_id'] = $this->randomMachineName(2);
$edit['piwik_url_http'] = 'http://www.example.com/piwik/';
$this->drupalPostForm('admin/config/system/piwik', $edit, 'Save configuration');
$this->assertRaw(t('A valid Piwik site ID is an integer only.'), '[testPiwikConfiguration]: Invalid Piwik site ID number validated.');
// Verify that invalid URLs throw a form error.
$edit = [];
$edit['piwik_site_id'] = 1;
$edit['piwik_url_http'] = 'http://www.example.com/piwik/';
$edit['piwik_url_https'] = 'https://www.example.com/piwik/';
$this->drupalPostForm('admin/config/system/piwik', $edit, t('Save configuration'));
$this->assertRaw('The validation of "http://www.example.com/piwik/piwik.php" failed with an exception', '[testPiwikConfiguration]: HTTP URL exception shown.');
$this->assertRaw('The validation of "https://www.example.com/piwik/piwik.php" failed with an exception', '[testPiwikConfiguration]: HTTPS URL exception shown.');
// User should have access to code snippets.
$this->assertFieldByName('piwik_codesnippet_before');
$this->assertFieldByName('piwik_codesnippet_after');
$this->assertNoFieldByXPath("//textarea[@name='piwik_codesnippet_before' and @disabled='disabled']", NULL, '"Code snippet (before)" is enabled.');
$this->assertNoFieldByXPath("//textarea[@name='piwik_codesnippet_after' and @disabled='disabled']", NULL, '"Code snippet (after)" is enabled.');
// Login as user without JS permissions.
$this->drupalLogin($this->noSnippetUser);
$this->drupalGet('admin/config/system/piwik');
// User should *not* have access to snippets, but create fields.
$this->assertFieldByName('piwik_codesnippet_before');
$this->assertFieldByName('piwik_codesnippet_after');
$this->assertFieldByXPath("//textarea[@name='piwik_codesnippet_before' and @disabled='disabled']", NULL, '"Code snippet (before)" is disabled.');
$this->assertFieldByXPath("//textarea[@name='piwik_codesnippet_after' and @disabled='disabled']", NULL, '"Code snippet (after)" is disabled.');
}
/**
* Tests if page visibility works.
*/
public function testPiwikPageVisibility() {
$site_id = '1';
$this->config('piwik.settings')->set('site_id', $site_id)->save();
$this->config('piwik.settings')->set('url_http', 'http://www.example.com/piwik/')->save();
$this->config('piwik.settings')->set('url_https', 'https://www.example.com/piwik/')->save();
// Show tracking on "every page except the listed pages".
$this->config('piwik.settings')->set('visibility.request_path_mode', 0)->save();
// Disable tracking one "admin*" pages only.
$this->config('piwik.settings')->set('visibility.request_path_pages', "/admin\n/admin/*")->save();
// Enable tracking only for authenticated users only.
$this->config('piwik.settings')->set('visibility.user_role_roles', [AccountInterface::AUTHENTICATED_ROLE => AccountInterface::AUTHENTICATED_ROLE])->save();
// Check tracking code visibility.
$this->drupalGet('');
$this->assertRaw('u+"piwik.php"', '[testPiwikPageVisibility]: Tracking code is displayed for authenticated users.');
// Test whether tracking code is not included on pages to omit.
$this->drupalGet('admin');
$this->assertNoRaw('u+"piwik.php"', '[testPiwikPageVisibility]: Tracking code is not displayed on admin page.');
$this->drupalGet('admin/config/system/piwik');
// Checking for tracking URI here, as $site_id is displayed in the form.
$this->assertNoRaw('u+"piwik.php"', '[testPiwikPageVisibility]: Tracking code is not displayed on admin subpage.');
// Test whether tracking code display is properly flipped.
$this->config('piwik.settings')->set('visibility.request_path_mode', 1)->save();
$this->drupalGet('admin');
$this->assertRaw('u+"piwik.php"', '[testPiwikPageVisibility]: Tracking code is displayed on admin page.');
$this->drupalGet('admin/config/system/piwik');
// Checking for tracking URI here, as $site_id is displayed in the form.
$this->assertRaw('u+"piwik.php"', '[testPiwikPageVisibility]: Tracking code is displayed on admin subpage.');
$this->drupalGet('');
$this->assertNoRaw('u+"piwik.php"', '[testPiwikPageVisibility]: Tracking code is NOT displayed on front page.');
// Test whether tracking code is not display for anonymous.
$this->drupalLogout();
$this->drupalGet('');
$this->assertNoRaw('u+"piwik.php"', '[testPiwikPageVisibility]: Tracking code is NOT displayed for anonymous.');
// Switch back to every page except the listed pages.
$this->config('piwik.settings')->set('visibility.request_path_mode', 0)->save();
// Enable tracking code for all user roles.
$this->config('piwik.settings')->set('visibility.user_role_roles', [])->save();
// Test whether 403 forbidden tracking code is shown if user has no access.
$this->drupalGet('admin');
$this->assertRaw('"403/URL = "', '[testPiwikPageVisibility]: 403 Forbidden tracking code shown if user has no access.');
// Test whether 404 not found tracking code is shown on non-existent pages.
$this->drupalGet($this->randomMachineName(64));
$this->assertRaw('"404/URL = "', '[testPiwikPageVisibility]: 404 Not Found tracking code shown on non-existent page.');
}
/**
* Tests if tracking code is properly added to the page.
*/
public function testPiwikTrackingCode() {
$site_id = '2';
$this->config('piwik.settings')->set('site_id', $site_id)->save();
$this->config('piwik.settings')->set('url_http', 'http://www.example.com/piwik/')->save();
$this->config('piwik.settings')->set('url_https', 'https://www.example.com/piwik/')->save();
// Show tracking code on every page except the listed pages.
$this->config('piwik.settings')->set('visibility.request_path_mode', 0)->save();
// Enable tracking code for all user roles.
$this->config('piwik.settings')->set('visibility.user_role_roles', [])->save();
/* Sample JS code as added to page:
<script type="text/javascript">
var _paq = _paq || [];
(function(){
var u=(("https:" == document.location.protocol) ? "https://{$PIWIK_URL}" : "http://{$PIWIK_URL}");
_paq.push(['setSiteId', {$IDSITE}]);
_paq.push(['setTrackerUrl', u+'piwik.php']);
_paq.push(['trackPageView']);
var d=document,
g=d.createElement('script'),
s=d.getElementsByTagName('script')[0];
g.type='text/javascript';
g.defer=true;
g.async=true;
g.src=u+'piwik.js';
s.parentNode.insertBefore(g,s);
})();
</script>
*/
// Test whether tracking code uses latest JS.
$this->config('piwik.settings')->set('cache', 0)->save();
$this->drupalGet('');
$this->assertRaw('u+"piwik.php"', '[testPiwikTrackingCode]: Latest tracking code used.');
// Test if tracking of User ID is enabled.
$this->config('piwik.settings')->set('track.userid', 1)->save();
$this->drupalGet('');
$this->assertRaw('_paq.push(["setUserId", ', '[testPiwikTrackingCode]: Tracking code for User ID is enabled.');
// Test if tracking of User ID is disabled.
$this->config('piwik.settings')->set('track.userid', 0)->save();
$this->drupalGet('');
$this->assertNoRaw('_paq.push(["setUserId", ', '[testPiwikTrackingCode]: Tracking code for User ID is disabled.');
// Test whether single domain tracking is active.
$this->drupalGet('');
$this->assertNoRaw('_paq.push(["setCookieDomain"', '[testPiwikTrackingCode]: Single domain tracking is active.');
// Enable "One domain with multiple subdomains".
$this->config('piwik.settings')->set('domain_mode', 1)->save();
$this->drupalGet('');
// Test may run on localhost, an ipaddress or real domain name.
// TODO: Workaround to run tests successfully. This feature cannot tested
// reliable.
global $cookie_domain;
if (count(explode('.', $cookie_domain)) > 2 && !is_numeric(str_replace('.', '', $cookie_domain))) {
$this->assertRaw('_paq.push(["setCookieDomain"', '[testPiwikTrackingCode]: One domain with multiple subdomains is active on real host.');
}
else {
// Special cases, Localhost and IP addresses don't show 'setCookieDomain'.
$this->assertNoRaw('_paq.push(["setCookieDomain"', '[testPiwikTrackingCode]: One domain with multiple subdomains may be active on localhost (test result is not reliable).');
}
// Test whether the BEFORE and AFTER code is added to the tracker.
$this->config('piwik.settings')->set('codesnippet.before', '_paq.push(["setLinkTrackingTimer", 250]);')->save();
$this->config('piwik.settings')->set('codesnippet.after', '_paq.push(["t2.setSiteId", 2]);if(1 == 1 && 2 < 3 && 2 > 1){console.log("Piwik: Custom condition works.");}_gaq.push(["t2.trackPageView"]);')->save();
$this->drupalGet('');
$this->assertRaw('setLinkTrackingTimer', '[testPiwikTrackingCode]: Before codesnippet has been found with "setLinkTrackingTimer" set.');
$this->assertRaw('t2.trackPageView', '[testPiwikTrackingCode]: After codesnippet with "t2" tracker has been found.');
$this->assertRaw('if(1 == 1 && 2 < 3 && 2 > 1){console.log("Piwik: Custom condition works.");}', '[testPiwikTrackingCode]: JavaScript code is not HTML escaped.');
}
}
@@ -0,0 +1,59 @@
<?php
namespace Drupal\piwik\Tests;
use Drupal\simpletest\WebTestBase;
use Drupal\Component\Serialization\Json;
/**
* Test custom url functionality of Piwik module.
*
* @group Piwik
*/
class PiwikCustomUrls extends WebTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['piwik'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$permissions = [
'access administration pages',
'administer piwik',
'administer modules',
'administer site configuration',
];
// User to set up piwik.
$this->admin_user = $this->drupalCreateUser($permissions);
}
/**
* Tests if user password page urls are overridden.
*/
public function testPiwikUserPasswordPage() {
$base_path = base_path();
$site_id = '1';
$this->config('piwik.settings')->set('site_id', $site_id)->save();
$this->config('piwik.settings')->set('url_http', 'http://www.example.com/piwik/')->save();
$this->config('piwik.settings')->set('url_https', 'https://www.example.com/piwik/')->save();
$this->drupalGet('user/password', ['query' => ['name' => 'foo']]);
$this->assertRaw('_paq.push(["setCustomUrl", ' . Json::encode($base_path . 'user/password') . ']);');
$this->drupalGet('user/password', ['query' => ['name' => 'foo@example.com']]);
$this->assertRaw('_paq.push(["setCustomUrl", ' . Json::encode($base_path . 'user/password') . ']);');
$this->drupalGet('user/password');
$this->assertNoRaw('_paq.push(["setCustomUrl", "', '[testPiwikCustomUrls]: Custom url not set.');
}
}
@@ -0,0 +1,133 @@
<?php
namespace Drupal\piwik\Tests;
use Drupal\Component\Serialization\Json;
use Drupal\simpletest\WebTestBase;
/**
* Test custom variables functionality of Piwik module.
*
* @group Piwik
*/
class PiwikCustomVariablesTest extends WebTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['piwik', 'token'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$permissions = [
'access administration pages',
'administer piwik',
];
// User to set up piwik.
$this->admin_user = $this->drupalCreateUser($permissions);
}
/**
* Tests if custom variables are properly added to the page.
*/
public function testPiwikCustomVariables() {
$site_id = '3';
$this->config('piwik.settings')->set('site_id', $site_id)->save();
$this->config('piwik.settings')->set('url_http', 'http://www.example.com/piwik/')->save();
$this->config('piwik.settings')->set('url_https', 'https://www.example.com/piwik/')->save();
// Basic test if the feature works.
$custom_vars = [
1 => [
'slot' => 1,
'name' => 'Foo 1',
'value' => 'Bar 1',
'scope' => 'visit',
],
2 => [
'slot' => 2,
'name' => 'Foo 2',
'value' => 'Bar 2',
'scope' => 'page',
],
3 => [
'slot' => 3,
'name' => 'Foo 3',
'value' => 'Bar 3',
'scope' => 'page',
],
4 => [
'slot' => 4,
'name' => 'Foo 4',
'value' => 'Bar 4',
'scope' => 'visit',
],
5 => [
'slot' => 5,
'name' => 'Foo 5',
'value' => 'Bar 5',
'scope' => 'visit',
],
];
$this->config('piwik.settings')->set('custom.variable', $custom_vars)->save();
$this->drupalGet('');
foreach ($custom_vars as $slot) {
$this->assertRaw('_paq.push(["setCustomVariable", ' . Json::encode($slot['slot']) . ', ' . Json::encode($slot['name']) . ', ' . Json::encode($slot['value']) . ', ' . Json::encode($slot['scope']) . ']);', '[testPiwikCustomVariables]: setCustomVariable ' . $slot['slot'] . ' is shown.');
}
// Test whether tokens are replaced in custom variable names.
$site_slogan = $this->randomMachineName(16);
$this->config('system.site')->set('slogan', $site_slogan)->save();
$custom_vars = [
1 => [
'slot' => 1,
'name' => 'Name: [site:slogan]',
'value' => 'Value: [site:slogan]',
'scope' => 'visit',
],
2 => [
'slot' => 2,
'name' => '',
'value' => $this->randomMachineName(16),
'scope' => 'page',
],
3 => [
'slot' => 3,
'name' => $this->randomMachineName(16),
'value' => '',
'scope' => 'visit',
],
4 => [
'slot' => 4,
'name' => '',
'value' => '',
'scope' => 'page',
],
5 => [
'slot' => 5,
'name' => '',
'value' => '',
'scope' => 'visit',
],
];
$this->config('piwik.settings')->set('custom.variable', $custom_vars)->save();
$this->verbose('<pre>' . print_r($custom_vars, TRUE) . '</pre>');
$this->drupalGet('');
$this->assertRaw('_paq.push(["setCustomVariable", 1, ' . Json::encode("Name: $site_slogan") . ', ' . Json::encode("Value: $site_slogan") . ', "visit"]', '[testPiwikCustomVariables]: Tokens have been replaced in custom variable.');
$this->assertNoRaw('_paq.push(["setCustomVariable", 2,', '[testPiwikCustomVariables]: Value with empty name is not shown.');
$this->assertNoRaw('_paq.push(["setCustomVariable", 3,', '[testPiwikCustomVariables]: Name with empty value is not shown.');
$this->assertNoRaw('_paq.push(["setCustomVariable", 4,', '[testPiwikCustomVariables]: Empty name and value is not shown.');
$this->assertNoRaw('_paq.push(["setCustomVariable", 5,', '[testPiwikCustomVariables]: Empty name and value is not shown.');
}
}
@@ -0,0 +1,107 @@
<?php
namespace Drupal\piwik\Tests;
use Drupal\Component\Utility\Html;
use Drupal\simpletest\WebTestBase;
/**
* Test php filter functionality of Piwik module.
*
* @group Piwik
*/
class PiwikPhpFilterTest extends WebTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['piwik', 'php'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
// Administrator with all permissions.
$permissions_admin_user = [
'access administration pages',
'administer piwik',
'use PHP for piwik tracking visibility',
];
$this->admin_user = $this->drupalCreateUser($permissions_admin_user);
// Administrator who cannot configure tracking visibility with PHP.
$permissions_delegated_admin_user = [
'access administration pages',
'administer piwik',
];
$this->delegated_admin_user = $this->drupalCreateUser($permissions_delegated_admin_user);
}
/**
* Tests if PHP module integration works.
*/
public function testPiwikPhpFilter() {
$site_id = '1';
$this->drupalLogin($this->admin_user);
$edit = [];
$edit['piwik_site_id'] = $site_id;
$edit['piwik_url_http'] = 'http://www.example.com/piwik/';
$edit['piwik_url_https'] = 'https://www.example.com/piwik/';
// Skip url check errors in automated tests.
$edit['piwik_url_skiperror'] = TRUE;
$edit['piwik_visibility_request_path_mode'] = 2;
$edit['piwik_visibility_request_path_pages'] = '<?php return 0; ?>';
$this->drupalPostForm('admin/config/system/piwik', $edit, t('Save configuration'));
// Compare saved setting with posted setting.
$piwik_visibility_request_path_pages = \Drupal::config('piwik.settings')->get('visibility.request_path_pages');
$this->assertEqual('<?php return 0; ?>', $piwik_visibility_request_path_pages, '[testPiwikPhpFilter]: PHP code snippet is intact.');
// Check tracking code visibility.
$this->config('piwik.settings')->set('visibility.request_path_pages', '<?php return TRUE; ?>')->save();
$this->drupalGet('');
$this->assertRaw('u+"piwik.php"', '[testPiwikPhpFilter]: Tracking is displayed on frontpage page.');
$this->drupalGet('admin');
$this->assertRaw('u+"piwik.php"', '[testPiwikPhpFilter]: Tracking is displayed on admin page.');
$this->config('piwik.settings')->set('visibility.request_path_pages', '<?php return FALSE; ?>')->save();
$this->drupalGet('');
$this->assertNoRaw('u+"piwik.php"', '[testPiwikPhpFilter]: Tracking is not displayed on frontpage page.');
// Test administration form.
$this->config('piwik.settings')->set('visibility.request_path_pages', '<?php return TRUE; ?>')->save();
$this->drupalGet('admin/config/system/piwik');
$this->assertRaw(t('Pages on which this PHP code returns <code>TRUE</code> (experts only)'), '[testPiwikPhpFilter]: Permission to administer PHP for tracking visibility.');
$this->assertRaw(Html::escape('<?php return TRUE; ?>'), '[testPiwikPhpFilter]: PHP code snippted is displayed.');
// Login the delegated user and check if fields are visible.
$this->drupalLogin($this->delegated_admin_user);
$this->drupalGet('admin/config/system/piwik');
$this->assertNoRaw(t('Pages on which this PHP code returns <code>TRUE</code> (experts only)'), '[testPiwikPhpFilter]: No permission to administer PHP for tracking visibility.');
$this->assertRaw(Html::escape('<?php return TRUE; ?>'), '[testPiwikPhpFilter]: No permission to view PHP code snippted.');
// Set a different value and verify that this is still the same after the
// post.
$this->config('piwik.settings')->set('visibility.request_path_pages', '<?php return 0; ?>')->save();
$edit = [];
$edit['piwik_site_id'] = $site_id;
$edit['piwik_url_http'] = 'http://www.example.com/piwik/';
$edit['piwik_url_https'] = 'https://www.example.com/piwik/';
// Required for testing only.
$edit['piwik_url_skiperror'] = TRUE;
$this->drupalPostForm('admin/config/system/piwik', $edit, t('Save configuration'));
// Compare saved setting with posted setting.
$piwik_visibility_request_path_mode = $this->config('piwik.settings')->get('visibility.request_path_mode');
$piwik_visibility_request_path_pages = $this->config('piwik.settings')->get('visibility.request_path_pages');
$this->assertEqual(2, $piwik_visibility_request_path_mode, '[testPiwikPhpFilter]: Pages on which this PHP code returns TRUE is selected.');
$this->assertEqual('<?php return 0; ?>', $piwik_visibility_request_path_pages, '[testPiwikPhpFilter]: PHP code snippet is intact.');
}
}
@@ -0,0 +1,107 @@
<?php
namespace Drupal\piwik\Tests;
use Drupal\Core\Session\AccountInterface;
use Drupal\simpletest\WebTestBase;
/**
* Test roles functionality of Piwik module.
*
* @group Piwik
*/
class PiwikRolesTest extends WebTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['piwik'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$permissions = [
'access administration pages',
'administer piwik',
];
// User to set up piwik.
$this->admin_user = $this->drupalCreateUser($permissions);
}
/**
* Tests if roles based tracking works.
*/
public function testPiwikRolesTracking() {
$site_id = '1';
$this->config('piwik.settings')->set('site_id', $site_id)->save();
$this->config('piwik.settings')->set('url_http', 'http://www.example.com/piwik/')->save();
$this->config('piwik.settings')->set('url_https', 'https://www.example.com/piwik/')->save();
// Test if the default settings are working as expected.
// Add to the selected roles only.
$this->config('piwik.settings')->set('visibility.user_role_mode', 0)->save();
// Enable tracking for all users.
$this->config('piwik.settings')->set('visibility.user_role_roles', [])->save();
// Check tracking code visibility.
$this->drupalGet('');
$this->assertRaw('u+"piwik.php"', '[testPiwikRoleVisibility]: Tracking code is displayed for anonymous users on frontpage with default settings.');
$this->drupalGet('admin');
$this->assertRaw('"403/URL = "', '[testPiwikRoleVisibility]: 403 Forbidden tracking code is displayed for anonymous users in admin section with default settings.');
$this->drupalLogin($this->admin_user);
$this->drupalGet('');
$this->assertRaw('u+"piwik.php"', '[testPiwikRoleVisibility]: Tracking code is displayed for authenticated users on frontpage with default settings.');
$this->drupalGet('admin');
$this->assertNoRaw('u+"piwik.php"', '[testPiwikRoleVisibility]: Tracking code is NOT displayed for authenticated users in admin section with default settings.');
// Test if the non-default settings are working as expected.
// Enable tracking only for authenticated users.
$this->config('piwik.settings')->set('visibility.user_role_roles', [AccountInterface::AUTHENTICATED_ROLE => AccountInterface::AUTHENTICATED_ROLE])->save();
$this->drupalGet('');
$this->assertRaw('u+"piwik.php"', '[testPiwikRoleVisibility]: Tracking code is displayed for authenticated users only on frontpage.');
$this->drupalLogout();
$this->drupalGet('');
$this->assertNoRaw('u+"piwik.php"', '[testPiwikRoleVisibility]: Tracking code is NOT displayed for anonymous users on frontpage.');
// Add to every role except the selected ones.
$this->config('piwik.settings')->set('visibility.user_role_mode', 1)->save();
// Enable tracking for all users.
$this->config('piwik.settings')->set('visibility.user_role_roles', [])->save();
// Check tracking code visibility.
$this->drupalGet('');
$this->assertRaw('u+"piwik.php"', '[testPiwikRoleVisibility]: Tracking code is added to every role and displayed for anonymous users.');
$this->drupalGet('admin');
$this->assertRaw('"403/URL = "', '[testPiwikRoleVisibility]: 403 Forbidden tracking code is shown for anonymous users if every role except the selected ones is selected.');
$this->drupalLogin($this->admin_user);
$this->drupalGet('');
$this->assertRaw('u+"piwik.php"', '[testPiwikRoleVisibility]: Tracking code is added to every role and displayed on frontpage for authenticated users.');
$this->drupalGet('admin');
$this->assertNoRaw('u+"piwik.php"', '[testPiwikRoleVisibility]: Tracking code is added to every role and NOT displayed in admin section for authenticated users.');
// Disable tracking for authenticated users.
$this->config('piwik.settings')->set('visibility.user_role_roles', [AccountInterface::AUTHENTICATED_ROLE => AccountInterface::AUTHENTICATED_ROLE])->save();
$this->drupalGet('');
$this->assertNoRaw('u+"piwik.php"', '[testPiwikRoleVisibility]: Tracking code is NOT displayed on frontpage for excluded authenticated users.');
$this->drupalGet('admin');
$this->assertNoRaw('u+"piwik.php"', '[testPiwikRoleVisibility]: Tracking code is NOT displayed in admin section for excluded authenticated users.');
$this->drupalLogout();
$this->drupalGet('');
$this->assertRaw('u+"piwik.php"', '[testPiwikRoleVisibility]: Tracking code is displayed on frontpage for included anonymous users.');
}
}
@@ -0,0 +1,98 @@
<?php
namespace Drupal\piwik\Tests;
use Drupal\simpletest\WebTestBase;
/**
* Test search functionality of Piwik module.
*
* @group Piwik
*/
class PiwikSearchTest extends WebTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['piwik', 'search', 'node'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']);
$permissions = [
'access administration pages',
'administer piwik',
'search content',
'create page content',
'edit own page content',
];
// User to set up piwik.
$this->admin_user = $this->drupalCreateUser($permissions);
$this->drupalLogin($this->admin_user);
}
/**
* Tests if search tracking is properly added to the page.
*/
public function testPiwikSearchTracking() {
$site_id = '1';
$this->config('piwik.settings')->set('site_id', $site_id)->save();
$this->config('piwik.settings')->set('url_http', 'http://www.example.com/piwik/')->save();
$this->config('piwik.settings')->set('url_https', 'https://www.example.com/piwik/')->save();
// Check tracking code visibility.
$this->drupalGet('');
$this->assertRaw($site_id, '[testPiwikSearch]: Tracking code is displayed for authenticated users.');
$this->drupalGet('search/node');
$this->assertNoRaw('_paq.push(["trackSiteSearch", ', '[testPiwikSearch]: Search tracker not added to page.');
// Enable site search support.
$this->config('piwik.settings')->set('track.site_search', 1)->save();
// Search for random string.
$search = [];
$search['keys'] = $this->randomMachineName(8);
// Create a node to search for.
// Create a node.
$edit = [];
$edit['title[0][value]'] = 'This is a test title';
$edit['body[0][value]'] = 'This test content contains ' . $search['keys'] . ' string.';
// Fire a search, it's expected to get 0 results.
$this->drupalPostForm('search/node', $search, t('Search'));
$this->assertRaw('_paq.push(["trackSiteSearch", ', '[testPiwikSearch]: Search results tracker is displayed.');
$this->assertRaw('window.piwik_search_results = 0;', '[testPiwikSearch]: Search yielded no results.');
// Save the node.
$this->drupalPostForm('node/add/page', $edit, t('Save'));
$this->assertText(t('@type @title has been created.', ['@type' => 'Basic page', '@title' => $edit['title[0][value]']]), 'Basic page created.');
// Index the node or it cannot found.
$this->cronRun();
$this->drupalPostForm('search/node', $search, t('Search'));
$this->assertRaw('_paq.push(["trackSiteSearch", ', '[testPiwikSearch]: Search results tracker is displayed.');
$this->assertRaw('window.piwik_search_results = 1;', '[testPiwikSearch]: One search result found.');
$this->drupalPostForm('node/add/page', $edit, t('Save'));
$this->assertText(t('@type @title has been created.', ['@type' => 'Basic page', '@title' => $edit['title[0][value]']]), 'Basic page created.');
// Index the node or it cannot found.
$this->cronRun();
$this->drupalPostForm('search/node', $search, t('Search'));
$this->assertRaw('_paq.push(["trackSiteSearch", ', '[testPiwikSearch]: Search results tracker is displayed.');
$this->assertRaw('window.piwik_search_results = 2;', '[testPiwikSearch]: Two search results found.');
}
}
@@ -0,0 +1,69 @@
<?php
namespace Drupal\piwik\Tests;
use Drupal\simpletest\WebTestBase;
/**
* Test status messages functionality of Piwik module.
*
* @group Piwik
*/
class PiwikStatusMessagesTest extends WebTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['piwik', 'piwik_test'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$permissions = [
'access administration pages',
'administer piwik',
];
// User to set up piwik.
$this->admin_user = $this->drupalCreateUser($permissions);
}
/**
* Tests if status messages tracking is properly added to the page.
*/
public function testPiwikStatusMessages() {
$site_id = '1';
$this->config('piwik.settings')->set('site_id', $site_id)->save();
$this->config('piwik.settings')->set('url_http', 'http://www.example.com/piwik/')->save();
$this->config('piwik.settings')->set('url_https', 'https://www.example.com/piwik/')->save();
// Enable logging of errors only.
$this->config('piwik.settings')->set('track.messages', ['error' => 'error'])->save();
$this->drupalPostForm('user/login', [], t('Log in'));
$this->assertRaw('_paq.push(["trackEvent", "Messages", "Error message", "Username field is required."]);', '[testPiwikStatusMessages]: trackEvent "Username field is required." is shown.');
$this->assertRaw('_paq.push(["trackEvent", "Messages", "Error message", "Password field is required."]);', '[testPiwikStatusMessages]: trackEvent "Password field is required." is shown.');
// Testing this drupal_set_message() requires an extra test module.
$this->drupalGet('piwik-test/drupal-set-message');
$this->assertNoRaw('_paq.push(["trackEvent", "Messages", "Status message", "Example status message."]);', '[testPiwikStatusMessages]: Example status message is not enabled for tracking.');
$this->assertNoRaw('_paq.push(["trackEvent", "Messages", "Warning message", "Example warning message."]);', '[testPiwikStatusMessages]: Example warning message is not enabled for tracking.');
$this->assertRaw('_paq.push(["trackEvent", "Messages", "Error message", "Example error message."]);', '[testPiwikStatusMessages]: Example error message is shown.');
$this->assertRaw('_paq.push(["trackEvent", "Messages", "Error message", "Example error message with html tags and link."]);', '[testPiwikStatusMessages]: HTML has been stripped successful from Example error message with html tags and link.');
// Enable logging of status, warnings and errors.
$this->config('piwik.settings')->set('track.messages', ['status' => 'status', 'warning' => 'warning', 'error' => 'error'])->save();
$this->drupalGet('piwik-test/drupal-set-message');
$this->assertRaw('_paq.push(["trackEvent", "Messages", "Status message", "Example status message."]);', '[testPiwikStatusMessages]: Example status message is enabled for tracking.');
$this->assertRaw('_paq.push(["trackEvent", "Messages", "Warning message", "Example warning message."]);', '[testPiwikStatusMessages]: Example warning message is enabled for tracking.');
$this->assertRaw('_paq.push(["trackEvent", "Messages", "Error message", "Example error message."]);', '[testPiwikStatusMessages]: Example error message is shown.');
$this->assertRaw('_paq.push(["trackEvent", "Messages", "Error message", "Example error message with html tags and link."]);', '[testPiwikStatusMessages]: HTML has been stripped successful from Example error message with html tags and link.');
}
}
@@ -0,0 +1,78 @@
<?php
namespace Drupal\piwik\Tests;
use Drupal\simpletest\WebTestBase;
/**
* Test uninstall functionality of Piwik module.
*
* @group Piwik
*/
class PiwikUninstallTest extends WebTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['piwik'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$permissions = [
'access administration pages',
'administer piwik',
'administer modules',
];
// User to set up piwik.
$this->admin_user = $this->drupalCreateUser($permissions);
$this->drupalLogin($this->admin_user);
}
/**
* Tests if the module cleans up the disk on uninstall.
*/
public function testPiwikUninstall() {
$cache_path = 'public://piwik';
$site_id = '1';
$this->config('piwik.settings')->set('site_id', $site_id)->save();
$this->config('piwik.settings')->set('url_http', 'http://www.example.com/piwik/')->save();
$this->config('piwik.settings')->set('url_https', 'https://www.example.com/piwik/')->save();
// Enable local caching of piwik.js.
$this->config('piwik.settings')->set('cache', 1)->save();
// Load front page to get the piwik.js downloaded into local cache. But
// loading the piwik.js is not possible as "url_http" is a test dummy only.
// Create a dummy file to complete the rest of the tests.
file_prepare_directory($cache_path, FILE_CREATE_DIRECTORY);
$data = $this->randomMachineName(128);
$file_destination = $cache_path . '/piwik.js';
file_unmanaged_save_data($data, $file_destination);
file_unmanaged_save_data(gzencode($data, 9, FORCE_GZIP), $file_destination . '.gz', FILE_EXISTS_REPLACE);
// Test if the directory and piwik.js exists.
$this->assertTrue(file_prepare_directory($cache_path), 'Cache directory "public://piwik" has been found.');
$this->assertTrue(file_exists($cache_path . '/piwik.js'), 'Cached piwik.js tracking file has been found.');
$this->assertTrue(file_exists($cache_path . '/piwik.js.gz'), 'Cached piwik.js.gz tracking file has been found.');
// Uninstall the module.
$edit = [];
$edit['uninstall[piwik]'] = TRUE;
$this->drupalPostForm('admin/modules/uninstall', $edit, t('Uninstall'));
$this->assertNoText(\Drupal::translation()->translate('Configuration deletions'), 'No configuration deletions listed on the module install confirmation page.');
$this->drupalPostForm(NULL, NULL, t('Uninstall'));
$this->assertText(t('The selected modules have been uninstalled.'), 'Modules status has been updated.');
// Test if the directory and all files have been removed.
$this->assertFalse(file_scan_directory($cache_path, '/.*/'), 'Cached JavaScript files have been removed.');
$this->assertFalse(file_prepare_directory($cache_path), 'Cache directory "public://piwik" has been removed.');
}
}
@@ -0,0 +1,71 @@
<?php
namespace Drupal\piwik\Tests;
use Drupal\simpletest\WebTestBase;
/**
* Test user fields functionality of Piwik module.
*
* @group Piwik
*/
class PiwikUserFieldsTestTest extends WebTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['piwik', 'field_ui'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$permissions = [
'access administration pages',
'administer user form display',
'opt-in or out of piwik tracking',
];
// User to set up piwik.
$this->admin_user = $this->drupalCreateUser($permissions);
$this->drupalLogin($this->admin_user);
}
/**
* Tests if "allow users to customize tracking on their account page" works.
*/
public function testPiwikUserFields() {
$ua_code = 'UA-123456-1';
$this->config('piwik.settings')->set('account', $ua_code)->save();
// Check if the pseudo field is shown on account forms.
$this->drupalGet('admin/config/people/accounts/form-display');
$this->assertResponse(200);
$this->assertRaw(t('Piwik settings'), '[testPiwikUserFields]: Piwik settings field exists on Manage form display.');
// No customization allowed.
$this->config('piwik.settings')->set('visibility.user_account_mode', 0)->save();
$this->drupalGet('user/' . $this->admin_user->id() . '/edit');
$this->assertResponse(200);
$this->assertNoRaw(t('Piwik settings'), '[testPiwikUserFields]: Piwik settings field does not exist on user edit page.');
// Tracking on by default, users with opt-in or out of tracking permission
// can opt out.
$this->config('piwik.settings')->set('visibility.user_account_mode', 1)->save();
$this->drupalGet('user/' . $this->admin_user->id() . '/edit');
$this->assertResponse(200);
$this->assertRaw(t('Users are tracked by default, but you are able to opt out.'), '[testPiwikUserFields]: Piwik settings field exists on on user edit page');
// Tracking off by default, users with opt-in or out of tracking permission
// can opt in.
$this->config('piwik.settings')->set('visibility.user_account_mode', 2)->save();
$this->drupalGet('user/' . $this->admin_user->id() . '/edit');
$this->assertResponse(200);
$this->assertRaw(t('Users are <em>not</em> tracked by default, but you are able to opt in.'), '[testPiwikUserFields]: Piwik settings field exists on on user edit page.');
}
}