class GoogleAnalyticsQuery in Google Analytics Reports 8.3
Defines a Views query class for Google Analytics Reports API.
Plugin annotation
@ViewsQuery(
id = "google_analytics_query",
title = @Translation("Google Analytics Query"),
help = @Translation("Defines a Views query class for Google Analytics Reports API.")
)
Hierarchy
- class \Drupal\Component\Plugin\PluginBase implements DerivativeInspectionInterface, PluginInspectionInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
- class \Drupal\views\Plugin\views\PluginBase implements DependentPluginInterface, ContainerFactoryPluginInterface, TrustedCallbackInterface, ViewsPluginInterface
- class \Drupal\views\Plugin\views\query\QueryPluginBase implements CacheableDependencyInterface
- class \Drupal\google_analytics_reports\Plugin\views\query\GoogleAnalyticsQuery uses StringTranslationTrait
- class \Drupal\views\Plugin\views\query\QueryPluginBase implements CacheableDependencyInterface
- class \Drupal\views\Plugin\views\PluginBase implements DependentPluginInterface, ContainerFactoryPluginInterface, TrustedCallbackInterface, ViewsPluginInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
Expanded class hierarchy of GoogleAnalyticsQuery
File
- src/
Plugin/ views/ query/ GoogleAnalyticsQuery.php, line 28
Namespace
Drupal\google_analytics_reports\Plugin\views\queryView source
class GoogleAnalyticsQuery extends QueryPluginBase {
use StringTranslationTrait;
/**
* A list of tables in the order they should be added, keyed by alias.
*
* @var array
*/
protected $tableQueue = [];
/**
* An array of fields.
*
* @var array
*/
protected $fields = [];
/**
* An array mapping table aliases and field names to field aliases.
*
* @var array
*/
protected $fieldAliases = [];
/**
* An array of sections of the WHERE query.
*
* Each section is in itself an array of pieces and a flag as to whether
* or not it should be AND or OR.
*
* @var array
*/
protected $where = [];
/**
* A simple array of order by clauses.
*
* @var array
*/
protected $orderby = [];
/**
* The default operator to use when connecting the WHERE groups.
*
* @var string
*/
protected $groupOperator = 'AND';
/**
* Module handler.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
public $moduleHandler;
/**
* Config factory.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
public $configFactory;
/**
* The messenger.
*
* @var \Drupal\Core\Messenger\MessengerInterface
*/
protected $messenger;
/**
* The state service.
*
* @var \Drupal\Core\State\StateInterface
*/
protected $state;
/**
* {@inheritdoc}
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, ModuleHandlerInterface $module_handler, ConfigFactoryInterface $config_factory, StateInterface $state, MessengerInterface $messenger) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->moduleHandler = $module_handler;
$this->configFactory = $config_factory;
$this->state = $state;
$this->messenger = $messenger;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container
->get('module_handler'), $container
->get('config.factory'), $container
->get('state'), $container
->get('messenger'));
}
/**
* Constructor; Create the basic query object and fill with default values.
*
* {@inheritdoc}
*/
public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {
parent::init($view, $display, $options);
$this
->unpackOptions($this->options, $options);
}
/**
* Add a metric or dimension to the query.
*
* @param string $table
* NULL in most cases, we could probably remove this altogether.
* @param string $field
* The name of the metric/dimension/field to add.
* @param string $alias
* Probably could get rid of this too.
* @param array $params
* Probably could get rid of this too.
*
* @return string
* The name that this field can be referred to as.
*/
public function addField($table, $field, $alias = '', array $params = []) {
// We check for this specifically because it gets a special alias.
if ($table == $this->view->storage
->get('base_table') && $field == $this->view->storage
->get('base_field') && empty($alias)) {
$alias = $this->view->storage
->get('base_field');
}
if ($table && empty($this->tableQueue[$table])) {
$this
->ensureTable($table);
}
if (!$alias && $table) {
$alias = $table . '_' . $field;
}
// Make sure an alias is assigned.
$alias = $alias ? $alias : $field;
// We limit the length of the original alias up to 60 characters
// to get a unique alias later if its have duplicates.
$alias = substr($alias, 0, 60);
// Create a field info array.
$field_info = [
'field' => $field,
'table' => $table,
'alias' => $alias,
] + $params;
// Test to see if the field is actually the same or not. Due to
// differing parameters changing the aggregation function, we need
// to do some automatic alias collision detection:
$base = $alias;
$counter = 0;
while (!empty($this->fields[$alias]) && $this->fields[$alias] != $field_info) {
$field_info['alias'] = $alias = $base . '_' . ++$counter;
}
if (empty($this->fields[$alias])) {
$this->fields[$alias] = $field_info;
}
// Keep track of all aliases used.
$this->fieldAliases[$table][$field] = $alias;
return $alias;
}
/**
* Add a filter string to the query.
*
* @param string $group
* The filter group to add these to; groups are used to create AND/OR
* sections of the Google Analytics query. Groups cannot be nested.
* Use 0 as the default group. If the group does not yet exist it will
* be created as an AND group.
* @param string $field
* The name of the metric/dimension/field to check.
* @param mixed $value
* The value to test the field against. In most cases, this is a scalar.
* @param string $operator
* The comparison operator, such as =, <, or >=.
*/
public function addWhere($group, $field, $value = NULL, $operator = NULL) {
// Ensure all variants of 0 are actually 0. Thus '', 0 and NULL are all
// the default group.
if (empty($group)) {
$group = 0;
}
// Check for a group.
if (!isset($this->where[$group])) {
$this
->setWhereGroup('AND', $group);
}
$this->where[$group]['conditions'][] = [
'field' => $field,
'value' => $value,
'operator' => $operator,
];
}
/**
* Add SORT attribute to the query.
*
* @param string $table
* NULL, don't use this.
* @param string $field
* The metric/dimensions/field.
* @param string $order
* Either '' for ascending or '-' for descending.
* @param string $alias
* Don't use this yet (at all?).
* @param array $params
* Don't use this yet (at all?).
*/
public function addOrderBy($table, $field = NULL, $order = 'ASC', $alias = '', array $params = []) {
$this->orderby[] = [
'field' => $field,
'direction' => strtoupper($order) == 'DESC' ? '-' : '',
];
}
/**
* {@inheritdoc}
*/
public function query($get_count = FALSE) {
$available_fields = google_analytics_reports_get_fields();
$query = [];
foreach ($this->fields as $field) {
$field_name = google_analytics_reports_variable_to_custom_field($field['field']);
if ($available_fields[$field_name]) {
$type = $available_fields[$field_name]->type;
$type = $type == 'dimension' ? 'dimensions' : 'metrics';
$query[$type][] = 'ga:' . $field['field'];
}
}
$filters = [];
if (isset($this->where)) {
foreach ($this->where as $where_group => $where) {
foreach ($where['conditions'] as $condition) {
$field_name = google_analytics_reports_variable_to_custom_field($condition['field']);
if ($field_name == '.start_date' || $field_name == '.end_date' || $field_name == 'profile_id') {
// Remove dot from begging of the string.
$field_name = ltrim($field_name, '.');
$query[$field_name] = intval($condition['value']);
}
elseif (!empty($available_fields[$field_name])) {
$filters[$where_group][] = 'ga:' . $condition['field'] . $condition['operator'] . $condition['value'];
}
}
if (!empty($filters[$where_group])) {
$glue = $where['type'] == 'AND' ? ';' : ',';
$filters[$where_group] = implode($glue, $filters[$where_group]);
}
}
}
if (!empty($filters)) {
$glue = $this->groupOperator == 'AND' ? ';' : ',';
$query['filters'] = implode($glue, $filters);
}
if (isset($this->orderby)) {
foreach ($this->orderby as $field) {
$query['sort_metric'][] = $field['direction'] . 'ga:' . $field['field'];
}
}
// Change reports profile.
if (!empty($this->options['reports_profile']) && !empty($this->options['profile_id'])) {
$query['profile_id'] = $this->options['profile_id'];
}
return $query;
}
/**
* {@inheritdoc}
*/
public function alter(ViewExecutable $view) {
$this->moduleHandler
->invokeAll('views_query_alter', [
$view,
$this,
]);
}
/**
* Builds the necessary info to execute the query.
*/
public function build(ViewExecutable $view) {
// Store the view in the object to be able to use it later.
$this->view = $view;
$view
->initPager();
// Let the pager modify the query to add limits.
$view->pager
->query();
$view->build_info['query'] = $this
->query();
$view->build_info['count_query'] = $this
->query(TRUE);
}
/**
* {@inheritdoc}
*/
public function execute(ViewExecutable $view) {
// Initial check to see if we should attempt to run the query.
if (!$this->state
->get('google_analytics_reports_api.access_token')) {
// Optionally do not warn users on every query attempt before auth.
$this->messenger
->addMessage($this
->t('You must <a href=":url">authorize your site</a> to use your Google Analytics account before you can view reports.', [
':url' => Url::fromRoute('google_analytics_reports_api.settings')
->toString(),
]));
return;
}
$query = $view->build_info['query'];
$count_query = $view->build_info['count_query'];
$start = microtime(TRUE);
// Query for total number of items.
$count_query['max_results'] = 9999;
$count_query['start_index'] = 1;
$count_feed = google_analytics_reports_api_report_data($count_query);
// Process only if data is available.
if (!empty($count_feed->results->rows)) {
$view->pager->total_items = count($count_feed->results->rows);
$view->pager
->updatePageInfo();
// Adjust based on the pager's modifications to limit and offset.
if (!empty($this->limit) || !empty($this->offset)) {
$query['max_results'] = intval(!empty($this->limit) ? $this->limit : 1000);
$query['start_index'] = intval(!empty($this->offset) ? $this->offset : 0) + 1;
}
$feed = google_analytics_reports_api_report_data($query);
$rows = $feed->results->rows;
$views_result = [];
$count = 0;
foreach ($rows as $row) {
$row['index'] = $count;
$views_result[] = new ResultRow($row);
$count++;
}
$view->result = isset($views_result) ? $views_result : [];
$view->execute_time = microtime(TRUE) - $start;
if ($view->pager
->usePager()) {
$view->total_rows = $view->pager
->getTotalItems();
}
// Add to build_info['query'] to render query in Views UI query summary
// area.
$view->build_info['query'] = print_r($feed->results->query, TRUE);
}
else {
// Set empty query instead of current query array to prevent error
// in Views UI.
$view->build_info['query'] = '';
// Display the error from Google.
if (!empty($count_feed->response->data)) {
$response_data = json_decode($count_feed->response->data);
if (isset($response_data['error']['message'])) {
$this->messenger
->addMessage(Html::escape($response_data['error']['message']), 'error');
}
}
}
}
/**
* {@inheritdoc}
*/
public function defineOptions() {
$options = parent::defineOptions();
$options['reports_profile'] = [
'default' => FALSE,
'translatable' => FALSE,
'bool' => TRUE,
];
$options['profile_id'] = [
'default' => FALSE,
];
return $options;
}
/**
* {@inheritdoc}
*/
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
parent::buildOptionsForm($form, $form_state);
// Load profiles list.
$profile_list = google_analytics_reports_api_profiles_list();
$profile_info = '';
if (isset($profile_list['current_profile'])) {
$profile_info = parse_url($profile_list['current_profile']->websiteUrl, PHP_URL_HOST) . ' - ' . $profile_list['current_profile']->name . ' (' . $profile_list['current_profile']->id . ')';
}
if ($profile_list) {
$form['reports_profile'] = [
'#title' => $this
->t('Use another reports profile'),
'#description' => $this
->t('This view will use another reports profile rather than system default profile: %profile.', [
'%profile' => $profile_info,
]),
'#type' => 'checkbox',
'#default_value' => !empty($this->options['reports_profile']),
];
$form['profile_id'] = [
'#type' => 'select',
'#title' => $this
->t('Reports profile'),
'#options' => $profile_list['options'],
'#description' => $this
->t('Choose your Google Analytics profile.'),
'#default_value' => $this->options['profile_id'],
'#dependency' => [
'edit-query-options-reports-profile' => '1',
],
];
}
}
/**
* Make sure table exists.
*
* @param string $table
* Table name.
* @param string $relationship
* Relationship.
* @param string $join
* Join.
*/
public function ensureTable($table, $relationship = NULL, $join = NULL) {
}
}
Members
Name![]() |
Modifiers | Type | Description | Overrides |
---|---|---|---|---|
DependencySerializationTrait:: |
protected | property | An array of entity type IDs keyed by the property name of their storages. | |
DependencySerializationTrait:: |
protected | property | An array of service IDs keyed by property name used for serialization. | |
DependencySerializationTrait:: |
public | function | 1 | |
DependencySerializationTrait:: |
public | function | 2 | |
GoogleAnalyticsQuery:: |
public | property | Config factory. | |
GoogleAnalyticsQuery:: |
protected | property | An array mapping table aliases and field names to field aliases. | |
GoogleAnalyticsQuery:: |
protected | property | An array of fields. | |
GoogleAnalyticsQuery:: |
protected | property | The default operator to use when connecting the WHERE groups. | |
GoogleAnalyticsQuery:: |
protected | property |
The messenger. Overrides MessengerTrait:: |
|
GoogleAnalyticsQuery:: |
public | property | Module handler. | |
GoogleAnalyticsQuery:: |
protected | property | A simple array of order by clauses. | |
GoogleAnalyticsQuery:: |
protected | property | The state service. | |
GoogleAnalyticsQuery:: |
protected | property | A list of tables in the order they should be added, keyed by alias. | |
GoogleAnalyticsQuery:: |
protected | property | An array of sections of the WHERE query. | |
GoogleAnalyticsQuery:: |
public | function | Add a metric or dimension to the query. | |
GoogleAnalyticsQuery:: |
public | function | Add SORT attribute to the query. | |
GoogleAnalyticsQuery:: |
public | function | Add a filter string to the query. | |
GoogleAnalyticsQuery:: |
public | function |
Let modules modify the query just prior to finalizing it. Overrides QueryPluginBase:: |
|
GoogleAnalyticsQuery:: |
public | function |
Builds the necessary info to execute the query. Overrides QueryPluginBase:: |
|
GoogleAnalyticsQuery:: |
public | function |
Provide a form to edit options for this plugin. Overrides PluginBase:: |
|
GoogleAnalyticsQuery:: |
public static | function |
Creates an instance of the plugin. Overrides PluginBase:: |
|
GoogleAnalyticsQuery:: |
public | function |
Information about options for all kinds of purposes will be held here. Overrides PluginBase:: |
|
GoogleAnalyticsQuery:: |
public | function | Make sure table exists. | |
GoogleAnalyticsQuery:: |
public | function |
Executes the query and fills the associated view object with according
values. Overrides QueryPluginBase:: |
|
GoogleAnalyticsQuery:: |
public | function |
Constructor; Create the basic query object and fill with default values. Overrides PluginBase:: |
|
GoogleAnalyticsQuery:: |
public | function |
Generate a query and a countquery from all of the information supplied
to the object. Overrides QueryPluginBase:: |
|
GoogleAnalyticsQuery:: |
public | function |
Constructs a PluginBase object. Overrides PluginBase:: |
|
MessengerTrait:: |
public | function | Gets the messenger. | 29 |
MessengerTrait:: |
public | function | Sets the messenger. | |
PluginBase:: |
protected | property | Configuration information passed into the plugin. | 1 |
PluginBase:: |
public | property | Plugins's definition | |
PluginBase:: |
public | property | The display object this plugin is for. | |
PluginBase:: |
public | property | Options for this plugin will be held here. | |
PluginBase:: |
protected | property | The plugin implementation definition. | 1 |
PluginBase:: |
protected | property | The plugin_id. | |
PluginBase:: |
protected | property | Stores the render API renderer. | 3 |
PluginBase:: |
protected | property | Denotes whether the plugin has an additional options form. | 8 |
PluginBase:: |
public | property | The top object of a view. | 1 |
PluginBase:: |
constant | A string which is used to separate base plugin IDs from the derivative ID. | ||
PluginBase:: |
public | function |
Clears a plugin. Overrides ViewsPluginInterface:: |
2 |
PluginBase:: |
protected | function | Do the work to filter out stored options depending on the defined options. | |
PluginBase:: |
public | function |
Filter out stored options depending on the defined options. Overrides ViewsPluginInterface:: |
|
PluginBase:: |
public | function |
Returns an array of available token replacements. Overrides ViewsPluginInterface:: |
|
PluginBase:: |
public | function |
Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the definition of the plugin implementation. Overrides PluginInspectionInterface:: |
3 |
PluginBase:: |
public | function |
Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface:: |
|
PluginBase:: |
public | function |
Returns the plugin provider. Overrides ViewsPluginInterface:: |
|
PluginBase:: |
protected | function | Returns the render API renderer. | 1 |
PluginBase:: |
public | function |
Adds elements for available core tokens to a form. Overrides ViewsPluginInterface:: |
|
PluginBase:: |
public | function |
Returns a string with any core tokens replaced. Overrides ViewsPluginInterface:: |
|
PluginBase:: |
constant | Include entity row languages when listing languages. | ||
PluginBase:: |
constant | Include negotiated languages when listing languages. | ||
PluginBase:: |
public | function | Determines if the plugin is configurable. | |
PluginBase:: |
protected | function | Makes an array of languages, optionally including special languages. | |
PluginBase:: |
public | function |
Return the human readable name of the display. Overrides ViewsPluginInterface:: |
|
PluginBase:: |
public static | function |
Moves form elements into fieldsets for presentation purposes. Overrides ViewsPluginInterface:: |
|
PluginBase:: |
public static | function |
Flattens the structure of form elements. Overrides ViewsPluginInterface:: |
|
PluginBase:: |
public static | function | Returns substitutions for Views queries for languages. | |
PluginBase:: |
protected | function | Fills up the options of the plugin with defaults. | |
PluginBase:: |
public | function |
Provide a full list of possible theme templates used by this style. Overrides ViewsPluginInterface:: |
1 |
PluginBase:: |
public static | function |
Lists the trusted callbacks provided by the implementing class. Overrides TrustedCallbackInterface:: |
6 |
PluginBase:: |
public | function |
Unpack options over our existing defaults, drilling down into arrays
so that defaults don't get totally blown away. Overrides ViewsPluginInterface:: |
|
PluginBase:: |
public | function |
Returns the usesOptions property. Overrides ViewsPluginInterface:: |
8 |
PluginBase:: |
public | function |
Validate that the plugin is correct and can be saved. Overrides ViewsPluginInterface:: |
6 |
PluginBase:: |
protected | function | Replaces Views' tokens in a given string. The resulting string will be sanitized with Xss::filterAdmin. | 1 |
PluginBase:: |
constant | Query string to indicate the site default language. | ||
QueryPluginBase:: |
protected | property | Stores the limit of items that should be requested in the query. | |
QueryPluginBase:: |
public | property | A pager plugin that should be provided by the display. | |
QueryPluginBase:: |
public | function | Add a signature to the query, if such a thing is feasible. | 1 |
QueryPluginBase:: |
public | function |
Calculates dependencies for the configured plugin. Overrides PluginBase:: |
1 |
QueryPluginBase:: |
public | function | Get aggregation info for group by queries. | 1 |
QueryPluginBase:: |
public | function |
The cache contexts associated with this object. Overrides CacheableDependencyInterface:: |
|
QueryPluginBase:: |
public | function |
The maximum age for which this object may be cached. Overrides CacheableDependencyInterface:: |
1 |
QueryPluginBase:: |
public | function |
The cache tags associated with this object. Overrides CacheableDependencyInterface:: |
1 |
QueryPluginBase:: |
public | function | Returns a Unix timestamp to database native timestamp expression. | 1 |
QueryPluginBase:: |
public | function | Creates cross-database date formatting. | 1 |
QueryPluginBase:: |
public | function | Returns an array of all tables from the query that map to an entity type. | |
QueryPluginBase:: |
public | function | Returns the limit of the query. | |
QueryPluginBase:: |
public | function | Get the timezone offset in seconds. | |
QueryPluginBase:: |
public | function | Loads all entities contained in the passed-in $results. . If the entity belongs to the base table, then it gets stored in $result->_entity. Otherwise, it gets stored in $result->_relationship_entities[$relationship_id]; | 1 |
QueryPluginBase:: |
public | function | Applies a timezone offset to the given field. | 2 |
QueryPluginBase:: |
public | function | Control how all WHERE and HAVING groups are put together. | |
QueryPluginBase:: |
public | function | Set a LIMIT on the query, specifying a maximum number of results. | |
QueryPluginBase:: |
public | function | Set an OFFSET on the query, specifying a number of results to skip | |
QueryPluginBase:: |
public | function | Set the database to the current user timezone. | 1 |
QueryPluginBase:: |
public | function | Create a new grouping for the WHERE or HAVING clause. | |
QueryPluginBase:: |
public | function |
Handle any special handling on the validate form. Overrides PluginBase:: |
1 |
QueryPluginBase:: |
public | function |
Returns the summary of the settings in the display. Overrides PluginBase:: |
|
QueryPluginBase:: |
public | function |
Validate the options form. Overrides PluginBase:: |
|
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. | |
TrustedCallbackInterface:: |
constant | Untrusted callbacks throw exceptions. | ||
TrustedCallbackInterface:: |
constant | Untrusted callbacks trigger silenced E_USER_DEPRECATION errors. | ||
TrustedCallbackInterface:: |
constant | Untrusted callbacks trigger E_USER_WARNING errors. |