<?php 
/*******************************************************************************
 * Copyright (c) 2007 Eclipse Foundation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Denis Roy (Eclipse Foundation)- initial implementation
 *******************************************************************************/
 
 
    #*****************************************************************************
    #
    # redirector.php
    #
    # Author:       Denis Roy
    # Date:         2007-09-07
    #
    # Description:  redirector for campaign URL tracking
    #
    #
    #*****************************************************************************

	function showErrorPage() {
		require_once($_SERVER['DOCUMENT_ROOT'] . "/eclipse.org-common/system/nav.class.php");
		require_once($_SERVER['DOCUMENT_ROOT'] . "/eclipse.org-common/system/menu.class.php");
		$App 	= new App();	$Nav	= new Nav();	$Menu 	= new Menu();		
		
		$html = '<div id="maincontent">
				<div id="midcolumn">
					<h1>Expired Link</h1>
			<p> There was an error processing this link.  It is likely you are following an old link to an expired campaign activity.  For example,
			you may have clicked on a link to a survey that is now closed or to a special offer that is no longer applicable.  If you believe 
			this link should work, please contact the source of the link.  While you are here, please browse some of our website by 
			clicking on the appropriate tab at the top of the page.
			</p>  
			
			<hr class="clearer" />
			</div>
		</div>';
		$App->generatePage($theme, $Menu, $Nav, $pageAuthor, $pageKeywords, $pageTitle, $html);
	}




	require_once($_SERVER['DOCUMENT_ROOT'] . "/eclipse.org-common/system/app.class.php");
	require_once "/home/data/httpd/eclipse-php-classes/system/dbconnection_rw.class.php";
	$App 	= new App();
	
	# get the incoming parameters
    $_TAG = $App->getHTTPParameter("tag", "GET");

	if(strlen($_TAG) < 1) {
    	# error
    	# header("Location: /");
    	showErrorPage();
    }
    
    
    $x = stripos($_TAG, '@'); 
    if ( $x !== FALSE) {
    	$_SUBTAG = substr($_TAG, $x + 1);
    	$_TAG = substr($_TAG, 0, $x);
    	}
     
    # echo 'SUBTAG:' . $_SUBTAG . ' TAG:' . $_TAG . '<br>';
    
    # strip potentially bad characters from file
    if ($_SUBTAG != "") $_SUBTAG = preg_replace('/["\'?%$#@!;*&]/i', '', $_SUBTAG);
	$_TAG = preg_replace('/["\'?%$#@!;*&]/i', '', $_TAG);



	

	# Connect to databases
	$dbc_RW 	= new DBConnectionRW();
	$dbh_RW		= $dbc_RW->connect();


	$SQL = "SELECT TargetUrl FROM Campaigns WHERE CampaignKey = " . $App->returnQuotedString($_TAG) . " AND DateExpires > CURDATE()";
	$rs 	= mysql_query($SQL, $dbh_RW);
	
	if($myrow = mysql_fetch_assoc($rs)) {
		# redirect the browser now
		header("Location: " . $myrow['TargetUrl']);
		
		# track the click
		# Do a reverse lookup on the client IP
		$client_hostname = @gethostbyaddr($_SERVER['REMOTE_ADDR']) ;
		$SQL = "INSERT /* /go/redirector.php */ DELAYED INTO CampaignClicks (
					ClickID,
  					CampaignKey,
  					SubKey,
  					HostName,
  					TimeClicked) VALUES (
  					NULL,
  					" . $App->returnQuotedString($_TAG) . ",
  					" . $App->returnQuotedString($_SUBTAG) . ",
  					" . $App->returnQuotedString($client_hostname) . ",
  					NOW())";
		
		mysql_query($SQL, $dbh_RW);
	}
	else {
		# error finding Campaign
		#header("Location: /");
		showErrorPage();
	}
	
	$dbc_RW->disconnect();  # disconnects all pending DB connections
	$rs 	= null;
	$dbh_RW	= null;
	$dbc_RW = null;

?>