sendgrid_integration_reports.module in SendGrid Integration 7
Same filename and directory in other branches
sendgrid_integration_reports.module Sendrid Reporst Module
File
modules/sendgrid_integration_reports/sendgrid_integration_reports.moduleView source
<?php
/**
* @file sendgrid_integration_reports.module
* Sendrid Reporst Module
*/
/**
* Implements hook_menu().
*/
function sendgrid_integration_reports_menu() {
$items = [];
$items['admin/config/services/sendgrid/reports'] = [
'title' => 'Administer Sendgrid Integration Reports',
'page callback' => 'drupal_get_form',
'page arguments' => [
'sendgrid_integration_reports_settings_form',
],
'access callback' => 'sendgrid_integration_reports_gatekeeper',
'type' => MENU_LOCAL_TASK,
];
$items['admin/reports/sendgrid'] = [
'title' => 'Sendgrid Reports Dashboard',
'page callback' => 'sendgrid_integration_reports_global',
'page arguments' => [],
'access arguments' => [
'access site reports',
],
'file' => 'sendgrid_integration_reports.pages.inc',
];
return $items;
}
/**
* Implements hook_permission().
*/
function sendgrid_integration_reports_permission() {
return [
'administer sendgrid integration reports' => [
'title' => t('Administer Sendgrid Reports'),
'description' => t('Perform adminstration functions on the Sendgrid Reports module.'),
],
];
}
/**
* Access callback for module.
* @return BOOL
*/
function sendgrid_integration_reports_gatekeeper() {
if (user_access('administer sendgrid integration reports') || user_access('administer modules')) {
return TRUE;
}
return FALSE;
}
/**
* Form builder.
*/
function sendgrid_integration_reports_settings_form($form, &$form_state) {
$form['message'] = [
'#markup' => t('Data and responses from Sendgrid are cached for performance reasons. If you make changes to these settings, you must !cache in order to load new charts.', [
'!cache' => l(t('clear your cache'), 'admin/config/development/performance'),
]),
];
$form['sendgrid_integration_reports_start_date'] = [
'#type' => 'textfield',
'#title' => t('Global Stats Start Date'),
'#default_value' => variable_get('sendgrid_integration_reports_start_date', date('Y-m-d', strtotime('today - 30 days'))),
'#required' => FALSE,
'#description' => t('Start date in the format of YYYY-mm-dd. Defaults to 30 days back.'),
];
$form['sendgrid_integration_reports_end_date'] = [
'#type' => 'textfield',
'#title' => t('Global Stats End Date'),
'#default_value' => variable_get('sendgrid_integration_reports_end_date', date('Y-m-d')),
'#required' => FALSE,
'#description' => t('End date in the format of YYYY-mm-dd. Defaults to today.'),
];
$form['sendgrid_integration_reports_aggregated_by'] = [
'#type' => 'select',
'#title' => t('Global Stats Agreggation'),
'#default_value' => variable_get('sendgrid_integration_reports_aggregated_by', 0),
'#required' => FALSE,
'#description' => t('Aggregation of data. Defaults to day.'),
'#options' => [
0 => 'day',
1 => 'week',
3 => 'month',
],
];
return system_settings_form($form);
}
/**
* Implements hook_validate().
* Validates the system settings form for module.
*
* @param $form
* @param $form_state
*
* @return BOOL
*/
function sendgrid_integration_reports_settings_form_validate($form, &$form_state) {
$sdate = $form_state['values']['sendgrid_integration_reports_start_date'];
$edate = $form_state['values']['sendgrid_integration_reports_end_date'];
// If both are empty then we are using defaults.
if (empty($edate) && empty($sdate)) {
variable_del('sendgrid_integration_reports_start_date');
variable_del('sendgrid_integration_reports_end_date');
drupal_set_message(t('Using default settings for dates.'), 'status', TRUE);
drupal_set_message(t('!cache for changes to take affect.', [
'!cache' => l(t('Clear your cache'), 'admin/config/development/performance'),
]), 'notice', TRUE);
return TRUE;
}
if (empty($sdate)) {
variable_del('sendgrid_integration_reports_start_date');
drupal_set_message(t('Using default settings for start date. 30 Days back.'), 'status', TRUE);
}
if (empty($edate)) {
variable_del('sendgrid_integration_reports_end_date');
drupal_set_message(t('Using default settings for end date. Today.'), 'status', TRUE);
}
$date_regex = '/^(19|20)\\d\\d[\\-\\/.](0[1-9]|1[012])[\\-\\/.](0[1-9]|[12][0-9]|3[01])$/';
if (!empty($sdate) && !preg_match($date_regex, $sdate)) {
form_set_error('sendgrid_integration_reports_start_date', t('This is not a valid start date. Date must be in the format YYYY-mm-dd.'));
return FALSE;
}
if (!empty($edate) && !preg_match($date_regex, $edate)) {
form_set_error('sendgrid_integration_reports_end_date', t('This is not a valid start date. Date must be in the format YYYY-mm-dd.'));
return FALSE;
}
drupal_set_message(t('!cache for changes to take affect.', [
'!cache' => l(t('Clear your cache'), 'admin/config/development/performance'),
]), 'notice', TRUE);
}
/**
* Implements hook_flush_caches().
*/
function sendgrid_integration_reports_flush_caches() {
return [
'cache_sendgrid_integration_reports',
];
}
/**
* Function to retrieve stats by categories.
*
* @return array
*/
function sendgrid_integration_reports_get_stats_categories($categories, $start_date = NULL, $end_date = NULL, $refresh = FALSE) {
$cache_id = 'sendgrid_reports_categories';
// Sanitize the categories array and generate the cache ID.
if ($categories && is_array($categories)) {
$categories = array_values($categories);
$cache_id .= '_' . implode('_', $categories);
}
else {
$categories = NULL;
}
return sendgrid_integration_reports_get_stats($cache_id, $categories, $start_date, $end_date, $refresh);
}
/**
* Function to retrieve global stats.
*
* @return array
*/
function sendgrid_integration_reports_get_stats_global() {
return sendgrid_integration_reports_get_stats('sendgrid_reports_global');
}
/**
* Function to retrieve stats and store them in cache.
*
* return array
*/
/**
* Check for an api key
*/
function sendgrid_integration_reports_api_key($key) {
if (!$key) {
// If not set in function call, load key from variables and throw errors if not there.
$key = variable_get('sendgrid_integration_apikey', '');
if (!$key) {
watchdog('sendgrid_integration_reports', t('Sendgrid Module is not setup with API key.'), array(), 'WATCHDOG_NOTICE', NULL);
drupal_set_message(t('Sendgrid Module is not setup with an API key.'), 'warning', TRUE);
}
}
return $key;
}
function sendgrid_integration_reports_get_stats($cache_id, $categories = [], $start_date = NULL, $end_date = NULL, $refresh = FALSE, $key_secret = NULL) {
if (!($key = sendgrid_integration_reports_api_key($key_secret))) {
return FALSE;
}
if (!$refresh && ($cache = cache_get($cache_id, 'cache_sendgrid_integration_reports'))) {
return $cache->data;
}
// Set headers and create a Guzzle client to communicate with Sendgrid.
$headers['Authorization'] = 'Bearer' . ' ' . $key;
$clienttest = new GuzzleHttp\Client([
'base_uri' => 'https://api.sendgrid.com/v3/',
'headers' => $headers,
]);
if ($start_date) {
$start_date = date('Y-m-d', strtotime($start_date));
}
else {
// Set start date and end date for global stats - default 30 days back.
$start_date = empty(variable_get('sendgrid_integration_reports_start_date')) ? date('Y-m-d', strtotime('today - 30 days')) : variable_get('sendgrid_integration_reports_start_date');
}
if ($end_date) {
$end_date = date('Y-m-d', strtotime($end_date));
}
else {
// Set the end date which defaults to today
$end_date = empty(variable_get('sendgrid_integration_reports_end_date')) ? date('Y-m-d', strtotime('today')) : variable_get('sendgrid_integration_reports_end_date');
}
// Set aggregation of stats - default day.
$aggregate = variable_get('sendgrid_integration_reports_aggregated_by', 0);
switch ($aggregate) {
case 0:
$aggregated_by = 'day';
break;
case 1:
$aggregated_by = 'week';
break;
case 2:
$aggregated_by = 'month';
break;
}
$path = 'stats';
$query = [
'start_date' => $start_date,
'end_date' => $end_date,
'aggregated_by' => $aggregated_by,
];
if ($categories) {
$path = 'categories/stats';
$query['categories'] = $categories;
$query_str = http_build_query($query, NULL, '&', PHP_QUERY_RFC3986);
$query = preg_replace('/%5B(?:[0-9]|[1-9][0-9]+)%5D=/', '=', $query_str);
}
// Lets attempt the request and catch an error if it fails.
try {
$response = $clienttest
->get($path, [
'query' => $query,
]);
} catch (GuzzleHttp\Exception\ClientException $e) {
$code = filter_xss($e
->getCode());
watchdog('sendgrid_integration_reports', t('Sendgrid Reports module faield to recieve data. HTTP Error Code @errno'), [
'@errno' => $e,
], 'WATCHDOG_ERROR', NULL);
drupal_set_message(t('Sendgrid Reports module faield to recieve data. See logs.'), 'error', TRUE);
return FALSE;
}
// Sanitize return before using in Drupal.
$body = filter_xss($response
->getBody());
$statsdata = json_decode($body);
$data = [];
foreach ($statsdata as $item) {
$data['global'][] = [
'date' => $item->date,
'opens' => $item->stats[0]->metrics->opens,
'processed' => $item->stats[0]->metrics->processed,
'requests' => $item->stats[0]->metrics->requests,
'clicks' => $item->stats[0]->metrics->clicks,
'delivered' => $item->stats[0]->metrics->delivered,
'deferred' => $item->stats[0]->metrics->deferred,
'unsubscribes' => $item->stats[0]->metrics->unsubscribes,
'unsubscribe_drops' => $item->stats[0]->metrics->unsubscribe_drops,
'invalid_emails' => $item->stats[0]->metrics->invalid_emails,
'bounces' => $item->stats[0]->metrics->bounces,
'bounce_drops' => $item->stats[0]->metrics->bounce_drops,
'unique_clicks' => $item->stats[0]->metrics->unique_clicks,
'blocks' => $item->stats[0]->metrics->blocks,
'spam_report_drops' => $item->stats[0]->metrics->spam_report_drops,
'spam_reports' => $item->stats[0]->metrics->spam_reports,
'unique_opens' => $item->stats[0]->metrics->unique_opens,
];
}
cache_set($cache_id, $data, 'cache_sendgrid_integration_reports', CACHE_TEMPORARY);
return $data;
}
/**
* Function to retrieve browser stats.
* @return array
*/
function sendgrid_integration_reports_get_stats_browser($key_secret = NULL) {
if (!($key = sendgrid_integration_reports_api_key($key_secret))) {
return FALSE;
}
$cache_key = hash('sha256', 'sr_browser:' . $key);
if ($cache = cache_get($cache_key, 'cache_sendgrid_integration_reports')) {
return $cache->data;
}
// Set headers and create a Guzzle client to communicate with Sendgrid.
$headers['Authorization'] = 'Bearer' . ' ' . $key;
$clienttest = new GuzzleHttp\Client([
'base_uri' => 'https://api.sendgrid.com/v3/',
'headers' => $headers,
]);
// Set start date and end date for global stats - default 30 days back.
$start_date = empty(variable_get('sendgrid_integration_reports_start_date')) ? date('Y-m-d', strtotime('today - 30 days')) : variable_get('sendgrid_integration_reports_start_date');
// Set the end date which defaults to today
$end_date = empty(variable_get('sendgrid_integration_reports_end_date')) ? date('Y-m-d', strtotime('today')) : variable_get('sendgrid_integration_reports_end_date');
// Set aggregation of stats - default day.
$aggregate = variable_get('sendgrid_integration_reports_aggregated_by', 0);
switch ($aggregate) {
case 0:
$aggregated_by = 'day';
break;
case 1:
$aggregated_by = 'week';
break;
case 2:
$aggregated_by = 'month';
break;
}
$query = [
'start_date' => $start_date,
'end_date' => $end_date,
'aggregated_by' => $aggregated_by,
];
// Lets try and retrieve the browser statistics.
try {
$response = $clienttest
->get('browsers/stats', [
'query' => $query,
]);
} catch (GuzzleHttp\Exception\ClientException $e) {
$code = filter_xss($e
->getCode());
watchdog('sendgrid_integration_reports', t('Sendgrid Reports module faield to recieve data. HTTP Error Code @errno'), [
'@errno' => $code,
], 'WATCHDOG_ERROR');
drupal_set_message(t('Sendgrid Reports module faield to recieve data. See logs.'), 'error', TRUE);
return FALSE;
}
// Sanitize return before using in Drupal.
$body = $response
->getBody();
$statsdata = json_decode($body);
$data = [];
// Determine all browsers. Nested foreach to iterate over all data returned per aggregation.
foreach ($statsdata as $item) {
foreach ($item->stats as $inneritem) {
if (array_key_exists($inneritem->name, $data)) {
$data[$inneritem->name] += $inneritem->metrics->clicks;
}
else {
$data[$inneritem->name] = $inneritem->metrics->clicks;
}
}
}
cache_set($cache_key, $data, 'cache_sendgrid_integration_reports', CACHE_TEMPORARY);
return $data;
}
/**
* Function to retrieve device stats.
* @return array
*/
function sendgrid_integration_reports_get_stats_devices($key_secret = NULL) {
if (!($key = sendgrid_integration_reports_api_key($key_secret))) {
return FALSE;
}
// Hash in the api key for unique cache per key
$cache_key = hash('sha256', 'sr_devices:' . $key);
if ($cache = cache_get($cache_key, 'cache_sendgrid_integration_reports')) {
return $cache->data;
}
// Set headers and create a Guzzle client to communicate with Sendgrid.
$headers['Authorization'] = 'Bearer' . ' ' . $key;
$clienttest = new GuzzleHttp\Client([
'base_uri' => 'https://api.sendgrid.com/v3/',
'headers' => $headers,
]);
// Set start date and end date for global stats - default 30 days back.
$start_date = empty(variable_get('sendgrid_integration_reports_start_date')) ? date('Y-m-d', strtotime('today - 30 days')) : variable_get('sendgrid_integration_reports_start_date');
// Set the end date which defaults to today
$end_date = empty(variable_get('sendgrid_integration_reports_end_date')) ? date('Y-m-d', strtotime('today')) : variable_get('sendgrid_integration_reports_end_date');
// Set aggregation of stats - default day.
$aggregate = variable_get('sendgrid_integration_reports_aggregated_by', 0);
switch ($aggregate) {
case 0:
$aggregated_by = 'day';
break;
case 1:
$aggregated_by = 'week';
break;
case 2:
$aggregated_by = 'month';
break;
}
$query = [
'start_date' => $start_date,
'end_date' => $end_date,
'aggregated_by' => $aggregated_by,
];
// Lets try and retrieve the browser statistics.
try {
$response = $clienttest
->get('devices/stats', [
'query' => $query,
]);
} catch (GuzzleHttp\Exception\ClientException $e) {
$code = filter_xss($e
->getCode());
watchdog('sendgrid_integration_reports', t('Sendgrid Reports module faield to recieve data. HTTP Error Code @errno'), [
'@errno' => $code,
], 'WATCHDOG_ERROR');
drupal_set_message(t('Sendgrid Reports module faield to recieve data. See logs.'), 'error', TRUE);
return FALSE;
}
// Sanitize return before using in Drupal.
$body = $response
->getBody();
$statsdata = json_decode($body);
$data = [];
// Determine all browsers. Nested foreach to iterate over all data returned per aggregation.
foreach ($statsdata as $item) {
foreach ($item->stats as $inneritem) {
if (array_key_exists($inneritem->name, $data)) {
$data[$inneritem->name] += $inneritem->metrics->opens;
}
else {
$data[$inneritem->name] = $inneritem->metrics->opens;
}
}
}
cache_set($cache_key, $data, 'cache_sendgrid_integration_reports', CACHE_TEMPORARY);
return $data;
}
Functions
Name | Description |
---|---|
sendgrid_integration_reports_api_key | Check for an api key |
sendgrid_integration_reports_flush_caches | Implements hook_flush_caches(). |
sendgrid_integration_reports_gatekeeper | Access callback for module. |
sendgrid_integration_reports_get_stats | |
sendgrid_integration_reports_get_stats_browser | Function to retrieve browser stats. |
sendgrid_integration_reports_get_stats_categories | Function to retrieve stats by categories. |
sendgrid_integration_reports_get_stats_devices | Function to retrieve device stats. |
sendgrid_integration_reports_get_stats_global | Function to retrieve global stats. |
sendgrid_integration_reports_menu | Implements hook_menu(). |
sendgrid_integration_reports_permission | Implements hook_permission(). |
sendgrid_integration_reports_settings_form | Form builder. |
sendgrid_integration_reports_settings_form_validate | Implements hook_validate(). Validates the system settings form for module. |