Add analytics
[bus.git] / busui / owa / modules / base / handlers / conversionHandlers.php
blob:a/busui/owa/modules/base/handlers/conversionHandlers.php -> blob:b/busui/owa/modules/base/handlers/conversionHandlers.php
  <?php
   
  //
  // Open Web Analytics - An Open Source Web Analytics Framework
  //
  // Copyright 2006 Peter Adams. All rights reserved.
  //
  // Licensed under GPL v2.0 http://www.gnu.org/copyleft/gpl.html
  //
  // Unless required by applicable law or agreed to in writing, software
  // distributed under the License is distributed on an "AS IS" BASIS,
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  // See the License for the specific language governing permissions and
  // limitations under the License.
  //
  // $Id$
  //
   
  if(!class_exists('owa_observer')) {
  require_once(OWA_DIR.'owa_observer.php');
  }
   
  /**
  * Conversion Event handlers
  *
  * @author Peter Adams <peter@openwebanalytics.com>
  * @copyright Copyright &copy; 2006 Peter Adams <peter@openwebanalytics.com>
  * @license http://www.gnu.org/copyleft/gpl.html GPL v2.0
  * @category owa
  * @package owa
  * @version $Revision$
  * @since owa 1.4.0
  */
   
  class owa_conversionHandlers extends owa_observer {
   
  /**
  * Notify Event Handler
  *
  * @param unknown_type $event
  * @access public
  */
  function notify($event) {
   
  $update = false;
  $conversion_info = $this->checkForConversion($event);
   
  if ($conversion_info) {
  $s = owa_coreAPI::entityFactory('base.session');
   
  $new_id = $s->generateId(trim( strtolower( $event->get('campaign') ) ) );
  $s->getByPk('id', $event->get('session_id'));
  $id = $s->get('id');
   
  // only record one goal of a particular type per session
  if ($id) {
  //record conversion
  if ( !empty( $conversion_info['conversion'] ) ) {
  $goal_column = 'goal_'.$conversion_info['conversion'];
  $already = $s->get( $goal_column );
  // see if an existing value has been set goal value
  $goal_value_column = 'goal_'.$conversion_info['conversion'].'_value';
  $existing_value = $s->get( $goal_value_column );
  $value = $conversion_info['value'];
   
  // determin is we have a conversion event worth updating
  if ( $already != true ) {
  // there is a goal conversion
  $s->set( $goal_column , true );
  $update = true;
  owa_coreAPI::debug( "$goal_column was achieved." );
  } else {
  // goal already happened but check to see if we need to add a value to it.
  // happens in the case of ecommerce transaction where the value
  // can come in a secondary request. if no value then return.
  if ( ! $value ) {
  owa_coreAPI::debug( 'Not updating session. Goal was already achieved and in same session.' );
  return OWA_EHS_EVENT_HANDLED;
  }
  }
   
  // Allow a value to be set if one has not be set already.
  // this is needed to support dynamic values passed by commerce transaction events
  if ( $value && ! $existing_value ) {
  $s->set( $goal_value_column, owa_lib::prepareCurrencyValue( $value ) );
  $update = true;
  }
  }
  //record goal start
  if ( !empty($conversion_info['start'] ) ) {
  $goal_start_column = 'goal_'.$conversion_info['start'].'_start';
  $already_started = $s->get( $goal_start_column );
   
  if ( $already_started != true ) {
   
  $s->set( $goal_start_column, true );
  $update = true;
  owa_coreAPI::debug( "$goal_start_column was started." );
   
  } else {
  owa_coreAPI::debug( "$goal_start_column was already started." );
  }
  }
   
  //update object
  if ( $update ) {
   
  // summarize goal conversions
  $s->set('num_goals', $this->countGoalConversions($s));
   
  // summarize goal conversion value
  $s->set('goals_value', $this->sumGoalValues($s));
   
  // summarize goal starts
  $s->set('num_goal_starts', $this->countGoalStarts($s));
   
  $ret = $s->update();
  if ( $ret ) {
  // create a new_conversion event so that the total conversion
  // metrics can be resummarized
  $this->dispatchNewConversionEvent($event);
  return OWA_EHS_EVENT_HANDLED;
  } else {
  return OWA_EHS_EVENT_FAILED;
  }
   
  } else {
  owa_coreAPI::debug( "nothing about this conversion is worth updating." );
  return OWA_EHS_EVENT_HANDLED;
  }
   
  } else {
  owa_coreAPI::debug("Conversion processing aborted. No session could be found.");
  return OWA_EHS_EVENT_FAILED;
  }
   
  } else {
  owa_coreAPI::debug('No goal start or conversion detected.');
  return OWA_EHS_EVENT_HANDLED;
  }
  }
   
  // create a new_conversion event so that the total conversion
  // metrics can be resummarized
  function dispatchNewConversionEvent($event) {
   
  $dispatch = owa_coreAPI::getEventDispatch();
  $ce = $dispatch->makeEvent( 'new_conversion' );
  $ce->set( 'session_id', $event->get( 'session_id' ) );
  $dispatch->asyncNotify( $ce );
  }
   
  function checkForConversion($event) {
   
  $goal_info = array('conversion' => '', 'value' => '', 'start' => '');
  $siteId = $event->get('siteId');
   
  if ( ! $siteId ) {
  $siteId = $event->get('site_id');
  }
   
  $gm = owa_coreAPI::supportClassFactory('base', 'goalManager', $siteId);
  $goals = $gm->getActiveGoals();
  owa_coreAPI::debug('active goals: '.print_r($goals, true));
  if (empty($goals)) {
  return;
  }
   
  $is_match = false;
   
  foreach ($goals as $num => $goal) {
   
  if (!empty($goal)) {
   
  if (array_key_exists('goal_status', $goal) && $goal['goal_status'] === 'active') {
  switch ($goal['goal_type']) {
   
  case 'url_destination':
   
  $match = $this->checkUrlDestinationGoal($event, $goal);
  $start = $this->checkGoalStart($event, $goal);
  break;
   
  case 'pages_per_visit':
   
  $match = $this->checkPagesPerVisitGoal($event, $goal);
  break;
   
  case 'visit_duration':
   
  $match = $this->checkPagesPerVisitGoal($event, $goal);
  break;
  }
   
  if ($match) {
  $goal_info['conversion'] = $match;
  }
   
  if ($start) {
  $goal_info['start'] = $start;
  }
   
  //check for dynamic value from commerce transaction
   
  if ($event->get('ct_total')) {
  $goal_value = $event->get('ct_total');
  } else {
  // else just use the static value if one is set.
  if ( array_key_exists('goal_value', $goal) ) {
  $goal_value = $goal['goal_value'];
  }
  }
   
  $goal_info['value'] = $goal_value;
  } else {
  owa_coreAPI::debug("Goal $num not active.");
  }
  }
  }
  owa_coreAPI::debug('conversion info: '.print_r($goal_info, true));
  return $goal_info;
  }
   
  function checkPagesPerVisitGoal($event, $goal) {
   
  $num = $event->get('npvs');
   
  if ($num) {
  $operator = $goal['details']['operator'];
  $req = $goal['details']['num_pageviews'];
   
  switch ($operator) {
   
  case '=':
  if ($num === $req) {
  return $goal['goal_number'];
  }
   
  case '<':
  if ($num < $req) {
  return $goal['goal_number'];
  }
   
  case '>':
  if ($num > $req) {
  return $goal['goal_number'];
  }
  }
  }
  return false;
  }
   
  function checkVisitDurationGoal($event, $goal) {
   
  $num = $event->get('session_duration');
  $operator = $goal['details']['operator'];
  $req = $goal['details']['duration'];
   
  switch ($operator) {
   
  case '=':
  if ($num === $req) {
  return $goal['goal_number'];
  }
   
  case '<':
  if ($num < $req) {
  return $goal['goal_number'];
  }
   
  case '>':
  if ($num > $req) {
  return $goal['goal_number'];
  }
  }
   
  return false;
  }
   
  function checkUrlDestinationGoal($event, $goal) {
  $match = '';
  $page_uri = $event->get('page_uri');
   
  switch ($goal['details']['match_type']) {
   
  case 'exact':
   
  if ( $page_uri === $goal['details']['goal_url'] ) {
  $match = $goal['goal_number'];
  }
  break;
   
  case 'begins':
   
  $length = strlen( $goal['details']['goal_url'] );
  $check = strpos( $page_uri, $goal['details']['goal_url']);
  if ( $check === 0 ) {
  $match = $goal['goal_number'];
  }
  break;
   
  case 'regex':
   
  $pattern = sprintf('@%s@i', $goal['details']['goal_url']);
  $check = preg_match( $pattern, $page_uri );
  if ( $check > 0 ) {
  $match = $goal['goal_number'];
  }
  break;
  }
   
  return $match;
  }
   
  function checkGoalStart($event, $goal) {
  $page_uri = $event->get('page_uri');
  // check for goal start
  if ( array_key_exists( 'funnel_steps', $goal['details'] ) ) {
  // check the first step
  $step = $goal['details']['funnel_steps'][1];
  $pattern = sprintf('@%s@i', $step['url']);
  $check = preg_match($pattern, $page_uri );
  if ($check > 0) {
  return $goal['goal_number'];
  }
  }
  }
   
  function countGoalConversions($session) {
   
  $num = owa_coreAPI::getSetting('base', 'numGoals');
  $count = 0;
  for ($i = 0;$i < $num;$i++) {
  $col_name = 'goal_'.$i;
  $count = $count + $session->get($col_name);
   
  }
  owa_coreAPI::debug('session total goal count: '.$count);
  return $count;
  }
   
  function countGoalStarts($session) {
   
  $num = owa_coreAPI::getSetting('base', 'numGoals');
  $count = 0;
  for ($i = 0;$i < $num;$i++) {
  $col_name = 'goal_'.$i.'_start';
  $count = $count + $session->get($col_name);
  }
  owa_coreAPI::debug('session total goal starts: '.$count);
  return $count;
  }
   
  function sumGoalValues($session) {
   
  $num = owa_coreAPI::getSetting('base', 'numGoals');
  $sum = 0;
  for ($i = 0;$i < $num;$i++) {
  $col_name = 'goal_'.$i.'_value';
  $sum = $sum + $session->get($col_name);
  }
  owa_coreAPI::debug('session total goal value: '.$sum);
  return $sum;
  }
  }
   
  ?>