Example module.inc file
Every module you add to an ATK application follows some basic principles.
Create a directory, where the name is equal to the module name. For example, if you're going to create a module 'users', name the directory 'users'. It's best to place it in the modules/ subdir of your application.
In the directory, you place your node files. A module does not necessarily have to have any nodes, but most modules will consist of one or more nodes.
The module file is the most important part of the directory, as it will define the module. This file should be called 'module.inc' and should contain the following code:
<?php
class mod_users extends atkModule
{
function getNodes()
{
registerNode("users.group", array("admin", "add", "edit", "delete"));
}
function getMenuItems()
{
$this->menuitem("groupadmin", dispatch_url("users.group", "admin"));
}
}
?>
registerNode()
The registerNode() function call lets the access control components of ATK know what nodes exist, and what actions can be performed on those nodes. Without explicitly adding nodes and actions, there is no way for any user (other than the administrator) to perform actions on nodes or even--in many cases--to see that an action (link) is even available. Note that registerNode() does not determine who gets to do what; only which actions are available. (Who gets to do what is controlled by ATK's group management interface, and stored in the access table in the database.)
registerNode() has two arguments: a node name (string) and an array of actions:
registerNode("user.student", array("admin", "add", "edit", "delete"));
This tells ATK that the "admin", "add", "edit" and "delete" actions are valid operations to perform on a "user.student" node.
(Note that removing registerNode() calls from module.inc does not disable those actions! It seems that the algorithm to figure out who gets to do what is something like: (1) use reflection to figure out what actions are possible; (2) look through the access table to see if the current user (via their group) is allowed to perform the action. i.e. registerNode() determines which actions are displayed by the admin interface, but not which actions are possible. Another implication of this approach is that actions must be removed from both registerNode() and the access table for them to be completely removed from the application. [Text should be cleaned up, integrated into the description above.])
menuitem()
This function takes several parameters, many of which are optional:
- The name of the menuitem. This string is transformed slightly for display--in the case below, the user will see "User management", not "user_management".
- The URL that should displayed when the user clicks the menu item. This can be any URL, though it's typically one generated by dispatch_url.
- The third parameter, $parent, determines whether the menu item is a first- or second-level menu item. If $parent is absent or equal to the string "main", the menu item appears at the top level. If $parent is a string, then the menu item appears as a sub-menu of the named menu item.
- The fourth parameter controls menu item visibility. (i.e. who can see the menu item--though note that access control is done separately! It's possible to be able to see a menu item, though not be able to access the page it links to.) This parameter can be either a boolean or an array.
- boolean - If true, then the menu item is always displayed; if false it's never displayed.
- array - The first element of the array must be a node (identified by modulename.nodename notation), the second element is an action. The third can be a node again, the fourth an action, and so on. If the user has the right to perform one of these actions, he will see the menu-item. In this case, the menu is displayed if the user has the ‘admin’ right on the 'users.group' node.
Example:
function getMenuItems()
{
$this->menuitem("user_management", dispatch_url("users.group", "admin"), "main", array("users.group", "admin"));
}