1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376
|
<!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"><link rel="shortcut icon" type="image/x-icon" href="images/favicon.ico"></head><body>
<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>
In most cases you will not need to implement this function because the
parent class baseModule loads attributes based on your meta data.<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 these 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 returned 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>
$this->attributes['objectClass'] = $attr['objectClass'];<br>
$this->orig['objectClass'] = $attr['objectClass'];<br>
}<br>
if (isset($attr['macAddress'])) {<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>
See also baseModule::addSimpleInputTextField() and
baseModule::addMultiValueInputTextField()/processMultiValueInputTextField()
if you only want to add some simple text fields.<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>
* @return htmlElement HTML meta data<br>
*/<br>
<span style="font-weight: bold;">function</span> <span style="color: rgb(255, 0, 0);">display_html_attributes</span>() {<br> $return = new htmlTable();<br>
$macCount = 0;<br>
// list current MACs<br>
if (isset($this->attributes['macAddress'])) {<br>
$macCount = sizeof($this->attributes['macAddress']);<br>
for ($i = 0;
$i < sizeof($this->attributes['macAddress']); $i++) {<br>
$return->addElement(new htmlOutputText(_('MAC
address')));<br>
$macInput = new htmlInputField('macAddress' . $i,
$this->attributes['macAddress'][$i]);<br>
$macInput->setFieldSize(17);<br>
$macInput->setFieldMaxLength(17);<br>
$return->addElement($macInput);<br>
$return->addElement(new htmlButton('delMAC' . $i,
'del.png', true));<br>
$return->addElement(new htmlHelpLink('mac'),
true);<br>
}<br>
}<br>
// input box for new MAC<br>
$return->addElement(new htmlOutputText(_('New MAC address')));<br>
$newMacInput = new htmlInputField('macAddress', '');<br>
$newMacInput->setFieldSize(17);<br>
$newMacInput->setFieldMaxLength(17);<br>
$return->addElement($newMacInput);<br>
$return->addElement(new htmlButton('addMAC', 'add.png', true));<br>
$return->addElement(new htmlHelpLink('mac'));<br>
$return->addElement(new htmlHiddenInput('mac_number', $macCount));<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 an empty array. 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>
$errors = 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>
$errors[] = $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>
$errors[] = $message;<br>
}<br>
}<br>
$this->attributes['macAddress'] =
array_unique($this->attributes['macAddress']);<br>
return $errors;<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 commands 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>
</body></html>
|