# Module HowTo - Self-service

Self-service is a LAM Pro feature. It allows your users to manage their own data (e.g. telephone numbers).
First you need to implement the function getSelfServiceFields() or use meta['selfServiceFieldSettings']. Each field has an ID and a descriptive name that will be displayed on the self service page.
Your input fields may also be defined as read-only in the self-service profile editor. If your fields supports read-only then use canSelfServiceFieldBeReadOnly() or meta['selfServiceReadOnlyFields'].
Example:
The inetOrgPerson module provides lots of possible input fields for the self-service.

/**
* Returns meta data that is interpreted by parent class
*
* @return array array with meta data
*/
function get_metaData() {
$return = array();
$return['selfServiceFieldSettings'] = array('firstName' => _('First name'), 'lastName' => _('Last name'),
'mail' => _('Email address'), 'telephoneNumber' => _('Telephone number'), 'mobile' => _('Mobile number'),
'faxNumber' => _('Fax number'), 'street' => _('Street'), 'postalAddress' => _('Postal address'), 'registeredAddress' => _('Registered address'),
'postalCode' => _('Postal code'), 'postOfficeBox' => _('Post office box'), 'jpegPhoto' => _('Photo'),
'homePhone' => _('Home telephone number'), 'roomNumber' => _('Room number'), 'carLicense' => _('Car license'),
'location' => _('Location'), 'state' => _('State'), 'officeName' => _('Office name'), 'businessCategory' => _('Business category'),
'departmentNumber' => _('Department'), 'initials' => _('Initials'), 'title' => _('Job title'), 'labeledURI' => _('Web site'),
'userCertificate' => _('User certificates'));
// possible self-service read-only fields
$return['selfServiceReadOnlyFields'] = array('firstName', 'lastName', 'mail', 'telephoneNumber', 'mobile', 'faxNumber', 'street',
'postalAddress', 'registeredAddress', 'postalCode', 'postOfficeBox', 'jpegPhoto', 'homePhone', 'roomNumber', 'carLicense',
'location', 'state', 'officeName', 'businessCategory', 'departmentNumber', 'initials', 'title', 'labeledURI', 'userCertificate');
[...]

In very rare cases you need to specify self-service search attributes. These are used to identify the user inside LDAP. Common examples are "uid" or "mail".
Example:
The inetOrgPerson module specifies several search attributes.

/** * Returns meta data that is interpreted by parent class * * @return array array with meta data */ function get_metaData() { $return = array(); // self-service search attributes $return['selfServiceSearchAttributes'] = array('uid', 'mail', 'cn', 'surname', 'givenName', 'employeeNumber'); [...]

The HTML code for the user page is generated with the function getSelfServiceOptions(). It returns one table row for each input field.
Please note that some fields may be defined as read-only ($readOnlyFields). If $passwordChangeOnly is set then no input fields other than the bind password should be displayed (you will not get any attribute values).
Example:
The windowsUser module uses the addSimpleSelfServiceTextField() function from baseModule to print the text field. You may also build the table row yourself if the input field is more complex.

/**
* Returns the meta HTML code for each input field.
* format: array(<field1> => array(<META HTML>), ...)
* It is not possible to display help links.
*
* @param array $fields list of active fields
* @param array $attributes attributes of LDAP account
* @param boolean $passwordChangeOnly indicates that the user is only allowed to change his password and no LDAP content is readable
* @param array $readOnlyFields list of read-only fields
* @return array list of meta HTML elements (field name => htmlTableRow)
*/
function getSelfServiceOptions($fields, $attributes, $passwordChangeOnly, $readOnlyFields) {
$return = array();
if ($passwordChangeOnly) {
return $return; // only password fields as long no LDAP content can be read
}
$this->addSimpleSelfServiceTextField($return, 'physicalDeliveryOfficeName', _('Office name'), $fields, $attributes, $readOnlyFields);
[...]

Of course, the user input should also be validated before making any LDAP changes. This is done in checkSelfServiceOptions().
The return value includes any error messages to display and also all LDAP operations.
Please note that some fields may be defined as read-only ($readOnlyFields). If $passwordChangeOnly is set then no input fields other than the bind password should be displayed (you will not get any attribute values).
Example:
The inetOrgPerson module has a field for the user's first name.

/**
* Checks if all input values are correct and returns the LDAP attributes which should be changed.
* <br>Return values:
* <br>messages: array of parameters to create status messages
* <br>add: array of attributes to add
* <br>del: array of attributes to remove
* <br>mod: array of attributes to modify
* <br>info: array of values with informational value (e.g. to be used later by pre/postModify actions)
*
* Calling this method does not require the existence of an enclosing {@link accountContainer}.
*
* @param string $fields input fields
* @param array $attributes LDAP attributes
* @param boolean $passwordChangeOnly indicates that the user is only allowed to change his password and no LDAP content is readable
* @param array $readOnlyFields list of read-only fields
* @return array messages and attributes (array('messages' => array(), 'add' => array('mail' => array('test@test.com')), 'del' => array(), 'mod' => array(), 'info' => array()))
*/
function checkSelfServiceOptions($fields, $attributes, $passwordChangeOnly, $readOnlyFields) {
$return = array('messages' => array(), 'add' => array(), 'del' => array(), 'mod' => array(), 'info' => array());
if ($passwordChangeOnly) {
return $return; // skip processing if only a password change is done
}
$attributeNames = array(); // list of attributes which should be checked for modification
$attributesNew = $attributes;
// first name
if (in_array('firstName', $fields) && !in_array('firstName', $readOnlyFields)) {
$attributeNames[] = 'givenName';
if (isset($_POST['inetOrgPerson_firstName']) && ($_POST['inetOrgPerson_firstName'] != '')) {
if (!get_preg($_POST['inetOrgPerson_firstName'], 'realname')) $return['messages'][] = $this->messages['givenName'][0];
else $attributesNew['givenName'][0] = $_POST['inetOrgPerson_firstName'];
}
elseif (isset($attributes['givenName'])) unset($attributesNew['givenName']);
}
[...]

The self-service also supports configuration settings for each module. See getSelfServiceSettings() or meta['selfServiceSettings'] to specify the options.
You can validate the input with checkSelfServiceSettings().
Self-service configuration settings are displayed on a separate tab in the self-service profile editor.

##