We have already introduced our new box system that will ship with WoltLab Suite Core 3.0. There, we have mentioned the system box type that allows dynamic box contents like a list of threads from a specific forum. In this post, we will show developers how to easily incorporate such a box controller into their packages.
The PHP class that is of interest for us in this case is wcf\system\box\AbstractDatabaseObjectListBoxController which already provides some common features of boxes displaying objects fetched via a wcf\data\DatabaseObjectList object. Otherwise, there is also the more general class wcf\system\box\AbstractBoxController which only provides a default implementation of the necessary wcf\system\box\IBoxController interface.
In the following, we will explain the different built-in possibilities of the AbstractDatabaseObjectListBoxController class.
Providing the Object List
One of two abstract methods of the AbstractDatabaseObjectListBoxController class is AbstractDatabaseObjectListBoxController::getObjectList() which needs to return a DatabaseObjectList object (whose objects have not already been read). If you want to display app\data\foo\Foo objects, you might want to create the following class:
(Please note that we will not show any imports or comments to keep the sample code short and focused on the main parts.)
Showing the Box Content
The second method you have to implement is AbstractDatabaseObjectListBoxController::getTemplate() which returns the box contents:
In this example, we have used some additional code to use a different template if the box is shown in a sidebar rather than elsewhere. To indicate which positions your box controller supports, you have to set the static property AbstractBoxController::$supportedPositions:
The available positions have already been shown in the introduction of the box system.
If you have a list of objects, you might want the administrator to set how they are ordered when fetched from database, i.e. the administrator should be able to set the sort field and sort order. There are basically only two things to need to do: Specify an array of possible sort fields in AbstractDatabaseObjectListBoxController::$validSortFields and set AbstractDatabaseObjectListBoxController::$sortFieldLanguageItemPrefix which is used for showing proper texts in the sort field selection.
Our example now looks like this:
Here you would allows sorting by the database table column subject, username and time and due to the value of AbstractDatabaseObjectListBoxController::$sortFieldLanguageItemPrefix, the system expects the language items app.foo.sortField.subject, app.foo.sortField.username and app.foo.sortField.time.
Number of Objects
In many cases, you do not want to display all objects that are saved in the database table as that would result in a list of hundreds or thousands of list items but rather set a limit. You can easily enable this option by setting the value of AbstractDatabaseObjectListBoxController::$defaultLimit to a positive value. When creating a new box, this value will be shown to the administrator, as the name of the property implies, as the default value. Additionally, you may also specify a minimum and maximum number of objects that the administrator can set by setting the values of the properties AbstractDatabaseObjectListBoxController::$minimumLimit and AbstractDatabaseObjectListBoxController::$maximumLimit.
Let us continue our example from above and assume that we want the default limit to be 5 and only allow the administrator to set a maximum number of 25:
Since WCF 2.1, we provide a powerful condition system that can be used in multiple locations and can work with DatabaseObjectList objects so that it is also perfectly suited to be used for boxes. To tell the system that the box supports conditions, you only need to set the value AbstractDatabaseObjectListBoxController::$conditionDefinition to the name of the condition object type definition for the box. (Please note that the condition object type processors need to implement wcf\system\condition\IObjectListCondition).
If you have already implemented conditions for your objects and implemented IObjectListCondition, you only create object types for you box condition object type definition and you are done.
If you want to deliver default boxes with preset conditions, you can use the wcf\system\box\BoxHandler::createBoxCondition() method in your package installation script to quickly set up these conditions.