MailGust Hacking Notes
MailGust is a mass mailer application. It's a fairly complex program, but, that's part of what makes it interesting. It's not straightforward like most PHP scripts -- that is, it is programmed by people who like to program, and use potentially confusing techniques.
This document describes, in some detail, the process of adding a first name field to the Subscription class. The database has been altered so there's a TINYTEXT field named "name" in the maillist_subscription table.
The application is based around the framework in /gorum.
index.php brings together a few things, eventually loads gorum/init.php and that runs gorumMain().
Application related values are set in constants.php. The defaultMethod is "showhtmllist" and the defaultClass is "maillist". This means that the default thing you see is alist of maillists.
The application state is stored in the URL. The The 'method' parameter is used to set the 'method' property of the class. The class is extracted from the 'list' paramter. (Think of the list as a table in the database.)
Methods are switched via the allowedMethods array, defined in gorum/gorumlib.php and constants.php. The method name maps to some PHP code, and that code is "eval'd".
list=subscription_ok means that the Subscription class is instantiated. method=showhtmllist means the showhtmllist method is used. (In allowedMethods, showhtmllist maps to the code "$ret=$base->showHtmlList($s);"
showHtmlList() (defined in Object) calls loadHtmlList, which calls base->getListQuery(). That function generates a string that's used to call base->loadObjectSQL().
getListQuery() is defined in HtmlList.php. It calls base->getListSelect(), base->getOrderBy(), and base->getLimit(). The results of these are used to build up the query string.
getListOrderBy() and getLimit() are defined in the HtmlList class, and automatically write code to sort and show a range of data. They use cookies to store the current page state.
getListSelect() is defined in the base class. The query in there is altered so the "name" field is included in the query.
The array at the top of subscription.php is subscription_typ. This array is a description of the list "subscription" and describes both the table in the database, and the Subscription class in the application. This element is added to the array: "name"=>array( "type"=>"TINYTEXT", "length"=>64, "text", "list", "details"),
Note that there are more elements in the array than in the table. The listName element maps to the list name column in the web page this class helps generate. The value of that column is calculated within this class.
The table is rendered by showHtmlList(). It scans through the subscription_typ array, and some elements become columns in the table. Elements with values of "no column" and "form invisible" will not be shown. Others will be shown. (Note that this _typ array does not affect the query used to populate the table. This is set in getListSelect(). The query generated should return columns named to match the elements in the _typ array, however.)
The table headings are taken from the lang/lang_en.php file.
Alter the lang/lang_en.php file, adding this line:
$lll[["subscription_name"]]="Name";
The key is generated by concatenating the class name, _, and the element from _typ.
In gust, each class maps to a table in the database. The Import class maps to maillist_import in the db. This is unusual, because typical applications would not save the input into the import scripts. This is how gust does it.
Forms for Import are generated via the generForm() function in form.php. It's called by Object:generForm() method in the parent class for Import. generForm users the data in the _typ variable to generate the form.
Importation modifications are made to the Import class.
The Importation process is interesting. It saves the import data to the db. Then it parses it into TempImport. Then, these are moved over to Subscriptions. This last part is done via a cron, so it can be batched. Thus, a new "name" field needs to be added to TempImport to hold our additional data.
If you're having a hard time reading the code, processing it with [PHPDocumentor] might help.
