Developer Documents
NOTE: some things are linked, like the word MySQL and INNODB and I have to figure out how to turn that off, or just do a forwarding page of some sort. Please ignore them in the meantime
Things cached in the $_SESSION variable and what they do
$_SESSION[uid] - The user's ID number. Useful for all kinds of look ups$_SESSION[username] - The user's username (EG: Kog). Useful for all manners of posting$_SESSION[email] - The user's email. For debugging.$_SESSION[country] - The user's current country. Useful for searches based on country information.$_SESSION[acct_type] - The user's account type. Currently we use this for security purposes (1 is regular user, 3 is administrator). We're moving to acct_status flag instead for things like suspended, deleted, administrative etc. For right now you can use 1 for regular user and 3 for administrator however.$_SESSION[lang] - Corresponds to the user's preferences table. This is the "tag" for the language and for now must be either en or es. This hooks into lang_<tag> in the database and is used with the grabStrings method to update the SESSION[dictionary]$_SESSION[dictionary] - Contains all the strings (translated) for the UI. These are tokens in the form of $key => $value, such as greeting => "Welcome to Info-Exchange". The site prints tokens in the form of $key, this allows us to have a dynamically translated site as long as someone maintains the dictionary. Currently there is only an English dictionary, Spanish is coming soon. Eventually there can be whatever language you want, but it will need its own table in the DB.Users
User accounts consist of the following:
- account_id - Auto-incrementing ID, easy reference to the user, also the link to other tables
- username - self explanitory
- pass - MD5 hash stored password. Stored encrypted, one way so that no one can browse the DB and view the password. There's a password recovery system built in that takes care of that functionality.
- first_name - self explanitory
- last_name - self explanitory
- email - Email for mailings and things like password recovery
- country - self explanitory
- acct_type - right now denotes 1 for user, 3 for administrator
- status - unused
- joined - MySQL DateTime, useful for statistics
- last_login - MySQL DateTime, for future use of a number of things including increased security
- reset_request - when someone looses a password, this is set. Cannot change the password without this being set, so this provides further security. Please see lost pass section
The user is linked to a Preference item containing:
- preference_id - unique identifier for the record
- preferred_language - spanish or english. Sets what language the page is viewed in
- user_id - links to the user
Translation
Our translation is static, and written ahead of time. Things such as seminars are written in their native language and viewed thusly. Machine translation nis not an option due to the high ammount of inaccuracy, so authors will need to write in whatever language they want viewed. Also handy in that it allows greater targetting.
The translation system is based on mysql tables prefixed with lang_<tag> as described above. The format is Key => Entry. Key corresponds to a phrase token embedded in the site.
Hello world! becomes: print "$_SESSION[dictionary][hello]"; where hello is arbitrarily decided as the "key" for phrase "hello world."The system is a bit cumbersome, but it fits the site due to its heavily static content in terms of translation. New items can be added by doing a MySQL INSERT statement such as
INSERT INTO `lang_es` ( `key` , `string` ) VALUES ('test', 'test');. To use the dictionary bit just tap into the super-global $_SESSION[dictionary][test] (where test is the `key` attribute). Bear in mind however that the `key` field is the primary key for the record and there can be only one per database. This was intentional.Lost Password System
Because the passwords are encrypted for reasons of security, there needs to be a way to recover passwords. The work flow is like this narrative:
- User goes to forgotPass.php, fills out the form. Sets a flag on the user account that they requested a new password.
- User gets an email with a link, the link contains the MD5 of your current password. Why is this secure? because you cannot reverse the user's password from the MD5, and you can never enter the MD5 into the system. The system automatically MD5s all incoming passwords with PHP's MD5() function.
- Takes the user to the profile page where it makes sure that the MD5 in the browser's GET is equal to the one in the DB, then it allows you to input two matching new passwords in and you change your password. This will not work if the flag on the user account is not set. Changing your password successfully turns off the request flag as well.
- Then you log in with your new password
So, why not make it based on email? Wasn't sure if Martha wanted email addresses to be unique. It's easily changable though. The system is pretty solid overall, and hard to spoof. The only annoyance is possibly getting multiple emails by accident. Unfortunately, the software uses PHP's mail feature, but you can definately swap that code out if you want. In fact, that might indeed be better.
Databasing
Unfortunately the application uses MySQL. Why? More hosts host MySQL, and the class it was written for uses MySQL. Is it hard to port? Probably not, just edit db.inc.php, then edit all queries to be PG, or MSSQL or whatever DBMS you have. I don't think I used any MySQL specific bits, except for the news script (I used a LIMIT modifier).
Because the script was written for MySQL 3.23 it doesn't do any real RDBMS things like foreign keys (the SQLD was compiled without InnoDB anyway...). However, a lot of checking is in the scripting and you can't inject SQL in any place in particular so you should be relatively safe. I would suggest foreign keying it up if you can...
One last note on the DB - the seminaring uses support for UTF in a hackish sort of way. It takes the XML entities of foreign charsets and stores it that way. When it retrieves, it uses a PHP function to render the correct character. Instead of 1xChar you end up with 5-6xchar to store each character. They are text fields so you should be ok for up to 4MB of text. Sorry, this is a MySQL + PHP issue and it can't really be fixed. Get a better platform that supports UTF8...
In terms of the Autoinc IDs, they're set unsigned bigints. You should be OK as long as you have less than a *lot* of records. A solution is to switch to a multipart key.
Licensing and what it means to developers
We've chosen the GPL license (except for these documents... which are Creative Commons v2) of both our own volition and the request of our partner, ECIE.org. They didn't want commercial usage, but instead free (as in beer and liberty) usage of the software with open source and all that good jazz. That's fine by me because I don't want the software sold either. This software is written by and for NGOs, community building organizations and things of that nature. Besides, there are probably other pieces of software with more bells and whistles for money making types.
What does this mean to developers? You can edit this code, but you must distribute that modification as well as the original if asked. You must leave our names (Shea Kauffman and Greg Feigenson) on the code. You cannot sell this or use this as a commercial component AT ALL. I believe that you may be able to have these requirements waived by the authors as they own the copyrights but I'm not sure. Nor do I believe that you can obtain such a waiver from either authors. Sorry.
I think Blackboard and WebX should both provide comperable, commercially viable equivalents.
This page is CategoryInfoExchange