465 lines
20 KiB
HTML
465 lines
20 KiB
HTML
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||
|
<html>
|
||
|
<head>
|
||
|
<title>Module HowTo - Account pages</title>
|
||
|
<link rel="stylesheet" type="text/css" href="style/layout.css">
|
||
|
</head>
|
||
|
<body>
|
||
|
|
||
|
<p align="center">
|
||
|
<script type="text/javascript"><!--
|
||
|
google_ad_client = "pub-4179059556107138";
|
||
|
google_alternate_ad_url = "http://lam.sourceforge.net/google_adsense_script.html";
|
||
|
google_ad_width = 728;
|
||
|
google_ad_height = 90;
|
||
|
google_ad_format = "728x90_as";
|
||
|
google_ad_type = "text_image";
|
||
|
google_ad_channel ="";
|
||
|
google_page_url = document.location;
|
||
|
google_color_border = "EEEEEE";
|
||
|
google_color_bg = "FFFFFF";
|
||
|
google_color_link = "0000FF";
|
||
|
google_color_url = "008000";
|
||
|
google_color_text = "000000";
|
||
|
//--></script>
|
||
|
<script type="text/javascript"
|
||
|
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
||
|
</script>
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<div style="text-align: center;">
|
||
|
<h1>Module HowTo - Account pages<br>
|
||
|
</h1>
|
||
|
<br>
|
||
|
<br>
|
||
|
<div style="text-align: left;"><br>
|
||
|
<h2>1. Loading the LDAP attributes<br>
|
||
|
</h2>
|
||
|
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.<br>
|
||
|
There are two variables in <span style="font-style: italic;">baseModule</span>
|
||
|
which should be used to store the attributes. The <span
|
||
|
style="font-weight: bold;">$attributes</span> variable stores the
|
||
|
current attributes including changes the user made. The <span
|
||
|
style="font-weight: bold;">$orig</span> variable stores the attributes
|
||
|
as they were originally when the account was loaded. This allows you to
|
||
|
see what changes were made.<br>
|
||
|
<br>
|
||
|
The <span style="font-weight: bold;">load_attributes()</span> function
|
||
|
in your module gets the complete attribute list from LDAP.<br>
|
||
|
<br>
|
||
|
<span style="font-weight: bold; text-decoration: underline;">Example:</span><br
|
||
|
style="font-weight: bold; text-decoration: underline;">
|
||
|
<br>
|
||
|
The <span style="font-style: italic;">ieee802Device</span> uses an
|
||
|
object class and the <span style="font-style: italic;">'macAddress'</span>
|
||
|
attribute. Therefore we will save this two values.<br>
|
||
|
<br>
|
||
|
<table style="width: 100%; text-align: left;" class="mod-code"
|
||
|
border="0" cellpadding="2" cellspacing="2">
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td style="vertical-align: top;"> /**<br>
|
||
|
* This function loads all needed attributes into the
|
||
|
object.<br>
|
||
|
*<br>
|
||
|
* @param array $attr an array as it is retured from
|
||
|
ldap_get_attributes<br>
|
||
|
*/<br>
|
||
|
<span style="font-weight: bold;">function</span> <span
|
||
|
style="color: rgb(255, 0, 0);">load_attributes</span>($attr) {<br>
|
||
|
|
||
|
$this->attributes['objectClass'] = array();<br>
|
||
|
|
||
|
$this->attributes['macAddress'] = array();<br>
|
||
|
$this->orig['objectClass'] =
|
||
|
array();<br>
|
||
|
$this->orig['macAddress'] =
|
||
|
array();<br>
|
||
|
if (isset($attr['objectClass'])) {<br>
|
||
|
|
||
|
unset($attr['objectClass']['count']);<br>
|
||
|
|
||
|
$this->attributes['objectClass'] = $attr['objectClass'];<br>
|
||
|
|
||
|
$this->orig['objectClass'] = $attr['objectClass'];<br>
|
||
|
}<br>
|
||
|
if (isset($attr['macAddress'])) {<br>
|
||
|
|
||
|
unset($attr['macAddress']['count']);<br>
|
||
|
|
||
|
$this->attributes['macAddress'] = $attr['macAddress'];<br>
|
||
|
|
||
|
$this->orig['macAddress'] = $attr['macAddress'];<br>
|
||
|
}<br>
|
||
|
return 0;<br>
|
||
|
}<br>
|
||
|
</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<br>
|
||
|
<br>
|
||
|
<h2>2. Page display</h2>
|
||
|
Now that you have defined your subpages you will need one function for
|
||
|
each page to display it. The function must return <span
|
||
|
style="font-style: italic;">meta HTML code</span> as defined in the <span
|
||
|
style="font-style: italic;">modules specification</span>.<br>
|
||
|
This function is called <span style="font-weight: bold;">display_html_<page
|
||
|
name>()</span> where <span style="font-style: italic;"><page
|
||
|
name></span> is the name of your subpage.<br>
|
||
|
<br>
|
||
|
<span style="font-weight: bold; text-decoration: underline;">Example:</span><br
|
||
|
style="font-weight: bold; text-decoration: underline;">
|
||
|
<br>
|
||
|
The
|
||
|
<span style="font-style: italic;">ieee802Device</span>
|
||
|
module has only one subpage called <span style="font-style: italic;">'attributes'</span>.<br>
|
||
|
<br>
|
||
|
The first half of the code displays the existing MAC addresses and the
|
||
|
second an input field for new values.<br>
|
||
|
The variable <span style="font-style: italic;">$this->attributes</span>
|
||
|
contains the LDAP attributes which are useful for this module.<br>
|
||
|
<br>
|
||
|
<table style="width: 100%; text-align: left;" class="mod-code"
|
||
|
border="0" cellpadding="2" cellspacing="2">
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td style="vertical-align: top;"> /**<br>
|
||
|
* This function will create the meta HTML code to
|
||
|
show a page with all attributes.<br>
|
||
|
*<br>
|
||
|
* @param array $post HTTP-POST values<br>
|
||
|
*/<br>
|
||
|
<span style="font-weight: bold;">function</span> <span
|
||
|
style="color: rgb(255, 0, 0);">display_html_attributes</span>($post) {<br>
|
||
|
$return = array();<br>
|
||
|
// list current MACs<br>
|
||
|
for ($i = 0; $i <
|
||
|
sizeof($this->attributes['macAddress']); $i++) {<br>
|
||
|
$return[] =
|
||
|
array(<br>
|
||
|
|
||
|
0 => array('kind' => 'text', 'text' =>
|
||
|
_('MAC address')),<br>
|
||
|
|
||
|
1 => array('kind' => 'input', 'name' =>
|
||
|
'macAddress' . $i, 'type' => 'text', 'size' => '17', 'maxlength'
|
||
|
=> '17', 'value' => $this->attributes['macAddress'][$i]),<br>
|
||
|
|
||
|
2 => array('kind' => 'input', 'type' =>
|
||
|
'submit', 'name' => 'delMAC' . $i, 'value' => _("Remove")),<br>
|
||
|
|
||
|
3 => array('kind' => 'help', 'value' =>
|
||
|
'mac'));<br>
|
||
|
}<br>
|
||
|
// input box for new MAC<br>
|
||
|
$return[] = array(<br>
|
||
|
0 =>
|
||
|
array('kind' => 'text', 'text' => _('New MAC address')),<br>
|
||
|
1 =>
|
||
|
array('kind' => 'input', 'name' => 'macAddress', 'type' =>
|
||
|
'text', 'size' => '17', 'maxlength' => '17', 'value' => ''),<br>
|
||
|
2 =>
|
||
|
array('kind' => 'input', 'type' => 'submit', 'name' =>
|
||
|
'addMAC', 'value' => _("Add")),<br>
|
||
|
3 =>
|
||
|
array('kind' => 'help', 'value' => 'mac'),<br>
|
||
|
4 =>
|
||
|
array('kind' => 'input', 'type' => 'hidden', 'value' =>
|
||
|
sizeof($this->attributes['macAddress']), 'name' => 'mac_number'));<br>
|
||
|
return $return;<br>
|
||
|
}<br>
|
||
|
</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<br>
|
||
|
<br>
|
||
|
<h2>3. Processing input data<br>
|
||
|
</h2>
|
||
|
Every time the user clicks on a submit button while your page is
|
||
|
displayed LAM will call a function in your module.<br>
|
||
|
This function is called <span style="font-weight: bold;">process_<page
|
||
|
name>()</span> where <span style="font-style: italic;"><page
|
||
|
name></span> is the name of your subpage.<br>
|
||
|
<br>
|
||
|
If all input data is ok then return "0" or an array containing no error
|
||
|
message. If you return one or more error messages then the user will be
|
||
|
redirected to your page.<br>
|
||
|
<br>
|
||
|
<span style="font-weight: bold; text-decoration: underline;">Example:</span><br
|
||
|
style="font-weight: bold; text-decoration: underline;">
|
||
|
<br>
|
||
|
The
|
||
|
<span style="font-style: italic;">ieee802Device</span>
|
||
|
module has only one subpage called <span style="font-style: italic;">'attributes'</span>
|
||
|
and therefore only <span style="font-style: italic;">process_attributes()</span>.<br>
|
||
|
<br>
|
||
|
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.<br>
|
||
|
<br>
|
||
|
<table style="width: 100%; text-align: left;" class="mod-code"
|
||
|
border="0" cellpadding="2" cellspacing="2">
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td style="vertical-align: top;"> /**<br>
|
||
|
* Write variables into object and do some regex
|
||
|
checks<br>
|
||
|
*<br>
|
||
|
* @param array $post HTTP-POST values<br>
|
||
|
*/<br>
|
||
|
<span style="font-weight: bold;">function</span> <span
|
||
|
style="color: rgb(255, 0, 0);">process_attributes</span>($post) {<br>
|
||
|
$this->triggered_messages =
|
||
|
array();<br>
|
||
|
|
||
|
$this->attributes['macAddress'] = array();<br>
|
||
|
// check old MACs<br>
|
||
|
if (isset($post['mac_number'])) {<br>
|
||
|
for ($i = 0;
|
||
|
$i < $post['mac_number']; $i++) {<br>
|
||
|
|
||
|
if (isset($post['delMAC' . $i])) continue;<br>
|
||
|
|
||
|
if (isset($post['macAddress' . $i]) &&
|
||
|
($post['macAddress' . $i] != "")) {<br>
|
||
|
|
||
|
// check if address has correct
|
||
|
format<br>
|
||
|
|
||
|
if (!get_preg($post['macAddress'
|
||
|
. $i], 'macAddress')) {<br>
|
||
|
|
||
|
$message =
|
||
|
$this->messages['mac'][0];<br>
|
||
|
|
||
|
$message[] =
|
||
|
$post['macAddress' . $i];<br>
|
||
|
|
||
|
|
||
|
$this->triggered_messages[] = array($message);<br>
|
||
|
|
||
|
}<br>
|
||
|
|
||
|
|
||
|
$this->attributes['macAddress'][] = $post['macAddress' . $i];<br>
|
||
|
|
||
|
}<br>
|
||
|
}<br>
|
||
|
}<br>
|
||
|
// check new MAC<br>
|
||
|
if (isset($post['macAddress'])
|
||
|
&& ($post['macAddress'] != "")) {<br>
|
||
|
// check if
|
||
|
address has correct format<br>
|
||
|
if
|
||
|
(get_preg($post['macAddress'], 'macAddress')) {<br>
|
||
|
|
||
|
$this->attributes['macAddress'][] =
|
||
|
$post['macAddress'];<br>
|
||
|
}<br>
|
||
|
else {<br>
|
||
|
|
||
|
$message =
|
||
|
$this->messages['mac'][0];<br>
|
||
|
|
||
|
$message[] = $post['macAddress'];<br>
|
||
|
|
||
|
$this->triggered_messages[] =
|
||
|
array($message);<br>
|
||
|
}<br>
|
||
|
}<br>
|
||
|
|
||
|
$this->attributes['macAddress'] =
|
||
|
array_unique($this->attributes['macAddress']);<br>
|
||
|
if
|
||
|
(sizeof($this->triggered_messages) > 0) {<br>
|
||
|
|
||
|
$this->inputCorrect = false;<br>
|
||
|
return
|
||
|
$this->triggered_messages;<br>
|
||
|
}<br>
|
||
|
else {<br>
|
||
|
|
||
|
$this->inputCorrect = true;<br>
|
||
|
return 0;<br>
|
||
|
}<br>
|
||
|
}<br>
|
||
|
</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<br>
|
||
|
<br>
|
||
|
<h2>4. Defining that your module is ready for user input and LDAP
|
||
|
add/modify</h2>
|
||
|
In most cases you will not need to implement these functions. The <span
|
||
|
style="font-style: italic;">baseModule</span> will return <span
|
||
|
style="font-style: italic;">true</span> for both functions.<br>
|
||
|
<br>
|
||
|
<span style="text-decoration: underline;"><br>
|
||
|
There are two functions which control the module status:</span><br
|
||
|
style="text-decoration: underline;">
|
||
|
<br>
|
||
|
The <span style="font-weight: bold;">module_ready()</span> function
|
||
|
has to
|
||
|
return <span style="font-style: italic;">true</span> if the user may
|
||
|
move to your module page. If it is <span style="font-style: italic;">false</span>
|
||
|
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).<br>
|
||
|
<br>
|
||
|
The second function is
|
||
|
<span style="font-weight: bold;">module_complete()</span>. The user
|
||
|
cannot do the LDAP operation if one or more modules return <span
|
||
|
style="font-style: italic;">false</span>. This defines if all needed
|
||
|
input data for your module was entered.<br>
|
||
|
Use this function if you want to check that all required attributes are
|
||
|
set.<br>
|
||
|
<br>
|
||
|
<span style="font-weight: bold; text-decoration: underline;">Example:</span><br
|
||
|
style="font-weight: bold; text-decoration: underline;">
|
||
|
<br>
|
||
|
The <span style="font-style: italic;">sambaSamAccount</span>
|
||
|
module needs the user's <span style="font-style: italic;">uidNumber</span>
|
||
|
and <span style="font-style: italic;">gidNumber</span> before it can
|
||
|
accept input and the account needs a <span style="font-style: italic;">sambaSID</span>
|
||
|
before it can be saved.<br>
|
||
|
<br>
|
||
|
<table style="width: 100%; text-align: left;" class="mod-code"
|
||
|
border="0" cellpadding="2" cellspacing="2">
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td style="vertical-align: top;"> /**<br>
|
||
|
* This function is used to check if this module page
|
||
|
can be displayed.<br>
|
||
|
* It returns false if a module depends on data from
|
||
|
other modules which was not yet entered.<br>
|
||
|
*<br>
|
||
|
* @return boolean true, if page can be displayed<br>
|
||
|
*/<br>
|
||
|
<span style="font-weight: bold;">function</span> <span
|
||
|
style="color: rgb(255, 0, 0);">module_ready</span>() {<br>
|
||
|
if
|
||
|
($_SESSION[$this->base]->module['posixAccount']->attributes['gidNumber'][0]=='')
|
||
|
return false;<br>
|
||
|
if
|
||
|
($_SESSION[$this->base]->module['posixAccount']->attributes['uidNumber'][0]=='')
|
||
|
return false;<br>
|
||
|
if
|
||
|
($this->attributes['uid'][0]=='') return false;<br>
|
||
|
return true;<br>
|
||
|
}<br>
|
||
|
<br>
|
||
|
/**<br>
|
||
|
* This functions is used to check if all settings
|
||
|
for this module have been made.<br>
|
||
|
*<br>
|
||
|
* @return boolean true, if settings are complete<br>
|
||
|
*/<br>
|
||
|
<span style="font-weight: bold;">function</span> <span
|
||
|
style="color: rgb(255, 0, 0);">module_complete</span>() {<br>
|
||
|
if (!$this->module_ready())
|
||
|
return false;<br>
|
||
|
if
|
||
|
($this->attributes['sambaSID'][0] == '') return false;<br>
|
||
|
return true;<br>
|
||
|
}<br>
|
||
|
<br>
|
||
|
</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<br>
|
||
|
<br>
|
||
|
<h2>5. Saving the LDAP attributes<br>
|
||
|
</h2>
|
||
|
In most cases you will not have to implement this option if you use <span
|
||
|
style="font-weight: bold;">$this->attributes</span> and <span
|
||
|
style="font-weight: bold;">$this->orig</span> to manage the LDAP
|
||
|
attributes. The <span style="font-style: italic;">baseModule</span>
|
||
|
will generate the save comands for you.<br>
|
||
|
<br>
|
||
|
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.<br>
|
||
|
This is done in the function <span style="font-weight: bold;">save_attributes()</span>.<br>
|
||
|
<br>
|
||
|
<span style="font-weight: bold; text-decoration: underline;">Example:</span><br
|
||
|
style="font-weight: bold; text-decoration: underline;">
|
||
|
<br>
|
||
|
The <span style="font-style: italic;">kolabUser</span> module uses
|
||
|
this function to make sure that its object class is saved. Other
|
||
|
modules (e.g. quota) use it build the lamdaemon commands.<br>
|
||
|
<br>
|
||
|
<table style="width: 100%; text-align: left;" class="mod-code"
|
||
|
border="0" cellpadding="2" cellspacing="2">
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td style="vertical-align: top;"> /**<br>
|
||
|
* Returns a list of modifications which have to be
|
||
|
made to the LDAP account.<br>
|
||
|
*<br>
|
||
|
* @return array list of modifications<br>
|
||
|
* <br>This function returns an array with 3
|
||
|
entries:<br>
|
||
|
* <br>array( DN1 ('add' => array($attr),
|
||
|
'remove' => array($attr), 'modify' => array($attr)), DN2 .... )<br>
|
||
|
* <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>
|
||
|
* <br>"add" are attributes which have to be
|
||
|
added to LDAP entry<br>
|
||
|
* <br>"remove" are attributes which have to be
|
||
|
removed from LDAP entry<br>
|
||
|
* <br>"modify" are attributes which have to
|
||
|
been modified in LDAP entry<br>
|
||
|
*/<br>
|
||
|
function save_attributes() {<br>
|
||
|
// add object class if needed<br>
|
||
|
if
|
||
|
(!isset($this->attributes['objectClass']) ||
|
||
|
!in_array('kolabInetOrgPerson', $this->attributes['objectClass'])) {<br>
|
||
|
|
||
|
$this->attributes['objectClass'][] = 'kolabInetOrgPerson';<br>
|
||
|
}<br>
|
||
|
return parent::save_attributes();<br>
|
||
|
}<br>
|
||
|
</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<br>
|
||
|
<br>
|
||
|
<span style="font-weight: bold;"></span>
|
||
|
<h2><span style="font-weight: bold;"></span></h2>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<p align="center">
|
||
|
<script type="text/javascript"><!--
|
||
|
google_ad_client = "pub-4179059556107138";
|
||
|
google_alternate_ad_url = "http://lam.sourceforge.net/google_adsense_script.html";
|
||
|
google_ad_width = 728;
|
||
|
google_ad_height = 90;
|
||
|
google_ad_format = "728x90_as";
|
||
|
google_ad_type = "text_image";
|
||
|
google_ad_channel ="";
|
||
|
google_page_url = document.location;
|
||
|
google_color_border = "EEEEEE";
|
||
|
google_color_bg = "FFFFFF";
|
||
|
google_color_link = "0000FF";
|
||
|
google_color_url = "008000";
|
||
|
google_color_text = "000000";
|
||
|
//--></script>
|
||
|
<script type="text/javascript"
|
||
|
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
||
|
</script>
|
||
|
</p>
|
||
|
|
||
|
</body>
|
||
|
</html>
|