I just converted an old custom tag I had created for hit counters into a function which can be used in a component. It increments a counter in a database table and returns the current hit number in a numeric and a graphic formats. It does not count unique visitors, it is very simple and you can count several pages and/or domains. After calling the function, you decide if you want to display the graphic result or just use the numeric value for some calculation.

You may download the component, instructions, images and test template [here].

Arguments to pass:

  • counterDSN, required
  • counterTable, required
  • domainName, required
  • pageName, optional, default = “home”
  • captureIP, optional, default = “true”, saves the IP in the “lastVisit” column
  • imagePath, optional, default = “”, image folder where the digits are located
  • width, optional, default = 15, width of the digits in pixels
  • height, optional, default = 20, height of the digits in pixels
  • numDigits, optional, default=””, number of digits to display with padding left zeroes

This is how you call the function:<cfscript>
oCnt = createObject("component", "rpCounters");
result = oCnt.getCounter(
    counterDSN="myDSN"
,   counterTable="myTable"
,   domainName="myDomain.com"
,   pageName="home"
,   numDigits="5"
);
</cfscript>
<cfoutput>
<div style="display:inline;float:left;">
    This is visitor number #result.value#
</div>
<br/>
<div>
    Number of visits: #result.image#
</div>
</cfoutput>

Here is the SQL script to create the table:USE [myDatabase]
GO
/****** Object: Table [dbo].[myTable] Script Date: 08/20/2008 23:47:13 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[myTable](
    [id] [varchar](36) COLLATE SQL_Latin1_General_CP1_CI_AS NULL CONSTRAINT [DF_counters_id] DEFAULT (newid()),
    [domainName] [varchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    [pageName] [varchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    [counter] [int] NULL CONSTRAINT [DF_counters_counter] DEFAULT (0),
    [lastVisit] [varchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    [lastDate] [datetime] NULL CONSTRAINT [DF_counters_lastDate] DEFAULT (getdate())
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF

And here is the component:<cfcomponent>
<cffunction name="getCounter" access="remote" output="false" returntype="Any">
    <cfargument name="counterDSN" type="string" required="true" hint="counter DSN" />
    <cfargument name="counterTable" type="string" required="true" hint="Counter table" />
    <cfargument name="domainName" type="string" required="true" hint="Domain Name" />
    <cfargument name="pageName" type="string" required="false" default="Home" hint="Page for hit count" />
    <cfargument name="capture" type="boolean" required="false" default="true" hint="Capture IP address" />
    <cfargument name="imagePath" type="string" required="false" default="" hint="Image path" />
    <cfargument name="width" type="string" required="false" default="15" hint="width of the counter in pixels" />
    <cfargument name="height" type="string" required="false" default="20" hint="height of ther counter in pixels" />
    <cfargument name="numDigits" type="string" required="false" default="" hint="number of digits to show" />
    <cfset result = structNew() />
    <cfif len(arguments.imagePath) and right(arguments.imagePath,1) is not "/">
        <cfset arguments.imagePath = arguments.imagePath & "/" />
    </cfif>
    <cfquery name="qCnt" datasource="#arguments.counterDSN#">
        <!--- if counter does not exist, create it --->
        if not exists (
            select top 1 counter
            from #arguments.counterTable#
            where domainName = '#arguments.domainName#' and pageName = '#arguments.pageName#'
        )
        begin
            insert into #arguments.counterTable# (
                domainName, pageName, lastDate, counter
            ) values (
                '#arguments.domainName#', '#arguments.pageName#', getDate(), 0
            )
        end
        <!--- now, add to the counter --->
        update #arguments.counterTable# set
            counter = counter +1
        ,    lastDate = getDate()
        <cfif arguments.capture>
        ,     lastVisit = '#cgi.REMOTE_ADDRESS#'
        </cfif>
        where domainName = '#arguments.domainName#' and pageName = '#arguments.pageName#'
        <!--- get the new counter --->
        select top 1 counter
        from #arguments.counterTable#
        where domainName = '#arguments.domainName#' and pageName = '#arguments.pageName#'
    </cfquery>
    <cfset result.value = qCnt.counter />
    <cfif len(trim(arguments.numDigits))>
        <cfset result.value = right(repeatString("0", arguments.numDigits) & trim(result.value), arguments.numDigits) />
    </cfif>
    <cfsavecontent variable="result.image">
    <cfoutput>
    <cfloop from="1" to="#len(result.value)#" index="x">
        <img src="#arguments.imagePath##mid(result.value,x,1)#.gif" style="width:#arguments.width#px;height:#arguments.height#px;border:0;float:left;" alt="#mid(result.value,x,1)#.gif" />
    </cfloop>
    </cfoutput>
    </cfsavecontent>
<cfreturn result />
</cffunction>
</cfcomponent>

Leave a Reply