1 <?php
4 class addressbookgosa extends plugin{
6 static function plInfo()
7 {
8 /* Adapt addressbook settings and mofiy required settings.
9 */
10 $attrs = addressbook::plInfo();
11 $attrs['plShortName'] = _("Addressbook")." - "._("GOsa");
12 $attrs['plDescription'] = _("Addressbook")." - "._("GOsa related objects");
13 $attrs['plSelfModify'] = TRUE;
14 $attrs['plPriority'] = 2;
15 $attrs['plCategory'] = array("addressbook");
16 return($attrs);
17 }
18 }
20 class addressbook extends plugin
21 {
22 /* Definitions */
23 var $plHeadline = "Addressbook";
24 var $plDescription= "This does something";
26 /* Generic */
27 var $ui;
29 /* Phonelist attributes */
30 var $telephone_list = array();
31 var $new_dn = "";
32 var $orig_cn = "";
33 var $storage_base = "";
34 var $orig_storage_base= "";
36 /* Filter attributes */
37 var $start = 0;
38 var $search_for = "*";
39 var $search_base = "";
40 var $search_type = "";
41 var $range = 20;
43 /* Currently edited/added entry attributes */
44 var $sn = "";
45 var $cn = "";
46 var $givenName = "";
47 var $mail = "";
48 var $title = "";
49 var $personalTitle = "";
50 var $initials = "";
51 var $homePostalAddress = "";
52 var $homePhone = "";
53 var $mobile = "";
54 var $o = "";
55 var $postalAddress = "";
56 var $l = "";
57 var $postalCode = "";
58 var $st = "";
59 var $ou = "";
60 var $telephoneNumber = "";
61 var $facsimileTelephoneNumber = "";
62 var $pager = "";
63 var $view_logged = FALSE;
65 /* attribute list for save action */
66 var $attributes= array("sn", "givenName", "mail", "title",
67 "initials", "homePostalAddress", "displayName",
68 "homePhone", "mobile", "o", "postalAddress", "l",
69 "postalCode", "st", "ou", "telephoneNumber",
70 "facsimileTelephoneNumber", "pager");
72 var $objectclasses= array("top", "person", "organizationalPerson", "inetOrgPerson");
74 var $abobjectclass= "dc=addressbook";
75 var $acl_targets_objects = array();
77 function addressbook (&$config, $dn= NULL)
78 {
79 /* Include config object */
80 $this->config= &$config;
82 /* Check if there is a special ldap-sub-tree specified, instead of dc=addressbook, */
83 $aoc = $this->config->search("addressbook", "addressbookBaseDN",array('menu'));
84 if ($aoc != ""){
85 $this->abobjectclass = $aoc;
86 }
88 /* Get global filter config */
89 if (!session::is_set("phonefilter")){
90 $ui = get_userinfo();
91 $base = get_base_from_people($ui->dn);
92 $phonefilter= array(
93 "search_base" => $base,
94 "organizational" => "checked",
95 "global" => "checked",
96 "search_for" => "*",
97 "object_type" => "*");
98 session::set("phonefilter", $phonefilter);
99 }
101 $this->ui = get_userinfo();
102 $this->acl_targets_objects = $this->ui->get_acl_target_objects();
103 }
105 function execute()
106 {
107 /* Call parent execute */
108 plugin::execute();
110 $smarty= get_smarty();
112 /* Prevent empty variables for smarty */
113 foreach($this->attributes as $atr) {
114 $smarty->assign($atr,"");
115 }
117 /* Save formular information */
118 $phonefilter= session::get("phonefilter");
119 foreach( array("search_for", "search_base", "object_type") as $type){
120 if (isset($_POST[$type])){
121 $phonefilter[$type]= $_POST[$type];
122 }
123 $this->$type= $phonefilter[$type];
124 }
125 if (isset($_POST['search_base'])){
126 foreach( array("organizational", "global") as $type){
127 if (isset($_POST[$type])){
128 $phonefilter[$type]= "checked";
129 } else {
130 $phonefilter[$type]= "";
131 }
132 }
133 }
135 /* Search string */
136 $s= $phonefilter['search_for'];
137 if ($s == "") {
138 $s= "*";
139 }
140 if (isset($_GET['search'])){
141 $s= validate(mb_substr($_GET['search'], 0, 1, "UTF8"))."*";
142 if ($s == "**"){
143 $s= "*";
144 }
145 $this->search_for= $s;
146 $phonefilter['search_for']= $s;
147 }
148 session::set("phonefilter", $phonefilter);
150 /* Assign create acl */
151 $acl = $this->get_entry_acls($this->dn);
152 $smarty->assign("internal_createable", preg_match("/c/",$acl));
153 $smarty->assign("internal_removeable", preg_match("/d/",$acl));
154 $smarty->assign("internal_editable", preg_match("/w/",$acl));
156 /* Perform actions with CTI hook */
157 if (isset($_GET['target'])
158 && isset($_GET['dial'])
159 && $this->config->get_cfg_value("ctiHook") != "" ){
161 $dialmode= $_GET['dial'];
162 if ($dialmode == "telephoneNumber" ||
163 $dialmode == "mobile" ||
164 $dialmode == "homePhone"){
166 /* Get target */
167 $ldap= $this->config->get_ldap_link();
168 $ldap->cat(base64_decode($_GET['target']), array('telephoneNumber', 'mobile', 'homePhone'));
169 $attrs= $ldap->fetch();
170 if (isset($attrs["$dialmode"])){
171 $target= $attrs[$dialmode][0];
172 } else {
173 $target= "";
174 }
176 /* Get source */
177 $ui= get_userinfo();
178 $ldap->cat($ui->dn, array('telephoneNumber'));
179 $attrs= $ldap->fetch();
180 if (isset($attrs["telephoneNumber"])){
181 $source= $attrs['telephoneNumber'][0];
182 } else {
183 $source= "";
184 }
186 /* Save to session */
187 session::set('source',$source);
188 session::set('target',$target);
190 /* Perform call */
191 if ($target != "" && $source != ""){
192 $smarty->assign("phone_image", get_template_path('plugins/addressbook/images/phone.png'));
193 $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>"));
194 return($smarty->fetch(get_template_path('dial.tpl', TRUE)));
195 return;
196 } else {
197 msg_dialog::display(_("Error"), _("You need to set your personal phone number in order to perform direct dials."), ERROR_DIALOG);
198 }
199 }
201 }
203 /* Finally dial */
204 if (isset($_POST['dial']) && session::is_set('source') && session::is_set('target')){
205 exec ($this->config->get_cfg_value("ctiHook")." '".session::get('source')."' '".session::get('target')."'", $dummy, $retval);
206 session::un_set('source');
207 session::un_set('target');
208 }
211 /* Delete entry? */
212 if (isset($_POST['delete_entry_confirm'])){
214 /* Some nice guy may send this as POST, so we've to check
215 for the permissions again. */
217 $acl = $this->get_entry_acls($this->dn);
218 if(preg_match("/d/",$acl)){
220 /* Delete request is permitted, perform LDAP action */
221 $ldap= $this->config->get_ldap_link();
222 $ldap->rmdir ($this->dn);
223 new log("remove","addressbook/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
224 if (!$ldap->success()){
225 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_DEL, get_class()));
226 }
227 new log("remove","addressbook/".get_class($this),$this->dn,array(),"Addressbook object'".$this->dn."' has been removed");
229 } else {
231 /* Normally this shouldn't be reached, send some extra
232 logs to notify the administrator */
233 msg_dialog::display(_("Permission"),permDelete($this->dn),ERROR_DIALOG);
234 new log("remove","addressbook/".get_class($this),$this->dn,array(),"Warning: '".$this->ui->uid."' tried to trick address book deletion.");
235 }
237 /* Remove lock file after successfull deletion */
238 del_lock ($this->dn);
240 /* Clean up */
241 if (session::is_set('saved_start')){
242 $_GET['start']= session::get('saved_start');
243 }
244 session::un_set('show_info');
245 session::un_set('saved_start');
246 }
249 /* Delete entry? */
250 if (isset($_POST['delete_cancel'])){
251 del_lock ($this->dn);
252 }
255 /* Save address entry? */
256 if (isset($_POST['save'])){
257 $this->save_object();
258 $this->storage_base= $_POST['storage_base'];
260 /* Perform checks */
261 $message= $this->check ();
263 /* No errors, save object */
264 if (count ($message) == 0){
265 $this->save();
267 /* Clean up */
268 if (session::is_set('saved_start')){
269 $_GET['start']= session::get('saved_start');
270 }
271 session::set('show_info',$this->dn);
272 session::un_set('saved_start');
273 } else {
274 /* Errors found, show message */
275 msg_dialog::displayChecks($message);
276 }
277 }
280 /* Close info window */
281 if (isset($_GET['close']) || isset($_POST['cancel'])){
282 if (session::is_set('saved_start')){
283 $_GET['start']= session::get('saved_start');
284 }
285 session::un_set('show_info');
286 session::un_set('saved_start');
287 }
290 /* Start address book edit mode? */
291 if (isset($_GET['global'])){
292 if (!session::is_set('saved_start') && isset($_GET['start'])){
293 session::set('saved_start',$_GET['start']);
294 }
295 switch ($_GET['global']){
296 case "add":
297 $this->dn= "new";
298 $this->orig_cn= "";
300 /* Clean values */
301 foreach ($this->attributes as $name){
302 $this->$name= "";
303 }
304 $this->saved_attributes= array();
305 $this->storage_base= $this->config->current["BASE"];
306 break;
308 case "edit":
309 /* Clean values */
310 foreach ($this->attributes as $name){
311 $this->$name= "";
312 }
313 $this->dn= session::get('show_info');
314 $this->load();
315 $this->orig_cn= $this->cn;
316 break;
317 case "remove":
318 $this->dn= session::get('show_info');
319 $this->load();
321 /* Load permissions for selected 'dn' and check if
322 we're allowed to remove this 'dn' */
323 $acl = $this->get_entry_acls($this->dn);
324 if(preg_match("/d/",$acl)){
326 /* Check locking, save current plugin in 'back_plugin', so
327 the dialog knows where to return. */
328 if (($user= get_lock($this->dn)) != ""){
329 return(gen_locked_message ($user, $this->dn));
330 }
332 /* Lock the current entry, so nobody will edit it during deletion */
333 $ui= get_userinfo();
334 add_lock ($this->dn, $ui->dn);
335 $smarty->assign("info", msgPool::deleteInfo($this->dn));
336 return($smarty->fetch(get_template_path('remove.tpl', TRUE)));
337 } else {
339 /* Obviously the user isn't allowed to delete. Show message and
340 clean session. */
341 msg_dialog::display(_("Permission"),permDelete($this->dn),ERROR_DIALOG);
342 }
343 }
344 session::set('show_info',"ADD");
345 }
348 /* Open info window */
349 if (isset($_GET['show'])){
350 if (!session::is_set('saved_start')){
351 session::set('saved_start',$_GET['start']);
352 }
353 $this->dn = base64_decode($_GET['show']);
354 $this->view_logged =FALSE;
355 if(!$this->view_logged){
356 $this->view_logged = TRUE;
357 new log("view","addressbook/".get_class($this),$this->dn);
358 }
359 session::set('show_info',base64_decode($_GET['show']));
360 }
363 /* Get ldap link / build filter */
364 $ldap= $this->config->get_ldap_link();
365 $this->telephone_list= array ();
368 /* Assemble bases
369 (Depending on checkboxes, we search for organisational entries or seperated
370 adressbook entries within dc=adressbook, ) */
371 $bases= array();
372 $filter= "";
373 if ($phonefilter['global'] == "checked"){
374 $bases[]= preg_replace("/".$this->config->current['BASE']."/", $this->abobjectclass.",".$this->config->current['BASE'], $this->search_base);
375 } else {
376 $filter= '(objectClass=gosaAccount)';
377 }
378 if ($phonefilter['organizational'] == "checked"){
379 $bases[]= $this->search_base;
380 }
383 /* Only display those entries that have at least on of this attributes set */
384 $must_have_this = array("telephoneNumber","facsimileTelephoneNumber","mobile","homePhone","mail");
386 /* Requested attributes in ldap search */
387 $attributes = array("sn", "givenName", "telephoneNumber", "facsimileTelephoneNumber", "mobile", "homePhone", "uid", "mail", "cn");
389 /* Create attribute filter part */
390 $attribute_filter = "";
391 foreach($attributes as $att){
392 $attribute_filter .= "(".$att."=".$s.")";
393 }
395 /* Walk through bases an check for usable entries */
396 foreach ($bases as $base){
398 $ldap->cd ($base);
400 if ($phonefilter['object_type'] == '*'){
401 $ldap->search (
402 "(&(objectClass=person)$filter(!(objectClass=gosaUserTemplate))". // Skip templates etc ..
403 "(!(uid=*$))". // Skip entries with ...$ as uid
404 "(|".$attribute_filter."))"
405 ,$attributes);
406 } else {
407 $ldap->search ("(&$filter(!(uid=*$))(!(objectClass=gosaUserTemplate))". //array
408 "(".$phonefilter['object_type']."=$s))", $attributes);
409 }
411 /* Walk through LDAP results */
412 while ($attrs= $ldap->fetch()){
414 /* prevent empty vaiables */
415 foreach($this->attributes as $atr) {
416 if(!isset($attrs[$atr][0])) {
417 $attrs[$atr][0] = "";
418 }
419 }
421 /* Check if page number was posted */
422 if(!isset($_GET['start'])) {
423 $_GET['start']="";
424 }
426 /* Check if at least one attribute is specified */
427 $skip = false;
429 foreach($must_have_this as $attr) {
430 if(isset($attrs[$attr][0]) && !empty($attrs[$attr][0])){
431 $skip =false;
432 break;
433 }
434 }
436 /* Skip all attributes that we are not allowed to read */
437 $any = false;
438 foreach($attributes as $attr){
440 $acls = $this->get_entry_acls($attrs['dn'],$attr);
441 if(!preg_match("/r/",$acls)){
442 $attrs[$attr][0] = "";
443 }else{
444 $any = true;
445 }
446 }
448 /* Only show lines that have set any mail or phone informations */
449 if(!$skip && $any){
451 $this->telephone_list[$attrs['sn'][0].$attrs['dn']]=
453 "<td class=\"phonelist\" title=\"".$attrs['sn'][0].", ".$attrs['givenName'][0].
454 "\"onClick='location.href=\"main.php?plug=".validate($_GET['plug']).
455 "&start=".validate($_GET['start']).
456 "&show=".urlencode(base64_encode($attrs['dn']))."\"'>
457 <a style='vertical-align:middle;' href=\"main.php?plug=".validate($_GET['plug']).
458 "&start=".validate($_GET['start']).
459 "&show=".urlencode(base64_encode($attrs['dn']))."\">".
460 $attrs['sn'][0].", ".$attrs['givenName'][0].
461 "</a>
462 </td>
463 <td class=\"phonelist\" title=\""._("Dial")." ".$attrs['telephoneNumber'][0]."\">
464 <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]."
465 </a>
466 </td>
467 <td class=\"phonelist\" title=\"".$attrs['facsimileTelephoneNumber'][0]."\">
468 ".$attrs['facsimileTelephoneNumber'][0]."
469 </td>
470 <td class=\"phonelist\" title=\""._("Dial")." ".$attrs['mobile'][0]."\">
471 <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]."
472 </a>
473 </td>
474 <td class=\"phonelist\" title=\""._("Dial")." ".$attrs['homePhone'][0]."\">
475 <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]."
476 </a>
477 </td>
478 <td>
479 <a href=\"plugins/addressbook/getvcard.php?dn=".base64_encode($attrs['dn'])."\">
480 <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])."\">
481 </a>";
484 if(preg_match("/r/",$this->get_entry_acls($attrs['dn'],"mail"))){
485 if (isset($attrs['mail'][0]) && !empty($attrs['mail'][0])){
486 $dest= sprintf(_("Send mail to %s"), $attrs['mail'][0]);
487 $this->telephone_list[$attrs['sn'][0].$attrs['dn']].=
489 "<a href=\"mailto:".htmlentities($attrs['mail'][0])."\">".
490 "<img align=\"top\" border=0 src=\"images/mailto.png\" alt=\"vcf\" title=\"$dest\"></a>";
491 }
492 }
493 $this->telephone_list[$attrs['sn'][0].$attrs['dn']].= " </td>";
494 }
495 }
496 error_reporting(E_ALL | E_STRICT);
497 }
499 /* Sort up list */
500 ksort ($this->telephone_list);
501 reset ($this->telephone_list);
503 /* Fill template variables */
504 $smarty->assign("search_for", $this->search_for);
505 $smarty->assign("object_type", $this->object_type);
507 /* Create list of readable departments */
508 $deps = array();
509 foreach($this->config->idepartments as $dn => $name){
510 if( $this->acl_is_readable($dn) || $dn == $this->config->current['BASE']){
511 $deps[$dn] = $name;
512 }
513 }
515 $this->base = $phonefilter['search_base'];
516 $smarty->assign("deplist", $deps);
517 $smarty->assign("depselect", $this->search_base);
518 $smarty->assign("global", $phonefilter['global']);
519 $smarty->assign("organizational", $phonefilter['organizational']);
520 $smarty->assign("search_image", get_template_path('images/lists/search.png'));
521 $smarty->assign("obj_image", get_template_path('plugins/addressbook/images/objects.png'));
522 $smarty->assign("tree_image", get_template_path('images/lists/search-subtree.png'));
523 $smarty->assign("infoimage", get_template_path('images/info.png'));
524 $smarty->assign("actionimage", get_template_path('images/action.png'));
525 $smarty->assign("launchimage", get_template_path('images/launch.png'));
527 /* Generate alphabet */
528 $alphabet= generate_alphabet();
530 /* Build list output */
531 $output= "";
532 $mod= 0;
535 /* View detailed infos */
536 $smarty->assign("show_info", "");
537 if (session::is_set('show_info')){
539 $range= 4;
540 $smarty->assign("show_info", "1");
541 $smarty->assign("url", "main.php?plug=".validate($_GET['plug'])."&close=1");
543 $tmp = $this->plInfo();
545 if(isset($_POST['storage_base'])){
546 $this->storage_base = $_POST['storage_base'];
547 }
549 switch (session::get('show_info')){
551 case "ADD":
553 $a_bases = $this->get_allowed_bases();
555 if(!isset($a_bases[$this->storage_base])){
556 $base = key($this->get_allowed_bases());
557 $this->storage_base = $base;
558 }
560 $smarty->assign ('storage_base', $this->storage_base);
561 $smarty->assign ('address_info', get_template_path('address_edit.tpl', TRUE));
563 foreach($tmp['plProvidedAcls'] as $name => $translated){
564 $smarty->assign($name."ACL",$this->get_entry_acls($this->abobjectclass.",".$base,$name));
565 }
566 break;
568 default:
569 $smarty->assign ('address_info', get_template_path('address_info.tpl', TRUE));
570 foreach($tmp['plProvidedAcls'] as $name => $translated){
571 $smarty->assign($name."ACL",$this->get_entry_acls($this->dn,$name));
572 }
573 break;
574 }
576 /* Fill variables from LDAP */
577 if (session::get('show_info') != "ADD"){
578 $ldap->cat(session::get('show_info'), $this->attributes);
579 $info= $ldap->fetch();
580 }
581 foreach ($this->attributes as $name){
583 $dn = $this->dn;
584 if($dn == "new") $dn = $this->base;
586 /* Skip entries we are not allowed to read */
587 if(!preg_match("/r/",$this->get_entry_acls($dn,$name))){
588 $smarty->assign("info_$name", "");
589 }else
591 if (session::get('show_info') != "ADD" && isset($info["$name"][0])){
592 error_reporting(0);
593 /* Special treatment for phone attributes */
594 if ($name == "mobile" ||
595 $name == "homePhone" ||
596 $name == "telephoneNumber"){
597 $smarty->assign("info_$name",
598 "<a title=\""._("Dial")." ".$info["$name"][0]."\" href=\"main.php?plug=".validate($_GET['plug'])."&dial=$name&start=".validate($_GET['start'])."&target=".base64_encode(session::get('show_info'))."\">".$info["$name"][0]."</a>");
599 } else {
600 $smarty->assign("info_$name", preg_replace("/\n/", "<br>", $info["$name"][0]));
601 }
602 error_reporting(E_ALL | E_STRICT);
603 } elseif (session::get('show_info') == "ADD" && isset($this->$name)) {
604 $smarty->assign("info_$name", $this->$name);
605 } else {
606 $smarty->assign("info_$name", "-");
607 }
608 }
609 if (preg_match("/,".$this->abobjectclass.",/", session::get('show_info'))){
610 $storage= _("global addressbook");
611 $smarty->assign("internal", 0);
612 } else {
613 $storage= _("user database");
614 $smarty->assign("internal", 1);
615 }
616 if (session::get('show_info') != "ADD"){
617 $smarty->assign("storage_info", sprintf(_("Contact stored in '%s'"), $storage));
618 } else {
619 $smarty->assign("storage_info", _("Creating new entry in"));
620 }
621 } else {
624 if(isset($_POST['EntryPerPage'])){
625 $this->range = $_POST['EntryPerPage'];
626 }
627 $range = $this->range;
628 $smarty->assign("internal", 1);
629 }
630 if (isset($_GET['start'])){
631 $this->start= validate($_GET['start']);
632 }
633 foreach ($this->telephone_list as $val){
634 if ($mod < $this->start) {
635 $mod++;
636 continue;
637 }
638 if ($mod >= ($this->start + $range)){
639 $mod++;
640 break;
641 }
642 if ( ($mod++) & 1){
643 $col= "style=\"background-color: #ECECEC;\"";
644 } else {
645 $col= "style=\"background-color: #F5F5F5;\"";
646 }
647 $output.= "<tr $col>\n$val</tr>\n";
648 }
650 $smarty->assign("search_result", $output);
651 $smarty->assign("apply", apply_filter());
652 $smarty->assign("alphabet", $alphabet);
653 if($range < 20){
654 $smarty->assign("range_selector", range_selector(count($this->telephone_list), $this->start, $range));
655 }else{
656 $smarty->assign("range_selector", range_selector(count($this->telephone_list), $this->start, $range, "EntryPerPage"));
657 }
658 $tmp= array("*" => _("All"), "sn" => _("Name"), "givenName" => _("Given name"),
659 "telephoneNumber" => _("Work phone"), "mobile" => _("Cell phone"),
660 "homePhone" => _("Home phone"), "uid" => _("User ID"));
661 natsort($tmp);
662 $smarty->assign("objlist", $tmp);
664 /* Show main page */
665 $smarty->assign ('personal_image', get_template_path('plugins/addressbook/images/addr_personal.png'));
666 $smarty->assign ('home_image', get_template_path('plugins/addressbook/images/addr_home.png'));
667 $smarty->assign ('company_image', get_template_path('plugins/addressbook/images/addr_company.png'));
668 $smarty->assign ('add_image', get_template_path('images/lists/paste.png'));
669 $smarty->assign ('edit_image', get_template_path('images/lists/edit.png'));
670 $smarty->assign ('delete_image', get_template_path('images/lists/delete.png'));
671 return($smarty->fetch(get_template_path('contents.tpl', TRUE)));
672 }
674 function save_object()
675 {
676 plugin::save_object();
677 foreach($this->attributes as $attr){
679 /* save attributes depending on acls */
680 $acl = $this->get_entry_acls($this->dn,$attr);
682 if(preg_match("/w/",$acl)){
683 if(isset($_POST[$attr])){
684 $this->$attr = $_POST[$attr];
685 }
686 }
688 }
689 }
691 function check()
692 {
693 /* Call common method to give check the hook */
694 $message= plugin::check();
696 /* must: sn, givenName */
697 if ($this->sn == ""){
698 $message[] = msgPool::required(_("Name"));
699 return ($message);
700 }
701 if ($this->givenName == ""){
702 $message[] = msgPool::required(_("Given name"));
703 return ($message);
704 }
706 /* Check for valid name definition */
707 if (preg_match ("/[\\\\]/", $this->sn)){
708 $message[] = msgPool::invalid(_("Name"),$this->sn,"/[\\\\]");
709 }
710 if (preg_match ("/[\\\\]/", $this->givenName)){
711 $message[] = msgPool::invalid(_("Given name"),$this->givenName,"/[\\\\]");
712 }
714 /* Check phone numbers */
715 if (!tests::is_phone_nr($this->homePhone)){
716 $message[] = msgPool::invalid(_("Phone"),$this->homePhone);
717 }
718 if (!tests::is_phone_nr($this->telephoneNumber)){
719 $message[] = msgPool::invalid(_("Telephone number"),$this->telephoneNumber);
720 }
721 if (!tests::is_phone_nr($this->facsimileTelephoneNumber)){
722 $message[] = msgPool::invalid(_("Fax"),$this->facsimileTelephoneNumber);
723 }
724 if (!tests::is_phone_nr($this->mobile)){
725 $message[] = msgPool::invalid(_("Mobile"),$this->mobile);
726 }
727 if (!tests::is_phone_nr($this->pager)){
728 $message[] = msgPool::invalid(_("Pager"),$this->pager);
729 }
730 /* Check for reserved characers */
731 if (preg_match ('/[,+"<>;]/', $this->givenName)){
732 $message[] = msgPool::invalid(_("Given name"),$this->givenName,'/[,+"<>;]/');
733 }
734 if (preg_match ('/[,+"<>;]/', $this->sn)){
735 $message[] = msgPool::invalid(_("Name"),$this->sn,'/[,+"<>;]/');
736 }
738 /* Check mail */
739 if (!tests::is_email($this->mail)){
740 $message[] = msgPool::invalid(_("Email"),"","","your-domain@your-domain.com");
741 }
743 /* Assemble cn/dn */
744 $this->cn= $this->givenName." ".$this->sn;
745 if ($this->orig_cn != $this->cn || $this->storage_base != $this->orig_storage_base){
746 $this->new_dn= $this->create_unique_dn("cn", preg_replace("/,*".$this->config->current['BASE']."$/", "", $this->storage_base).",".$this->abobjectclass.",".$this->config->current['BASE']);
747 if ($this->new_dn == "none"){
748 $message[]= _("Cannot create a unique DN for your entry. Please fill more formular fields.");
749 return ($message);
750 }
751 } else {
752 $this->new_dn= $this->dn;
753 }
755 return ($message);
756 }
759 function load()
760 {
761 /* Load base attributes */
762 plugin::plugin ($this->config, $this->dn);
763 $this->view_logged = FALSE;
764 $this->storage_base= preg_replace('/^[^,]+,/', '', preg_replace('/'.$this->abobjectclass.',/', '', $this->dn));
765 }
768 function save()
769 {
770 /* First use parents methods to do some basic fillup in $this->attrs */
771 plugin::save ();
773 $this->attrs['cn']= $this->cn;
774 $this->attrs['displayName']= $this->givenName." ".$this->sn;
776 /* Move entry if it got another name... */
777 if ($this->dn != "new" && $this->dn != $this->new_dn){
778 $this->move($this->dn, $this->new_dn);
779 }
780 $this->dn= $this->new_dn;
782 /* Save data. Using 'modify' implies that the entry is already present, use 'add' for
783 new entries. So do a check first... */
784 $ldap= $this->config->get_ldap_link();
785 $ldap->cat ($this->dn,array('dn'));
786 if ($ldap->fetch()){
787 $mode= "modify";
788 } else {
789 $mode= "add";
790 $ldap->cd($this->config->current['BASE']);
791 $ldap->create_missing_trees(preg_replace('/^[^,]+,/', '', $this->dn));
792 }
794 /* Finally write data with selected 'mode' */
795 $ldap->cd ($this->dn);
796 $this->cleanup();
797 $ldap->$mode ($this->attrs);
798 if (!$ldap->success()){
799 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_DEL, get_class()));
800 return (1);
801 }
803 if($mode == "add"){
804 new log("create","addressbook/".get_class($this),$this->dn, array_keys($this->attrs),$ldap->get_error());
805 }else{
806 new log("modify","addressbook/".get_class($this),$this->dn, array_keys($this->attrs),$ldap->get_error());
807 }
808 }
811 /* Return entry acls */
812 function get_entry_acls($dn,$attr = "")
813 {
814 $acls = "";
815 $combineACLs = FALSE;
817 /* If combineACLs is set to false:
818 Differentiate between user and addressbook acls, thus leads into two object categories.
819 - real GOsa users
820 - and addressbook entries
821 To view addressbook entries (e.g. ou=addressbook,) you just require permissions on the ldap base for 'addressbook'.
822 To view real GOsa users you have to additionally add user permissions.
824 You can enable this option, to use only addressbook acls.
825 */
826 if($combineACLs){
827 $dn = preg_replace("/".preg_quote($this->abobjectclass, '/').",/","",$dn);
828 $acls = $this->ui->get_permissions($dn,"addressbook/addressbook",$attr);
829 }else{
831 /* Use addressbook acls */
832 if(preg_match("/".preg_quote($this->abobjectclass, '/')."/",$dn)) {
833 $acls = "";
834 foreach($this->acl_targets_objects as $path){
835 $acls .= $this->ui->get_permissions($path,"addressbook/addressbook",$attr);
836 }
837 }
839 /* Use Organizational Person acls */
840 else{
841 $acls = $this->ui->get_permissions($dn,"addressbook/addressbookgosa",$attr);
842 }
843 }
845 return($acls);
846 }
849 /* Return plugin informations for acl handling */
850 static function plInfo()
851 {
852 return (array(
853 "plShortName" => _("Addressbook")." - "._("Addressbook entries"),
854 "plDescription" => _("Addressbook")." - "._("Addressbook related objects"),
855 "plSelfModify" => FALSE,
856 "plDepends" => array(),
857 "plPriority" => 0,
858 "plSection" => array("addon" => _("Addons")),
859 "plCategory" => array("addressbook" => array("objectClass" => "inetOrgPerson", "description" => _("Addressbook"))),
861 "plProvidedAcls" => array(
862 "sn" => _("Surename"),
863 "givenName" => _("Given name"),
864 "telephoneNumber" => _("Telefon number"),
865 "facsimileTelephoneNumber" => _("Fax number"),
866 "mobile" => _("Mobile number"),
867 "homePhone" => _("Home phone number"),
868 "uid" => _("User identification"),
869 "mail" => _("Mail address"),
870 "pager" => _("Pager"),
871 "o" => _("Organization"),
872 "ou" => _("Department"),
873 "l" => _("Location"),
874 "postalAddress" => _("Postal address"),
875 "postalCode" => _("Postal address"),
876 "st" => _("State"),
877 "initials" => _("Initials"),
878 "title" => _("Title"),
879 "homePostalAddress" => _("Home postal address"),
880 "cn" => _("Common name"))
881 ));
882 }
883 }
884 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
885 ?>