Contests

part of the ArsDigita Community System by

The Big Idea

People like to get free stuff. The contest module allows publishers to create a doorprize like contest and allows registered users to participate in the contest. Contest can be a simple "visit this page to get entered" or a more complex "please give us some information while entering" page. The publisher can then choose an arbitrary number of winners from the pool of contestants.

Publishing Decisions

Contests can be simple entry buttons, or they can be forms which ask for information. When you're creating a contest, the admin pages provide a customization feature where you can specify any extra data to be collected (such as a yes/no question, or a text field for free-form commentary). You can either use the automatically generated contest entry page (which looks at your customizations and generates the HTML
elements) or you can create your own page and include some hidden values which are used in entry processing.

Choosing Winners

When it's time to choose winners, go to the contest management page. You can specify the time range to choose entrants from (say from the last month), and the number of unique winners to return. The contest module will grovel through the database and return a unique set of results, which you can then do what you wish. (send them email, deliver a box of chocolate)

Under the Hood

There are two primary tables which hold the contest information, and a new table is created for each contest to hold any customized entry fields.

contest_domains is the table that holds general information about each contest:

create table contest_domains (
        domain_id               integer not null primary key,
        domain                  varchar(21) not null unique,
        -- the unique constraint creates an index for us
        entrants_table_name     varchar(30),
        pretty_name             varchar(100) not null,
        -- where the contest starts
        home_url        varchar(200),
        -- arbitrary HTML text that goes at the top of 
        -- the auto-generated entry form
        blather         varchar(4000),
        -- where to send users after they enter
        -- (if blank, we use a generated form)
        post_entry_url  varchar(200),
        maintainer      not null references users(user_id),
        notify_of_additions_p   char(1) default 'f' check (notify_of_additions_p in ('t', 'f')),  -- send email when a person enters
        us_only_p               char(1) default 'f' check (us_only_p in ('t', 'f')),
        start_date              date,   -- these are optional
        end_date                date
);
In earlier versions of this module, the domain column was the primary key. It has been changed to an integer (domain_id) because of performance enhancements to the site-wide search. There is some backwards-compatibility code in the contest module that uses the domain column if there is no domain_id provided in the form data.

When a new contest is created, a new row is added to contest_domains, and a new table called contest_entrants_$domain (where $domain is the value of the domain column). This new entrants table looks like this:

create table contest_entrants_whatever (
        entry_date      date not null,
        user_id         not null references users
);
We don't really care how many times they enter. We'll do a "distinct" query when choosing the winners. For contests that allow extra information to be provided by the user, we may want them to be able to enter multiple times.

Now, how is this extra information handled? When you add a custom column to a contest, a row gets added to the table contest_extra_columns:

create table contest_extra_columns (
        domain_id               not null references contest_domains,
        column_pretty_name      varchar(30),
        column_actual_name      varchar(200) not null,
        column_type             varchar(200) not null,  -- things like 'boolean' or 'text'
        column_extra_sql        varchar(200)    -- things like 'not null' or 'default 5'
);
The column_pretty_name is what is displayed to the user, while column_actual_name> is the name of the column in the contest specific contest_entrants_$domain table. These new columns get added to the entrants table as the contest gets customized. (e.g. at any time)