You are here

function simplenews_statistics_click_page in Simplenews Statistics 7

Same name and namespace in other branches
  1. 7.2 includes/simplenews_statistics.pages.inc \simplenews_statistics_click_page()

Check and log newsletter URL clicks.

1 string reference to 'simplenews_statistics_click_page'
simplenews_statistics_menu in ./simplenews_statistics.module
Implements hook_menu().

File

includes/simplenews_statistics.pages.inc, line 58
Contains page function for simplenews statistics.

Code

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();
}