"Fossies" - the Fresh Open Source Software Archive

Member "Open-Web-Analytics-1.7.0/modules/base/classes/client.php" (16 Sep 2020, 31316 Bytes) of package /linux/www/Open-Web-Analytics-1.7.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) PHP source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "client.php" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.6.9_vs_1.7.0.

    1 <?php
    2 
    3 //
    4 // Open Web Analytics - An Open Source Web Analytics Framework
    5 //
    6 // Copyright 2006 Peter Adams. All rights reserved.
    7 //
    8 // Licensed under GPL v2.0 http://www.gnu.org/copyleft/gpl.html
    9 //
   10 // Unless required by applicable law or agreed to in writing, software
   11 // distributed under the License is distributed on an "AS IS" BASIS,
   12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   13 // See the License for the specific language governing permissions and
   14 // limitations under the License.
   15 //
   16 // $Id$
   17 //
   18 
   19 require_once( OWA_BASE_CLASSES_DIR . 'owa_caller.php' );
   20 
   21 /**
   22  * OWA Client Class
   23  * 
   24  * Abstract Client Class for use in php based applications
   25  * 
   26  * @author      Peter Adams <peter@openwebanalytics.com>
   27  * @copyright   Copyright &copy; 2006 Peter Adams <peter@openwebanalytics.com>
   28  * @license     http://www.gnu.org/copyleft/gpl.html GPL v2.0
   29  * @category    owa
   30  * @package     owa
   31  * @version        $Revision$
   32  * @since        owa 1.4.0
   33  */
   34 
   35 class owa_client extends owa_caller {
   36 
   37     var $commerce_event;
   38 
   39     var $pageview_event;
   40 
   41     var $global_event_properties = array();
   42 
   43     var $stateInit;
   44 
   45     var $organicSearchEngines;
   46 
   47     // set one traffic has been attributed.
   48     var $isTrafficAttributed;
   49 
   50     public function __construct($config = null) {
   51 
   52         parent::__construct($config);
   53 
   54         $this->pageview_event = $this->makeEvent();
   55         $this->pageview_event->setEventType('base.page_request');
   56         // Set the page url from environmental vars
   57         $this->setGlobalEventProperty( 'page_url', owa_coreAPI::getCurrentUrl() );
   58         owa_coreAPI::registerStateStore('v', time()+3600*24*365*10, '', 'assoc', 'cookie', true);
   59         owa_coreAPI::registerStateStore('s', time()+3600*24*365*10, '', 'assoc', 'cookie', true);
   60         owa_coreAPI::registerStateStore('b', null, '', 'json', 'cookie', true);
   61         $cwindow = owa_coreAPI::getSetting( 'base', 'campaignAttributionWindow' );
   62         owa_coreAPI::registerStateStore('c', time() + 3600 * 24 * $cwindow , '', 'json', 'cookie', true);
   63 
   64         $this->organicSearchEngines = [
   65             ['d' => 'google', 'q' => 'q'],
   66             ['d' => 'yahoo', 'q' => 'p'],
   67             ['d' => 'msn', 'q' => 'q'],
   68             ['d' => 'bing', 'q' => 'q'],
   69             ['d' => 'images.google', 'q' => 'q'],
   70             ['d' => 'images.search.yahoo.com', 'q' => 'p'],
   71             ['d' => 'aol', 'q' => 'query'],
   72             ['d' => 'aol', 'q' => 'encquery'],
   73             ['d' => 'aol', 'q' => 'q'],
   74             ['d' => 'lycos', 'q' => 'query'],
   75             ['d' => 'ask', 'q' => 'q'],
   76             ['d' => 'altavista', 'q' => 'q'],
   77             ['d' => 'netscape', 'q' => 'query'],
   78             ['d' => 'cnn', 'q' => 'query'],
   79             ['d' => 'about', 'q' => 'terms'],
   80             ['d' => 'mamma', 'q' => 'q'],
   81             ['d' => 'daum', 'q' => 'q'],
   82             ['d' => 'eniro', 'q' => 'search_word'],
   83             ['d' => 'naver', 'q' => 'query'],
   84             ['d' => 'pchome', 'q' => 'q'],
   85             ['d' => 'alltheweb', 'q' => 'q'],
   86             ['d' => 'voila', 'q' => 'rdata'],
   87             ['d' => 'virgilio', 'q' => 'qs'],
   88             ['d' => 'live', 'q' => 'q'],
   89             ['d' => 'baidu', 'q' => 'wd'],
   90             ['d' => 'alice', 'q' => 'qs'],
   91             ['d' => 'yandex', 'q' => 'text'],
   92             ['d' => 'najdi', 'q' => 'q'],
   93             ['d' => 'mama', 'q' => 'query'],
   94             ['d' => 'seznam', 'q' => 'q'],
   95             ['d' => 'search', 'q' => 'q'],
   96             ['d' => 'wp', 'q' => 'szukaj'],
   97             ['d' => 'onet', 'q' => 'qt'],
   98             ['d' => 'szukacz', 'q' => 'q'],
   99             ['d' => 'yam', 'q' => 'k'],
  100             ['d' => 'kvasir', 'q' => 'q'],
  101             ['d' => 'sesam', 'q' => 'q'],
  102             ['d' => 'ozu', 'q' => 'q'],
  103             ['d' => 'terra', 'q' => 'query'],
  104             ['d' => 'mynet', 'q' => 'q'],
  105             ['d' => 'ekolay', 'q' => 'q'],
  106             ['d' => 'rambler', 'q' => 'query'],
  107             ['d' => 'rambler', 'q' => 'words'],
  108             ['d' => 'duckduckgo', 'q' => 'q'],
  109         ];
  110     }
  111 
  112     public function setPageTitle($value) {
  113         $this->pageview_event->set('page_title', $value);
  114     }
  115 
  116     public function setPageType($value) {
  117         $this->pageview_event->set('page_type', $value);
  118     }
  119 
  120     public function setProperty($name, $value) {
  121         $this->setGlobalEventProperty($name, $value);
  122     }
  123 
  124     private function setGlobalEventProperty($name, $value) {
  125 
  126         $this->global_event_properties[$name] = $value;
  127     }
  128 
  129     private function getGlobalEventProperty($name) {
  130 
  131         if ( array_key_exists($name, $this->global_event_properties) ) {
  132             return $this->global_event_properties[$name];
  133         }
  134     }
  135 
  136     private function deleteGlobalEventProperty( $name ) {
  137 
  138         if ( array_key_exists($name, $this->global_event_properties) ) {
  139             unset($this->global_event_properties[$name]);
  140         }
  141     }
  142 
  143     private function manageState( &$event ) {
  144 
  145         if ( ! $this->stateInit ) {
  146 
  147             $this->setVisitorId( $event );
  148             $this->setFirstSessionTimestamp( $event );
  149             $this->setLastRequestTime( $event );
  150             $this->setSessionId( $event );
  151             $this->setNumberPriorSessions( $event );
  152             $this->setDaysSinceLastSession( $event );
  153             $this->setTrafficAttribution( $event );
  154             $this->stateInit = true;
  155         }
  156     }
  157 
  158     private function setVisitorId( &$event ) {
  159 
  160         $visitor_id =  owa_coreAPI::getStateParam( 'v', 'vid' );
  161 
  162         if ( ! $visitor_id ) {
  163             $visitor_id =  owa_coreAPI::getStateParam( 'v' );
  164             owa_coreAPI::clearState( 'v' );
  165             owa_coreAPI::setState( 'v', 'vid', $visitor_id, 'cookie', true );
  166 
  167         }
  168 
  169         if ( ! $visitor_id ) {
  170             $visitor_id = $event->getSiteSpecificGuid( $this->site_id );
  171             $this->setGlobalEventProperty( 'is_new_visitor', true );
  172             owa_coreAPI::setState( 'v', 'vid', $visitor_id, 'cookie', true );
  173         }
  174         // set property on event object
  175         $this->setGlobalEventProperty( 'visitor_id', $visitor_id );
  176     }
  177 
  178     private function setNumberPriorSessions( &$event ) {
  179         // if check for nps value in vistor cookie.
  180         $nps = owa_coreAPI::getStateParam('v', 'nps');
  181 
  182         // if new session, increment visit count and persist to state store
  183         if ( $this->getGlobalEventProperty('is_new_session' ) ) {
  184 
  185             // set value to 0 if not found.
  186             if ( ! $nps ) {
  187 
  188                 $nps = "0";
  189 
  190             } else {
  191 
  192                 $nps = $nps + 1;
  193             }
  194 
  195             owa_coreAPI::setState('v', 'nps', $nps, 'cookie', true);
  196         }
  197 
  198         // set property on the event object
  199         $this->setGlobalEventProperty('nps', $nps);
  200     }
  201 
  202     private function setFirstSessionTimestamp( &$event ) {
  203 
  204         $fsts = owa_coreAPI::getStateParam( 'v', 'fsts' );
  205 
  206         if ( ! $fsts ) {
  207             $fsts = $event->get('timestamp');
  208             owa_coreAPI::setState(owa_coreAPI::getSetting('base', 'visitor_param'), 'fsts', $fsts , 'cookie', true);
  209         }
  210 
  211         $this->setGlobalEventProperty( 'fsts', $fsts );
  212 
  213         // calc days since first session
  214         $dsfs = round( ( $fsts - $event->get( 'timestamp' ) ) / ( 3600 * 24 ) ) ;
  215         owa_coreAPI::setState(owa_coreAPI::getSetting('base', 'visitor_param'), 'dsfs', $dsfs , 'cookie', true);
  216         $this->setGlobalEventProperty( 'dsfs', $dsfs );
  217     }
  218 
  219     private function setDaysSinceLastSession( &$event ) {
  220 
  221         owa_coreAPI::debug('setting days since last session.');
  222         $dsps = '';
  223         if ( $this->getGlobalEventProperty( 'is_new_session' ) ) {
  224             owa_coreAPI::debug( 'timestamp: ' . $event->get( 'timestamp' ) );
  225             $last_req = $this->getGlobalEventProperty( 'last_req' );
  226             if ( ! $last_req ) {
  227                 $last_req = $event->get( 'timestamp' );
  228             }
  229             owa_coreAPI::debug( 'last_req: ' . $last_req );
  230             $dsps = round( ( $event->get( 'timestamp' ) - $last_req ) / ( 3600*24 ) );
  231             owa_coreAPI::setState('s', 'dsps', $dsps , 'cookie', true);
  232         }
  233 
  234         if ( ! $dsps ) {
  235             $dsps = owa_coreAPI::getState( 's', 'dsps' );
  236 
  237             if ( ! $dsps ) {
  238                 $dsps = 0;
  239             }
  240         }
  241 
  242         $this->setGlobalEventProperty( 'dsps', $dsps );
  243     }
  244 
  245     private function setSessionId( &$event ) {
  246 
  247         $is_new_session = $this->isNewSession( $event->get( 'timestamp' ),  $this->getGlobalEventProperty( 'last_req' ) );
  248         if ( $is_new_session ) {
  249             //set prior_session_id
  250             $prior_session_id = owa_coreAPI::getStateParam('s', 'sid');
  251             if ( ! $prior_session_id ) {
  252                 $state_store_name = sprintf('%s_%s', owa_coreAPI::getSetting('base', 'site_session_param'), $this->site_id);
  253                 $prior_session_id = owa_coreAPI::getStateParam($state_store_name, 's');
  254             }
  255             if ($prior_session_id) {
  256                 $this->setGlobalEventProperty( 'prior_session_id', $prior_session_id );
  257             }
  258 
  259             $this->resetSessionState();
  260 
  261             $session_id = $event->getSiteSpecificGuid( $this->site_id );
  262 
  263                //mark new session flag on current request
  264             $this->setGlobalEventProperty( 'is_new_session', true );
  265             owa_coreAPI::setState( 's', 'sid', $session_id, 'cookie', true );
  266 
  267         } else {
  268             // Must be an active session so just pull the session id from the state store
  269             $session_id = owa_coreAPI::getStateParam('s', 'sid');
  270 
  271             // support for old style cookie
  272             if ( ! $session_id ) {
  273                 $state_store_name = sprintf('%s_%s', owa_coreAPI::getSetting('base', 'site_session_param'), $this->site_id);
  274                 $session_id = owa_coreAPI::getStateParam($state_store_name, 's');
  275 
  276             }
  277 
  278             // fail-safe just in case there is no session_id
  279             if ( ! $session_id ) {
  280                 $session_id = $event->getSiteSpecificGuid( $this->site_id );
  281                 //mark new session flag on current request
  282                 $this->setGlobalEventProperty( 'is_new_session', true );
  283                 owa_coreAPI::debug('setting failsafe session id');
  284             }
  285         }
  286 
  287         // set global event property
  288            $this->setGlobalEventProperty( 'session_id', $session_id );
  289         // set sid state
  290         owa_coreAPI::setState( 's', 'sid', $session_id, 'cookie', true );
  291     }
  292 
  293     private function setLastRequestTime( &$event ) {
  294 
  295         $last_req = owa_coreAPI::getStateParam('s', 'last_req');
  296 
  297         // suppport for old style cookie
  298         if ( ! $last_req ) {
  299             $state_store_name = sprintf( '%s_%s', owa_coreAPI::getSetting( 'base', 'site_session_param' ), $this->site_id );
  300             $last_req = owa_coreAPI::getStateParam( $state_store_name, 'last_req' );
  301         }
  302         // set property on event object
  303         $this->setGlobalEventProperty( 'last_req', $last_req );
  304         owa_coreAPI::debug("setting last_req value of $last_req as global event property.");
  305         // store new state value
  306         owa_coreAPI::setState( 's', 'last_req', $event->get( 'timestamp' ), 'cookie', true );
  307     }
  308 
  309     /**
  310      * Check to see if request is a new or active session
  311      *
  312      * @return boolean
  313      */
  314     private function isNewSession($timestamp = '', $last_req = 0) {
  315 
  316         $is_new_session = false;
  317 
  318         if ( ! $timestamp ) {
  319             $timestamp = time();
  320         }
  321 
  322         $time_since_lastreq = $timestamp - $last_req;
  323         $len = owa_coreAPI::getSetting( 'base', 'session_length' );
  324         if ( $time_since_lastreq < $len ) {
  325             owa_coreAPI::debug("This request is part of a active session.");
  326             return false;
  327         } else {
  328             //NEW SESSION. prev session expired, because no requests since some time.
  329             owa_coreAPI::debug("This request is the start of a new session. Prior session expired.");
  330             return true;
  331         }
  332     }
  333 
  334     /**
  335      * Logs tracking event
  336      *
  337      * This function fires a tracking event that will be processed and then dispatched
  338      *
  339      * @param object $event
  340      * @return boolean
  341      */
  342     public function trackEvent($event) {
  343 
  344         // do not track anything if user is in overlay mode
  345         if (owa_coreAPI::getStateParam('overlay')) {
  346             return false;
  347         }
  348 
  349         $this->setGlobalEventProperty( 'HTTP_REFERER', owa_coreAPI::getServerParam('HTTP_REFERER') );
  350 
  351         // needed by helper page tags function so it can append to first hit tag url
  352         if (!$this->getSiteId()) {
  353             $this->setSiteId($event->get('site_id'));
  354         }
  355 
  356         if (!$this->getSiteId()) {
  357             $this->setSiteId(owa_coreAPI::getRequestParam('site_id'));
  358         }
  359 
  360         // set various state properties.
  361         $this->manageState( $event );
  362 
  363         $event = $this->setAllGlobalEventProperties( $event );
  364 
  365         // send event to log API for processing.
  366         return owa_coreAPI::logEvent($event->getEventType(), $event);
  367     }
  368 
  369     public function setAllGlobalEventProperties( $event ) {
  370 
  371         if ( ! $event->get('site_id') ) {
  372             $event->set( 'site_id', $this->getSiteId() );
  373         }
  374 
  375         // add custom variables to global properties if not there already
  376         for ( $i=1; $i <= owa_coreAPI::getSetting('base', 'maxCustomVars'); $i++ ) {
  377             $cv_param_name = 'cv' . $i;
  378             $cv_value = '';
  379 
  380             // if the custom var is not already a global property
  381             if ( ! $this->getGlobalEventProperty( $cv_param_name ) ) {
  382                 // check to see if it exists
  383                 $cv_value = $this->getCustomVar( $i );
  384                 // if so add it
  385                 if ( $cv_value ) {
  386                     $this->setGlobalEventProperty( $cv_param_name, $cv_value );
  387                 }
  388             }
  389         }
  390 
  391         // merge global event properties
  392         $event->setNewProperties( $this->global_event_properties );
  393 
  394         return $event;
  395 
  396     }
  397 
  398     public function getAllEventProperties( $event ) {
  399 
  400         $event = $this->setAllGlobalEventProperties( $event );
  401         return $event->getProperties();
  402     }
  403 
  404     public function trackPageview($event = '') {
  405 
  406         if ($event) {
  407             $event->setEventType('base.page_request');
  408             $this->pageview_event = $event;
  409         }
  410         return $this->trackEvent($this->pageview_event);
  411     }
  412 
  413     public function trackAction($action_group = '', $action_name, $action_label = '', $numeric_value = 0) {
  414 
  415         $event = $this->makeEvent();
  416         $event->setEventType('track.action');
  417         $event->set('action_group', $action_group);
  418         $event->set('action_name', $action_name);
  419         $event->set('action_label', $action_label);
  420         $event->set('numeric_value', $numeric_value);
  421         $event->set('site_id', $this->getSiteId());
  422         return $this->trackEvent($event);
  423     }
  424 
  425     /**
  426      * Creates a ecommerce Transaction event
  427      *
  428      * Creates a parent commerce.transaction event
  429      */
  430     public function addTransaction(
  431             $order_id,
  432             $order_source = '',
  433             $total = 0,
  434             $tax = 0,
  435             $shipping = 0,
  436             $gateway = '',
  437             $country = '',
  438             $state = '',
  439             $city = '',
  440             $page_url = '',
  441             $session_id = ''
  442         ) {
  443 
  444         $this->commerce_event = $this->makeEvent();
  445         $this->commerce_event->setEventType( 'ecommerce.transaction' );
  446         $this->commerce_event->set( 'ct_order_id', $order_id );
  447         $this->commerce_event->set( 'ct_order_source', $order_source );
  448         $this->commerce_event->set( 'ct_total', $total );
  449         $this->commerce_event->set( 'ct_tax', $tax );
  450         $this->commerce_event->set( 'ct_shipping', $shipping );
  451         $this->commerce_event->set( 'ct_gateway', $gateway );
  452         $this->commerce_event->set( 'page_url', $page_url );
  453         $this->commerce_event->set( 'ct_line_items', array() );
  454         $this->commerce_event->set( 'country', $country );
  455         $this->commerce_event->set( 'state', $state );
  456         $this->commerce_event->set( 'city', $city );
  457         if ( $session_id ) {
  458             $this->commerce_event->set( 'original_session_id', $session_id );
  459             // tells the client to NOT manage state properties as we are
  460             // going to look them up from the session later.
  461             $this->commerce_event->set( 'is_state_set', true );
  462         }
  463     }
  464 
  465     /**
  466      * Adds a line item to a commerce transaction
  467      *
  468      * Creates and a commerce.line_item event and adds it to the parent transaction event
  469      */
  470     public function addTransactionLineItem($order_id, $sku = '', $product_name = '', $category = '', $unit_price = 0, $quantity = 0) {
  471 
  472         if ( empty( $this->commerce_event ) ) {
  473             $this->addTransaction('none set');
  474         }
  475 
  476         $li = array();
  477         $li['li_order_id'] = $order_id ;
  478         $li['li_sku'] = $sku ;
  479         $li['li_product_name'] = $product_name ;
  480         $li['li_category'] = $category ;
  481         $li['li_unit_price'] = $unit_price ;
  482         $li['li_quantity'] = $quantity ;
  483 
  484         $items = $this->commerce_event->get( 'ct_line_items' );
  485         $items[] = $li;
  486         $this->commerce_event->set( 'ct_line_items', $items );
  487     }
  488 
  489     /**
  490      * tracks a commerce events
  491      *
  492      * Tracks a parent transaction event by sending it to the event queue
  493      */
  494     public function trackTransaction() {
  495 
  496         if ( ! empty( $this->commerce_event ) ) {
  497             $this->trackEvent( $this->commerce_event );
  498             $this->commerce_event = '';
  499         }
  500     }
  501 
  502     public function createSiteId($value) {
  503 
  504         return md5($value);
  505     }
  506 
  507     public function setCampaignNameKey( $key ) {
  508 
  509         $campaign_params = owa_coreAPI::getSetting( 'base', 'campaign_params' );
  510         $campaign_params[ 'campaign' ] = $key;
  511         owa_coreAPI::setSetting('base', 'campaign_params', $campaign_params);
  512     }
  513 
  514     public function setCampaignMediumKey( $key ) {
  515 
  516         $campaign_params = owa_coreAPI::getSetting( 'base', 'campaign_params' );
  517         $campaign_params[ 'medium' ] = $key;
  518         owa_coreAPI::setSetting('base', 'campaign_params', $campaign_params);
  519     }
  520 
  521     public function setCampaignSourceKey( $key ) {
  522 
  523         $campaign_params = owa_coreAPI::getSetting( 'base', 'campaign_params' );
  524         $campaign_params[ 'source' ] = $key;
  525         owa_coreAPI::setSetting('base', 'campaign_params', $campaign_params);
  526     }
  527 
  528     public function setCampaignSearchTermsKey( $key ) {
  529 
  530         $campaign_params = owa_coreAPI::getSetting( 'base', 'campaign_params' );
  531         $campaign_params[ 'search_terms' ] = $key;
  532         owa_coreAPI::setSetting('base', 'campaign_params', $campaign_params);
  533     }
  534 
  535     public function setCampaignAdKey( $key ) {
  536 
  537         $campaign_params = owa_coreAPI::getSetting( 'base', 'campaign_params' );
  538         $campaign_params[ 'ad' ] = $key;
  539         owa_coreAPI::setSetting('base', 'campaign_params', $campaign_params);
  540     }
  541 
  542     public function setCampaignAdTypeKey( $key ) {
  543 
  544         $campaign_params = owa_coreAPI::getSetting( 'base', 'campaign_params' );
  545         $campaign_params[ 'ad_type' ] = $key;
  546         owa_coreAPI::setSetting('base', 'campaign_params', $campaign_params);
  547     }
  548 
  549     public function setUserName( $value ) {
  550 
  551         $this->setGlobalEventProperty( 'user_name', $value );
  552     }
  553 
  554     function getCampaignProperties( $event ) {
  555 
  556         $campaign_params = owa_coreAPI::getSetting( 'base', 'campaign_params' );
  557         $campaign_properties = array();
  558         $campaign_state = array();
  559         $request = owa_coreAPI::getRequest();
  560         foreach ( $campaign_params as $k => $param ) {
  561             //look for property on the event
  562             $property = $event->get( $param );
  563 
  564             // look for property on the request scope.
  565             if ( ! $property ) {
  566                 $property = $request->getRequestParam( $param );
  567             }
  568             if ( $property ) {
  569                 $campaign_properties[ $k ] = $property;
  570             }
  571         }
  572 
  573         // backfill values for incomplete param combos
  574 
  575         if (array_key_exists('ad_type', $campaign_properties) && !array_key_exists('ad', $campaign_properties)) {
  576             $campaign_properties['ad'] = '(not set)';
  577         }
  578 
  579         if (array_key_exists('ad', $campaign_properties) && !array_key_exists('ad_type', $campaign_properties)) {
  580             $campaign_properties['ad_type'] = '(not set)';
  581         }
  582 
  583         if (!empty($campaign_properties)) {
  584             //$campaign_properties['ts'] = $event->get('timestamp');
  585         }
  586 
  587         owa_coreAPI::debug('campaign properties: '. print_r($campaign_properties, true));
  588 
  589         return $campaign_properties;
  590     }
  591 
  592     private function setCampaignSessionState( $properties ) {
  593 
  594         $campaign_params = owa_coreAPI::getSetting( 'base', 'campaign_params' );
  595         foreach ($campaign_params as $k => $v) {
  596 
  597             if (array_key_exists( $k, $properties ) ) {
  598 
  599                 owa_coreAPI::setState( 's', $k, $properties[$k] );
  600             }
  601         }
  602     }
  603 
  604     function directAttributionModel( &$campaign_properties ) {
  605 
  606         // add new campaign info to existing campaign cookie.
  607         if ( $campaign_properties ) {
  608 
  609             // get prior campaing touches from c cookie
  610             $campaign_state = $this->getCampaignState();
  611 
  612             // add new campaign into state array
  613             $campaign_state[] = (object) $campaign_properties;
  614 
  615             // if more than x slice the first one off to make room
  616             $count = count( $campaign_state );
  617             $max = owa_coreAPI::getSetting( 'base', 'max_prior_campaigns');
  618             if ($count > $max ) {
  619                 array_shift( $campaign_state );
  620             }
  621 
  622             // reset state
  623             $this->setCampaignCookie($campaign_state);
  624 
  625             // set flag
  626             $this->isTrafficAttributed = true;
  627 
  628             // persist state to session store
  629             $this->setCampaignSessionState( $campaign_properties );
  630         }
  631 
  632     }
  633 
  634     function originalAttributionModel( &$campaign_properties ) {
  635 
  636         $campaign_state = $this->getCampaignState();
  637         // orignal touch was set previously. jus use that.
  638         if (!empty($campaign_state)) {
  639             // do nothing
  640             // set the attributes from the first campaign touch
  641             $campaign_properties = $campaign_state[0];
  642             $this->isTrafficAttributed = true;
  643 
  644         // no orginal touch, set one if it's a new campaign touch
  645         } else {
  646 
  647             if (!empty($campaign_properties)) {
  648                 // add timestamp
  649                 //$campaign_properties['ts'] = $event->get('timestamp');
  650                 owa_coreAPI::debug('Setting original Campaign attrbution.');
  651                 $campaign_state[] = $campaign_properties;
  652                 // set cookie
  653                 $this->setCampaignCookie($campaign_state);
  654                 $this->isTrafficAttributed = true;
  655             }
  656         }
  657 
  658         // persist state to session store
  659         $this->setCampaignSessionState( $campaign_properties );
  660     }
  661 
  662     function getCampaignState() {
  663 
  664         $campaign_state = owa_coreAPI::getState( 'c', 'attribs' );
  665         if ( ! $campaign_state ) {
  666 
  667             $campaign_state = array();
  668         }
  669 
  670         return $campaign_state;
  671     }
  672 
  673     function setTrafficAttribution( &$event ) {
  674 
  675         // if not then look for individual campaign params on the request.
  676         // this happens when the client is php and the params are on the url
  677         $campaign_properties = $this->getCampaignProperties( $event );
  678         if ( $campaign_properties ) {
  679             $campaign_properties['ts'] = $event->get('timestamp');
  680         }
  681 
  682         // choose attribution model.
  683         $model = owa_coreAPI::getSetting('base', 'trafficAttributionMode');
  684         switch ( $model ) {
  685 
  686             case 'direct':
  687                 owa_coreAPI::debug( 'Applying "Direct" Traffic Attribution Model' );
  688                 $this->directAttributionModel( $campaign_properties );
  689                 break;
  690             case 'original':
  691                 owa_coreAPI::debug( 'Applying "Original" Traffic Attribution Model' );
  692                 $this->originalAttributionModel( $campaign_properties );
  693                 break;
  694             default:
  695                 owa_coreAPI::debug( 'Applying Default (Direct) Traffic Attribution Model' );
  696                 $this->directAttributionModel( $campaign_properties );
  697         }
  698 
  699         // if one of the attribution methods attributes the traffic them
  700         // set attribution properties on the event object
  701         if ( $this->isTrafficAttributed ) {
  702 
  703             owa_coreAPI::debug( 'Attributing Traffic to: %s', print_r($campaign_properties, true ) );
  704 
  705         } else {
  706             // infer the attribution from the referer
  707             // if the request is the start of a new session
  708             if ( $this->getGlobalEventProperty( 'is_new_session' ) ) {
  709                 owa_coreAPI::debug( 'Infering traffic attribution.' );
  710                 $this->inferTrafficAttribution();
  711             }
  712         }
  713 
  714         // apply traffic attribution realted properties to events
  715         // all properties should be set in the state store by this point.
  716         $campaign_params = owa_coreAPI::getSetting('base', 'campaign_params');
  717         foreach( $campaign_params as $k => $v ) {
  718 
  719             $value = owa_coreAPI::getState( 's', $k );
  720 
  721             if ( $value ) {
  722                 $this->setGlobalEventProperty( $k, $value );
  723             }
  724         }
  725 
  726         // set sesion referer
  727         $session_referer = owa_coreAPI::getState('s', 'referer');
  728         if ( $session_referer ) {
  729 
  730             $this->setGlobalEventProperty( 'session_referer', $session_referer );
  731         }
  732 
  733         // set campaign touches
  734         $campaign_state = owa_coreAPI::getState('c', 'attribs');
  735         if ( $campaign_state ) {
  736 
  737             $this->setGlobalEventProperty( 'attribs', json_encode( $campaign_state ));
  738         }
  739     }
  740 
  741     private function inferTrafficAttribution() {
  742 
  743         $ref = owa_coreAPI::getServerParam('HTTP_REFERER');
  744         $medium = 'direct';
  745         $source = '(none)';
  746         $search_terms = '(none)';
  747         $session_referer = '(none)';
  748 
  749         if ( $ref ) {
  750             $uri = owa_lib::parse_url( $ref );
  751 
  752             // check for external referer
  753             $host = owa_coreAPI::getServerParam('HTTP_HOST');
  754             if ( $host != $uri['host'] ) {
  755 
  756                 $medium = 'referral';
  757                 $source = owa_lib::stripWwwFromDomain( $uri['host'] );
  758                 $engine = $this->isRefererSearchEngine( $uri );
  759                 $session_referer = $ref;
  760                 if ( $engine ) {
  761                     $medium = 'organic-search';
  762                     $search_terms = $engine['t'];
  763                 }
  764             }
  765         }
  766 
  767         owa_coreAPI::setState('s', 'referer', $session_referer);
  768         owa_coreAPI::setState('s', 'medium', $medium);
  769         owa_coreAPI::setState('s', 'source', $source);
  770         owa_coreAPI::setState('s', 'search_terms', $search_terms);
  771     }
  772 
  773     private function isRefererSearchEngine( $uri ) {
  774 
  775         if ( !isset( $uri['host'] ) ) {
  776             return null;
  777         }
  778 
  779         $host = $uri['host'];
  780 
  781         $searchEngine = [];
  782 
  783         foreach ( $this->organicSearchEngines as $engine ) {
  784             $domain = $engine['d'];
  785 
  786             if (strpos($host, $domain) === false) {
  787                 continue;
  788             }
  789 
  790             $query_param = $engine['q'];
  791             $term = '';
  792 
  793             if (isset($uri['query_params'][$query_param])) {
  794                 $term = $uri['query_params'][$query_param];
  795             }
  796 
  797             owa_coreAPI::debug( 'Found search engine: %s with query param %s:, query term: %s', $domain, $query_param, $term);
  798 
  799             $searchEngine = ['d' => $domain, 'q' => $query_param, 't' => $term];
  800             break;
  801         }
  802 
  803         return $searchEngine;
  804     }
  805 
  806     function setCampaignCookie($values) {
  807         // reset state
  808         owa_coreAPI::setState('c', 'attribs', $values);
  809     }
  810 
  811     // sets cookies domain
  812     function setCookieDomain($domain) {
  813 
  814         if (!empty($domain)) {
  815             $c = owa_coreAPI::configSingleton();
  816             // sanitizes the domain
  817             $c->setCookieDomain($domain);
  818         }
  819     }
  820 
  821     /**
  822      * Set a custom variable
  823      *
  824      * @param    slot    int        the identifying number for the custom variable. 1-5.
  825      * @param    name    string    the key of the custom variable.
  826      * @param    value    string    the value of the varible
  827      * @param    scope    string    the scope of the variable. can be page, session, or visitor
  828      */
  829     public function setCustomVar( $slot, $name, $value, $scope = '' ) {
  830 
  831         $cv_param_name = 'cv' . $slot;
  832         $cv_param_value = $name . '=' . $value;
  833 
  834         if ( strlen( $cv_param_value ) > 65 ) {
  835             owa_coreAPI::debug('Custom variable name + value is too large. Must be less than 64 characters.');
  836             return;
  837         }
  838 
  839         switch ( $scope ) {
  840 
  841             case 'session':
  842 
  843                 // store in session cookie
  844                 owa_coreAPI::setState( 'b', $cv_param_name, $cv_param_value );
  845                 owa_coreAPI::debug( 'just set custom var on session.' );
  846                 break;
  847 
  848             case 'visitor':
  849 
  850                 // store in visitor cookie
  851                 owa_coreAPI::setState( 'v', $cv_param_name, $cv_param_value );
  852                 // remove slot from session level cookie
  853                 owa_coreAPI::clearState( 'b', $cv_param_name );
  854                 break;
  855         }
  856 
  857         $this->setGlobalEventProperty( $cv_param_name, $cv_param_value );
  858     }
  859 
  860     public function getCustomVar( $slot ) {
  861 
  862         $cv_param_name = 'cv' . $slot;
  863         $cv = '';
  864         // check request/page level
  865         $cv = $this->getGlobalEventProperty( $cv_param_name );
  866         //check session store
  867         if ( ! $cv ) {
  868             $cv = owa_coreAPI::getState( 'b', $cv_param_name );
  869         }
  870         // check visitor store
  871         if ( ! $cv ) {
  872             $cv = owa_coreAPI::getState( 'v', $cv_param_name );
  873         }
  874 
  875         return $cv;
  876 
  877     }
  878 
  879     public function deleteCustomVar( $slot ) {
  880 
  881         $cv_param_name = 'cv' . $slot;
  882         //clear session level
  883         owa_coreAPI::clearState( 'b', $cv_param_name );
  884         //clear visitor level
  885         owa_coreAPI::clearState( 'v', $cv_param_name );
  886         // clear page level
  887         $this->deleteGlobalEventProperty( $cv_param_name );
  888 
  889         owa_coreAPI::debug("Deleting custom variable named $cv_param_name in slot $slot.");
  890     }
  891 
  892     private function resetSessionState() {
  893 
  894         $last_req = owa_coreAPI::getState( 's', 'last_req' );
  895         owa_coreAPI::clearState( 's' );
  896         owa_coreAPI::setState( 's', 'last_req', $last_req);
  897     }
  898 
  899     public function addOrganicSearchEngine( $domain, $query_param, $prepend = '' ) {
  900 
  901         $engine = array('d' => $domain, 'q' => $query_param);
  902         if ( $prepend) {
  903             array_unshift($this->organicSearchEngines, $engine );
  904         } else {
  905                 $this->organicSearchEngines[] = $engine;
  906         }
  907     }
  908 }
  909 
  910 ?>