It is well-known that programmers are lazy people. Thanks to this fact a lot of good stuff are written. The same is the story with DList. It starts on one sunny day near the old office of AIP Solutions. The server-side team of the company, represented by Me and Mr. Marin Todorov, decided to have a lunch in the restaurant near the office. We was outside and the weather was so pleasant so we decided that it will be one very very long lunch. But we needed an excuse. Our idea was to say our colleagues that we had done some work. So we took a couple of napkins and started our software design work.
Ok I finished the introduction. So I’ll try to explain something about DList.
After we analysed our server-side programming work. We found that all the time we do the same. We add, edit and remove some items in database tables. Then we retrieve the content of those tables. So we decided to create a generic class which will implement all the stuff we need. It’s called DList (DataList). DList is an abstraction for list with items. The constructor of the class takes an object as an argument. The type of this object is “DListConf” (DList Configuration) or also known as DLC. The DLC object contains all the information DList needs to know about the table in database, which DList have to manage. After DList class is instantiated we have an object which implements so called DList interface. That means the object has this list of methods:
DList|array static DList::Make('DLC Name [,DLC name1 ...]')
void DList::setOrderMethod($orderString);
void DList::setFilter($filterString);
void DList::setPaging($pagingObject);
array DList::add($info)
void DList::edit($Id, $info)
bool DList::remove($Id)
array DList::getInfo($Id, $langId)
array DList::getList($langId)
array DList::getFullList($langId)
int DList::getCount()
When we have this methods we can do most ot our work without writing SQL queries. So this class provide some kind of database abstraction layer. It increases the level of predictability of the code written from any member of our team. And one very important thing, it saves time, a lot of time. Of course I’m not saying that everyting could be done with DList, but it does very good work in most of the cases.
DList usage
There are two ways for creating instance of DList. The classic approach with new keyword in PHP.
$products = new DList($productsDLC);
In this case $productsDLC is our DList Configuration object and $products is the DList object.
If we need more DList objects, we can use the Make static method.
list($products, $categories, $news) = DList::Make('productsDLC, categoriesDLC, newsDLC');
In this example I use the Make method to create three DList objects at once. This method returns an array with DList objects inside. Make method has an other very useful feature, it automatically includes the files with DLC definitions. This files should be in aip.conf folder and its names should be like in this example: productsDLC.php, categoriesDLC.php, newsDLC.php.
Before I continue with DList features I’d like to write something more about DListConf or DLC. It is very important, because withour properly configured DLC you won’t have an operational DList object. DListConf is configuration container. Our convention is make DLC objects in files with the same name. For example:
$productsDLC = DListConf('productsList');
We create object called $productsDLC in a file called productsDLC.php. This is not required, but it makes things easy and clear and for the staff of AIP Solutions it is obligatory. Also this convention is required for static method Make(). The constructor of DListConf takes only one argument and it should be the name of the table in database, which Dlist should manage. This is an example of a real DLC file - productsDLC.php:
$productsDLC = new DListConf('productsList'); /* name of the table */
$productsDLC->setLangCount(2); /* default:1 */
$productsDLC->setTextKey('name'); /* default:name */
$productsDLC->setLangKey('langId'); /* default:langId, false for none */
$productsDLC->setParentKey('parentId'); /* default:parentId, false for none */
$productsDLC->setOrderMethod('orderId ASC'); /* default:Id ASC */
$productsDLC->addField('parentId', 'int');
$productsDLC->addField('imageId', 'int');
$productsDLC->addField('price', 'price'); /* in DList we have standard datatype 'price' */
$productsDLC->addField('descr', 'rtf');
$productsDLC->addField('abstract', 'rtf');
$productsDLC->addField('orderId', 'int');
The first method in this example is setLangCount(int $languageCount);. We use this method to tell to DList that the data it will manage will be translated in 2 languages. In this case DList knows that for each item added to the table it has to make 2 records - one record for each language. In other words if you add 1 product into the database and you have setLangCount(2); in you $productsDLC, DList will insert 2 rows in productsList table.
The next method is setTextKey(string $fieldName). This tells which field in the table can be defined as a “name” of the items saved in this table. In our case with productsList table we use the filed name, which is the name of the product. This parameter is used in DList::getList() method, which will be discussed later.
The other main method is setLangKey(string fieldName). It shows which field in DB table should be used for storing the language ID of each record. So in our example this is langId field. Which means that if we add 1 product to the database DList will make 1 record with langId = 1 and 1 record with langId = 2.
The method setParentKey(string fieldName) also takes the name of a field in DB table as an argument. This field should be used when we need parent-child relation between two tables managed by DList. An example for this case is when we have products, which are grouped in different categories. So in products we make DB table field called parentId and use setParentKey('parentId').Then when we have to add product we have to write its parent category ID in this field.
Method called setOrderMethod(string $orderSqlString) is used to set the default order of items recorded in the table. The parameter which method takes is the ORDER BY clause in SQL. But without ORDER BY at the begging. For example: name ASC. In this case when we retrieve a list of items from the table using DList::getList() or DList::getFullList() methods, the result will be ordered by product name in ascending sort.
The last method in our example is addField(string $fieldName, string $dataType). We use this method for describing the fields in the table. Every field (well,there are some exceptions) in the DB table should be defined with this method. The first argument is the name of the field and the second argument is its data type. In fact we don’t use the standard data types in SQL. Dlist uses the following data types:
int, string, rtf, file, date, price, enum.
int type is for integer data - numbers
string is used for strings. it is important that DList perform some operations on data defined as a string. It replaces the quotes and slashes with its HTML codes.
rtf is like a string but DList doesn’t make any changes on the strings. It should be used for textareas with rich text formatted texts.
file - this data type should be used when the information is file name.
date - data type for storing dates.
price - store decimal prices with this data type.
price - it should be used for enum MySQL fields.
The fields that should not be defined with addField(string $fieldName, string $dataType) method are fields defined as an Text Key and Language Key with setTextKey() and setLangKey() methods. In our example this are name and langId fields. In fact if some field is not defined in the DLC, Dlist will work well, but this field will stay “invisible” for the object. You will not be able to add, edit or even read the information in this field.