You are here

analytic.inc in Analytics 6

Class definition for analytics.

File

includes/analytic.inc
View source
<?php

/**
 * @file
 * Class definition for analytics.
 */
class Analytic {
  public $properties;
  public $data;
  public $event_name;
  public $event_id;

  /**
   * Constructor to set event name and event ID.
   *
   * @param $event_name
   */
  public function __construct($event_name = NULL) {
    if ($event_name != NULL) {
      $this
        ->setEventName($event_name);
    }
  }

  /**
   * Primary function to record a data point.
   *
   * @param $event_name
   * @param $properties
   */
  public function track($event_name, array $data = array()) {

    // Set default properties
    $this->event_name = $event_name;

    // Peel off IP address and user_id
    $ip_address = $data['ip_address'];
    $unique_id = $data['unique_id'];
    unset($data['ip_address'], $data['unique_id']);
    if (empty($ip_address)) {
      $ip_address = $_SERVER['REMOTE_ADDR'];
    }
    foreach ($data as $key => $value) {
      if (is_numeric($key)) {
        unset($data[$key]);
      }
    }
    $this->data = $data;
    $this
      ->setEventName($event_name);
    $this
      ->writeEventRecord($ip_address, $unique_id);
  }

  /**
   * Return a keyed array of info related to properties.
   *
   * This functionr returns an array of data related to properties including the
   * property_id, property_name, and property_instance_id for the current event.
   *
   * @param $key string Which property the returned array will be keyed by.
   * @return array An array with the keys responding to the
   */
  public function getProperties($key = 'property_name') {
    if (isset($this->data)) {

      // Make a copy for properties that we don't know about yet.
      $new_properties = $this->data;
      $query = db_select('analytics_properties', 'ap')
        ->condition('property_name', array_keys($this->data), 'IN');
      $query
        ->addField('api', 'id', 'property_instance_id');
      $query
        ->addField('ap', 'id', 'property_id');
      $query
        ->addField('ap', 'property_name', 'property_name');
      $query
        ->join('analytics_property_instance', 'api', 'ap.id = api.property_id AND api.event_id = :event_id', array(
        ':event_id' => $this->event_id,
      ));
      $result = $query
        ->execute();
      foreach ($result as $item) {
        $data_properties[] = array(
          'property_id' => $item->property_id,
          'property_instance_id' => $item->property_instance_id,
          'property_name' => $item->property_name,
        );
        unset($new_properties[$item->property_name]);
      }

      // See if there are properties that aren't in the DB yet.
      if (!empty($new_properties)) {
        foreach (array_keys($new_properties) as $property_name) {
          $result = db_select('analytics_properties', 'ap')
            ->fields('ap')
            ->condition('property_name', $property_name)
            ->execute()
            ->fetch();
          $property_id = $result->id;
          if (empty($property_id)) {

            // Unknown property save first, then add instance
            $property_id = db_insert('analytics_properties')
              ->fields(array(
              'property_name' => $property_name,
            ))
              ->execute();
          }
          $property_instance_id = db_insert('analytics_property_instance')
            ->fields(array(
            'event_id' => $this->event_id,
            'property_id' => $property_id,
          ))
            ->execute();
          $data_properties[] = array(
            'property_id' => $property_id,
            'property_instance_id' => $property_instance_id,
            'property_name' => $property_name,
          );
          unset($new_properties[$property_name]);
        }
      }
    }
    else {
      if (empty($this->event_id)) {
        watchdog('analytics', 'Attempted to fetch properties without setting event_name or ID first.', array(), WATCHDOG_ERROR);
        return FALSE;
      }
      $query = db_select('analytics_properties', 'ap');
      $query
        ->join('analytics_property_instance', 'api', 'ap.id = api.property_id AND api.event_id = :event_id', array(
        ':event_id' => $this->event_id,
      ));
      $query
        ->addField('api', 'id', 'property_instance_id');
      $query
        ->addField('ap', 'id', 'property_id');
      $query
        ->addField('ap', 'property_name', 'property_name');
      $result = $query
        ->execute();
      foreach ($result as $item) {
        $data_properties[] = array(
          'property_id' => $item->property_id,
          'property_instance_id' => $item->property_instance_id,
          'property_name' => $item->property_name,
        );
        unset($new_properties[$item->property_name]);
      }
    }
    foreach ($data_properties as &$item) {
      if (isset($this->data)) {
        $item['data'] = $this->data[$item['property_name']];
      }
      switch ($key) {
        case 'property_name':
          $properties['property_name'][$item['property_name']] = $item;
          break;
        case 'property_id':
          $properties['property_id'][$item['property_id']] = $item;
          break;
        case 'property_instance_id':
          $properties['property_instance_id'][$item['property_instance_id']] = $item;
          break;
      }
    }
    return $properties[$key];
  }

  /**
   * Store the analytic data for an event.
   *
   * @param $ip_address
   * @param $unique_id
   * @return unknown_type
   */
  protected function writeEventRecord($ip_address, $unique_id = NULL) {
    $event_instance_id = db_insert('analytics_event_instance')
      ->fields(array(
      'event_id' => $this->event_id,
      'date' => date('Y-m-d H:i:s'),
      'year' => date('Y'),
      'month' => date('n'),
      'week' => date('W'),
      'ip' => $ip_address,
      'unique_id' => $unique_id,
    ))
      ->execute();
    $query = db_insert('analytics_property_values')
      ->fields(array(
      'property_id',
      'event_instance_id',
      'value',
    ));
    foreach ($this
      ->getProperties() as $item) {
      $query
        ->values(array(
        'property_id' => $item['property_id'],
        'event_instance_id' => $event_instance_id,
        'value' => $item['data'],
      ));
    }
    $query
      ->execute();
  }

  /**
   * Public setter for event name.
   *
   * @param $event_name string Name of the event to set.
   */
  public function setEventName($event_name) {
    $this->event_name = $event_name;

    // Fetch event IDs
    $event = db_select('analytics_events', 'a')
      ->fields('a', array(
      'id',
    ))
      ->condition('event_name', $this->event_name)
      ->range(0, 1)
      ->execute()
      ->fetch();
    if ($event->id) {
      $this->event_id = $event->id;
    }
    else {
      $this->event_id = db_insert('analytics_events')
        ->fields(array(
        'event_name' => $this->event_name,
      ))
        ->execute();
    }
  }

  /**
   * Public setter for event id.
   *
   * @param $event_id integer ID of the event to set.
   */
  public function setEventId($event_id) {
    $this->event_id = $event_id;
  }

  /**
   * Static function to list all known events.
   *
   * @return unknown_type
   */
  public static function listEvents() {
    $result = db_select('analytics_events', 'ae')
      ->fields('ae')
      ->execute();
    $events = array();
    foreach ($result as $item) {
      $events[$item->id] = $item->event_name;
    }
    return $events;
  }

  /**
   * Return all known values for a property.
   */
  public function getPropertyValues($property_name, $count = FALSE) {
    $query = db_select('analytics_property_values', 'apv')
      ->fields('apv', array(
      'value',
    ))
      ->distinct(TRUE);
    $query
      ->join('analytics_properties', 'ap', 'apv.property_id = ap.id AND ap.property_name = :name', array(
      ':name' => $property_name,
    ));
    $query
      ->join('analytics_event_instance', 'aei', 'apv.event_instance_id = aei.id AND aei.event_id = :event_id', array(
      ':event_id' => $this->event_id,
    ));
    if ($count) {
      $query
        ->addExpression('COUNT(DISTINCT apv.value)', 'count');
      $result = $query
        ->execute()
        ->fetch();
      return $result->count;
    }
    $result = $query
      ->execute();
    $values = array();
    foreach ($result as $item) {
      $values[] = $item->value;
    }
    return $values;
  }

}

Classes

Namesort descending Description
Analytic @file Class definition for analytics.