simplenews_statistics.pages.inc in Simplenews Statistics 7
Same filename and directory in other branches
Contains page function for simplenews statistics.
File
includes/simplenews_statistics.pages.incView source
<?php
/**
* @file
* Contains page function for simplenews statistics.
*/
/**
* Check and log newsletter opens.
*/
function simplenews_statistics_open_page($nid, $snid, $terminate = TRUE) {
// Call possible decoders for nid & snid in modules implementing the hook.
// Modules implementing this hook should validate this input themself because
// we can not know what kind of string they will generate.
$hook = 'simplenews_statistics_decode';
foreach (module_implements($hook) as $module) {
$function = $module . '_' . $hook;
if (function_exists($function)) {
$nid = $function($nid, 'nid');
$snid = $function($snid, 'snid');
}
}
// Once decoded properly we can know for sure that nid & snid are numeric.
if (!is_numeric($nid) || !is_numeric($snid)) {
watchdog('simplenews_statistics', 'Simplenews statistics open called with illegal parameter(s). Node ID: @nid. Subscriber ID: @snid', array(
'@nid' => $nid,
'@snid' => $snid,
));
}
else {
$subscriber = simplenews_subscriber_load($snid);
if (!empty($subscriber) && $subscriber->snid == $snid) {
$record = new stdClass();
$record->snid = $subscriber->snid;
$record->nid = $nid;
$record->timestamp = time();
drupal_write_record('simplenews_statistics_open', $record);
}
}
if ($terminate == FALSE) {
return;
// Allow PHP execution to continue.
}
// Render a transparent image and stop PHP execution.
$type = 'image/png; utf-8';
$file = drupal_get_path('module', 'simplenews_statistics') . '/images/count.png';
// Default headers are set by drupal_page_header(), just set content type.
drupal_add_http_header('Content-Type', $type);
drupal_add_http_header('Content-Length', filesize($file));
readfile($file);
drupal_exit();
}
/**
* Check and log newsletter URL clicks.
*/
function simplenews_statistics_click_page($urlid, $snid) {
// Call possible decoders for urlid & snid in modules implementing the hook.
$hook = 'simplenews_statistics_decode';
foreach (module_implements($hook) as $module) {
$function = $module . '_' . $hook;
if (function_exists($function)) {
$urlid = $function($urlid, 'urlid');
$snid = $function($snid, 'snid');
}
}
// Once decoded properly we can know for sure that the $urlid and $snid are
// numeric. Fallback on any error is to go to the homepage.
if (!is_numeric($urlid) || !is_numeric($snid)) {
watchdog('simplenews_statistics', 'Simplenews statistics click called with illegal parameter(s). URL ID: @urlid. Subscriber ID: @snid', array(
'@urlid' => $urlid,
'@snid' => $snid,
));
drupal_set_message(t('Could not resolve destination URL.'), 'error');
drupal_goto();
}
// Track click if there is an url and a valid subscriber. For test mails the
// snid can be 0, so no valid subscriber will be loaded and the click won't
// be counted. But the clicked link will still redirect properly.
$query = db_select('simplenews_statistics_url', 'ssu')
->fields('ssu')
->condition('urlid', $urlid);
$url_record = $query
->execute()
->fetchObject();
$subscriber = simplenews_subscriber_load($snid);
if (!empty($subscriber) && $subscriber->snid == $snid && isset($url_record)) {
$click_record = new stdClass();
$click_record->urlid = $urlid;
$click_record->snid = $snid;
$click_record->timestamp = time();
drupal_write_record('simplenews_statistics_click', $click_record);
// Check if the open action was registered for this subscriber. If not we
// can track the open here to improve statistics accuracy.
$query = db_select('simplenews_statistics_open', 'sso');
$query
->condition('snid', $snid);
$num_rows = $query
->countQuery()
->execute()
->fetchField();
if ($num_rows == 0) {
simplenews_statistics_open_page($url_record->nid, $snid, FALSE);
}
}
// Redirect to the right URL.
if (!empty($url_record) && !empty($url_record->url)) {
// Split the URL into it's parts for easier handling.
$path = $url_record->url;
$options = array(
'fragment' => '',
'query' => array(),
);
// The fragment should always be after the query, so we get that first.
// We format it for the options array for drupal_goto().
$fragment_position = strpos($path, '#');
if (FALSE !== $fragment_position) {
$fragment = substr($path, $fragment_position + 1);
$path = str_replace('#' . $fragment, '', $path);
$options['fragment'] = $fragment;
}
// Determine the position of the query string, get it, delete it from the
// original path and then we explode the parts and the key-value pairs to
// get a clean output that we can use in drupal_goto().
$query_position = strpos($path, '?');
if (FALSE !== $query_position) {
$query = substr($path, $query_position + 1);
$path = str_replace('?' . $query, '', $path);
$element = explode('&', $query);
foreach ($element as $pair) {
$pair = explode('=', $pair);
if (!isset($pair[1])) {
$pair[1] = '';
}
$options['query'][$pair[0]] = $pair[1];
}
}
// Call possible rewriters for the url.
$hook = 'simplenews_statistics_rewrite_goto_url';
foreach (module_implements($hook) as $module) {
$function = $module . '_' . $hook;
if (function_exists($function)) {
$function($path, $options, $snid, $url_record->nid);
}
}
// Fragment behaviour can get out of spec here.
drupal_goto($path, $options);
}
// Fallback on any error is to go to the homepage.
watchdog('simplenews_statistics', 'URL could not be resolved. URL ID: @urlid. Subscriber ID: @snid', array(
'@urlid' => $urlid,
'@snid' => $snid,
));
drupal_set_message(t('Could not resolve destination URL.'), 'error');
drupal_goto();
}
/**
* Page callback to render a view with contextual links.
*/
function simplenews_statistics_embed_view($view_name, $display_id) {
$view = views_embed_view($view_name);
return render($view);
}
Functions
Name | Description |
---|---|
simplenews_statistics_click_page | Check and log newsletter URL clicks. |
simplenews_statistics_embed_view | Page callback to render a view with contextual links. |
simplenews_statistics_open_page | Check and log newsletter opens. |