--- a/busui/owa/modules/base/handlers/conversionHandlers.php +++ b/busui/owa/modules/base/handlers/conversionHandlers.php @@ -1,1 +1,367 @@ - +<?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 © 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; + } +} + +?>