1 <?php
2 /*
3 * This code is part of GOsa (https://gosa.gonicus.de)
4 * Copyright (C) 2008 Cajus Pollmeier
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
21 # Load Groupware defintion table
22 new GroupwareDefinitions();
25 class Groupware extends plugin
26 {
27 var $plHeadline = "Groupware";
28 var $plDescription = "GOsa groupware extension.";
29 var $pathTitle = "GOsa groupware extension.";
30 var $view_logged = FALSE;
32 var $FolderWidget = NULL;
34 var $accountInitialized = FALSE;
35 var $rpcError = FALSE;
36 var $rpcErrorMessage = "";
38 var $attributes = array(
39 "mailAddress", "mailLocation", "quotaUsage", "quotaSize", "alternateAddresses",
40 "forwardingAddresses", "vacationEnabled", "vacationMessage",
41 "mailBoxWarnLimitEnabled", "mailBoxWarnLimitValue",
42 "mailBoxSendSizelimitEnabled", "mailBoxSendSizelimitValue", "mailBoxHardSizelimitEnabled",
43 "mailBoxHardSizelimitValue", "mailBoxAutomaticRemovalEnabled", "mailBoxAutomaticRemovalValue",
44 "localDeliveryOnly", "dropOwnMails", "mailFolder", "mailLimitReceiveValue", "mailLimitSendValue",
45 "mailLimitReceiveEnabled", "mailLimitSendEnabled");
47 var $enabledFeatures = array();
49 var $flagAttributes = array("vacationEnabled","mailBoxWarnLimitEnabled","mailBoxSendSizelimitEnabled",
50 "mailBoxHardSizelimitEnabled","mailBoxAutomaticRemovalEnabled","localDeliveryOnly","dropOwnMails",
51 "mailLimitReceiveEnabled", "mailLimitSendEnabled");
53 var $mailAddressSelectDialog = NULL;
54 var $filterManager = NULL;
55 var $filterRules = array();
56 var $vacationTemplates = array();
59 //the dropdown
60 var $mailLocations = array();
62 var $mailAddress = "";
63 var $mailLocation = "";
64 var $mailFolder = NULL;
65 var $mailFolderChanged = NULL;
67 var $quotaUsage = 0;
68 var $quotaSize = 0;
69 var $alternateAddresses = array();
70 var $forwardingAddresses = array();
71 var $vacationEnabled = FALSE;
72 var $vacationMessage = "";
73 var $mailBoxWarnLimitEnabled = FALSE;
74 var $mailBoxWarnLimitValue = 100;
75 var $mailBoxSendSizelimitEnabled = FALSE;
76 var $mailBoxSendSizelimitValue = 100;
77 var $mailBoxHardSizelimitEnabled = FALSE;
78 var $mailBoxHardSizelimitValue = 100;
79 var $mailBoxAutomaticRemovalEnabled = FALSE;
80 var $mailBoxAutomaticRemovalValue = 100;
81 var $localDeliveryOnly = FALSE;
82 var $dropOwnMails = FALSE;
83 var $mailLimitReceiveEnabled = FALSE;
84 var $mailLimitReceiveValue = 0;
85 var $mailLimitSendEnabled = FALSE;
86 var $mailLimitSendValue = 0;
89 var $groupwareDao = null;
91 // Used in the folder editor as the starting folder, usually user/username
92 var $folderPrefix = "";
95 /*! \brief
96 */
97 function __construct ($config, $dn= NULL)
98 {
99 plugin::plugin($config,$dn);
101 // Get attributes from parent object
102 if(isset($this->attrs['uid'])){
103 $this->uid = $this->attrs['uid'][0];
104 }
106 // Set initial folder prefix
107 $this->folderPrefix = "user/{$this->uid}";
109 // Initialize the plugin using rpc.
110 $this->init();
111 }
114 /*! \brief Try to execute a function on the gosa backend using json-rpc.
115 * This method also takes care about errors and sets the required
116 * class members, such as rpcError and rpcErrorMessage.
117 * @param String function The name of the function to call.
118 * @param Mixed args[0-n] The parameter to use.
119 * @return Mixed The result of the function call on success else NULL.
120 */
121 function rpcExec($function)
122 {
123 $params = func_get_args();
124 unset($params[0]);
125 $rpc = $this->config->getRpcHandle();
126 $res = call_user_func_array(array($rpc,$function),array_values($params));
127 $this->rpcError = !$rpc->success();
128 if($this->rpcError){
129 $this->rpcErrorMessage = $rpc->get_error();
130 return(NULL);
131 }
132 return($res);
133 }
136 /*! \brief Checks if feature is availavle on the server (a call to getCapabilities achieves this.)
137 */
138 public function isFeatureEnabled($featureName)
139 {
140 if(!isset($this->enabledFeatures[$featureName])){
141 trigger_error("No such feature '{$featureName}'!");
142 }
143 return(isset($this->enabledFeatures[$featureName]) && $this->enabledFeatures[$featureName]);
144 }
147 /*! \brief Checking if the feature has been changed since loading it from server (initial state)
148 */
149 public function hasFeaturebeenChanged($featureName)
150 {
151 //TODO: must be implemented.
152 return TRUE;
153 }
156 /*! \brief Try initialize the groupware account.
157 * This method fetches all required information to manage the
158 * account using the GOsa gui.
159 */
160 function init()
161 {
162 // Detect feature availability and enable/disable services correspondingly.
163 $this->groupwareDao = new GroupwareDao($this);
165 // Feature names with a list of groupware functions that must be available.
166 $features = array();
167 $featureReq = array(
168 "primaryMail" => array(
169 'acctGetPrimaryMailAddress'),
170 "quotaUsage" => array(
171 'acctGetQuota'),
172 "quotaSize" => array(
173 'acctSetQuota','acctGetQuota'),
174 "mailLocations" => array("_off",
175 'getMailboxLocations'),
176 "mailFilter" => array("_off",
177 'acctDelFilter','acctGetFilters','acctSetFilters','acctSetFilters'),
178 "alternateAddresses" => array(
179 'acctDelAlternateMailAddress','acctSetAlternateMailAddresses',
180 'acctAddAlternateMailAddress','acctGetAlternateMailAddresses'),
181 "forwardingAddresses" => array(
182 'acctAddMailForwardAddress','acctDelMailForwardAddress',
183 'acctGetMailForwardAddresses','acctSetMailForwardAddresses'),
184 "vacationMessage" => array(
185 'acctSetOutOfOfficeReply', 'acctGetOutOfOfficeReply'),
186 "mailBoxWarnLimit" => array(
187 'acctSetQuota','acctGetQuota'),
188 "mailBoxSendSizelimit" => array(
189 'acctSetQuota','acctGetQuota'),
190 //This is the same as qotaSize - should stay turned off
191 "mailBoxHardSizelimit" => array("_off",
192 'acctSetQuota','acctGetQuota'),
193 "mailBoxAutomaticRemoval" => array("_off",
194 'acctSetQuota','acctGetQuota'),
195 "localDeliveryOnly" => array( "_off",
196 'acctDelFilter','acctGetFilters','acctSetFilters','acctSetFilters'),
197 "dropOwnMails" => array( "_off",
198 'acctDelFilter','acctGetFilters','acctSetFilters','acctSetFilters'),
199 "mailFolder" => array(
200 'folderList','folderDel','folderAdd'),
201 "mailLimit" => array(
202 'acctGetMailLimit', 'acctSetMailLimit'),
203 //Just for speedup
204 "folderListWithMembers" => array(
205 'acctGetComprehensiveUser'),
206 "folderACLs" => array(
207 'folderGetMembers', 'folderSetMembers'),
208 "comprehensiveUser" => array(
209 'acctGetComprehensiveUser')
210 );
212 // Check if all required methods can be called!
213 foreach($featureReq as $name => $requires){
214 $active = TRUE;
215 foreach($requires as $methodName){
216 $active &= $this->groupwareDao->gwFeatureAvailable($methodName);
217 }
218 $this->enabledFeatures[$name] = $active;
219 }
221 // Load mail locations.
222 if ($this->isFeatureEnabled("mailLocations")){
223 $this->mailLocations = $this->groupwareDao->get('mailLocations', array());
224 }
226 // If this is a new user, then do not try to check the account status,
227 // the account cannot exists.
228 if($this->dn == "new"){
229 $this->initially_was_account = $this->is_account = FALSE;
230 $this->accountInitialized = TRUE;
231 }else{
233 // Get rpc handle to fetch account info and feature availability.
234 $status = $this->rpcExec('gwAcctExists', $this->uid);
235 if($status !== NULL){
236 $this->initially_was_account = $this->is_account = $status;
237 if($this->is_account){
238 $response = $this->groupwareDao->getComprehensiverUser($this->uid);
239 $this->saved_attributes = $response;
240 $this->mapComprehensiveUserData($response);
241 }
242 $this->accountInitialized = TRUE;
243 }
244 }
246 // Set vacation start/stop if not set alreasy
247 $this->vacationStart = time();
248 $this->vacationStop = time() + (14 * 60*60*24);
250 // Prepare vacation start/stop time to be initially valid.
251 $this->vacationStart= date('d.m.Y', $this->vacationStart);
252 $this->vacationStop= date('d.m.Y', $this->vacationStop);
253 }
256 /*! \brief Generates the HTML user interface for the groupware plugin
257 * and take of several ui actions like adding or removing
258 * forward addresses, filters and the account itself.
259 */
260 function execute()
261 {
262 // Register plugin execution
263 $display = plugin::execute();
265 // Log plugin execution.
266 if($this->is_account && !$this->view_logged){
267 $this->view_logged = TRUE;
268 new log("view","users/".get_class($this),$this->dn);
269 }
271 // Check if we were able to initialize the account already.
272 if(!$this->accountInitialized){
273 $this->init();
274 if(!$this->accountInitialized){
275 $smarty = get_smarty();
276 $smarty->assign("initFailed", !$this->accountInitialized);
277 return($smarty->fetch(get_template_path("generic.tpl",TRUE,dirname(__FILE__))));
278 }
279 }
281 // Check if we were able to initialize the account already.
282 if($this->rpcError){
283 $smarty = get_smarty();
284 $smarty->assign("initFailed", !$this->accountInitialized);
285 $smarty->assign("rpcError", $this->rpcError);
286 return($smarty->fetch(get_template_path("generic.tpl",TRUE,dirname(__FILE__))));
287 }
289 /****************
290 Filter editor
291 ****************/
293 if(isset($_POST['filterManager_cancel'])) $this->filterManager = NULL;
294 if(isset($_POST['filterManager_ok'])){
295 $this->filterManager->save_object();
296 $msgs = $this->filterManager->check();
297 if(count($msgs)){
298 msg_dialog::displayChecks($msgs);
299 }else{
300 $this->filterRules = $this->filterManager->save();
301 $this->filterManager = NULL;
302 }
303 }
304 if(isset($_POST['configureFilter'])){
305 $this->filterManager = new FilterManager($this->config, $this,$this->filterRules);
306 $this->filterManager->acl_base = $this->acl_base;
307 $this->filterManager->acl_category = $this->acl_category;
308 }
309 $this->dialog = FALSE;
310 if($this->filterManager instanceOf FilterManager){
311 $this->filterManager->save_object();
312 $this->dialog = TRUE;
313 return($this->filterManager->execute());
314 }
316 /****************
317 Folder editor
318 ****************/
320 if(isset($_POST['FolderWidget_cancel'])) $this->FolderWidget = NULL;
321 if(isset($_POST['FolderWidget_ok'])){
322 $this->FolderWidget->save_object();
323 $msgs = $this->FolderWidget->check();
324 if(count($msgs)){
325 msg_dialog::displayChecks($msgs);
326 }else{
328 if(!empty($this->mailFolderChanges)){
329 $this->mailFolderChanges = array_merge($this->mailFolderChanges, $this->FolderWidget->save());
330 }
331 else{
332 $this->mailFolderChanges = $this->FolderWidget->save();
333 }
335 $this->folderSave($this->uid);
336 $this->FolderWidget = NULL;
337 }
338 }
340 // Act on requests to edit mailFolder entries.
341 if(isset($_POST['configureFolder'])){
343 // Load mail folder entries on demand, this will increase the account
344 // instantiation a lot.
345 if($this->mailFolder === NULL){
346 $this->mailFolder = array();
347 if($this->initially_was_account){
348 $this->mailFolder = $this->groupwareDao->getListOfMailFolders();
349 }
350 }
352 $folders = $this->mailFolder;
353 if(!isset($folders[$this->folderPrefix])){
354 $folders[$this->folderPrefix] = array('name' => $this->uid,'status' => 'added','acls' => array());
355 }
356 $this->FolderWidget = new FolderWidget($this->config,$folders, $this->folderPrefix);
357 $this->FolderWidget->setPermissions(GroupwareDefinitions::getPermissions());
358 $this->FolderWidget->acl_base = $this->acl_base;
359 $this->FolderWidget->acl_category = $this->acl_category;
360 }
361 $this->dialog = FALSE;
362 if($this->FolderWidget instanceOf FolderWidget){
363 $this->FolderWidget->save_object();
364 $this->dialog = TRUE;
365 return($this->FolderWidget->execute());
366 }
368 /****************
369 Account status
370 ****************/
372 if(isset($_POST['modify_state'])){
373 if($this->is_account && $this->acl_is_removeable()){
374 $this->is_account= FALSE;
375 }elseif(!$this->is_account && $this->acl_is_createable()){
376 $this->is_account= TRUE;
377 }
378 }
379 if(!$this->multiple_support_active){
380 if (!$this->is_account && $this->parent === NULL){
381 $display= "<img alt=\"\" src=\"images/small-error.png\" align=\"middle\"> <b>".
382 msgPool::noValidExtension(_("Mail"))."</b>";
383 $display.= back_to_main();
384 return ($display);
385 }
386 if ($this->parent !== NULL){
387 if ($this->is_account){
388 $display= $this->show_disable_header(msgPool::removeFeaturesButton(_("Groupware")),
389 msgPool::featuresEnabled(_("Groupware")));
390 } else {
391 $display= $this->show_enable_header(msgPool::addFeaturesButton(_("Groupware")),
392 msgPool::featuresDisabled(_("Groupware")));
393 return ($display);
394 }
395 }
396 }
398 /****************
399 Forward addresses
400 ****************/
402 // Display dialog to select a local fowarder
403 if (isset($_POST['addLocalForwardingAddress'])){
404 $this->mailAddressSelectDialog= new mailAddressSelect($this->config, get_userinfo());
406 $this->dialog= TRUE;
407 }
409 // Close dialogs, action was canceled
410 if (isset($_POST['mailAddressSelect_cancel'])){
411 $this->mailAddressSelectDialog= FALSE;
412 $this->dialog= FALSE;
413 }
415 // Append selected forwarding addresses now.
416 if (isset($_POST['mailAddressSelect_save']) && $this->mailAddressSelectDialog instanceOf mailAddressSelect){
417 if($this->acl_is_writeable("forwardingAddresses")){
418 $list = $this->mailAddressSelectDialog->save();
419 foreach ($list as $entry){
420 $val = $entry['mail'][0];
421 if (!in_array_strict($val, $this->alternateAddresses) && $val != $this->mailAddress){
422 $this->addForwarder($val);
423 $this->is_modified= TRUE;
424 }
425 }
426 $this->mailAddressSelectDialog= FALSE;
427 $this->dialog= FALSE;
428 } else {
429 msg_dialog::display(_("Error"), _("Please select an entry!"), ERROR_DIALOG);
430 }
431 }
433 // Display the address selection dialog.
434 if($this->mailAddressSelectDialog instanceOf mailAddressSelect){
435 $used = array();
436 $used['mail'] = array_values($this->alternateAddresses);
437 $used['mail'] = array_merge($used['mail'], array_values($this->forwardingAddresses));
438 $used['mail'][] = $this->mailAddress;
440 // Build up blocklist
441 session::set('filterBlacklist', $used);
442 return($this->mailAddressSelectDialog->execute());
443 }
445 // Add manually inserted forwarding address.
446 if (isset($_POST['addForwardingAddress'])){
447 if ($_POST['forwardingAddressInput'] != ""){
448 $address= get_post('forwardingAddressInput');
449 $valid= FALSE;
450 if (!tests::is_email($address)){
451 if (!tests::is_email($address, TRUE)){
452 if ($this->is_template){
453 $valid= TRUE;
454 } else {
455 msg_dialog::display(_("Error"), msgPool::invalid(_("Mail address"),
456 "","","your-address@your-domain.com"),ERROR_DIALOG);
457 }
458 }
459 } elseif ($address == $this->mailAddress || in_array_strict($address, $this->alternateAddresses)) {
460 msg_dialog::display(_("Error"),_("Cannot add primary address to the list of forwarders!") , ERROR_DIALOG);
461 } else {
462 $valid= TRUE;
463 }
464 if ($valid){
465 if($this->acl_is_writeable("forwardingAddresses")){
466 $this->addForwarder ($address);
467 $this->is_modified= TRUE;
468 }
469 }
470 }
471 }
472 if (isset($_POST['deleteForwardingAddress'])){
473 $this->delForwarder ($_POST['forwardingAddressList']);
474 }
476 /****************
477 Alternate addresses
478 ****************/
479 // Add manually inserted alternate mail address.
480 if (isset($_POST['addAlternateAddress'])){
481 $valid= FALSE;
482 if (!tests::is_email($_POST['alternateAddressInput'])){
483 if ($this->is_template){
484 if (!(tests::is_email($_POST['alternateAddressInput'], TRUE))){
485 msg_dialog::display(_("Error"),msgPool::invalid(_("Mail address"),
486 "","","your-domain@your-domain.com"),ERROR_DIALOG);
487 } else {
488 $valid= TRUE;
489 }
490 } else {
491 msg_dialog::display(_("Error"),msgPool::invalid(_("Mail address"),
492 "","","your-domain@your-domain.com"),ERROR_DIALOG);
493 }
494 } else {
495 $valid= TRUE;
496 }
497 if ($valid && ($user= $this->addAlternate (get_post('alternateAddressInput'))) != ""){
498 $ui= get_userinfo();
499 $addon= "";
500 if ($user[0] == "!") {
501 $addon= sprintf(_("Address is already in use by group '%s'."), mb_substr($user, 1));
502 } else {
503 $addon= sprintf(_("Address is already in use by user '%s'."), $user);
504 }
505 msg_dialog::display(_("Error"), msgPool::duplicated(_("Mail address"))."<br><br><i>".
506 "$addon</i>", ERROR_DIALOG);
507 }
508 }
510 // Remove alternate mail address.
511 if (isset($_POST['deleteAlternateAddress']) && isset($_POST['alternateAddressList'])){
512 $this->delAlternate ($_POST['alternateAddressList']);
513 }
515 /****************
516 SMARTY- Assign smarty variables
517 ****************/
519 $smarty = get_smarty();
520 foreach($this->attributes as $attr){
521 print
522 $smarty->assign($attr, $this->$attr);
523 }
525 $plInfo = $this->plInfo();
526 foreach($plInfo['plProvidedAcls'] as $acl => $name){
527 $smarty->assign($acl."ACL", $this->getacl($acl));
528 }
529 foreach($this->enabledFeatures as $feature => $state){
530 $smarty->assign($feature."_isActive", $state);
531 }
533 $smarty->assign("mailLocations", $this->mailLocations);
534 if (count($this->vacationTemplates)){
535 $smarty->assign("displayTemplateSelector", "TRUE");
536 $smarty->assign("vacationTemplate", set_post($this->vacationTemplate));
537 $smarty->assign("vacationTemplates", set_post($this->vacationTemplates));
538 $smarty->assign("template", set_post(get_post('vacation_template')));
539 } else {
540 $smarty->assign("displayTemplateSelector", "FALSE");
541 }
543 $smarty->assign("uid", $this->uid);
544 $smarty->assign("initFailed", !$this->accountInitialized);
545 $smarty->assign("rpcError", $this->rpcError);
546 $smarty->assign("rpcErrorMessage", $this->rpcErrorMessage);
548 return($display.$smarty->fetch(get_template_path("generic.tpl",TRUE,dirname(__FILE__))));
549 }
552 /*! \brief This method handles potential _POST and _GET values.
553 * It captures modifcations from the ui, like changing
554 * the mailAddress.
555 * This method respects the attribute permissions.
556 */
557 function save_object()
558 {
559 if(isset($_POST['groupwarePluginPosted'])){
561 // We ran into a communication error with the backend.
562 // Try a simple communication operation with the backend
563 // again and let us see if it works.
564 if(isset($_POST['retry'])){
565 $this->rpcExec('gwGetCapabilities');
566 }
568 // Get posted mail address modifications
569 if(isset($_POST['mailAddress']) && $this->acl_is_writeable('mailAddress') && $this->isFeatureEnabled('primaryMail')){
570 $this->mailAddress = get_post('mailAddress');
571 }
573 // Get ui modifications and store them in the class.
574 $testAttrs = array("mailLocation","quotaUsage","quotaSize",
575 "alternateAddresses","forwardingAddresses","vacationMessage");
576 foreach($testAttrs as $attr){
577 if(isset($_POST[$attr]) && $this->acl_is_writeable($attr) && $this->isFeatureEnabled($attr)){
578 $this->$attr = get_post($attr);
579 }
580 }
582 // Detect checkbox states
583 $checkAttrs = array(
584 "mailBoxWarnLimit" => "mailBoxWarnLimit",
585 "mailBoxSendSizelimit" => "mailBoxSendSizelimit",
586 "mailBoxHardSizelimit" => "mailBoxHardSizelimit",
587 "mailBoxAutomaticRemoval" => "mailBoxAutomaticRemoval",
588 "mailLimitReceive" => "mailLimit",
589 "mailLimitSend" => "mailLimit");
590 foreach($checkAttrs as $boxname => $feature){
591 if($this->acl_is_writeable($boxname) && $this->isFeatureEnabled($feature)){
592 $v = $boxname."Value";
593 $e = $boxname."Enabled";
594 $this->$e = isset($_POST[$e]);
595 if($this->$e){
596 $this->$v = get_post($v);
597 }
598 }
599 }
601 // Check for a changed vacation status
602 if($this->acl_is_writeable('vacationMessage') && $this->isFeatureEnabled('vacationMessage')){
603 $this->vacationEnabled = isset($_POST['vacationEnabled']);
604 }
606 // Get posted flag changes
607 $flagAttrs = array("localDeliveryOnly","dropOwnMails");
608 foreach($flagAttrs as $attr){
609 if($this->acl_is_writeable($attr) && $this->isFeatureEnabled($attr)){
610 $this->$attr = isset($_POST[$attr]);
611 }
612 }
613 }
614 }
617 /*! \brief Parse vacation templates and build up an array
618 * containing 'filename' => 'description'.
619 * Used to fill vacation dropdown box.
620 * @return Array All useable vacation templates.
621 */
622 function get_vacation_templates_usedSomewhere()
623 {
624 $vct = array();
625 if ($this->config->get_cfg_value("core","vacationTemplateDirectory") != ""){
626 $dir= $this->config->get_cfg_value("core","vacationTemplateDirectory");
627 if (is_dir($dir) && is_readable($dir)){
628 $dh = opendir($dir);
629 while($file = readdir($dh)){
630 $description= "";
631 if (is_file($dir."/".$file)){
632 $fh = fopen($dir."/".$file, "r");
633 $line= fgets($fh, 256);
634 if (!preg_match('/^DESC:/', $line)){
635 msg_dialog::display(_("Configuration error"), sprintf(_("No DESC tag in vacation template '%s'!"), $file), ERROR_DIALOG);
636 }else{
637 $description= trim(preg_replace('/^DESC:\s*/', '', $line));
638 }
639 fclose ($fh);
640 }
641 if ($description != ""){
642 $vct["$dir/$file"]= $description;
643 }
644 }
645 closedir($dh);
646 }
647 }
648 return($vct);
649 }
652 /*! \brief Adds the given mail address to the list of mail forwarders
653 */
654 function addForwarder($address)
655 {
656 if(empty($address)) return;
657 if($this->acl_is_writeable("forwardingAddresses")){
658 //Check if the address is a valid address on the Groupwareserver
660 $isMailAvailabel = $this->rpcExec("gwMailAddressExists", $address);
661 if(empty($isMailAvailabel)){
662 msg_dialog::display(_("Permission error"), _("This email address is not available as forwarding recipient in your groupware."), ERROR_DIALOG);
663 }
664 else{
665 $this->forwardingAddresses[]= $address;
666 $this->forwardingAddresses= array_unique ($this->forwardingAddresses);
667 sort ($this->forwardingAddresses);
668 reset ($this->forwardingAddresses);
669 $this->is_modified= TRUE;
670 }
671 }else{
672 msg_dialog::display(_("Permission error"), _("You have no permission to modify these addresses!"), ERROR_DIALOG);
673 }
674 }
677 /*! \brief Removes the given mail address from the list of mail forwarders
678 */
679 function delForwarder($addresses)
680 {
682 if($this->acl_is_writeable("forwardingAddresses")){
683 $this->forwardingAddresses= array_remove_entries ($addresses, $this->forwardingAddresses);
684 $this->is_modified= TRUE;
685 }else{
686 msg_dialog::display(_("Permission error"), _("You have no permission to modify these addresses!"), ERROR_DIALOG);
687 }
688 }
691 /*! \brief Add given mail address to the list of alternate adresses ,
692 * check if this mal address is used, skip adding in this case
693 */
694 function addAlternate($address)
695 {
696 if(empty($address)) return;
697 if($this->acl_is_writeable("alternateAddresses")){
698 $ldap= $this->config->get_ldap_link();
699 $address= strtolower($address);
701 /* Is this address already assigned in LDAP? */
702 $ldap->cd ($this->config->current['BASE']);
703 $ldap->search ("(&(!(objectClass=gosaUserTemplate))(objectClass=gosaMailAccount)(|(mail=$address)".
704 "(alias=$address)(gosaMailAlternateAddress=$address)))", array("uid", "cn"));
705 if ($ldap->count() > 0){
706 $attrs= $ldap->fetch ();
707 if (!isset($attrs["uid"])) {
708 return ("!".$attrs["cn"][0]);
709 }
710 return ($attrs["uid"][0]);
711 }
712 if (!in_array_strict($address, $this->alternateAddresses)){
713 $this->alternateAddresses[]= $address;
714 $this->is_modified= TRUE;
715 }
716 sort ($this->alternateAddresses);
717 reset ($this->alternateAddresses);
718 return ("");
719 }else{
720 msg_dialog::display(_("Permission error"), _("You have no permission to modify these addresses!"), ERROR_DIALOG);
721 }
722 }
725 /*! \brief Removes the given mail address from the alternate addresses list
726 */
727 function delAlternate($addresses)
728 {
729 if($this->acl_is_writeable("alternateAddresses")){
730 $this->alternateAddresses= array_remove_entries ($addresses,$this->alternateAddresses);
731 $this->is_modified= TRUE;
732 }else{
733 msg_dialog::display(_("Permission error"), _("You have no permission to modify these addresses!"), ERROR_DIALOG);
734 }
735 }
738 /*! \brief Prepare importet vacation string. \
739 * Replace placeholder like %givenName a.s.o.
740 * @param string Vacation string
741 * @return string Completed vacation string
742 */
743 private function prepare_vacation_template_usedSomewhere($contents)
744 {
745 /* Replace attributes */
746 $attrs = array();
747 $obj = NULL;
748 if(isset($this->parent->by_object['user'])){
749 $attrs = $this->parent->by_object['user']->attributes;
750 $obj = $this->parent->by_object['user'];
751 }else{
752 $obj = new user($this->config,$this->dn);
753 $attrs = $obj->attributes;
754 }
755 if($obj){
757 /* Replace vacation start and end time */
758 if($this->enabledFeatures['vacationMessage']){
759 if(preg_match("/%start/",$contents)){
760 $contents = preg_replace("/%start/",$this->vacationStart,$contents);
761 }
762 if(preg_match("/%end/",$contents)){
763 $contents = preg_replace("/%end/",$this->vacationStop,$contents);
764 }
765 }else{
766 if(preg_match("/%start/",$contents)){
767 $contents = preg_replace("/%start/", _("unknown"),$contents);
768 }
769 if(preg_match("/%end/",$contents)){
770 $contents = preg_replace("/%end/", _("unknown"), $contents);
771 }
772 }
774 foreach ($attrs as $val){
776 // We can only replace strings here
777 if(!is_string($obj->$val)) continue;
779 if(preg_match("/dateOfBirth/",$val)){
780 if($obj->use_dob){
781 $contents= preg_replace("/%$val/",date("Y-d-m",$obj->dateOfBirth),$contents);
782 }
783 }else {
784 $contents= preg_replace("/%$val/",
785 $obj->$val, $contents);
786 }
788 }
789 }
790 $contents = ltrim(preg_replace("/^DESC:.*$/m","",$contents),"\n ");
791 return($contents);
792 }
795 /*! \brief Remove the account form the groupware server completely.
796 */
797 function remove_from_parent()
798 {
799 // Get rpc handle to remove the account
800 if($this->initially_was_account){
801 if($this->rpcExec('gwAcctDel', $this->uid) === NULL){
802 msg_dialog::display(_("Error"), _("Groupware account removal failed!"), ERROR_DIALOG);
803 }
804 }
805 }
808 /* \brief Persists the values of this plugin to the groupware server.
809 * Save method is called on "apply" and "ok" in the Gosa Frontend.
810 * All other actions will update values in the form or
811 * cancel and therefore discard the changes so far.
812 */
813 function save()
814 {
815 // Get rpc handle to create or update the account
816 if(!$this->initially_was_account){
817 $res = $this->rpcExec('gwAcctAdd', $this->uid, $this->mailAddress);
818 if($res === NULL){
819 $message = _("Groupware account creation failed!");
820 msg_dialog::display(_("Error"),$message."<br>".sprintf(_("Error was: '%s'."),$this->rpcErrorMessage),ERROR_DIALOG);
821 return;
822 }
823 }
825 // Save the primary Email Address.
826 if($this->isFeatureEnabled("primaryMail")&& $this->hasFeaturebeenChanged("primaryMail")){
828 $res = $this->groupwareDao->save("primaryMail", $this->uid, $this->mailAddress);
829 if($res === NULL){
830 $message = _("Setting account mail address failed!");
831 msg_dialog::display(_("Error"),$message."<br>".sprintf(_("Error was: '%s'."),$this->rpcErrorMessage),ERROR_DIALOG);
832 }
833 }
835 // Save alternateAddresses
836 if($this->isFeatureEnabled("alternateAddresses")&& $this->hasFeaturebeenChanged("alternateAddresses")){
837 if(isset($this->alternateAddresses) && is_array($this->alternateAddresses)){
838 if(!empty($this->alternateAddresses)){
839 $res = $this->groupwareDao->save("alternateAddresses", $this->uid, array($this->alternateAddresses));
840 }
841 else{
843 $res = $this->groupwareDao->save("alternateAddresses", $this->uid, array(array()));
844 }
845 if($res === NULL){
846 $message = _("Saving alternate addresses failed!");
847 msg_dialog::display(_("Error"),$message."<br>".sprintf(_("Error was: '%s'."),$this->rpcErrorMessage),ERROR_DIALOG);
848 }
849 }
850 }
852 // Save forwardingAddresses
853 if($this->isFeatureEnabled("forwardingAddresses") && $this->hasFeaturebeenChanged("forwardingAddresses")){
855 // Transform simple address array into, $addresses[address] = ForwardFlag;
856 $addresses = array();
857 if(!empty($this->forwardingAddresses)){
858 foreach($this->forwardingAddresses as $address) $addresses[$address] = TRUE;
860 $res = $this->groupwareDao->save("forwardingAddresses", $this->uid, array($addresses));
861 }
862 else{
863 $res = $this->groupwareDao->save("forwardingAddresses", $this->uid, array(array()));
864 }
866 if($res === NULL){
867 $message = _("Saving forward addresses failed!");
868 msg_dialog::display(_("Error"),$message."<br>".sprintf(_("Error was: '%s'."),$this->rpcErrorMessage),ERROR_DIALOG);
869 }
870 }
872 //Save quota - it consists of four values...
873 if( ($this->isFeatureEnabled("mailBoxWarnLimit") ||
874 $this->isFeatureEnabled("mailBoxSendSizelimit") ||
875 $this->isFeatureEnabled("quotaSize") ||
876 $this->isFeatureEnabled("mailBoxAutomaticRemoval"))
877 && ($this->hasFeaturebeenChanged("mailBoxWarnLimit") ||
878 $this->hasFeaturebeenChanged("mailBoxSendSizelimit") ||
879 $this->hasFeaturebeenChanged("quotaSize") ||
880 $this->hasFeaturebeenChanged("mailBoxAutomaticRemoval") )){
882 if(!$this->mailBoxWarnLimitEnabled){
883 $this->mailBoxWarnLimitValue = null;
884 }
886 if(!$this->mailBoxSendSizelimitEnabled){
887 $this->mailBoxSendSizelimitValue = null;
888 }
890 $quota = array( "warn_limit" => $this->mailBoxWarnLimitValue,
891 "send_limit" => $this->mailBoxSendSizelimitValue,
892 "hard_limit" => $this->quotaSize);
893 //hold cannot be saved (in Exchange) right now - should be excluded for now.
894 //"hold" => $this->mailBoxAutomaticRemovalValue);
896 $res = $this->groupwareDao->save("quotaSize", $this->uid, $quota);
897 if($res === NULL){
898 $message = _("Saving quota failed!");
899 msg_dialog::display(_("Error"),$message."<br>".sprintf(_("Error was: '%s'."),$this->rpcErrorMessage),ERROR_DIALOG);
900 }
901 }
903 // TODO: Check the following paragraph
904 // Save account folders
905 if($this->mailFolder !== NULL && $this->isFeatureEnabled("mailFolder") && $this->hasFeaturebeenChanged("mailFolder")){
906 //$res = $this->saveFoldersAndAcls($this->uid, $this->mailFolder);
907 if($res === NULL){
908 $message = _("Saving mail folder failed!");
909 msg_dialog::display(_("Error"),$message."<br>".sprintf(_("Error was: '%s'."),$this->rpcErrorMessage),ERROR_DIALOG);
910 }
911 }
913 if($this->isFeatureEnabled("mailLocations") && $this->hasFeaturebeenChanged("mailLocation")){
914 $res = $this->groupwareDao->save("mailLocation", $this->uid, $this->mailLocation);
915 if($res === NULL){
916 $message = _("Saving mail location failed!");
917 msg_dialog::display(_("Error"),$message."<br>".sprintf(_("Error was: '%s'."),$this->rpcErrorMessage),ERROR_DIALOG);
918 }
919 }
921 //checks for feature "mailLimit"
922 if($this->isFeatureEnabled("mailLimit") && $this->hasFeaturebeenChanged("mailLimit")){
923 if(!$this->mailLimitReceiveEnabled){
924 $this->mailLimitReceiveValue = 0;
925 }
926 if(!$this->mailLimitSendEnabled){
927 $this->mailLimitSendValue = 0;
928 }
929 $res = $this->groupwareDao->save("mailLimit", $this->uid, array( $this->mailLimitSendValue, $this->mailLimitReceiveValue));
930 if($res === NULL){
931 $message = _("Saving mail limitations failed!");
932 msg_dialog::display(_("Error"),$message."<br>".sprintf(_("Error was: '%s'."),$this->rpcErrorMessage),ERROR_DIALOG);
933 }
934 }
937 if($this->isFeatureEnabled("vacationMessage")&& $this->hasFeaturebeenChanged("vacationMessage")){
938 if($this->vacationEnabled){
939 //setting an message means that the OOOReply is switched off.
940 $res = $this->groupwareDao->save("vacationMessage", $this->uid, $this->vacationMessage);
941 }else{
942 //setting no message means that the OOOReply is switched off.
943 $res = $this->groupwareDao->save("vacationMessage", $this->uid, null);
944 }
945 if($res === NULL){
946 $message = _("Saving vacation message failed!");
947 msg_dialog::display(_("Error"),$message."<br>".sprintf(_("Error was: '%s'."),$this->rpcErrorMessage),ERROR_DIALOG);
948 }
949 }
950 //Todo: Remove this
951 $this->folderSave($this->uid);
952 }
953 //checks for feature "quotaUsage"
954 //not to be saved
956 # //checks for feature "mailFilter"
957 # if($this->isFeatureEnabled("mailFilter") && $this->hasFeaturebeenChanged("mailFilter")){}
958 #
959 # //checks for feature "mailBoxAutomaticRemoval"
960 # if($this->isFeatureEnabled("mailBoxAutomaticRemoval") && $this->hasFeaturebeenChanged("mailBoxAutomaticRemoval")){}
961 #
962 # //checks for feature "localDeliveryOnly"
963 # if($this->isFeatureEnabled("localDeliveryOnly") && $this->hasFeaturebeenChanged("localDeliveryOnly")){}
964 #
965 # //checks for feature "dropOwnMails"
966 # if($this->isFeatureEnabled("dropOwnMails") && $this->hasFeaturebeenChanged("dropOwnMails")){}
969 /*! \brief TODO remove this function later
970 */
971 function folderSave($id){
972 if($this->isFeatureEnabled("mailFolder")&& $this->hasFeaturebeenChanged("mailFolder")){
973 //is sorting necessary?
974 //Find folders to add
975 if(empty($this->mailFolderChanges)){
976 return;
977 }
979 //Remove the root folder - the widget adds it as new
980 unset($this->mailFolderChanges["user/".$this->uid]);
982 foreach($this->mailFolderChanges as $folder => $memberlist){
984 if($this->mailFolderChanges[$folder]["status"] == "added"){
985 $this->groupwareDao->save("mailFolder", $folder);
986 }
987 if($this->mailFolderChanges[$folder]["status"] == "removed"){
988 $this->groupwareDao->del("mailFolder", $folder);
989 }
991 $memberListToBeSaved = array();
992 if($this->isFeatureEnabled("folderACLs")){
993 //checking if ACL has been changed.
994 if($this->mailFolderChanges[$folder]["status"] == "added"){
995 if(isset($memberlist["acls"])){
997 //set Default ACLs if not yet set by User
998 $defAcls = GroupwareDefinitions::getDefaultFolderACLs();
999 $memberListToBeSaved = $defAcls;
1000 //append all mebers set in Gosa widget.
1001 foreach($memberlist["acls"] as $member){
1002 $memberListToBeSaved[$member["name"]] = $member["acl"];
1003 }
1004 }
1005 }
1006 else{
1007 //Todo: remove debugs
1008 /*
1009 echo "--- Hello1";
1010 print_a($memberlist["acls"]);
1011 echo "--- Hello2";
1012 print_a($this->mailFolderChanges[$folder]["acls"]);
1013 */
1014 if(array_differs($memberlist["acls"], $this->mailFolder[$folder]["acls"])){
1015 //append all mebers set in Gosa widget.
1016 echo "ACLs have changed.";
1017 foreach($memberlist["acls"] as $member){
1018 $memberListToBeSaved[$member["name"]] = $member["acl"];
1019 }
1020 }
1021 }
1022 if(!empty($memberListToBeSaved)){
1023 //Todo: remove debugs
1024 /*
1025 echo "List To save:<pre>";
1026 print_r($memberListToBeSaved);
1027 echo "</pre><br>";
1028 */
1029 $this->groupwareDao->save("folderACLs", $folder, array($memberListToBeSaved));
1030 }
1031 }
1032 }
1033 }
1034 //reset the changes.. we have persisted them.
1035 $this->mailFolderChanges = null;
1036 }
1038 /*! \brief Check given values
1039 */
1040 function check()
1041 {
1042 //checke features only if they are enabled.
1043 $messages = plugin::check();
1045 // For newly created users!
1046 // We can input every 'uid' we want for new users, so we've to check if uids weren't used yet.
1047 if(!$this->initially_was_account){
1048 $exists = $this->rpcExec('gwAcctExists', $this->uid);
1049 if($this->rpcError){
1050 $messages[] = sprintf(_("Failed to validate groupware account."), $this->uid);
1051 }elseif($exists){
1052 $messages[] = sprintf(_("Account id, already used '%s'!"), $this->uid);
1053 }
1054 }
1056 // Check for valid mailAddresses
1057 if ($this->isFeatureEnabled("primaryMail")){
1059 if(!tests::is_email ($this->mailAddress)){
1060 $messages[] = msgPool::invalid(_("Mail address"),$this->mailAddress , "", "user@exdom.intranet.gonicus.de knibbel");
1061 }
1063 // Ensure that the mailAddress isn't used yet.
1064 if(!$this->initially_was_account || $this->mailAddress != $this->saved_attributes['primaryMail']){
1065 $exists = $this->rpcExec("gwMailAddressExists", $this->mailAddress);
1066 if($this->rpcError){
1067 $messages[] = sprintf(_("Failed to validate mail address '%s'."), $this->mailAddress);
1068 }elseif($exists){
1069 $messages[] = msgPool::duplicated(_("Mail address"));
1070 }
1071 }
1072 }
1074 //checks for feature "forwardingAddresses"
1075 if ($this->isFeatureEnabled("forwardingAddresses")){
1076 if(isset($this->forwardingAddresses) && is_array($this->forwardingAddresses)){
1077 foreach($this->forwardingAddresses as $fAddress){
1078 if(!tests::is_email ($fAddress)){
1079 $messages[] = msgPool::invalid(_("Forwarding address"),$fAddress, "",
1080 "user@exdom.intranet.gonicus.de");
1081 }
1082 //Check if the address is a valid address on the Groupwareserver
1083 $isMailAvailabel = $this->rpcExec("gwMailAddressExists", $fAddress);
1084 if(empty($isMailAvailabel)){
1085 $messages[] = _("This email address is not available as forwarding recipient in your groupware.");
1086 }
1087 if($fAddress == $this->mailAddress){
1088 $messages[] = _("The primary address cannot be used as forwarding address!");
1089 }
1090 }
1091 }
1092 }
1094 //checks for feature "mailLimit" - integer
1095 if ($this->isFeatureEnabled("mailLimit")){
1096 if (!is_numeric($this->mailLimitReceiveValue)){
1097 $messages[] = msgPool::invalid(_("Value for mailbox size receive limit"),$this->mailLimitReceiveValue , "", "1024 = 1MB");
1098 }
1099 if (!is_numeric($this->mailLimitSendValue)){
1100 $messages[] = msgPool::invalid(_("Value for mailbox size send limit"),$this->mailLimitSendValue , "", "1024 = 1MB");
1101 }
1102 }
1104 //checks for feature "mailBoxWarnLimit"
1105 if ($this->isFeatureEnabled("quotaSize")){
1106 //Todo: wrong test
1107 if (!is_numeric($this->quotaSize)){
1108 $messages[] = msgPool::invalid(_("Value for Quota size"),$this->quotaSize , "", "1024 = 1GB");
1109 }
1110 }
1112 //checks for feature "mailBoxSendSizelimit"
1113 if ($this->isFeatureEnabled("mailBoxSendSizelimit")){
1114 //Todo: wrong test
1115 if (!is_numeric($this->mailBoxSendSizelimitValue)){
1116 $messages[] = msgPool::invalid(_("Value refuse incoming mails limit"),$this->mailBoxSendSizelimitValue , "", "1024 = 1GB");
1117 }
1118 }
1119 //checks for feature "mailBoxHardSizelimit"
1120 if ($this->isFeatureEnabled("mailBoxWarnLimit")){
1121 //Todo: wrong test
1122 if (!is_numeric($this->mailBoxWarnLimitValue)){
1123 $messages[] = msgPool::invalid(_("Value warn about full mailbox"),$this->mailBoxWarnLimitValue , "", "1024 = 1GB");
1124 }
1125 }
1127 # //checks for feature "vacationMessage"
1128 # if ($this->isFeatureEnabled("vacationMessage")){}
1129 #
1130 # //checks for feature "mailBoxAutomaticRemoval"
1131 # if ($this->isFeatureEnabled("mailBoxAutomaticRemoval")){}
1132 #
1133 # //checks for feature "localDeliveryOnly"
1134 # if ($this->isFeatureEnabled("localDeliveryOnly")){}
1135 #
1136 # //checks for feature "dropOwnMails"
1137 # if ($this->isFeatureEnabled("dropOwnMails")){}
1138 #
1139 # //checks for feature "mailFolder"
1140 # if ($this->isFeatureEnabled("mailFolder")){}
1141 #
1142 # //checks for feature "quotaUsage"
1143 # if ($this->isFeatureEnabled("quotaUsage")){}
1144 #
1145 # //checks for feature "mailLocations"
1146 # if ($this->isFeatureEnabled("mailLocations")){}
1147 #
1148 # //checks for feature "mailFilter"
1149 # if ($this->isFeatureEnabled("mailFilter")){}
1150 #
1151 # //checks for feature "alternateAddresses"
1152 # if ($this->isFeatureEnabled("alternateAddresses")){}
1154 return($messages);
1155 }
1158 /*! \brief ACL settings
1159 */
1160 static function plInfo()
1161 {
1162 return (array(
1163 "plShortName" => _("Groupware"),
1164 "plDescription" => _("Groupware settings"),
1165 "plSelfModify" => TRUE,
1166 "plDepends" => array("user"), // This plugin depends on
1167 "plPriority" => 4, // Position in tabs
1168 "plSection" => array("personal" => _("My account")),
1169 "plCategory" => array("users"),
1170 "plOptions" => array(),
1171 "plProvidedAcls" => array(
1172 "mailAddress" => _("Mail address"),
1173 "mailLocation" => _("Mail location"),
1174 "mailFolder" => _("Mail folder"),
1175 "quotaUsage" => _("Quota usage"),
1176 "mailFilter" => _("Mail filter"),
1177 "mailFilter" => _("Mail filter"),
1178 "quotaSize" => _("Quota size"),
1179 "alternateAddresses" => _("Alternate mail addresses"),
1180 "forwardingAddresses" => _("Forwarding mail addresses"),
1181 "vacationEnabled" => _("Vaction switch"),
1182 "vacationMessage" => _("Vacation message"),
1183 "mailBoxWarnLimit" => _("Warn sizelimit"),
1184 "mailBoxSendSizelimit" => _("Send sizelimit"),
1185 "mailBoxHardSizelimit" => _("Hard sizelimit"),
1186 "mailBoxAutomaticRemoval" => _("Automatic mail removal"),
1187 "localDeliveryOnly" => _("Local delivery only"),
1188 "dropOwnMails" => _("Drop own mails"),
1189 "mailLimitSend" => _("mail Limit send"),
1190 "mailLimitReceive" => _("mail Limit receive")
1191 )
1192 ));
1193 }
1196 /*! \brief Maps the resultset fetched from the Dao to the class variables
1197 * of the plugin.
1198 */
1199 function mapComprehensiveUserData($callBackMap)
1200 {
1202 $map = array(
1203 "mailLocations" => "mailLocations",
1204 "mailFolder" => "mailFolder",
1205 "mailAddress" => "primaryMail",
1206 "mailLocation" => "mailLocation",
1207 "quotaUsage" => "quotaUsage",
1208 "quotaSize" => "mailBoxHardSizelimitValue",
1209 "alternateAddresses" => "alternateAddresses",
1210 "forwardingAddresses" => "forwardingAddresses",
1211 "vacationEnabled" => "vacationEnabled",
1212 "vacationMessage" => "vacationMessage",
1213 "mailBoxWarnLimitEnabled" => "mailBoxWarnLimitEnabled",
1214 "mailBoxWarnLimitValue" => "mailBoxWarnLimitValue",
1215 "mailBoxSendSizelimitEnabled" => "mailBoxSendSizelimitEnabled",
1216 "mailBoxSendSizelimitValue" => "mailBoxSendSizelimitValue",
1217 "mailBoxHardSizelimitEnabled" => "mailBoxHardSizelimitEnabled",
1218 "mailBoxHardSizelimitValue" => "mailBoxHardSizelimitValue",
1219 "mailBoxAutomaticRemovalEnabled" => "mailBoxAutomaticRemovalEnabled",
1220 "mailBoxAutomaticRemovalValue" => "mailBoxAutomaticRemovalValue",
1221 "localDeliveryOnly" => "localDeliveryOnly",
1222 "dropOwnMails" => "dropOwnMails",
1223 "mailLimitReceiveValue" => "mailLimitReceiveValue",
1224 "mailLimitSendValue" => "mailLimitSendValue",
1225 "mailLimitReceiveEnabled" => "mailLimitReceiveEnabled",
1226 "mailLimitSendEnabled" => "mailLimitSendEnabled"
1227 );
1229 // Map values from source array to class members
1230 foreach($map as $target => $source){
1231 if(isset($callBackMap[$source])){
1232 $this->$target = $callBackMap[$source];
1233 }
1234 }
1235 }
1238 /*! \brief This is a feature with many datasets inside which should be
1240 function saveFoldersAndAcls($id, $mailFolder)
1241 {
1242 // In the tests with the exchange server groupware setting acls is very
1243 // slow. So this function has got o be checked for modifications.
1244 $res = TRUE;
1245 foreach($mailFolder as $key => $val)
1246 {
1247 if(!empty($val["status"])){
1248 switch($val["status"]){
1249 case "add":
1250 $res = $this->groupwareDao->save("mailFolder", $id, $key);
1251 break;
1252 case "del":
1253 $res = $this->groupwareDao->delete("mailFolder", $id, $key);
1254 break;
1255 }
1256 }
1257 if($res === NULL) return($res);
1258 }
1259 return($res);
1260 }
1261 */
1262 }
1265 ?>