1. Loading the LDAP attributes
Every time the user selects an existing account to modify LAM will load
the complete LDAP entry of it. Your module then should select the
attributes which are useful for it.
There are two variables in
baseModule
which should be used to store the attributes. The
$attributes variable stores the
current attributes including changes the user made. The
$orig variable stores the attributes
as they were originally when the account was loaded. This allows you to
see what changes were made.
The
load_attributes() function
in your module gets the complete attribute list from LDAP.
In most cases you will not need to implement this function because the
parent class baseModule loads attributes based on your meta data.
Example:
The
ieee802Device uses an
object class and the
'macAddress'
attribute. Therefore we will save these two values.
* This function loads all needed attributes into the
object.
*
* @param array $attr an array as it is returned from
ldap_get_attributes
*/
function load_attributes($attr) {
$this->attributes['objectClass'] = array();
$this->attributes['macAddress'] = array();
$this->orig['objectClass'] =
array();
$this->orig['macAddress'] =
array();
if (isset($attr['objectClass'])) {
$this->attributes['objectClass'] = $attr['objectClass'];
$this->orig['objectClass'] = $attr['objectClass'];
}
if (isset($attr['macAddress'])) {
$this->attributes['macAddress'] = $attr['macAddress'];
$this->orig['macAddress'] = $attr['macAddress'];
}
return 0;
}
2. Page display
Now that you have defined your subpages you will need one function for
each page to display it. The function must return
meta HTML code as defined in the
modules specification.
This function is called
display_html_<page
name>() where
<page
name> is the name of your subpage.
See also baseModule::addSimpleInputTextField() and
baseModule::addMultiValueInputTextField()/processMultiValueInputTextField()
if you only want to add some simple text fields.
Example:
The
ieee802Device
module has only one subpage called
'attributes'.
The first half of the code displays the existing MAC addresses and the
second an input field for new values.
The variable
$this->attributes
contains the LDAP attributes which are useful for this module.
* This function will create the meta HTML code to
show a page with all attributes.
*
* @return htmlElement HTML meta data
*/
function display_html_attributes() {
$return = new htmlTable();
$macCount = 0;
// list current MACs
if (isset($this->attributes['macAddress'])) {
$macCount = sizeof($this->attributes['macAddress']);
for ($i = 0;
$i < sizeof($this->attributes['macAddress']); $i++) {
$return->addElement(new htmlOutputText(_('MAC
address')));
$macInput = new htmlInputField('macAddress' . $i,
$this->attributes['macAddress'][$i]);
$macInput->setFieldSize(17);
$macInput->setFieldMaxLength(17);
$return->addElement($macInput);
$return->addElement(new htmlButton('delMAC' . $i,
'del.png', true));
$return->addElement(new htmlHelpLink('mac'),
true);
}
}
// input box for new MAC
$return->addElement(new htmlOutputText(_('New MAC address')));
$newMacInput = new htmlInputField('macAddress', '');
$newMacInput->setFieldSize(17);
$newMacInput->setFieldMaxLength(17);
$return->addElement($newMacInput);
$return->addElement(new htmlButton('addMAC', 'add.png', true));
$return->addElement(new htmlHelpLink('mac'));
$return->addElement(new htmlHiddenInput('mac_number', $macCount));
return $return;
}
3. Processing input data
Every time the user clicks on a submit button while your page is
displayed LAM will call a function in your module.
This function is called
process_<page
name>() where
<page
name> is the name of your subpage.
If all input data is ok then return an empty array. If you return one or more error messages then the user will be
redirected to your page.
Example:
The
ieee802Device
module has only one subpage called
'attributes'
and therefore only
process_attributes().
The function checks the input fields and fills the LDAP attributes. If
all is ok it will enable the user to move to another module page.
* Write variables into object and do some regex
checks
*
* @param array $post HTTP-POST values
*/
function process_attributes($post) {
$errors = array();
$this->attributes['macAddress'] = array();
// check old MACs
if (isset($post['mac_number'])) {
for ($i = 0;
$i < $post['mac_number']; $i++) {
if (isset($post['delMAC' . $i])) continue;
if (isset($post['macAddress' . $i]) &&
($post['macAddress' . $i] != "")) {
// check if address has correct
format
if (!get_preg($post['macAddress'
. $i], 'macAddress')) {
$message =
$this->messages['mac'][0];
$message[] =
$post['macAddress' . $i];
$errors[] = $message;
}
$this->attributes['macAddress'][] = $post['macAddress' . $i];
}
}
}
// check new MAC
if (isset($post['macAddress'])
&& ($post['macAddress'] != "")) {
// check if
address has correct format
if
(get_preg($post['macAddress'], 'macAddress')) {
$this->attributes['macAddress'][] =
$post['macAddress'];
}
else {
$message =
$this->messages['mac'][0];
$message[] = $post['macAddress'];
$errors[] = $message;
}
}
$this->attributes['macAddress'] =
array_unique($this->attributes['macAddress']);
return $errors;
}
4. Defining that your module is ready for user input and LDAP
add/modify
In most cases you will not need to implement these functions. The
baseModule will return
true for both functions.
There are two functions which control the module status:
The
module_ready() function
has to
return
true if the user may
move to your module page. If it is
false
the user will be shown an error message that your module is not yet
ready. You can use this if your module depends on input data from other
modules (e.g. you need the user name from posixAccount first).
The second function is
module_complete(). The user
cannot do the LDAP operation if one or more modules return
false. This defines if all needed
input data for your module was entered.
Use this function if you want to check that all required attributes are
set.
Example:
The
sambaSamAccount
module needs the user's
uidNumber
and
gidNumber before it can
accept input and the account needs a
sambaSID
before it can be saved.
* This function is used to check if this module page
can be displayed.
* It returns false if a module depends on data from
other modules which was not yet entered.
*
* @return boolean true, if page can be displayed
*/
function module_ready() {
if
($_SESSION[$this->base]->module['posixAccount']->attributes['gidNumber'][0]=='')
return false;
if
($_SESSION[$this->base]->module['posixAccount']->attributes['uidNumber'][0]=='')
return false;
if
($this->attributes['uid'][0]=='') return false;
return true;
}
/**
* This functions is used to check if all settings
for this module have been made.
*
* @return boolean true, if settings are complete
*/
function module_complete() {
if (!$this->module_ready())
return false;
if
($this->attributes['sambaSID'][0] == '') return false;
return true;
}
5. Saving the LDAP attributes
In most cases you will not have to implement this option if you use
$this->attributes and
$this->orig to manage the LDAP
attributes. The
baseModule
will generate the save commands for you.
When all modules report that they are ready for LDAP add/modify and the
user clicks on the add/modify button your module will be asked what
changes have to be made.
This is done in the function
save_attributes().
Example:
The
kolabUser module uses
this function to make sure that its object class is saved. Other
modules (e.g. quota) use it build the lamdaemon commands.
* Returns a list of modifications which have to be
made to the LDAP account.
*
* @return array list of modifications
* <br>This function returns an array with 3
entries:
* <br>array( DN1 ('add' => array($attr),
'remove' => array($attr), 'modify' => array($attr)), DN2 .... )
* <br>DN is the DN to change. It may be
possible to change several DNs (e.g. create a new user and add him to
some groups via attribute memberUid)
* <br>"add" are attributes which have to be
added to LDAP entry
* <br>"remove" are attributes which have to be
removed from LDAP entry
* <br>"modify" are attributes which have to
been modified in LDAP entry
*/
function save_attributes() {
// add object class if needed
if
(!isset($this->attributes['objectClass']) ||
!in_array('kolabInetOrgPerson', $this->attributes['objectClass'])) {
$this->attributes['objectClass'][] = 'kolabInetOrgPerson';
}
return parent::save_attributes();
}