Gossamer Forum
Home : Products : Gossamer Links : Version 1.x :

Counting jumps to "detailed" pages.

Quote Reply
Counting jumps to "detailed" pages.
This works with everything except the "page.cgi" dynamic routines. I haven't figured out a way around it yet. So, if you're using page.cgi, this will not serve up dynamic detailed pages.

I wanted to count hits to my detailed pages, as the "interest" factor, as well as "site visits" which is how many times people then clicked on the actual URL.

The way I did it, is by passing jump.cgi not just an ID, but an "ID.html"

Jump.cgi assumes if there is no .html that it's a jump to a real URL, if there is a .html, it's a jump to a detailed page.

Code:
$id = $in->param('ID');
## $offset = $id;
if ($id != 'random') {
($offset) = ($id =~ /(\d+)/); ### trims off the .html
}

This needs to be added at the very top. It allows the "ID" to be found so you can get the offset in the file.

Then, I needed to add an option to the main "if" clause to check if it was a detailed page hit:

Code:
## if not random, check to see if it's a detailed page hit
} elsif ($id =~ /^\d+\.html$/) { ## if the id is nnnn.html this should find it
($id) = ($id =~ /(\d+)/); ## cut off the nnnn part into the numeric ID

That checks for the '.html' and if it's found, it enters this clause that is a clone of the "we have a link" clause, doing all the clean up and such, and then sends the user to the /detailed/page/path/detailed.html page.

In order to track the hits vs site_visits, I added a new field to the links and validate tables, called "Site_Visits", same definitions as the "hits" field.

So, the "detalied page" clause updates the "hits_track" field, and in the "Now send the user to the URL" I replace the update Hits_Track with:

Code:
$db->do ("UPDATE Links SET Site_Visits = Site_Visits + 1 WHERE ID = $offset"); ## update the site visits

Here's the entire jump.cgi as I've modified it. You should be able to cut/paste it into a file, then upload it as jump2.cgi and make a test link to see how it works.

It's not very elegant, and I really haven't updated it since the 1.0 release, other than cut in the "attchment" clause, so it might need some tweaking on your site, but it is one way to differentiate between lookers and jumpers, without counting duplicate "hits" from the same user -- they get one "hit" and one "jump" per unit time.

============

Code:

#!/usr/local/bin/perl
# ==============================================================
# -------------
# Links SQL
# -------------
# Links Manager
#
# Author: Alex Krohn
# Email: alex@gossamer-threads.com
# Web: http://www.gossamer-threads.com/
# Version: 1.01-1.11
# Modified by PUGDOG/POSTCARDS.COM to allow
# tracking of "hits" vs "visits" and detailed page jumps.
#
# COPYRIGHT NOTICE:
#
# Copyright 1999 Gossamer Threads Inc. All Rights Reserved.
# No redistribution of this script may be made without prior
# written consent.
#
# By using this program you agree to indemnify Gossamer Threads
# Inc. from any liability.
#
# Please see the README for full license details.
#
# ==============================================================

# Load required modules.
# ---------------------------------------------------
use CGI ();
use CGI::Carp qw/fatalsToBrowser/;
use lib 'admin';
use Links;
use Links: B_Utils;
use Links: BSQL;
use strict;
$|++;

# Create our CGI, and DB objects.
# ---------------------------------------------------
my $in = new CGI;
my ($db, $id, $sth, $total, $rec, $offset, $goto, $track, $update, $time, $SendCGI, $Title);

# Create our database object and get the id number.
$db = new Links: BSQL $LINKS{admin_root_path} . "/defs/Links.def";
$id = $in->param('ID');
#### initialize $offset for banner rotation -- if 'random' $offset will be re-initialized below.
## $offset = $id; #### otherwise, $offset is set to the image ID, still offering a unique per-page number
if ($id != 'random') {
($offset) = ($id =~ /(\d+)/); ### trims off the .html
}


# If we are chosing a random link, then get the total and go to one at random.
if ($id eq "random") {
$total = $db->total();
$offset = int rand $total;
my $check_cat = '20'; ##_## set the test
my $tries = '0';
until ((($check_cat < '16') && ($check_cat > '37')) | | ($tries > '5')) {

$sth = $db->prepare ( " SELECT * FROM Links LIMIT $offset, 1 ");
$sth->execute() or die $DBI::errstr;

$rec = $sth->fetchrow_hashref;

$check_cat = $rec=>{'CategoryID'}; ##_## if not a shopping site, will fall through
$tries++;
$offset = int rand $total; ##_## set up for next pass
}

$goto = $rec->{'URL'};

## if not random, check to see if it's a detailed page hit
} elsif ($id =~ /^\d+\.html$/) { ## if the id is nnnn.html this should find it
($id) = ($id =~ /(\d+)/); ## cut off the nnnn part into the numeric ID

## look up the record
$rec = $db->get_record ($id, 'HASH');
$rec or &error ("Can't find link id in my new routine: $id");
$goto = $rec->{'URL'};
# Remove old hit tracks.
$db->do ("DELETE FROM Hits_Track WHERE TO_DAYS(NOW()) - TO_DAYS(created) > 2");

# Add this to the hit track table, and if we were able to add, then
# let's update/insert the hit total table.
$sth = $db->prepare ("SELECT 1 FROM Hits_Track WHERE LinkID = $id AND IP = '$ENV{'REMOTE_ADDR'}'");
$sth->execute();
if (! $sth->rows) {
$sth = $db->prepare ("SELECT 1 FROM Build_Update WHERE LinkID = $id");
$sth->execute();
($sth->rows) ?
$db->do ("UPDATE Build_Update SET Hits = Hits + 1 WHERE LinkID = $id") :
$db->do ("INSERT INTO Build_Update (LinkID, Hits, Votes, Rating) VALUES ($id, 1, 0, 0)");
$db->do ("INSERT INTO Hits_Track (LinkID, IP) VALUES ($id, '$ENV{'REMOTE_ADDR'}')");
}

## now go to the detailed page
## if '$goto' has a value, the record was found, and we can redirect, but my site can't redirect to '$goto'
## we need to redirect to detailed.page
$goto ? print $in->redirect ("/pcSQL/pages/Detailed/$id.html") : &error ("Record not found: $id");
exit;

# Otherwise, if we have a link, let's look it up.
} elsif (defined $id) {
($id =~ /^\d+$/) or &error ("Invalid id: $id");

$rec = $db->get_record ($id, 'HASH');
$rec or &error ("Can't find link id: $id");
$goto = $rec->{'URL'};

# Remove old hit tracks.
$db->do ("DELETE FROM Hits_Track WHERE TO_DAYS(NOW()) - TO_DAYS(created) > 2");

# Add this to the hit track table, and if we were able to add, then
# let's update/insert the hit total table.
$sth = $db->prepare ("SELECT 1 FROM Hits_Track WHERE LinkID = $id AND IP = '$ENV{'REMOTE_ADDR'}'");
$sth->execute();
if (! $sth->rows) {
$sth = $db->prepare ("SELECT 1 FROM Build_Update WHERE LinkID = $id");
$sth->execute();
($sth->rows) ?
$db->do ("UPDATE Build_Update SET Hits = Hits + 1 WHERE LinkID = $id") :
$db->do ("INSERT INTO Build_Update (LinkID, Hits, Votes, Rating) VALUES ($id, 1, 0, 0)");
$db->do ("INSERT INTO Hits_Track (LinkID, IP) VALUES ($id, '$ENV{'REMOTE_ADDR'}')");
}
}
# Oops, no link.
else {
&error ("No link specified!");
}

# If we've been asked to display an attachment, do so.
if ($in->param('AID')) {
my ($att_list, $attach, $file, $read, $buffer);
$att_list = $db->list_attach ($rec->{ID});
if (! (ref $att_list)) {
return &error ("No associated attachments.");
}
foreach (@$att_list) {
if ($in->param('AID') eq $_->{ID}) {
$attach = $_; last;
}
}
if (! $attach) {
return &error ("Invalid attachment ID.");
}
$file = $LINKS{attach_dir} . "/" . $attach->{ID} . ".fil";
if ($attach->{FileType}) {
print $in->header($attach->{FileType});
}
else {
(-T $file) ? (print $in->header()) : (print $in->header('application/octet-stream'));
}
open FILE, $file;
while ($read = read (*FILE, $buffer, 1024)) {
print $buffer;
}
close FILE;
}
else {

# Now let's send the user to the url..
if ($goto =~ /^http/ ) {

$db->do ("UPDATE Links SET Site_Visits = Site_Visits + 1 WHERE ID = $offset"); ## update the site visits
$goto ? print $in->redirect ($goto) : &error ("Record not found: $id");
}
else
{
### if there is no http:// it means a local image, so I print out a custom page with the image.
print "Content-type: text/html\n\n";
print "<HTML><HEAD><TITLE></TITLE>";
### other stuff.
print "</DIV></BODY></HTML>\n\n";
}

} ## end else - if -- send user to URL



sub error {
# ------------------------------------------
#
print "Content-type: text/plain\n\n";
print "Error: $_[0]\n";
exit;
}


------------------
POSTCARDS.COM -- Everything Postcards on the Internet www.postcards.com
LinkSQL FAQ: www.postcards.com/FAQ/LinkSQL/










[This message has been edited by pugdog (edited March 13, 2000).]
Quote Reply
Re: Counting jumps to "detailed" pages. In reply to
Can this be modified to work with the standard version of Links 2.0?
Quote Reply
Re: Counting jumps to "detailed" pages. In reply to
The principle would be the same.

you'd need to add another routine to look for the "ID.html" rather than the "ID" and if you find it, process the information as a "hit" and jump to the detailed page, not the URL.

I ported the original version over from Links to the SQL version.

It was just easier with the SQL version to make the database changes, and such to add fields.
Quote Reply
Re: Counting jumps to "detailed" pages. In reply to
Hi

I get this error when I just copy and replace smile with D

Software error:
Execution of /link/jump.cgi aborted due to compilation errors.
Quote Reply
Re: Counting jumps to "detailed" pages. In reply to
areh,
When you copy someones code, just copy it from the edit post screen. It is the icon with the pencil and paper.

By the way, you don't replace the smiley faces with just a D, you replace it with a colon :, and a D



------------------
Robert Blackstone
Webmaster of Scato Search
www.scato.com
Quote Reply
Re: Counting jumps to "detailed" pages. In reply to
Robert_B:

That's a GREAT HINT!!!

Quote Reply
Re: Counting jumps to "detailed" pages. In reply to
Hi

thanks for the tip!!

I get 505 Internal Server Error. Could this be because tables is not created or something, or is this a more serious error relating directly to the script?
Quote Reply
Re: Counting jumps to "detailed" pages. In reply to
Check your error.log ... it will tell you exactly what the problem is.

There's almost no way to figure out what's wrong without the log.
Quote Reply
Re: Counting jumps to "detailed" pages. In reply to
So this mod counts all hits on Title and Detail; you dont know nothing more than the sum?!
Better would be a whole new count as
Title (x) --- go to detailpage (y)
Has someone an idea to do that?
Robert