The name "UserDB" stands for a set of built-in Interchange features related to the user database. That includes the database table that will hold your visitors data, and the set of functions operating either on that database or on people's session information.
Interchange's set of user database functions is elaborate, but it still manages not to place application-specific requirements on your practical database. While it is possible to use Interchange's UserDB functions with your custom type of database, it is strongly recommended to follow simple UserDB naming and usage standards. That alone will instantly give you a huge amount of built-in userdb functionality with no overhead programming.
The whole UserDB set consists of:
The user database. It is the database table that will actually contain all persistent information for visitors who create an account at your website. This table has only a few required fields.
Set of predefined Interchange variables (such as mv_username
,
mv_password
and mv_verify
.)
As you will see, most of the UserDB functions in
Interchange will be simplified to placing data in predefined variables
and then invoking required actions; no matter how complex the
actions might be internally.
The [userdb]
tag. This tag is the convenient method of invoking
UserDB functions. As long as you will adhere to naming and usage
standards, UserDB invocations will be as simple as
[userdb login]
, [userdb save]
or
[userdb logout]
.
To create the database, you could follow a very simple structure. The only two required fields are username and password. Your sample test database could look like this:
code password
(Note that the name of the first column — the primary key — is arbitrary because Interchange's default functions are not accessing it by name. But it is a good standard to name the first field code in all your database tables).
It is, however, recommended to use an SQL database for any more complex functions. Let's take a look at a more elaborate user database that, among other things, has support for visitors' first and last name, inactivity flag and billing and shipping addresses:
Database userdb LENGTH_EXCEPTION_DEFAULT truncate_log Database userdb DEFAULT_TYPE varchar(255) Database userdb COLUMN_DEF "username=varchar(64) NOT NULL PRIMARY KEY" Database userdb COLUMN_DEF "password=varchar(64) NOT NULL" Database userdb COLUMN_DEF "accounts=text" Database userdb COLUMN_DEF "acl=text" Database userdb COLUMN_DEF "address1=varchar(64)" Database userdb COLUMN_DEF "address2=varchar(64)" Database userdb COLUMN_DEF "address3=varchar(64)" Database userdb COLUMN_DEF "address_book=text" Database userdb COLUMN_DEF "b_address1=varchar(64)" Database userdb COLUMN_DEF "b_address2=varchar(64)" Database userdb COLUMN_DEF "b_address3=varchar(64)" Database userdb COLUMN_DEF "b_city=varchar(30)" Database userdb COLUMN_DEF "b_company=varchar(64)" Database userdb COLUMN_DEF "b_country=varchar(10)" Database userdb COLUMN_DEF "b_fname=varchar(30)" Database userdb COLUMN_DEF "b_lname=varchar(30)" Database userdb COLUMN_DEF "b_nickname=text" Database userdb COLUMN_DEF "b_phone=varchar(30)" Database userdb COLUMN_DEF "b_state=varchar(10)" Database userdb COLUMN_DEF "b_zip=varchar(10)" Database userdb COLUMN_DEF "carts=text" Database userdb COLUMN_DEF "city=varchar(30)" Database userdb COLUMN_DEF "company=varchar(64)" Database userdb COLUMN_DEF "country=varchar(10)" Database userdb COLUMN_DEF "credit_limit=varchar(16)" Database userdb COLUMN_DEF "db_acl=text" Database userdb COLUMN_DEF "dealer=varchar(32)" Database userdb COLUMN_DEF "email=varchar(42)" Database userdb COLUMN_DEF "fax=varchar(30)" Database userdb COLUMN_DEF "file_acl=text" Database userdb COLUMN_DEF "fname=varchar(30)" Database userdb COLUMN_DEF "inactive=varchar(8)" Database userdb COLUMN_DEF "lname=varchar(30)" Database userdb COLUMN_DEF "mail_list=text" Database userdb COLUMN_DEF "mod_time=varchar(20)" Database userdb COLUMN_DEF "mv_shipmode=varchar(255)" Database userdb COLUMN_DEF "owner=varchar(20)" Database userdb COLUMN_DEF "p_nickname=text" Database userdb COLUMN_DEF "phone_day=varchar(30)" Database userdb COLUMN_DEF "phone_night=varchar(30)" Database userdb COLUMN_DEF "price_level=varchar(30)" Database userdb COLUMN_DEF "preferences=text" Database userdb COLUMN_DEF "s_nickname=text" Database userdb COLUMN_DEF "state=varchar(20)" Database userdb COLUMN_DEF "zip=varchar(10)" Database userdb DEFAULT "inactive=''"
The above is Interchange's database representation format that allows Interchange to be aware of the database structure and automagically create it if it's missing. See database glossary entry for complete information.
The above is PostgreSQL-compatible definition. We have the equivalent
MySQL version available
(in short, you only need to replace
type =text
with MySQL's =BLOB
).
To make the new database table accessible to Interchange, and to define
a couple more UserDB-specific options, you could add the following
to your catalog.cfg
:
# For SQL databases: Database userdb userdb.txt # Or for file-based database (DBM): Database userdb userdb.txt TAB # Encrypt passwords? UserDB default crypt 0 # Ignore uppercase/lowercase in usernames? UserDB default ignore_case 1 # Enable this in combination with the above, so that # username is always 'normalized': Filter mv_username lc # To disable field containing date of last change: UserDB default time_field none # To enable field containing date of last change #UserDB default time_field mod_time UserDB default logfile var/log/userdb.log # To allow people login using their email, and not their username # (in that case, username does not have to be meaningful and # can be automatically assigned, like "U00001"): #UserDB default indirect_login email
The login page could again be very simple, like this:
[set Login] [userdb login] [/set] <form action="[process secure=1]" method="POST"> <input type="hidden" name="mv_todo" value="return"> <input type="hidden" name="mv_nextpage" value="index"> <input type="hidden" name="mv_click" value="Login"> [form-session-id] <input name="mv_username" type="text"> <input name="mv_password" type="password"> <input value="Submit" type="submit"> </form>
More complex login page with support for cookies and "remembering" users, and that displays a logout option if the user is already logged in could look like this:
[set Login] [userdb login] [/set] [set Logout_choice] [if type=explicit compare="[userdb function=logout clear='[cgi clear_values]']"] [set mv_no_count]1[/set] [set mv_no_session_id]1[/set] [if cgi clear_cart] [calc] @$Items = (); return; [/calc] [/if] [/if] [/set] [tmp cookie_username][read-cookie MV_USERNAME][/tmp] <form action="[process secure=1]" method="POST"> <input type="hidden" name="mv_todo" value="return"> <input type="hidden" name="mv_nextpage" value="index"> [form-session-id] [if !session logged_in] <input type="hidden" name="mv_click" value="Login"> <input name="mv_username" type="text"> <input name="mv_password" type="password"> [if config CookieLogin] <input type="hidden" name="mv_cookie_password" value="0"> <input type="checkbox" name="mv_cookie_password" value="1" [if scratch cookie_username]CHECKED[/if]> [/if] [else] <input type="hidden" name="mv_click" value="Logout_choice"> Logged in as [data session username]. <input class="input" type="hidden" name="clear_values" value="1"> <input class="input" type="checkbox" name="clear_values" checked value="1"> Erase values. [/else] [/if] <input type="submit" value="Submit"> </form>
When the user logs in, user database values are automatically
copied to their values space and can be retrieved at
any time using the [value]
tag. (Values which are not present
in the database might take on a default value defined with
ValuesDefault
).
Often times, you would like to save users' data back to the user database, be it during or at the end of user session. You can automatically do this with a combination of form processing directives, but if you want to do it manually, use the following simple yet powerful code:
[update values] [userdb save]
The above code saves all users' values back to the database. Values which do not have a corresponding database field are ignored (as there's no place to save them). This is a fault-tolerant behavior and something you almost always want to happen anyway.
For all advanced examples and more technical discussion, see
[userdb]
tag documentation.