Send notification emails if user has edit right to resource
authorMichael Spahn <m.spahn@metaways.de>
Mon, 8 Dec 2014 16:20:42 +0000 (17:20 +0100)
committerPhilipp Schüle <p.schuele@metaways.de>
Mon, 9 Feb 2015 12:13:56 +0000 (13:13 +0100)
If you add a resource to your event, every user who is allowed
to edit this resouce receives the mail as well.

Change-Id: I1f3dfa321e28c475b6ec7b633763c5a96d5ac964
Reviewed-on: http://gerrit.tine20.com/customers/1430
Tested-by: Jenkins CI (http://ci.tine20.com/)
Tested-by: sstamer <s.stamer@metaways.de>
Reviewed-by: Philipp Schüle <p.schuele@metaways.de>
tests/tine20/Calendar/Controller/EventNotificationsTests.php
tine20/Calendar/Config.php
tine20/Calendar/Controller.php
tine20/Calendar/Controller/Event.php
tine20/Calendar/Controller/EventNotifications.php
tine20/Calendar/Controller/Resource.php
tine20/Calendar/Model/Attender.php

index f82c120..ce0a428 100644 (file)
@@ -1328,4 +1328,42 @@ class Calendar_Controller_EventNotificationsTests extends Calendar_TestCase
         
         $this->assertEquals(2, count($messages), 'two mails should be send to current user (resource + attender)');
     }
+
+    /**
+     * Enable by a preference which sends mails to every user who got permissions to edit the resource
+     */
+    public function testResourceNotificationForGrantedUsers()
+    {
+        // Enable feature, disabled by default!
+        Calendar_Config::getInstance()->set(Calendar_Config::RESOURCE_MAIL_FOR_EDITORS, true);
+
+        $resource = $this->_getResource();
+        $resource->email = Tinebase_Core::getUser()->accountEmailAddress;
+        $persistentResource = Calendar_Controller_Resource::getInstance()->create($resource);
+
+        $event = $this->_getEvent(/*now = */ true);
+        $event->attendee->addRecord($this->_createAttender($persistentResource->getId(), Calendar_Model_Attender::USERTYPE_RESOURCE));
+        $grants = Tinebase_Container::getInstance()->getGrantsOfContainer($resource->container_id);
+
+        $newGrants = array(
+                'account_id' => $this->_personas['sclever']->getId(),
+                'account_type' => 'user',
+                Tinebase_Model_Grants::GRANT_READ => true,
+                Tinebase_Model_Grants::GRANT_EDIT => true
+            );
+
+        Tinebase_Container::getInstance()->setGrants($resource->container_id, new Tinebase_Record_RecordSet('Tinebase_Model_Grants', array_merge(array($newGrants), $grants->toArray())), TRUE);
+
+        self::flushMailer();
+
+        $persistentEvent = $this->_eventController->create($event);
+
+        $messages = self::getMessages();
+
+        Tinebase_Container::getInstance()->setGrants($resource->container_id, $grants);
+
+        $this->assertContains('Meeting Room (Required, No response)', print_r($messages, true));
+        $this->assertEquals(4, count($messages), 'four mails should be send to current user (resource + attender + everybody whos allowed to edit this resource)');
+        $this->assertEquals(3, count($persistentEvent->attendee));
+    }
 }
index 71f032f..b9388d8 100644 (file)
@@ -91,7 +91,12 @@ class Calendar_Config extends Tinebase_Config_Abstract
      * @var string
      */
     const SKIP_DOUBLE_EVENTS = 'skipdoubleevents';
-    
+
+    /**
+     * Send attendee mails to users with edit permissions to the added resource
+     */
+    const RESOURCE_MAIL_FOR_EDITORS = 'resourcemailforeditors';
+
     /**
      * (non-PHPdoc)
      * @see tine20/Tinebase/Config/Definition::$_properties
@@ -213,6 +218,16 @@ class Calendar_Config extends Tinebase_Config_Abstract
                 'setBySetupModule'      => FALSE,
                 'default'               => '',
         ),
+        self::RESOURCE_MAIL_FOR_EDITORS => array(
+            //_('Send notifications to every user with edit permissions of the added resources')
+            'label'                 => 'Send notifications to every user with edit permissions of the added resources',
+            'description'           => 'Send notifications to every user with edit permissions of the added resources',
+            'type'                  => Tinebase_Config_Abstract::TYPE_BOOL,
+            'clientRegistryInclude' => false,
+            'setBySetupModule'      => false,
+            'setByAdminModule'      => false,
+            'default'               => false
+        )
     );
     
     /**
index 1abb260..0370711 100644 (file)
@@ -227,7 +227,7 @@ class Calendar_Controller extends Tinebase_Controller_Event implements Tinebase_
      * @param Calendar_Model_Event       $_oldEvent
      * @return void
      */
-    public function sendEventNotifications($_event, $_updater, $_action, $_oldEvent=NULL)
+    public function sendEventNotifications($_event, $_updater, $_action, $_oldEvent = NULL)
     {
         Calendar_Controller_EventNotifications::getInstance()->doSendNotifications($_event, $_updater, $_action, $_oldEvent);
     }
index 1c2042a..c0b6a81 100644 (file)
@@ -2237,9 +2237,10 @@ class Calendar_Controller_Event extends Tinebase_Controller_Record_Abstract impl
      * @param Tinebase_Model_FullAccount $_updater
      * @param Sting                      $_action
      * @param Calendar_Model_Event       $_oldEvent
+     * @param Array                      $_additionalRecipients
      * @return void
      */
-    public function doSendNotifications($_event, $_updater, $_action, $_oldEvent=NULL)
+    public function doSendNotifications($_event, $_updater, $_action, $_oldEvent = NULL)
     {
         Tinebase_ActionQueue::getInstance()->queueAction('Calendar.sendEventNotifications', 
             $_event, 
index 4ba8402..a38c3a9 100644 (file)
             $this->sendNotificationToAttender($organizer, $_event, $_updater, 'changed', self::NOTIFICATION_LEVEL_ATTENDEE_STATUS_UPDATE, $updates);
         }
     }
-    
+
     /**
      * send notification to a single attender
      * 
      * @param array                      $_updates
      * @return void
      */
-    public function sendNotificationToAttender($_attender, $_event, $_updater, $_action, $_notificationLevel, $_updates = NULL)
+    public function sendNotificationToAttender(Calendar_Model_Attender $_attender, $_event, $_updater, $_action, $_notificationLevel, $_updates = NULL)
     {
         try {
             $organizer = $_event->resolveOrganizer();
             if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " receiver: '{$_attender->getEmail()}'");
             if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " subject: '$messageSubject'");
             if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " body: $messageBody");
-            
+
             $sender = $_action == 'alarm' ? $prefUser : $_updater;
-        
-            Tinebase_Notification::getInstance()->send($sender, array($attendee), $messageSubject, $messageBody, $calendarPart, $attachments);
+
+            $recipients = array($attendee);
+            if ($_attender->user_type == Calendar_Model_Attender::USERTYPE_RESOURCE
+                && Calendar_Config::getInstance()->get(Calendar_Config::RESOURCE_MAIL_FOR_EDITORS)
+            ) {
+                $recipients = array_merge($recipients,
+                    Calendar_Controller_Resource::getInstance()->getNotificationRecipients(
+                        Calendar_Controller_Resource::getInstance()->get($_attender->user_id)
+                    )
+                );
+            }
+            Tinebase_Notification::getInstance()->send($sender, $recipients, $messageSubject, $messageBody, $calendarPart, $attachments);
         } catch (Exception $e) {
             Tinebase_Exception::log($e);
             return;
index 7d91d4d..b3937f6 100644 (file)
@@ -93,7 +93,7 @@ class Calendar_Controller_Resource extends Tinebase_Controller_Record_Abstract
         )), NULL, TRUE);
         
         if ($_record->grants instanceof Tinebase_Record_RecordSet) {
-            $grants = Tinebase_Container::getInstance()->setGrants($container->getId(), $_record->grants, TRUE, FALSE);
+            Tinebase_Container::getInstance()->setGrants($container->getId(), $_record->grants, TRUE, FALSE);
         }
         
         $_record->container_id = $container->getId();
@@ -165,4 +165,45 @@ class Calendar_Controller_Resource extends Tinebase_Controller_Record_Abstract
         }
         return parent::_deleteLinkedObjects($_record);
     }
+
+    /**
+     * returns recipients for a resource notification
+     *
+     *  users who are allowed to edit a resource, should receive a notification
+     *
+     * @param  Calendar_Model_Resource $_lead
+     * @return array          array of int|Addressbook_Model_Contact
+     */
+    public function getNotificationRecipients(Calendar_Model_Resource $resource)
+    {
+        $recipients = array();
+
+        $relations = Tinebase_Relations::getInstance()->getRelations('Calendar_Model_Resource', 'Sql', $resource->getId(), true);
+
+        foreach ($relations as $relation) {
+            if ($relation->related_model == 'Addressbook_Model_Contact' && $relation->type == 'RESPONSIBLE') {
+                $recipients[] = $relation->related_record;
+            }
+        }
+
+        if (empty($recipients)) {
+            if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__CLASS__ . '::' . __METHOD__ . '::' . __LINE__ . ' no responsibles found for calendar resource: ' .
+                $resource->getId() . ' sending notification to all people having edit access to container ' . $resource->container_id);
+
+            $containerGrants = Tinebase_Container::getInstance()->getGrantsOfContainer($resource->container_id, TRUE);
+
+            foreach ($containerGrants as $grant) {
+                if ($grant['account_type'] == Tinebase_Acl_Rights::ACCOUNT_TYPE_USER && $grant[Tinebase_Model_Grants::GRANT_EDIT] == 1) {
+                    try {
+                        $recipients[] = Addressbook_Controller_Contact::getInstance()->getContactByUserId($grant['account_id'], TRUE);
+                    } catch (Addressbook_Exception_NotFound $aenf) {
+                        if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) Tinebase_Core::getLogger()->notice(__CLASS__ . '::' . __METHOD__ . '::' . __LINE__
+                            . ' Do not send notification to non-existant user: ' . $aenf->getMessage());
+                    }
+                }
+            }
+        }
+
+        return $recipients;
+    }
 }
index d058c0c..17593ab 100644 (file)
@@ -170,7 +170,7 @@ class Calendar_Model_Attender extends Tinebase_Record_Abstract
                 break;
             case self::USERTYPE_GROUP:
             case self::USERTYPE_RESOURCE:
-                return $resolvedUser->name;
+                return $resolvedUser->name ?: $resolvedUser->n_fileas;
                 break;
             default:
                 throw new Exception("type $type not yet supported");