View source
<?php
module_load_include('inc', 'yandex_metrics_reports', 'yandex_metrics_reports.reports');
define('YANDEX_METRICS_REPORTS_SEARCH_PHRASES_QUANTITY', 12);
define('YANDEX_METRICS_REPORTS_POPULAR_CONTENT_COUNT', 30);
define('YANDEX_METRICS_REPORTS_POPULAR_CONTENT_BLOCK_LIMIT', 50);
function yandex_metrics_reports_permission() {
return array(
'access Yandex.Metrics report' => array(
'title' => t('Access Yandex.Metrics report'),
),
);
}
function yandex_metrics_reports_views_api() {
return array(
'api' => 3,
'path' => drupal_get_path('module', 'yandex_metrics_reports') . '/views',
);
}
function _yandex_metrics_reports_filter_to_date_range($filter) {
switch ($filter) {
case 'day':
return array(
'start_date' => date('Ymd'),
'end_date' => date('Ymd'),
);
case 'yesterday':
return array(
'start_date' => date('Ymd', time() - 60 * 60 * 24),
'end_date' => date('Ymd', time() - 60 * 60 * 24),
);
case 'week':
default:
return array(
'start_date' => date('Ymd', time() - 60 * 60 * 24 * 6),
'end_date' => date('Ymd'),
);
case 'month':
return array(
'start_date' => date('Ymd', time() - 60 * 60 * 24 * 31),
'end_date' => date('Ymd'),
'group' => 'week',
);
}
}
function yandex_metrics_reports_retreive_data($service_uri, $parameters = array(), $result_type = 'json') {
$parameters['oauth_token'] = yandex_services_auth_info('token');
$query_parts = array();
foreach ($parameters as $key => $value) {
$query_parts[] = $key . '=' . $value;
}
$parameter_string = implode('&', $query_parts);
$full_service_url = "http://api-metrika.yandex.ru" . $service_uri . "." . $result_type . "?" . $parameter_string;
$request = Drupal::httpClient()
->get($full_service_url);
try {
$response = $request
->send();
return $response;
} catch (RequestException $e) {
watchdog_exception('yandex_metrics_reports', $e);
return FALSE;
} catch (ClientErrorResponseException $e) {
watchdog_exception('yandex_metrics_reports', $e);
return FALSE;
} catch (\Exception $e) {
watchdog_exception('yandex_metrics_reports', $e);
return FALSE;
}
}
function yandex_metrics_reports_get_counter_for_current_site() {
$counter_id = \Drupal::state()
->get('yandex_metrics_reports_counter_id');
if (!empty($counter_id)) {
return $counter_id;
}
$result = yandex_metrics_reports_retreive_data('/counters', array(
'field' => 'mirrors',
));
if (!$result) {
watchdog('yandex_metrics_reports', 'Counters request seems to be fail.', WATCHDOG_WARNING);
return;
}
$counters = json_decode($result
->getBody(TRUE));
$current_host = $_SERVER['HTTP_HOST'];
$decoded_domain = _yandex_metrics_reports_idna_decode($current_host);
if ($decoded_domain != FALSE && $decoded_domain != $current_host) {
$current_host = $decoded_domain;
}
foreach ($counters->counters as $key => $counter) {
if ($counter->site == $current_host) {
\Drupal::state()
->set('yandex_metrics_reports_counter_id', $counter->id);
return $counter->id;
}
if (isset($counter->mirrors) && in_array($current_host, $counter->mirrors)) {
\Drupal::state()
->set('yandex_metrics_reports_counter_id', $counter->id);
return $counter->id;
}
}
return FALSE;
}
function yandex_metrics_reports_save_popular_content($cron = FALSE) {
$counter_code = \Drupal::config('yandex_metrics.settings')
->get('counter_code');
if (empty($counter_code) && !$cron) {
drupal_set_message(t('Perhaps you have not yet placed Yandex.Metrics counter code on the site. You can do this !link.', array(
'!link' => l(t('here'), 'admin/settings/yandex_metrics'),
)), 'notice');
return;
}
$counter_id = yandex_metrics_reports_get_counter_for_current_site();
if (empty($counter_id)) {
if ($cron) {
watchdog('yandex_metrics_reports', 'Cron: counter ID is not set.', array(), WATCHDOG_WARNING);
}
else {
drupal_set_message(t('Please create Yandex.Metrics counter for the site first. See more details !link.', array(
'!link' => l(t('here'), 'admin/config/system/yandex_metrics'),
)), 'error');
}
return;
}
$authorisation_token = yandex_services_auth_info('token');
if (empty($authorisation_token)) {
if ($cron) {
watchdog('yandex_metrics_reports', 'Cron: application is not authorised.', array(), WATCHDOG_WARNING);
}
else {
drupal_set_message(t('Please make sure that your application is authorized !link.', array(
'!link' => l(t('here'), 'admin/settings/yandex_metrics/authorization'),
)), 'error');
}
return;
}
$filter = \Drupal::config('yandex_metrics_reports.settings')
->get('popular_content_date_period');
$date_range = _yandex_metrics_reports_filter_to_date_range($filter);
$parameters = array(
'id' => $counter_id,
'date1' => $date_range['start_date'],
'date2' => $date_range['end_date'],
);
$report_content = yandex_metrics_reports_retreive_data('/stat/content/popular', $parameters);
$content = json_decode($report_content->data);
if (isset($content->errors) && count($content->errors) > 0 && $content->errors[0]->code != 'ERR_NO_DATA') {
watchdog('yandex_metrics_reports', 'Fetching of popular content failed due to error %error.', array(
'%error' => $content->errors[0]->text,
), WATCHDOG_ERROR);
return;
}
db_truncate('yandex_metrics_reports_popular_content')
->execute();
if (empty($content->data)) {
watchdog('yandex_metrics_reports', 'There is no popular content for the selected date period %filter.', array(
'%filter' => $filter,
), WATCHDOG_NOTICE);
return;
}
$counter = 1;
foreach ($content->data as $value) {
$parsed_url = parse_url($value->url);
global $base_root;
$base_root_parts = parse_url($base_root);
$pattern = "/(\\.|^)" . preg_quote($base_root_parts['host'], "/") . "\$/i";
if (!preg_match($pattern, $parsed_url['host'], $matches)) {
continue;
}
$page_language = yandex_metrics_reports_language_from_url($value->url);
$page_title = yandex_metrics_reports_obtain_page_title($parsed_url['path'], $page_language);
db_insert('yandex_metrics_reports_popular_content')
->fields(array(
'url' => $value->url,
'language' => $page_language,
'page_title' => $page_title,
'page_views' => $value->page_views,
))
->execute();
if ($counter++ >= YANDEX_METRICS_REPORTS_POPULAR_CONTENT_BLOCK_LIMIT) {
break;
}
}
watchdog('yandex_metrics_reports', 'Popular content for %filter has been fetched.', array(
'%filter' => $filter,
), WATCHDOG_NOTICE);
}
function yandex_metrics_reports_obtain_page_title($path, $language = 'en') {
$path = ltrim($path, '/');
$site_frontpage = \Drupal::config('system.site')
->get('page.front');
if (empty($path) || $path == $site_frontpage || $path == $language . '/' . $site_frontpage) {
return \Drupal::config('system.site')
->get('name');
}
$normal_path = \Drupal::service('path.alias_manager.cached')
->getSystemPath($path);
$item = menu_get_item($normal_path);
if (empty($item) || empty($item['title'])) {
return $path;
}
return $item['title'];
}
function yandex_metrics_reports_cron() {
if (!_yandex_metrics_reports_is_popular_content_enabled()) {
return;
}
yandex_metrics_reports_save_popular_content(TRUE);
}
function yandex_metrics_reports_ajax($counter_id, $filter, $type) {
$output = '';
$reports = yandex_metrics_reports_get_list();
if (isset($reports[$type]) && isset($reports[$type]['callback']) && function_exists($reports[$type]['callback'])) {
$output = call_user_func($reports[$type]['callback'], $counter_id, $filter);
}
print $output;
die;
}
function yandex_metrics_reports_chart_color_schemes() {
return array(
'yandex_metrics_reports' => array(
'ff3030',
'ff8800',
'00b6f7',
'95d900',
'ffea00',
'bb7bf1',
'0080ff',
'ff8888',
'87888e',
'457f51',
'b5b6be',
),
);
}
function _yandex_metrics_reports_idna_decode($domain) {
return idn_to_utf8($domain);
}
function yandex_metrics_reports_help($path, $arg) {
switch ($path) {
case 'admin/help#yandex_metrics_reports':
$output = '';
$output .= '<h3>' . t('About the module') . '</h3>';
$output .= '<p>' . t('The <a href="@yandex_metrika" target="_blank">Yandex.Metrics</a> service is European alternative of Google Analytics. This is a free tool that helps you to increase the conversion rate of your site.', array(
'@yandex_metrika' => 'http://metrika.yandex.ru/',
)) . '</p>';
$output .= '<p>' . t('The Yandex.Metrics Reports module allows to authorize the site on Yandex and view basic reports by key effectiveness indicators.') . '</p>';
$output .= '<h3>' . t('Usage') . '</h3>';
$output .= '<dl>';
$output .= '<dt>' . t('Authorizing site') . '</dt>';
$output .= '<dd>' . t('To get access to the <a href="@reports-url">reports</a> register Yandex application at !app_register_link. Then enter your application Client ID and Client Secret in the appropriate fields on the <a href="@authorization-page">Authorization</a> page. The full list of your Yandex applications is located !app_list_link.', array(
'!app_register_link' => l('https://oauth.yandex.ru/client/new', 'https://oauth.yandex.ru/client/new', array(
'attributes' => array(
'target' => '_blank',
),
)),
'!app_list_link' => l(t('here'), 'https://oauth.yandex.ru/client/my', array(
'attributes' => array(
'target' => '_blank',
),
)),
'@reports-url' => url('admin/reports/yandex_metrics_summary'),
'@authorization-page' => url('admin/config/system/yandex_metrics/authorization'),
)) . '</dd>';
$output .= '<dt>' . t('Configuring reports') . '</dt>';
$output .= '<dd>' . t('You can choose necessary reports <a href="@report-setting-page">here</a> to display on <a href="@summary-report-page">Yandex.Metrics Summary Report</a> page. Also, we recommend you to enable AJAX for reports by checking appropriate field on the <a href="@report-setting-page">report settings page</a>.', array(
'@summary-report-page' => url('admin/reports/yandex_metrics_summary'),
'@report-setting-page' => url('admin/config/system/yandex_metrics/reports'),
)) . '</dd>';
$output .= '<dt>' . t('Configuring cron') . '</dt>';
$output .= '<dd>' . t('You can configure cron settings for the module, such as date period of data for <a href="@popular-content-view-page">Popular Content view</a>. To do it go to <a href="@cron-setting-page">Cron settings page</a>.', array(
'@cron-setting-page' => url('admin/config/system/yandex_metrics/cron'),
'@popular-content-view-page' => url('admin/structure/views/view/popular_content'),
)) . '</dd>';
$output .= '<dt>' . t('Reports API') . '</dt>';
$output .= '<dd>' . t('The module has API for developers which allows you to implement new reports in own modules. Please read module README.txt file for more information.') . '</dd>';
$output .= '</dl>';
return $output;
case 'admin/config/system/yandex_metrics/authorization':
$output = '<p>' . t('To get access to the <a href="@reports-url">reports</a> register Yandex application at !app_register_link. Then enter your application Client ID and Client Secret in the appropriate fields on this page. The full list of your Yandex applications is located !app_list_link.', array(
'!app_register_link' => l('https://oauth.yandex.ru/client/new', 'https://oauth.yandex.ru/client/new', array(
'attributes' => array(
'target' => '_blank',
),
)),
'!app_list_link' => l(t('here'), 'https://oauth.yandex.ru/client/my', array(
'attributes' => array(
'target' => '_blank',
),
)),
'@reports-url' => url('admin/reports/yandex_metrics_summary'),
)) . '</p>';
$output .= '<p>' . t('Your Yandex application Callback URI: @callback-uri', array(
'@callback-uri' => url('yandex_metrics/oauth', array(
'absolute' => TRUE,
)),
)) . '</p>';
return $output;
case 'admin/config/system/yandex_metrics/cron':
$output = '<p>' . t('Here you can specify settings which are used in cron.') . '</p>';
return $output;
case 'admin/config/system/yandex_metrics/reports':
return '<p>' . t('You can choose necessary reports to display on <a href="@summary-report-page">Yandex.Metrics Summary Report</a> page. Also, we recommend you to enable AJAX for reports by checking the appropriate field on this page.', array(
'@summary-report-page' => url('admin/reports/yandex_metrics_summary'),
)) . '</p>';
}
}
function _yandex_metrics_reports_is_popular_content_enabled() {
$result = db_select("block")
->condition("module", "yandex_metrics_reports")
->condition("delta", "popular_content")
->condition("status", 1)
->fields('block')
->execute()
->fetchField();
$views = \Drupal\views\Views::getView('popular_content');
if (!empty($views) && !$views->disabled) {
$result = 1;
}
return !empty($result);
}
function yandex_metrics_reports_yandex_metrics_reports_list() {
$reports = array();
$reports['visits_chart'] = array(
'title' => t('Page Views, Visitors, New Visitors'),
'callback' => 'yandex_metrics_reports_visits_chart',
);
$reports['sources_chart'] = array(
'title' => t('Traffic Sources'),
'callback' => 'yandex_metrics_reports_sources_chart',
);
$reports['search_phrases'] = array(
'title' => t('Popular Search Phrases'),
'callback' => 'yandex_metrics_reports_search_phrases',
);
$reports['popular_content'] = array(
'title' => t('Popular Content'),
'callback' => 'yandex_metrics_reports_popular_content',
);
$reports['geo_chart'] = array(
'title' => t('Geography of Visits'),
'callback' => 'yandex_metrics_reports_geo_chart',
);
$reports['hourly_chart'] = array(
'title' => t('Hourly Traffic'),
'callback' => 'yandex_metrics_reports_traffic_hourly_chart',
);
$reports['gender_chart'] = array(
'title' => t('Demography of Visits'),
'callback' => 'yandex_metrics_reports_gender_chart',
);
return $reports;
}
function yandex_metrics_reports_get_list($reset = FALSE) {
$reports =& drupal_static(__FUNCTION__);
if (!isset($reports) || $reset) {
$cache = \Drupal::cache()
->get('yandex_metrics_reports_list');
if ($cache === FALSE || $reset) {
$reports = array();
foreach (\Drupal::moduleHandler()
->getImplementations('yandex_metrics_reports_list') as $module) {
$module_report_list = \Drupal::moduleHandler()
->invoke($module, 'yandex_metrics_reports_list');
if (isset($module_report_list) && is_array($module_report_list)) {
$reports = array_merge($reports, $module_report_list);
}
}
\Drupal::moduleHandler()
->alter('yandex_metrics_reports_list', $reports);
\Drupal::cache()
->set('yandex_metrics_reports_list', $reports);
}
else {
$reports = $cache->data;
}
}
return $reports;
}
function yandex_metrics_reports_get_active_list() {
$reports = yandex_metrics_reports_get_list();
foreach ($reports as $report_name => $report_data) {
if (!variable_get('yandex_metrics_reports_' . $report_name . '_visible', TRUE) || !function_exists($report_data['callback'])) {
unset($reports[$report_name]);
}
}
return $reports;
}
function yandex_metrics_reports_chart_alter(&$chart) {
if (!empty($chart['#fluid_grid_adjust']['#max'])) {
_yandex_metrics_chart_adjust_resolution($chart['#data'], $chart['#fluid_grid_adjust']['#max']);
$chart['#adjust_resolution'] = FALSE;
}
}
function yandex_metrics_reports_language_from_url($url) {
require_once DRUPAL_ROOT . '/core/includes/locale.inc';
require_once DRUPAL_ROOT . '/core/includes/language.inc';
$default_language = language_default();
$url_language = $default_language->language;
if (!language_negotiation_get_any(LOCALE_LANGUAGE_NEGOTIATION_URL)) {
return $url_language;
}
$languages = language_list();
$url_parts = parse_url($url);
$host = $url_parts['host'];
$path = ltrim($url_parts['path'], '/');
switch (variable_get('locale_language_negotiation_url_part', LOCALE_LANGUAGE_NEGOTIATION_URL_PREFIX)) {
case LOCALE_LANGUAGE_NEGOTIATION_URL_PREFIX:
list($language, $path) = language_url_split_prefix($path, $languages);
if ($language !== FALSE) {
$url_language = $language->language;
}
break;
case LOCALE_LANGUAGE_NEGOTIATION_URL_DOMAIN:
foreach ($languages as $language) {
if ($language->domain) {
$language_host = 'http://' . str_replace(array(
'http://',
'https://',
), '', $language->domain);
$language_host = parse_url($language_host, PHP_URL_HOST);
if ($host == $language_host) {
$url_language = $language->language;
break;
}
}
}
break;
}
return $url_language;
}