1 <?php
3 class addressbook extends plugin
4 {
5 /* Definitions */
6 var $plHeadline = "Addressbook";
7 var $plDescription= "This does something";
9 /* Generic */
10 var $ui;
12 /* Phonelist attributes */
13 var $telephone_list = array();
14 var $new_dn = "";
15 var $orig_cn = "";
16 var $storage_base = "";
17 var $orig_storage_base= "";
19 /* Filter attributes */
20 var $start = 0;
21 var $search_for = "*";
22 var $search_base = "";
23 var $search_type = "";
24 var $range = 20;
26 /* Currently edited/added entry attributes */
27 var $sn = "";
28 var $cn = "";
29 var $givenName = "";
30 var $mail = "";
31 var $title = "";
32 var $personalTitle = "";
33 var $initials = "";
34 var $homePostalAddress = "";
35 var $homePhone = "";
36 var $mobile = "";
37 var $o = "";
38 var $postalAddress = "";
39 var $l = "";
40 var $postalCode = "";
41 var $st = "";
42 var $ou = "";
43 var $telephoneNumber = "";
44 var $facsimileTelephoneNumber = "";
45 var $pager = "";
47 /* attribute list for save action */
48 var $attributes= array("sn", "givenName", "mail", "title",
49 "initials", "homePostalAddress", "displayName",
50 "homePhone", "mobile", "o", "postalAddress", "l",
51 "postalCode", "st", "ou", "telephoneNumber",
52 "facsimileTelephoneNumber", "pager");
54 var $objectclasses= array("top", "person", "organizationalPerson", "inetOrgPerson");
56 var $abobjectclass= "dc=addressbook";
58 function addressbook ($config, $dn= NULL)
59 {
60 /* Include config object */
61 $this->config= $config;
63 /* Check if there is a special ldap-sub-tree specified, instead of dc=addressbook, */
64 $aoc = search_config($this->config->data['MENU'], "addressbook", "LDAP_OBJECT_CLASS");
65 if ($aoc != ""){
66 $this->abobjectclass = $aoc;
67 }
69 /* Get global filter config */
70 if (!is_global("phonefilter")){
71 $ui = get_userinfo();
72 $base = get_base_from_people($ui->dn);
73 $phonefilter= array(
74 "search_base" => $base,
75 "organizational" => "checked",
76 "global" => "checked",
77 "search_for" => "*",
78 "object_type" => "*");
79 register_global("phonefilter", $phonefilter);
80 }
82 $this->ui = get_userinfo();
83 }
85 function execute()
86 {
87 /* Call parent execute */
88 plugin::execute();
90 $smarty= get_smarty();
92 /* Prevent empty variables for smarty */
93 foreach($this->attributes as $atr) {
94 $smarty->assign($atr,"");
95 }
97 /* Save formular information */
98 $phonefilter= get_global("phonefilter");
99 foreach( array("search_for", "search_base", "object_type") as $type){
100 if (isset($_POST[$type])){
101 $phonefilter[$type]= $_POST[$type];
102 }
103 $this->$type= $phonefilter[$type];
104 }
105 if (isset($_POST['search_base'])){
106 foreach( array("organizational", "global") as $type){
107 if (isset($_POST[$type])){
108 $phonefilter[$type]= "checked";
109 } else {
110 $phonefilter[$type]= "";
111 }
112 }
113 }
115 /* Search string */
116 $s= $phonefilter['search_for'];
117 if ($s == "") {
118 $s= "*";
119 }
120 if (isset($_GET['search'])){
121 $s= validate(mb_substr($_GET['search'], 0, 1, "UTF8"))."*";
122 if ($s == "**"){
123 $s= "*";
124 }
125 $this->search_for= $s;
126 $phonefilter['search_for']= $s;
127 }
128 register_global("phonefilter", $phonefilter);
130 /* Assign create acl */
131 $acl = $this->get_entry_acls($this->abobjectclass.",".$phonefilter['search_base']);
132 $smarty->assign("internal_createable", preg_match("/c/",$acl));
133 $smarty->assign("internal_removeable", preg_match("/d/",$acl));
134 $smarty->assign("internal_editable", preg_match("/w/",$acl));
136 /* Perform actions with CTI hook */
137 if (isset($_GET['target'])
138 && isset($_GET['dial'])
139 && isset($this->config->current['CTIHOOK'])){
141 $dialmode= $_GET['dial'];
142 if ($dialmode == "telephoneNumber" ||
143 $dialmode == "mobile" ||
144 $dialmode == "homePhone"){
146 /* Get target */
147 $ldap= $this->config->get_ldap_link();
148 $ldap->cat(base64_decode($_GET['target']), array('telephoneNumber', 'mobile', 'homePhone'));
149 $attrs= $ldap->fetch();
150 if (isset($attrs["$dialmode"])){
151 $target= $attrs[$dialmode][0];
152 } else {
153 $target= "";
154 }
156 /* Get source */
157 $ui= get_userinfo();
158 $ldap->cat($ui->dn, array('telephoneNumber'));
159 $attrs= $ldap->fetch();
160 if (isset($attrs["telephoneNumber"])){
161 $source= $attrs['telephoneNumber'][0];
162 } else {
163 $source= "";
164 }
166 /* Save to session */
167 $_SESSION['source']= $source;
168 $_SESSION['target']= $target;
170 /* Perform call */
171 if ($target != "" && $source != ""){
172 $smarty->assign("phone_image", get_template_path('images/phone.png'));
173 $smarty->assign("dial_info", sprintf(_("Dial from %s to %s now?"), "<b style='font-size:22px; color:red'>".$source."</b>", "<b style='font-size:22px;color:red'>".$target."</b>"));
174 return($smarty->fetch(get_template_path('dial.tpl', TRUE)));
175 return;
176 } else {
177 print_red (_("You have no personal phone number set. Please change that in order to perform direct dials."));
178 }
179 }
181 }
183 /* Finally dial */
184 if (isset($_POST['dial']) && isset($_SESSION['source']) && isset($_SESSION['target'])){
185 exec ($this->config->current['CTIHOOK']." '".$_SESSION['source']."' '".$_SESSION['target']."'", $dummy, $retval);
186 unset($_SESSION['source']);
187 unset($_SESSION['target']);
188 }
191 /* Delete entry? */
192 if (isset($_POST['delete_entry_confirm'])){
194 /* Some nice guy may send this as POST, so we've to check
195 for the permissions again. */
197 $acl = $this->get_entry_acls($this->dn);
198 if(preg_match("/d/",$acl)){
200 /* Delete request is permitted, perform LDAP action */
201 $ldap= $this->config->get_ldap_link();
202 $ldap->rmdir ($this->dn);
203 show_ldap_error($ldap->get_error(), sprintf(_("Removing of addressbook entry '%s' failed."),$this->dn));
204 gosa_log ("Address book object'".$this->dn."' has been removed");
206 } else {
208 /* Normally this shouldn't be reached, send some extra
209 logs to notify the administrator */
210 print_red (_("You are not allowed to delete this entry!"));
211 gosa_log ("Warning: '".$this->ui->uid."' tried to trick address book deletion.");
212 }
214 /* Remove lock file after successfull deletion */
215 del_lock ($this->dn);
217 /* Clean up */
218 if (isset($_SESSION['saved_start'])){
219 $_GET['start']= $_SESSION['saved_start'];
220 }
221 unset($_SESSION['show_info']);
222 unset($_SESSION['saved_start']);
223 }
226 /* Delete entry? */
227 if (isset($_POST['delete_cancel'])){
228 del_lock ($this->dn);
229 }
232 /* Save address entry? */
233 if (isset($_POST['save'])){
234 $this->save_object();
235 $this->storage_base= $_POST['storage_base'];
237 /* Perform checks */
238 $message= $this->check ();
240 /* No errors, save object */
241 if (count ($message) == 0){
242 $this->save();
243 gosa_log ("Addressbook object '".$this->dn."' has been saved");
245 /* Clean up */
246 if (isset($_SESSION['saved_start'])){
247 $_GET['start']= $_SESSION['saved_start'];
248 }
249 $_SESSION['show_info']= $this->dn;
250 unset($_SESSION['saved_start']);
251 } else {
252 /* Errors found, show message */
253 show_errors ($message);
254 }
255 }
258 /* Close info window */
259 if (isset($_GET['close']) || isset($_POST['cancel'])){
260 if (isset($_SESSION['saved_start'])){
261 $_GET['start']= $_SESSION['saved_start'];
262 }
263 unset($_SESSION['show_info']);
264 unset($_SESSION['saved_start']);
265 }
268 /* Start address book edit mode? */
269 if (isset($_GET['global'])){
270 if (!isset($_SESSION['saved_start']) && isset($_GET['start'])){
271 $_SESSION['saved_start']= $_GET['start'];
272 }
273 switch ($_GET['global']){
274 case "add":
275 $this->dn= "new";
276 $this->orig_cn= "";
278 /* Clean values */
279 foreach ($this->attributes as $name){
280 $this->$name= "";
281 }
282 $this->saved_attributes= array();
283 $this->storage_base= $this->config->current["BASE"];
284 break;
286 case "edit":
287 /* Clean values */
288 foreach ($this->attributes as $name){
289 $this->$name= "";
290 }
291 $this->dn= $_SESSION['show_info'];
292 $this->load();
293 $this->orig_cn= $this->cn;
294 break;
295 case "remove":
296 $this->dn= $_SESSION['show_info'];
297 $this->load();
299 /* Load permissions for selected 'dn' and check if
300 we're allowed to remove this 'dn' */
301 $acl = $this->get_entry_acls($this->dn);
302 if(preg_match("/d/",$acl)){
304 /* Check locking, save current plugin in 'back_plugin', so
305 the dialog knows where to return. */
306 if (($user= get_lock($this->dn)) != ""){
307 return(gen_locked_message ($user, $this->dn));
308 }
310 /* Lock the current entry, so nobody will edit it during deletion */
311 $ui= get_userinfo();
312 add_lock ($this->dn, $ui->dn);
313 $smarty->assign("info", sprintf(_("You're about to delete the entry %s."), $this->dn));
314 return($smarty->fetch(get_template_path('remove.tpl', TRUE)));
315 } else {
317 /* Obviously the user isn't allowed to delete. Show message and
318 clean session. */
319 print_red (_("You are not allowed to delete this entry!"));
320 }
321 }
322 $_SESSION['show_info']= "ADD";
323 }
326 /* Open info window */
327 if (isset($_GET['show'])){
328 if (!isset($_SESSION['saved_start'])){
329 $_SESSION['saved_start']= $_GET['start'];
330 }
331 $this->dn = base64_decode($_GET['show']);
332 $_SESSION['show_info']= base64_decode($_GET['show']);
333 }
336 /* Get ldap link / build filter */
337 $ldap= $this->config->get_ldap_link();
338 $this->telephone_list= array ();
341 /* Assemble bases
342 (Depending on checkboxes, we search for organisational entries or seperated
343 adressbook entries within dc=adressbook, ) */
344 $bases= array();
345 $filter= "";
346 if ($phonefilter['global'] == "checked"){
347 $bases[]= preg_replace("/".$this->config->current['BASE']."/", $this->abobjectclass.",".$this->config->current['BASE'], $this->search_base);
348 } else {
349 $filter= '(objectClass=gosaAccount)';
350 }
351 if ($phonefilter['organizational'] == "checked"){
352 $bases[]= $this->search_base;
353 }
356 /* Only display those entries that have at least on of this attributes set */
357 $must_have_this = array("telephoneNumber","facsimileTelephoneNumber","mobile","homePhone","mail");
359 /* Requested attributes in ldap search */
360 $attributes = array("sn", "givenName", "telephoneNumber", "facsimileTelephoneNumber", "mobile", "homePhone", "uid", "mail", "cn");
362 /* Create attribute filter part */
363 $attribute_filter = "";
364 foreach($attributes as $att){
365 $attribute_filter .= "(".$att."=".$s.")";
366 }
368 /* Walk through bases an check for usable entries */
369 foreach ($bases as $base){
371 $ldap->cd ($base);
373 if ($phonefilter['object_type'] == '*'){
374 $ldap->search (
375 "(&(objectClass=person)$filter(!(objectClass=gosaUserTemplate))". // Skip templates etc ..
376 "(!(uid=*$))". // Skip entries with ...$ as uid
377 "(|".$attribute_filter."))"
378 ,$attributes);
379 } else {
380 $ldap->search ("(&$filter(!(uid=*$))(!(objectClass=gosaUserTemplate))". //array
381 "(".$phonefilter['object_type']."=$s))", $attributes);
382 }
384 /* Walk through LDAP results */
385 while ($attrs= $ldap->fetch()){
387 /* prevent empty vaiables */
388 foreach($this->attributes as $atr) {
389 if(!isset($attrs[$atr][0])) {
390 $attrs[$atr][0] = "";
391 }
392 }
394 /* Check if page number was posted */
395 if(!isset($_GET['start'])) {
396 $_GET['start']="";
397 }
399 /* Check if at least one attribute is specified */
400 $skip = false;
402 foreach($must_have_this as $attr) {
403 if(isset($attrs[$attr][0]) && !empty($attrs[$attr][0])){
404 $skip =false;
405 break;
406 }
407 }
409 /* Skip all attributes that we are not allowed to read */
410 $any = false;
411 foreach($attributes as $attr){
413 $acls = $this->get_entry_acls($attrs['dn'],$attr);
414 if(!preg_match("/r/",$acls)){
415 $attrs[$attr][0] = "";
416 }else{
417 $any = true;
418 }
419 }
421 /* Only show lines that have set any mail or phone informations */
422 if(!$skip && $any){
424 $this->telephone_list[$attrs['sn'][0].$attrs['dn']]=
426 "<td class=\"phonelist\" title=\"".$attrs['sn'][0].", ".$attrs['givenName'][0]."\" onClick='location.href=\"main.php?plug=".validate($_GET['plug'])."&start=".validate($_GET['start'])."&show=".base64_encode($attrs['dn'])."\"'><a style='vertical-align:middle;' href=\"main.php?plug=".validate($_GET['plug'])."&start=".validate($_GET['start'])."&show=".base64_encode($attrs['dn'])."\">".$attrs['sn'][0].", ".$attrs['givenName'][0].
427 "</a>
428 </td>
429 <td class=\"phonelist\" title=\""._("Dial")." ".$attrs['telephoneNumber'][0]."\">
430 <a style='vertical-align:middle;' href=\"main.php?plug=".validate($_GET['plug'])."&dial=telephoneNumber&start=".validate($_GET['start'])."&target=".base64_encode($attrs['dn'])."\">".$attrs['telephoneNumber'][0]."
431 </a>
432 </td>
433 <td class=\"phonelist\" title=\"".$attrs['facsimileTelephoneNumber'][0]."\">
434 ".$attrs['facsimileTelephoneNumber'][0]."
435 </td>
436 <td class=\"phonelist\" title=\""._("Dial")." ".$attrs['mobile'][0]."\">
437 <a style='vertical-align:middle;' href=\"main.php?plug=".validate($_GET['plug'])."&dial=mobile&start=".validate($_GET['start'])."&target=".base64_encode($attrs['dn'])."\">".$attrs['mobile'][0]."
438 </a>
439 </td>
440 <td class=\"phonelist\" title=\""._("Dial")." ".$attrs['homePhone'][0]."\">
441 <a style='vertical-align:middle;' href=\"main.php?plug=".validate($_GET['plug'])."&dial=homePhone&start=".validate($_GET['start'])."&target=".base64_encode($attrs['dn'])."\">".$attrs['homePhone'][0]."
442 </a>
443 </td>
444 <td>
445 <a href=\"getvcard.php?dn=".base64_encode($attrs['dn'])."\">
446 <img align=\"top\" border=0 src=\"images/save.png\" alt=\"vcf\" title=\"".sprintf(_("Save contact for %s as vcard"), $attrs['givenName'][0]." ".$attrs['sn'][0])."\">
447 </a>";
450 if(preg_match("/r/",$this->get_entry_acls($attrs['dn'],"mail"))){
451 if (isset($attrs['mail'][0]) && !empty($attrs['mail'][0])){
452 $dest= sprintf(_("Send mail to %s"), $attrs['mail'][0]);
453 $this->telephone_list[$attrs['sn'][0].$attrs['dn']].=
455 "<a href=\"mailto:".htmlentities($attrs['mail'][0])."\">".
456 "<img align=\"top\" border=0 src=\"images/mailto.png\" alt=\"vcf\" title=\"$dest\"></a>";
457 }
458 }
459 $this->telephone_list[$attrs['sn'][0].$attrs['dn']].= "</td>";
460 }
461 }
462 error_reporting(E_ALL);
463 }
465 /* Sort up list */
466 ksort ($this->telephone_list);
467 reset ($this->telephone_list);
469 /* Fill template variables */
470 $smarty->assign("search_for", $this->search_for);
471 $smarty->assign("object_type", $this->object_type);
473 $this->base = $phonefilter['search_base'];
474 $smarty->assign("deplist", $this->get_allowed_bases());
475 $smarty->assign("depselect", $this->search_base);
476 $smarty->assign("global", $phonefilter['global']);
477 $smarty->assign("organizational", $phonefilter['organizational']);
478 $smarty->assign("search_image", get_template_path('images/search.png'));
479 $smarty->assign("obj_image", get_template_path('images/list_ogroup.png'));
480 $smarty->assign("tree_image", get_template_path('images/tree.png'));
481 $smarty->assign("infoimage", get_template_path('images/info.png'));
482 $smarty->assign("actionimage", get_template_path('images/action.png'));
483 $smarty->assign("launchimage", get_template_path('images/launch.png'));
485 /* Generate alphabet */
486 $alphabet= generate_alphabet();
488 /* Build list output */
489 $output= "";
490 $mod= 0;
493 /* View detailed infos */
494 $smarty->assign("show_info", "");
495 if (isset($_SESSION['show_info'])){
497 $range= 4;
498 $smarty->assign("show_info", "1");
499 $smarty->assign("url", "main.php?plug=".validate($_GET['plug'])."&close=1");
501 $tmp = $this->plInfo();
503 if(isset($_POST['storage_base'])){
504 $this->storage_base = $_POST['storage_base'];
505 }
507 switch ($_SESSION['show_info']){
509 case "ADD":
511 $a_bases = $this->get_allowed_bases();
513 if(!isset($a_bases[$this->storage_base])){
514 $base = key($this->get_allowed_bases());
515 $this->storage_base = $base;
516 }
518 $smarty->assign ('storage_base', $this->storage_base);
519 $smarty->assign ('address_info', get_template_path('address_edit.tpl', TRUE));
521 foreach($tmp['plProvidedAcls'] as $name => $translated){
522 $smarty->assign($name."ACL",$this->get_entry_acls($this->abobjectclass.",".$base,$name));
523 }
524 break;
526 default:
527 $smarty->assign ('address_info', get_template_path('address_info.tpl', TRUE));
528 foreach($tmp['plProvidedAcls'] as $name => $translated){
529 $smarty->assign($name."ACL",$this->get_entry_acls($this->dn,$name));
530 }
531 break;
532 }
534 /* Fill variables from LDAP */
535 if ($_SESSION['show_info'] != "ADD"){
536 $ldap->cat($_SESSION['show_info'], $this->attributes);
537 $info= $ldap->fetch();
538 }
539 foreach ($this->attributes as $name){
541 /* Skip entries we are not allowed to read */
542 if(!preg_match("/r/",$this->get_entry_acls($this->dn,$name))){
543 $smarty->assign("info_$name", "");
544 }else
546 if ($_SESSION['show_info'] != "ADD" && isset($info["$name"][0])){
547 error_reporting(0);
548 /* Special treatment for phone attributes */
549 if ($name == "mobile" ||
550 $name == "homePhone" ||
551 $name == "telephoneNumber"){
552 $smarty->assign("info_$name",
553 "<a title=\""._("Dial")." ".$info["$name"][0]."\" href=\"main.php?plug=".validate($_GET['plug'])."&dial=$name&start=".validate($_GET['start'])."&target=".base64_encode($_SESSION['show_info'])."\">".$info["$name"][0]."</a>");
554 } else {
555 $smarty->assign("info_$name", preg_replace("/\n/", "<br>", $info["$name"][0]));
556 }
557 error_reporting(E_ALL);
558 } elseif ($_SESSION['show_info'] == "ADD" && isset($this->$name)) {
559 $smarty->assign("info_$name", $this->$name);
560 } else {
561 $smarty->assign("info_$name", "-");
562 }
563 }
564 if (preg_match("/,".$this->abobjectclass.",/", $_SESSION['show_info'])){
565 $storage= _("global addressbook");
566 $smarty->assign("internal", 0);
567 } else {
568 $storage= _("user database");
569 $smarty->assign("internal", 1);
570 }
571 if ($_SESSION['show_info'] != "ADD"){
572 $smarty->assign("storage_info", sprintf(_("Contact stored in '%s'"), $storage));
573 } else {
574 $smarty->assign("storage_info", _("Creating new entry in"));
575 }
576 } else {
579 if(isset($_POST['EntryPerPage'])){
580 $this->range = $_POST['EntryPerPage'];
581 }
582 $range = $this->range;
583 $smarty->assign("internal", 1);
584 }
585 if (isset($_GET['start'])){
586 $this->start= validate($_GET['start']);
587 }
588 foreach ($this->telephone_list as $val){
589 if ($mod < $this->start) {
590 $mod++;
591 continue;
592 }
593 if ($mod >= ($this->start + $range)){
594 $mod++;
595 break;
596 }
597 if ( ($mod++) & 1){
598 $col= "style=\"background-color: #ECECEC;\"";
599 } else {
600 $col= "style=\"background-color: #F5F5F5;\"";
601 }
602 $output.= "<tr $col>\n$val</tr>\n";
603 }
605 $smarty->assign("search_result", $output);
606 $smarty->assign("apply", apply_filter());
607 $smarty->assign("alphabet", $alphabet);
608 if($range < 20){
609 $smarty->assign("range_selector", range_selector(count($this->telephone_list), $this->start, $range));
610 }else{
611 $smarty->assign("range_selector", range_selector(count($this->telephone_list), $this->start, $range, "EntryPerPage"));
612 }
613 $tmp= array("*" => _("All"), "sn" => _("Name"), "givenName" => _("Given name"),
614 "telephoneNumber" => _("Work phone"), "mobile" => _("Cell phone"),
615 "homePhone" => _("Home phone"), "uid" => _("User ID"));
616 natsort($tmp);
617 $smarty->assign("objlist", $tmp);
619 /* Show main page */
620 $smarty->assign ('personal_image', get_template_path('images/addr_personal.png'));
621 $smarty->assign ('home_image', get_template_path('images/addr_home.png'));
622 $smarty->assign ('company_image', get_template_path('images/addr_company.png'));
623 $smarty->assign ('add_image', get_template_path('images/editpaste.png'));
624 $smarty->assign ('edit_image', get_template_path('images/edit.png'));
625 $smarty->assign ('delete_image', get_template_path('images/editdelete.png'));
626 return($smarty->fetch(get_template_path('contents.tpl', TRUE)));
627 }
629 function save_object()
630 {
631 plugin::save_object();
632 foreach($this->attributes as $attr){
634 /* save attributes depending on acls */
635 $acl = $this->get_entry_acls($this->dn,$attr);
637 if(preg_match("/w/",$acl)){
638 if(isset($_POST[$attr])){
639 $this->$attr = $_POST[$attr];
640 }
641 }
643 }
644 }
646 function check()
647 {
648 /* Call common method to give check the hook */
649 $message= plugin::check();
651 /* must: sn, givenName */
652 if ($this->sn == ""){
653 $message[]= _("The required field 'Name' is not set.");
654 return ($message);
655 }
656 if ($this->givenName == ""){
657 $message[]= _("The required field 'Given name' is not set.");
658 return ($message);
659 }
661 /* Check for valid name definition */
662 if (preg_match ("/[\\\\]/", $this->sn)){
663 $message[]= _("The field 'Name' contains invalid characters.");
664 }
665 if (preg_match ("/[\\\\]/", $this->givenName)){
666 $message[]= _("The field 'Given name' contains invalid characters.");
667 }
669 /* Check phone numbers */
670 if (!is_phone_nr($this->homePhone)){
671 $message[]= _("The field 'Phone' contains an invalid phone number.");
672 }
673 if (!is_phone_nr($this->telephoneNumber)){
674 $message[]= _("The field 'Phone' contains an invalid phone number.");
675 }
676 if (!is_phone_nr($this->facsimileTelephoneNumber)){
677 $message[]= _("The field 'Fax' contains an invalid phone number.");
678 }
679 if (!is_phone_nr($this->mobile)){
680 $message[]= _("The field 'Mobile' contains an invalid phone number.");
681 }
682 if (!is_phone_nr($this->pager)){
683 $message[]= _("The field 'Pager' contains an invalid phone number.");
684 }
686 /* Check for reserved characers */
687 if (preg_match ('/[,+"<>;]/', $this->givenName)){
688 $message[]= _("The field 'Given name' contains invalid characters.");
689 }
690 if (preg_match ('/[,+"<>;]/', $this->sn)){
691 $message[]= _("The field 'Name' contains invalid characters.");
692 }
694 /* Check mail */
695 if (!is_email($this->mail)){
696 $message[]= _("Please enter a valid email address in 'Primary address' field.");
697 }
699 /* Assemble cn/dn */
700 $this->cn= $this->givenName." ".$this->sn;
701 if ($this->orig_cn != $this->cn || $this->storage_base != $this->orig_storage_base){
702 $this->new_dn= $this->create_unique_dn("cn", preg_replace("/,*".$this->config->current['BASE']."$/", "", $this->storage_base).",".$this->abobjectclass.",".$this->config->current['BASE']);
703 if ($this->new_dn == "none"){
704 $message[]= _("Cannot create a unique DN for your entry. Please fill more formular fields.");
705 return ($message);
706 }
707 } else {
708 $this->new_dn= $this->dn;
709 }
711 return ($message);
712 }
715 function load()
716 {
717 /* Load base attributes */
718 plugin::plugin ($this->config, $this->dn);
719 $this->storage_base= preg_replace('/^[^,]+,/', '', preg_replace('/'.$this->abobjectclass.',/', '', $this->dn));
720 }
723 function save()
724 {
725 /* First use parents methods to do some basic fillup in $this->attrs */
726 plugin::save ();
728 $this->attrs['cn']= $this->cn;
729 $this->attrs['displayName']= $this->givenName." ".$this->sn;
731 /* Move entry if it got another name... */
732 if ($this->dn != "new" && $this->dn != $this->new_dn){
733 $this->move($this->dn, $this->new_dn);
734 }
735 $this->dn= $this->new_dn;
737 /* Save data. Using 'modify' implies that the entry is already present, use 'add' for
738 new entries. So do a check first... */
739 $ldap= $this->config->get_ldap_link();
740 $ldap->cat ($this->dn,array('dn'));
741 if ($ldap->fetch()){
742 $mode= "modify";
743 } else {
744 $mode= "add";
745 $ldap->cd($this->config->current['BASE']);
746 $ldap->create_missing_trees(preg_replace('/^[^,]+,/', '', $this->dn));
747 }
749 /* Finally write data with selected 'mode' */
750 $ldap->cd ($this->dn);
751 $this->cleanup();
752 $ldap->$mode ($this->attrs);
753 if (show_ldap_error($ldap->get_error(), sprintf(_("Removing of addressbook entry '%s' failed."),$this->dn))){
754 return (1);
755 }
756 }
759 /* Return entry acls */
760 function get_entry_acls($dn,$attr = "")
761 {
762 $acls = "";
764 /* Use addressbook acls */
765 if(preg_match("/".normalizePreg($this->abobjectclass)."/",$dn)) {
766 $dn = preg_replace("/".normalizePreg($this->abobjectclass).",/","",$dn);
767 $acls = $this->ui->get_permissions($dn,"addressbook/addressbook",$attr);
768 }
770 /* Use Organizational Person acls */
771 else{
772 $acls = $this->ui->get_permissions($dn,"users/user",$attr);
773 }
775 return($acls);
776 }
779 /* Return plugin informations for acl handling */
780 function plInfo()
781 {
782 return (array(
783 "plShortName" => _("Addressbook"),
784 "plDescription" => _("Addressbook entry acls"),
785 "plSelfModify" => FALSE,
786 "plDepends" => array(),
787 "plPriority" => 0,
788 "plSection" => array("addons" => _("Addons")),
789 "plCategory" => array("addressbook" => array("objectClass" => "inetOrgPerson", "description" => _("Addressbook"))),
791 "plProvidedAcls" => array(
792 "sn" => _("Surename"),
793 "givenName" => _("Given name"),
794 "telephoneNumber" => _("Telefon number"),
795 "facsimileTelephoneNumber" => _("Fax number"),
796 "mobile" => _("Mobile number"),
797 "homePhone" => _("Home phone number"),
798 "uid" => _("User identification"),
799 "mail" => _("Mail address"),
800 "pager" => _("Pager"),
801 "o" => _("Organization"),
802 "ou" => _("Department"),
803 "l" => _("Location"),
804 "postalAddress" => _("Postal address"),
805 "postalCode" => _("Postal address"),
806 "st" => _("State"),
807 "initials" => _("Initials"),
808 "title" => _("Title"),
809 "homePostalAddress" => _("Home postal address"),
810 "cn" => _("Common name"))
811 ));
812 }
813 }
814 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
815 ?>