public function validate($username, $password)
 {
     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Options: ' . print_r($this->_options, true));
     }
     $url = isset($this->_options['url']) ? $this->_options['url'] : 'https://localhost/validate/check';
     $adapter = new Zend_Http_Client_Adapter_Socket();
     $adapter->setStreamContext($this->_options = array('ssl' => array('verify_peer' => isset($this->_options['ignorePeerName']) ? false : true, 'allow_self_signed' => isset($this->_options['allowSelfSigned']) ? true : false)));
     $client = new Zend_Http_Client($url, array('maxredirects' => 0, 'timeout' => 30));
     $client->setAdapter($adapter);
     $params = array('user' => $username, 'pass' => $password);
     $client->setParameterPost($params);
     try {
         $response = $client->request(Zend_Http_Client::POST);
     } catch (Zend_Http_Client_Adapter_Exception $zhcae) {
         Tinebase_Exception::log($zhcae);
         return Tinebase_Auth::FAILURE;
     }
     $body = $response->getBody();
     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Request: ' . $client->getLastRequest());
     }
     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Response: ' . $body);
     }
     if ($response->getStatus() !== 200) {
         return Tinebase_Auth::FAILURE;
     }
     $result = Tinebase_Helper::jsonDecode($body);
     if (isset($result['result']) && $result['result']['status'] === true && $result['result']['value'] === true) {
         return Tinebase_Auth::SUCCESS;
     } else {
         return Tinebase_Auth::FAILURE;
     }
 }
 public function getCoreData()
 {
     try {
         $result = CoreData_Controller::getInstance()->getCoreData()->toArray();
     } catch (Exception $e) {
         Tinebase_Exception::log($e);
         $result = array();
     }
     return array('results' => $result, 'totalcount' => count($result));
 }
 /**
  * update to 7.2
  * - add uid field
  */
 public function update_1()
 {
     $this->validateTableVersion('tasks', 6);
     // first add with notnull == false ...
     $declaration = new Setup_Backend_Schema_Field_Xml('
         <field>
             <name>uid</name>
             <type>text</type>
             <length>255</length>
             <notnull>false</notnull>
         </field>
     ');
     try {
         $this->_backend->addCol('tasks', $declaration);
     } catch (Exception $e) {
         Tinebase_Exception::log($e);
     }
     $tasksBackend = new Tinebase_Backend_Sql(array('modelName' => 'Tasks_Model_Task', 'tableName' => 'tasks'));
     $allTasks = $tasksBackend->getAll();
     // add uid to all tasks
     foreach ($allTasks as $task) {
         $task->uid = $task->id;
         if (empty($task->status)) {
             $task->status = 'UNKNOWN';
         }
         $tasksBackend->update($task);
     }
     // ... now set notnull to true
     $declaration = new Setup_Backend_Schema_Field_Xml('
         <field>
             <name>uid</name>
             <type>text</type>
             <length>255</length>
             <notnull>true</notnull>
         </field>
     ');
     $this->_backend->alterCol('tasks', $declaration);
     $declaration = new Setup_Backend_Schema_Index_Xml('
         <index>
             <name>uid--id</name>
             <field>
                 <name>uid</name>
             </field>
             <field>
                 <name>id</name>
             </field>
         </index>
     ');
     $this->_backend->addIndex('tasks', $declaration);
     $this->setTableVersion('tasks', 7);
     $this->setApplicationVersion('Tasks', '7.2');
 }
 /**
  * creates the groups if not created already
  */
 protected function _createGroups()
 {
     $fe = new Admin_Frontend_Json();
     $internalAddressbook = Tinebase_Container::getInstance()->getContainerByName('Addressbook', 'Internal Contacts', Tinebase_Model_Container::TYPE_SHARED);
     foreach ($this->_groups as $groupArray) {
         $groupArray['container_id'] = $internalAddressbook->getId();
         $members = array();
         foreach ($groupArray['groupMembers'] as $member) {
             $members[] = $this->_personas[$member]->getId();
         }
         try {
             $this->_groups[$groupArray['groupData']['name']] = $fe->saveGroup($groupArray['groupData'], $members);
         } catch (Exception $e) {
             Tinebase_Exception::log($e);
             echo 'Group "' . $groupArray['groupData']['name'] . '" already exists. Skipping...' . PHP_EOL;
             $gr = Tinebase_Group::getInstance()->getGroupByName($groupArray['groupData']['name']);
             $this->_groups[$groupArray['groupData']['name']] = $fe->getGroup($gr->getId());
         }
     }
 }
 /**
  * convert Tinebase_Record_RecordSet to Sabre\VObject\Component
  *
  * @param  Tinebase_Record_RecordSet  $_records
  * @return Sabre\VObject\Component
  */
 public function fromTine20RecordSet(Tinebase_Record_RecordSet $_records)
 {
     if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) {
         Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' Events: ' . print_r($_records->toArray(), true));
     }
     // required vcalendar fields
     $version = Tinebase_Application::getInstance()->getApplicationByName('Calendar')->version;
     $vcalendar = new \Sabre\VObject\Component\VCalendar(array('PRODID' => "-//tine20.com//Tine 2.0 Calendar V{$version}//EN", 'VERSION' => '2.0', 'CALSCALE' => 'GREGORIAN'));
     if (isset($this->_method)) {
         $vcalendar->add('METHOD', $this->_method);
     }
     $originatorTz = $_records->getFirstRecord() ? $_records->getFirstRecord()->originator_tz : NULL;
     if (empty($originatorTz)) {
         throw new Tinebase_Exception_Record_Validation('originator_tz needed for conversion to Sabre\\VObject\\Component');
     }
     try {
         $vcalendar->add(new Sabre_VObject_Component_VTimezone($originatorTz));
     } catch (Exception $e) {
         Tinebase_Exception::log($e);
         throw new Tinebase_Exception_Record_Validation('Bad Timezone: ' . $originatorTz);
     }
     foreach ($_records as $_record) {
         $this->_convertCalendarModelEvent($vcalendar, $_record);
         if ($_record->exdate instanceof Tinebase_Record_RecordSet) {
             $_record->exdate->addIndices(array('is_deleted'));
             $eventExceptions = $_record->exdate->filter('is_deleted', false);
             foreach ($eventExceptions as $eventException) {
                 $this->_convertCalendarModelEvent($vcalendar, $eventException, $_record);
             }
         }
     }
     $this->_afterFromTine20Model($vcalendar);
     if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) {
         Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' card ' . $vcalendar->serialize());
     }
     return $vcalendar;
 }
 /**
  * (non-PHPdoc)
  * @see Tinebase_Server_Interface::handle()
  */
 public function handle(\Zend\Http\Request $request = null, $body = null)
 {
     $this->_request = $request instanceof \Zend\Http\Request ? $request : Tinebase_Core::get(Tinebase_Core::REQUEST);
     $this->_body = $this->_getBody($body);
     try {
         list($loginName, $password) = $this->_getAuthData($this->_request);
     } catch (Tinebase_Exception_NotFound $tenf) {
         header('WWW-Authenticate: Basic realm="ActiveSync for Tine 2.0"');
         header('HTTP/1.1 401 Unauthorized');
         return;
     }
     if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) {
         Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' is ActiveSync request.');
     }
     Tinebase_Core::initFramework();
     try {
         $authResult = $this->_authenticate($loginName, $password, $this->_request);
     } catch (Exception $e) {
         Tinebase_Exception::log($e);
         $authResult = false;
     }
     if ($authResult !== true) {
         header('WWW-Authenticate: Basic realm="ActiveSync for Tine 2.0"');
         header('HTTP/1.1 401 Unauthorized');
         return;
     }
     if (!$this->_checkUserPermissions($loginName)) {
         return;
     }
     $this->_initializeRegistry();
     $request = new Zend_Controller_Request_Http();
     $request->setRequestUri($this->_request->getRequestUri());
     $syncFrontend = new Syncroton_Server(Tinebase_Core::getUser()->accountId, $request, $this->_body);
     $syncFrontend->handle();
     Tinebase_Controller::getInstance()->logout();
 }
 /**
  * add email notes to contacts with email addresses in $_recipients
  *
  * @param array $_recipients
  * @param string $_subject
  * 
  * @todo add email home (when we have OR filters)
  * @todo add link to message in sent folder?
  */
 protected function _addEmailNote($_recipients, $_subject, $_body)
 {
     $filter = new Addressbook_Model_ContactFilter(array(array('field' => 'email', 'operator' => 'in', 'value' => $_recipients)));
     $contacts = Addressbook_Controller_Contact::getInstance()->search($filter);
     if (count($contacts)) {
         $translate = Tinebase_Translation::getTranslation($this->_applicationName);
         Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' Adding email notes to ' . count($contacts) . ' contacts.');
         $truncatedBody = extension_loaded('mbstring') ? mb_substr($_body, 0, 4096, 'UTF-8') : substr($_body, 0, 4096);
         $noteText = $translate->_('Subject') . ':' . $_subject . "\n\n" . $translate->_('Body') . ': ' . $truncatedBody;
         try {
             foreach ($contacts as $contact) {
                 $note = new Tinebase_Model_Note(array('note_type_id' => Tinebase_Notes::getInstance()->getNoteTypeByName('email')->getId(), 'note' => $noteText, 'record_id' => $contact->getId(), 'record_model' => 'Addressbook_Model_Contact'));
                 Tinebase_Notes::getInstance()->addNote($note);
             }
         } catch (Zend_Db_Statement_Exception $zdse) {
             Tinebase_Core::getLogger()->err(__METHOD__ . '::' . __LINE__ . ' Saving note failed: ' . $noteText);
             Tinebase_Exception::log($zdse);
         }
     } else {
         Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__ . ' Found no contacts to add notes to.');
     }
 }
 /**
  * create new setupuser
  *
  * @return Tinebase_Model_FullUser|null
  */
 protected function _createSetupuser()
 {
     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Creating new setupuser.');
     }
     $adminGroup = Tinebase_Group::getInstance()->getDefaultAdminGroup();
     $setupUser = new Tinebase_Model_FullUser(array('accountLoginName' => 'setupuser', 'accountStatus' => Tinebase_Model_User::ACCOUNT_STATUS_DISABLED, 'visibility' => Tinebase_Model_FullUser::VISIBILITY_HIDDEN, 'accountPrimaryGroup' => $adminGroup->getId(), 'accountLastName' => 'setupuser', 'accountDisplayName' => 'setupuser', 'accountExpires' => NULL));
     try {
         $setupUser = Tinebase_User::getInstance()->addUser($setupUser);
         Tinebase_Group::getInstance()->addGroupMember($setupUser->accountPrimaryGroup, $setupUser->getId());
     } catch (Exception $e) {
         // no setup user could be created
         // TODO we should try to fetch an admin user here (see Sales_Setup_Update_Release8::_updateContractsFields)
         Tinebase_Exception::log($e);
         $setupUser = null;
     }
     return $setupUser;
 }
 /**
  * update to 8.3
  * - normalize all rrules
  */
 public function update_2()
 {
     // find all events with rrule
     $eventIds = $this->_db->query("SELECT " . $this->_db->quoteIdentifier('id') . " FROM " . $this->_db->quoteIdentifier(SQL_TABLE_PREFIX . "cal_events") . " WHERE " . $this->_db->quoteIdentifier("rrule") . " IS NOT NULL")->fetchAll(Zend_Db::FETCH_ASSOC);
     // NOTE: we need a generic sql BE to circumvent calendar specific acl issues
     $eventBE = new Tinebase_Backend_Sql(array('modelName' => 'Calendar_Model_Event', 'tableName' => 'cal_events', 'modlogActive' => false));
     foreach ($eventIds as $eventId) {
         $event = $eventBE->get($eventId['id']);
         $oldRruleString = (string) $event->rrule;
         $rrule = Calendar_Model_Rrule::getRruleFromString($oldRruleString);
         $rrule->normalize($event);
         if ($oldRruleString != (string) $rrule) {
             $event->rrule = (string) $rrule;
             try {
                 $eventBE->update($event);
             } catch (Tinebase_Exception_Record_Validation $terv) {
                 Tinebase_Exception::log($terv, null, $event->toArray());
             } catch (Tinebase_Exception_UnexpectedValue $teuv) {
                 Tinebase_Exception::log($teuv, null, $event->toArray());
             }
         }
     }
     $this->setApplicationVersion('Calendar', '8.3');
 }
 /**
  * check admin group membership
  * 
  * @param Tinebase_Model_FullUser $user
  */
 protected function _checkAdminGroupMembership($user)
 {
     $adminGroup = Tinebase_Group::getInstance()->getDefaultAdminGroup();
     $memberships = Tinebase_Group::getInstance()->getGroupMemberships($user);
     if (!in_array($adminGroup->getId(), $memberships)) {
         try {
             Tinebase_Group::getInstance()->addGroupMember($adminGroup, $user);
             echo "Added user to default admin group\n";
             // @todo clear roles/groups cache
         } catch (Exception $e) {
             Tinebase_Exception::log($e);
             echo "Could not add user to default admin group: " . $e->getMessage();
         }
     }
 }
 /**
  * send pending alarms
  *
  * @param mixed $_eventName
  * @return void
  * 
  * @todo sort alarms (by model/...)?
  * @todo what to do about Tinebase_Model_Alarm::STATUS_FAILURE alarms?
  */
 public function sendPendingAlarms($_eventName)
 {
     $eventName = is_array($_eventName) ? $_eventName['eventName'] : $_eventName;
     $job = Tinebase_AsyncJob::getInstance()->startJob($eventName);
     if (!$job) {
         return;
     }
     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' No ' . $eventName . ' is running. Starting new one.');
     }
     try {
         // get all pending alarms
         $filter = new Tinebase_Model_AlarmFilter(array(array('field' => 'alarm_time', 'operator' => 'before', 'value' => Tinebase_DateTime::now()->subMinute(1)->get(Tinebase_Record_Abstract::ISO8601LONG)), array('field' => 'sent_status', 'operator' => 'equals', 'value' => Tinebase_Model_Alarm::STATUS_PENDING)));
         $limit = Tinebase_Config::getInstance()->get(Tinebase_Config::ALARMS_EACH_JOB, 100);
         $pagination = $limit > 0 ? new Tinebase_Model_Pagination(array('limit' => $limit)) : null;
         $alarms = $this->_backend->search($filter, $pagination);
         if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
             Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Sending ' . count($alarms) . ' alarms (limit: ' . $limit . ').');
         }
         // loop alarms and call sendAlarm in controllers
         foreach ($alarms as $alarm) {
             list($appName, $i, $itemName) = explode('_', $alarm->model);
             $appController = Tinebase_Core::getApplicationInstance($appName, $itemName);
             if ($appController instanceof Tinebase_Controller_Alarm_Interface) {
                 $alarm->sent_time = Tinebase_DateTime::now();
                 try {
                     // NOTE: we set the status here, so controller can adopt the status itself
                     $alarm->sent_status = Tinebase_Model_Alarm::STATUS_SUCCESS;
                     $appController->sendAlarm($alarm);
                 } catch (Exception $e) {
                     Tinebase_Exception::log($e);
                     $alarm->sent_message = $e->getMessage();
                     $alarm->sent_status = Tinebase_Model_Alarm::STATUS_FAILURE;
                 }
                 if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
                     Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Updating alarm status: ' . $alarm->sent_status);
                 }
                 $this->update($alarm);
             }
         }
         $job = Tinebase_AsyncJob::getInstance()->finishJob($job);
     } catch (Exception $e) {
         // save new status 'failure'
         $job = Tinebase_AsyncJob::getInstance()->finishJob($job, Tinebase_Model_AsyncJob::STATUS_FAILURE, $e->getMessage());
         if (Tinebase_Core::isLogLevel(Zend_Log::WARN)) {
             Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' Job failed: ' . $e->getMessage());
         }
         if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
             Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' ' . $e->getTraceAsString());
         }
     }
     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Job ' . $eventName . ' finished.');
     }
 }
 /**
  * Search server plugins from applications configuration
  *
  */
 protected static function _searchServerPlugins()
 {
     $cache = Tinebase_Core::getCache();
     if ($cache && ($plugins = $cache->load(self::TINEBASE_SERVER_PLUGINS))) {
         return $plugins;
     }
     // get list of available applications
     $applications = array();
     $d = dir(realpath(__DIR__ . '/../'));
     while (false !== ($entry = $d->read())) {
         if ($entry[0] == '.') {
             continue;
         }
         if (ctype_upper($entry[0]) && is_dir($d->path . DIRECTORY_SEPARATOR . $entry)) {
             $applications[] = $entry;
         }
     }
     $d->close();
     // get list of plugins
     $plugins = array();
     foreach ($applications as $application) {
         $config = $application . '_Config';
         try {
             if (class_exists($config)) {
                 $reflectedClass = new ReflectionClass($config);
                 if ($reflectedClass->isSubclassOf('Tinebase_Config_Abstract')) {
                     $plugins = array_merge($plugins, call_user_func(array($config, 'getServerPlugins')));
                 }
             }
         } catch (Exception $e) {
             Tinebase_Exception::log($e);
         }
     }
     // sort plugins by priority
     asort($plugins);
     $plugins = array_keys($plugins);
     if ($cache) {
         $cache->save($plugins, self::TINEBASE_SERVER_PLUGINS);
     }
     return $plugins;
 }
 /**
  * Returns registry data of all applications current user has access to
  * @see Tinebase_Application_Json_Abstract
  *
  * @return mixed array 'variable name' => 'data'
  */
 public function getAllRegistryData()
 {
     $registryData = array();
     if (Tinebase_Core::getUser()) {
         $userApplications = Tinebase_Core::getUser()->getApplications(TRUE);
         $clientConfig = Tinebase_Config::getInstance()->getClientRegistryConfig();
         if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) {
             /** @noinspection PhpUndefinedFieldInspection */
             Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' User applications to fetch registry for: ' . print_r($userApplications->name, TRUE));
         }
         /** @noinspection PhpUndefinedFieldInspection */
         if (!in_array('Tinebase', $userApplications->name)) {
             Tinebase_Core::getLogger()->err(__METHOD__ . '::' . __LINE__ . ' User has no permissions to run Tinebase.');
             $this->logout();
             throw new Tinebase_Exception_AccessDenied('User has no permissions to run Tinebase');
         }
         foreach ($userApplications as $application) {
             $jsonAppName = $application->name . '_Frontend_Json';
             if (class_exists($jsonAppName)) {
                 if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
                     Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Getting registry data for app ' . $application->name);
                 }
                 try {
                     $applicationJson = new $jsonAppName();
                     $registryData[$application->name] = isset($registryData[$application->name]) || array_key_exists($application->name, $registryData) ? array_merge_recursive($registryData[$application->name], $applicationJson->getRegistryData()) : $applicationJson->getRegistryData();
                 } catch (Exception $e) {
                     Tinebase_Exception::log($e);
                     if (!$e instanceof Tinebase_Exception_AccessDenied && !in_array($application->name, array('Tinebase', 'Addressbook', 'Admin'))) {
                         Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' Disabling ' . $application->name . ': ' . $e);
                         Tinebase_Application::getInstance()->setApplicationState(array($application->getId()), Tinebase_Application::DISABLED);
                     }
                     unset($registryData[$application->name]);
                     continue;
                 }
                 $registryData[$application->name]['rights'] = Tinebase_Core::getUser()->getRights($application->name);
                 $registryData[$application->name]['config'] = isset($clientConfig[$application->name]) ? $clientConfig[$application->name]->toArray() : array();
                 $registryData[$application->name]['models'] = $applicationJson->getModelsConfiguration();
                 $registryData[$application->name]['defaultModel'] = $applicationJson->getDefaultModel();
                 foreach ($applicationJson->getRelatableModels() as $relModel) {
                     $registryData[$relModel['ownApp']]['relatableModels'][] = $relModel;
                 }
                 // @todo do we need this for all apps?
                 $exportDefinitions = Tinebase_ImportExportDefinition::getInstance()->getExportDefinitionsForApplication($application);
                 $registryData[$application->name]['exportDefinitions'] = array('results' => $exportDefinitions->toArray(), 'totalcount' => count($exportDefinitions));
                 $customfields = Tinebase_CustomField::getInstance()->getCustomFieldsForApplication($application);
                 Tinebase_CustomField::getInstance()->resolveConfigGrants($customfields);
                 $registryData[$application->name]['customfields'] = $customfields->toArray();
                 // add preferences for app
                 $appPrefs = Tinebase_Core::getPreference($application->name);
                 if ($appPrefs !== NULL) {
                     $allPrefs = $appPrefs->getAllApplicationPreferences();
                     if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) {
                         Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' ' . print_r($allPrefs, TRUE));
                     }
                     foreach ($allPrefs as $pref) {
                         try {
                             $registryData[$application->name]['preferences'][$pref] = $appPrefs->{$pref};
                         } catch (Exception $e) {
                             Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' Could not get ' . $pref . '  preference: ' . $e);
                         }
                     }
                 }
             }
         }
     } else {
         $registryData['Tinebase'] = $this->getRegistryData();
     }
     return $registryData;
 }
 /**
  * testParallelAlarmTrigger
  * 
  * @see 0004878: improve asyncJob fencing
  */
 public function testParallelAlarmTrigger()
 {
     $this->_testNeedsTransaction();
     try {
         $this->_emailTestClass = new Felamimail_Controller_MessageTest();
         $this->_emailTestClass->setup();
     } catch (Exception $e) {
         Tinebase_Exception::log($e);
         $this->markTestIncomplete('email not available.');
     }
     Tinebase_Alarm::getInstance()->sendPendingAlarms("Tinebase_Event_Async_Minutely");
     self::flushMailer();
     $this->_getAlarmMails(TRUE);
     $event = $this->_getEvent();
     $event->dtstart = Tinebase_DateTime::now()->addMinute(15);
     $event->dtend = clone $event->dtstart;
     $event->dtend->addMinute(30);
     $event->attendee = $this->_getAttendee();
     $event->alarms = new Tinebase_Record_RecordSet('Tinebase_Model_Alarm', array(new Tinebase_Model_Alarm(array('minutes_before' => 30), TRUE)));
     $persistentEvent = $this->_eventController->create($event);
     try {
         Tinebase_AsyncJobTest::triggerAsyncEvents();
     } catch (Exception $e) {
         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Something strange happened and the async jobs did not complete ... maybe the test system is not configured correctly for this: ' . $e);
         $this->markTestIncomplete($e->getMessage());
     }
     $result = $this->_getAlarmMails(TRUE);
     $this->assertEquals(1, count($result), 'expected exactly 1 alarm mail, got: ' . print_r($result->toArray(), TRUE));
 }
 /**
  * fetch import definition data
  *
  * @return array
  */
 protected function _getImportDefinitionRegistryData()
 {
     $definitionConverter = new Tinebase_Convert_ImportExportDefinition_Json();
     $importDefinitions = $this->_getImportDefinitions();
     $defaultDefinition = $this->_getDefaultImportDefinition($importDefinitions);
     try {
         $defaultDefinitionArray = $definitionConverter->fromTine20Model($defaultDefinition);
     } catch (Exception $e) {
         Tinebase_Exception::log($e);
         $defaultDefinitionArray = array();
     }
     try {
         $definitionsArray = $definitionConverter->fromTine20RecordSet($importDefinitions);
     } catch (Exception $e) {
         Tinebase_Exception::log($e);
         $definitionsArray = array();
     }
     $definitionData = array('defaultImportDefinition' => $defaultDefinitionArray, 'importDefinitions' => array('results' => $definitionsArray, 'totalcount' => count($definitionsArray)));
     return $definitionData;
 }
 /**
  * set flags on cache if different
  * 
  * @param array $flags
  * @param Felamimail_Model_Folder $_folderId
  * @param Tinebase_Record_RecordSet $messages
  * @param boolean $checkDiff
  */
 protected function _setFlagsOnCache($flags, $folder, $messages, $checkDiff = true)
 {
     $transactionId = Tinebase_TransactionManager::getInstance()->startTransaction(Tinebase_Core::getDb());
     $supportedFlags = array_keys(Felamimail_Controller_Message_Flags::getInstance()->getSupportedFlags(FALSE));
     $updateCount = 0;
     foreach ($messages as $cachedMessage) {
         if (isset($flags[$cachedMessage->messageuid]) || array_key_exists($cachedMessage->messageuid, $flags)) {
             $newFlags = array_intersect($flags[$cachedMessage->messageuid]['flags'], $supportedFlags);
             if ($checkDiff) {
                 $cachedFlags = array_intersect($cachedMessage->flags, $supportedFlags);
                 $diff1 = array_diff($cachedFlags, $newFlags);
                 $diff2 = array_diff($newFlags, $cachedFlags);
             }
             if (!$checkDiff || count($diff1) > 0 || count($diff2) > 0) {
                 try {
                     $this->_backend->setFlags(array($cachedMessage->getId()), $newFlags, $folder->getId());
                     $updateCount++;
                 } catch (Zend_Db_Statement_Exception $zdse) {
                     if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) {
                         Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__ . ' Could not update flags, maybe message was deleted or is not in the cache yet.');
                     }
                     Tinebase_Exception::log($zdse);
                 }
             }
         }
     }
     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Updated ' . $updateCount . ' messages.');
     }
     Tinebase_TransactionManager::getInstance()->commitTransaction($transactionId);
 }
 /**
  * install given application
  *
  * @param  SimpleXMLElement $_xml
  * @param  array | optional $_options
  * @return void
  * @throws Tinebase_Exception_Backend_Database
  */
 protected function _installApplication(SimpleXMLElement $_xml, $_options = null)
 {
     if ($this->_backend === NULL) {
         throw new Tinebase_Exception_Backend_Database('Need configured and working database backend for install.');
     }
     try {
         if (Setup_Core::isLogLevel(Zend_Log::INFO)) {
             Setup_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' Installing application: ' . $_xml->name);
         }
         $createdTables = array();
         // traditional xml declaration
         if (isset($_xml->tables)) {
             foreach ($_xml->tables[0] as $tableXML) {
                 $table = Setup_Backend_Schema_Table_Factory::factory('Xml', $tableXML);
                 $this->_createTable($table);
                 $createdTables[] = $table;
             }
         } else {
             $application = Setup_Core::getApplicationInstance($_xml->name, '', true);
             $models = $application->getModels(true);
             if (count($models) > 0) {
                 // create tables using doctrine 2
                 Setup_SchemaTool::createSchema($_xml->name, $models);
                 // adopt to old workflow
                 foreach ($models as $model) {
                     $modelConfiguration = $model::getConfiguration();
                     $createdTables[] = (object) array('name' => Tinebase_Helper::array_value('name', $modelConfiguration->getTable()), 'version' => $modelConfiguration->getVersion());
                 }
             }
         }
         $application = new Tinebase_Model_Application(array('name' => (string) $_xml->name, 'status' => $_xml->status ? (string) $_xml->status : Tinebase_Application::ENABLED, 'order' => $_xml->order ? (string) $_xml->order : 99, 'version' => (string) $_xml->version));
         $application = Tinebase_Application::getInstance()->addApplication($application);
         // keep track of tables belonging to this application
         foreach ($createdTables as $table) {
             Tinebase_Application::getInstance()->addApplicationTable($application, (string) $table->name, (int) $table->version);
         }
         // insert default records
         if (isset($_xml->defaultRecords)) {
             foreach ($_xml->defaultRecords[0] as $record) {
                 $this->_backend->execInsertStatement($record);
             }
         }
         // look for import definitions and put them into the db
         $this->createImportExportDefinitions($application);
         Setup_Initialize::initialize($application, $_options);
     } catch (Exception $e) {
         Tinebase_Exception::log($e, false);
         throw $e;
     }
 }
 /**
  * delete groups
  *
  * @param   mixed $_groupId
  * @throws  Tinebase_Exception_Backend
  */
 public function deleteGroups($_groupId)
 {
     $groupIds = array();
     if (is_array($_groupId) or $_groupId instanceof Tinebase_Record_RecordSet) {
         foreach ($_groupId as $groupId) {
             $groupIds[] = Tinebase_Model_Group::convertGroupIdToInt($groupId);
         }
     } else {
         $groupIds[] = Tinebase_Model_Group::convertGroupIdToInt($_groupId);
     }
     try {
         $transactionId = Tinebase_TransactionManager::getInstance()->startTransaction(Tinebase_Core::getDb());
         $this->deleteGroupsInSqlBackend($groupIds);
         if ($this instanceof Tinebase_Group_Interface_SyncAble) {
             $this->deleteGroupsInSyncBackend($groupIds);
         }
         Tinebase_TransactionManager::getInstance()->commitTransaction($transactionId);
     } catch (Exception $e) {
         Tinebase_TransactionManager::getInstance()->rollBack();
         Tinebase_Exception::log($e);
         throw new Tinebase_Exception_Backend($e->getMessage());
     }
 }
 /**
  * get registry data from application frontend json class
  *
  * @param Tinebase_Model_Application $application
  * @return array
  * @throws Tinebase_Exception_InvalidArgument
  */
 protected function _getCustomAppRegistry(Tinebase_Model_Application $application)
 {
     $jsonAppName = $application->name . '_Frontend_Json';
     if (!class_exists($jsonAppName)) {
         return array();
     }
     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Getting registry data for app ' . $application->name);
     }
     try {
         $applicationJson = new $jsonAppName();
         $registryData = $applicationJson->getRegistryData();
     } catch (Exception $e) {
         Tinebase_Exception::log($e);
         if (!$e instanceof Tinebase_Exception_AccessDenied && !in_array($application->name, array('Tinebase', 'Addressbook', 'Admin'))) {
             Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' Disabling ' . $application->name . ': ' . $e);
             Tinebase_Application::getInstance()->setApplicationState(array($application->getId()), Tinebase_Application::DISABLED);
         }
         return array();
     }
     // TODO get this from app controller / modelconfig
     foreach ($applicationJson->getRelatableModels() as $relModel) {
         $registryData[$relModel['ownApp']]['relatableModels'][] = $relModel;
     }
     $registryData['models'] = $applicationJson->getModelsConfiguration();
     $registryData['defaultModel'] = $applicationJson->getDefaultModel();
     return $registryData;
 }
 /**
  * send deactivation email to user
  * 
  * @param mixed $accountId
  */
 public function sendDeactivationNotification($accountId)
 {
     if (!Tinebase_Config::getInstance()->get(Tinebase_Config::ACCOUNT_DEACTIVATION_NOTIFICATION)) {
         if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
             Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Deactivation notification disabled.');
         }
         return;
     }
     try {
         $user = $this->getFullUserById($accountId);
         if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
             Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Send deactivation notification to user ' . $user->accountLoginName);
         }
         $translate = Tinebase_Translation::getTranslation('Tinebase');
         $view = new Zend_View();
         $view->setScriptPath(dirname(__FILE__) . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'views');
         $view->translate = $translate;
         $view->accountLoginName = $user->accountLoginName;
         // TODO add this?
         //$view->deactivationDate     = $user->deactivationDate;
         $view->tine20Url = Tinebase_Core::getHostname();
         $messageBody = $view->render('deactivationNotification.php');
         $messageSubject = $translate->_('Your Tine 2.0 account has been deactivated');
         $recipient = Addressbook_Controller_Contact::getInstance()->getContactByUserId($user->getId(), true);
         Tinebase_Notification::getInstance()->send(null, array($recipient), $messageSubject, $messageBody);
     } catch (Exception $e) {
         Tinebase_Exception::log($e);
     }
 }
 /**
  * saves image to db
  *
  * @param  string $contactId
  * @param  blob $imageData
  * @return blob|string
  */
 public function _saveImage($contactId, $imageData)
 {
     if (!empty($imageData)) {
         // make sure that we got a valid image blob
         try {
             Tinebase_ImageHelper::getImageInfoFromBlob($imageData);
         } catch (Exception $e) {
             Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__ . ' Invalid image blob data, preserving old image');
             Tinebase_Exception::log($e);
             return $this->getImage($contactId);
         }
     }
     if (!empty($imageData)) {
         $currentImg = $this->getImage($contactId);
         if (empty($currentImg)) {
             if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
                 Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Creating contact image.');
             }
             $this->_db->insert($this->_tablePrefix . 'addressbook_image', array('contact_id' => $contactId, 'image' => base64_encode($imageData)));
         } else {
             if ($currentImg !== $imageData) {
                 if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
                     Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Updating contact image.');
                 }
                 $where = array($this->_db->quoteInto($this->_db->quoteIdentifier('contact_id') . ' = ?', $contactId));
                 $this->_db->update($this->_tablePrefix . 'addressbook_image', array('image' => base64_encode($imageData)), $where);
             }
         }
     } else {
         $this->_db->delete($this->_tablePrefix . 'addressbook_image', $this->_db->quoteInto($this->_db->quoteIdentifier('contact_id') . ' = ?', $contactId));
     }
     return $imageData;
 }
 /**
  * get grants for containers assigned to given account of multiple records
  *
  * @param   Tinebase_Record_RecordSet   $_records records to get the grants for
  * @param   string|Tinebase_Model_User  $_accountId the account to get the grants for
  * @param   string                      $_containerProperty container property
  * @param   string                      $_grantModel
  * @throws  Tinebase_Exception_NotFound
  * @return  array of containers|void
  */
 public function getContainerGrantsOfRecords(Tinebase_Record_RecordSet $_records, $_accountId, $_containerProperty = 'container_id', $_grantModel = 'Tinebase_Model_Grants')
 {
     $containerIds = array();
     foreach ($_records as $record) {
         if (isset($record[$_containerProperty]) && !isset($containerIds[Tinebase_Model_Container::convertContainerIdToInt($record[$_containerProperty])])) {
             $containerIds[Tinebase_Model_Container::convertContainerIdToInt($record[$_containerProperty])] = null;
         }
     }
     if (empty($containerIds)) {
         return array();
     }
     $accountId = $_accountId instanceof Tinebase_Record_Abstract ? $_accountId->getId() : $_accountId;
     $select = $this->_getSelect('*', TRUE)->where("{$this->_db->quoteIdentifier('container.id')} IN (?)", array_keys($containerIds))->join(array('container_acl' => SQL_TABLE_PREFIX . 'container_acl'), "{$this->_db->quoteIdentifier('container_acl.container_id')} = {$this->_db->quoteIdentifier('container.id')}", array('*', 'account_grants' => $this->_dbCommand->getAggregate('container_acl.account_grant')))->group('container.id', 'container_acl.account_type', 'container_acl.account_id');
     $this->addGrantsSql($select, $accountId, '*');
     Tinebase_Backend_Sql_Abstract::traitGroup($select);
     $stmt = $this->_db->query('/*' . __FUNCTION__ . '*/' . $select);
     $rows = $stmt->fetchAll(Zend_Db::FETCH_ASSOC);
     $containers = array();
     // add results to container ids and get grants array
     foreach ($rows as $row) {
         // NOTE id is non-ambiguous
         $row['id'] = $row['container_id'];
         $grantsArray = array_unique(explode(',', $row['account_grants']));
         $row['account_grants'] = $this->_getGrantsFromArray($grantsArray, $accountId, $_grantModel)->toArray();
         $containers[$row['id']] = new Tinebase_Model_Container($row, TRUE);
         try {
             $containers[$row['id']]->path = $containers[$row['id']]->getPath();
         } catch (Exception $e) {
             // @todo is it correct to catch all exceptions here?
             Tinebase_Exception::log($e);
         }
     }
     return $containers;
 }
 /**
  * call configured hooks for adjusting synced user data
  * 
  * @param Tinebase_Model_FullUser $user
  * @param array $userProperties
  * @return boolean if false, user is skipped
  */
 protected static function _syncUserHook(Tinebase_Model_FullUser $user, $userProperties)
 {
     $result = true;
     $hookClass = Tinebase_Config::getInstance()->get(Tinebase_Config::SYNC_USER_HOOK_CLASS);
     if ($hookClass && class_exists($hookClass)) {
         $hook = new $hookClass();
         if (method_exists($hook, 'syncUser')) {
             if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
                 Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Calling ' . $hookClass . '::syncUser() ...');
             }
             try {
                 $result = call_user_func_array(array($hook, 'syncUser'), array($user, $userProperties));
             } catch (Tinebase_Exception $te) {
                 Tinebase_Exception::log($te);
                 return false;
             }
         }
     }
     return $result;
 }
 /**
  * get Syncroton_Model_Folder folders recursively by parentFolder
  *
  * @param Expressomail_Model_Folder $parentFolder
  * @param array $result
  * @return array of Syncroton_Model_Folder
  */
 protected function _getFolders($parentFolder = NULL, &$result = array())
 {
     $globalname = $parentFolder ? $parentFolder->globalname : '';
     $account = $this->_getAccount();
     if (!$account) {
         return array();
     }
     $filter = new Expressomail_Model_FolderFilter(array(array('field' => 'globalname', 'operator' => 'startswith', 'value' => $globalname), array('field' => 'account_id', 'operator' => 'equals', 'value' => $account->getId())));
     try {
         $folders = Expressomail_Controller_Folder::getInstance()->search($filter);
     } catch (Expressomail_Exception_IMAPInvalidCredentials $feiic) {
         Tinebase_Exception::log($feiic, null, array('accountname' => $account->name));
         return array();
     }
     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " Found " . count($folders) . ' subfolders of folder "' . $globalname . '"');
     }
     foreach ($folders as $folder) {
         if (!$folder->is_selectable) {
             continue;
         }
         $serverId = md5($folder->getId());
         $result[$serverId] = new Syncroton_Model_Folder(array('serverId' => $serverId, 'parentId' => $parentFolder ? md5($parentFolder->getId()) : 0, 'displayName' => substr($folder->localname, 0, 254), 'type' => $this->_getFolderType($folder), 'bigfolderid' => $folder->getId()));
         if ($folder->has_children) {
             $this->_getFolders($folder, $result);
         }
     }
     return $result;
 }
 /**
  * get addressbook import definitions
  * 
  * @return array
  * 
  * @todo generalize this
  */
 protected function _getImportDefinitions()
 {
     $filter = new Tinebase_Model_ImportExportDefinitionFilter(array(array('field' => 'application_id', 'operator' => 'equals', 'value' => Tinebase_Application::getInstance()->getApplicationByName('Calendar')->getId()), array('field' => 'type', 'operator' => 'equals', 'value' => 'import')));
     $definitionConverter = new Tinebase_Convert_ImportExportDefinition_Json();
     try {
         $importDefinitions = Tinebase_ImportExportDefinition::getInstance()->search($filter);
         $defaultDefinition = $this->_getDefaultImportDefinition($importDefinitions);
         $result = array('results' => $definitionConverter->fromTine20RecordSet($importDefinitions), 'totalcount' => count($importDefinitions), 'default' => $defaultDefinition ? $definitionConverter->fromTine20Model($defaultDefinition) : array());
     } catch (Exception $e) {
         Tinebase_Exception::log($e);
         $result = array(array('results' => array(), 'totalcount' => 0, 'default' => array()));
     }
     return $result;
 }
 /**
  * processAutoInvoiceIteration
  * 
  * @param Tinebase_Record_RecordSet $contracts
  * @param Tinebase_DateTime $currentDate
  * @param boolean $merge
  */
 public function processAutoInvoiceIteration($contracts, $currentDate, $merge)
 {
     Timetracker_Controller_Timeaccount::getInstance()->resolveCustomfields(FALSE);
     Timetracker_Controller_Timesheet::getInstance()->resolveCustomfields(FALSE);
     Sales_Controller_Contract::getInstance()->resolveCustomfields(FALSE);
     Sales_Controller_Contract::getInstance()->setHandleDependentRecords(FALSE);
     Sales_Controller_ProductAggregate::getInstance()->resolveCustomfields(FALSE);
     $contracts->setTimezone(Tinebase_Core::getUserTimezone());
     foreach ($contracts as $contract) {
         $transactionId = Tinebase_TransactionManager::getInstance()->startTransaction(Tinebase_Core::getDb());
         try {
             $this->_createAutoInvoicesForContract($contract, clone $currentDate, $merge);
             Tinebase_TransactionManager::getInstance()->commitTransaction($transactionId);
         } catch (Exception $e) {
             Tinebase_TransactionManager::getInstance()->rollBack();
             $failure = 'Could not create auto invoice for contract "' . $contract->title . '" Exception: ' . $e->getCode() . ' has been thrown: "' . $e->getMessage() . '".';
             $this->_autoInvoiceIterationFailures[] = $failure;
             Tinebase_Exception::log($e, FALSE);
         }
     }
     Sales_Controller_Contract::getInstance()->setHandleDependentRecords(TRUE);
     Sales_Controller_Contract::getInstance()->resolveCustomfields(TRUE);
     Sales_Controller_ProductAggregate::getInstance()->resolveCustomfields(TRUE);
     Timetracker_Controller_Timeaccount::getInstance()->resolveCustomfields(TRUE);
     Timetracker_Controller_Timesheet::getInstance()->resolveCustomfields(TRUE);
 }
 /**
  * cleanup old sessions files => needed only for filesystems based sessions
  */
 public function cleanupSessions()
 {
     $config = Tinebase_Core::getConfig();
     $backendType = $config->session && $config->session->backend ? ucfirst($config->session->backend) : 'File';
     if (strtolower($backendType) == 'file') {
         $maxLifeTime = $config->session && $config->session->lifetime ? $config->session->lifetime : 86400;
         $path = Tinebase_Session_Abstract::getSessionDir();
         $unlinked = 0;
         try {
             $dir = new DirectoryIterator($path);
         } catch (Exception $e) {
             if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) {
                 Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__ . " Could not cleanup sessions");
             }
             Tinebase_Exception::log($e);
             return;
         }
         foreach ($dir as $fileinfo) {
             if (!$fileinfo->isDot() && !$fileinfo->isLink() && $fileinfo->isFile()) {
                 if ($fileinfo->getMTime() < Tinebase_DateTime::now()->getTimestamp() - $maxLifeTime) {
                     unlink($fileinfo->getPathname());
                     $unlinked++;
                 }
             }
         }
         if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) {
             Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . " Deleted {$unlinked} expired session files");
         }
         Tinebase_Config::getInstance()->set(Tinebase_Config::LAST_SESSIONS_CLEANUP_RUN, Tinebase_DateTime::now()->toString());
     }
 }
 /**
  * send notification to a single attender
  * 
  * @param Calendar_Model_Attender    $_attender
  * @param Calendar_Model_Event       $_event
  * @param Tinebase_Model_FullAccount $_updater
  * @param string                     $_action
  * @param string                     $_notificationLevel
  * @param array                      $_updates
  * @return void
  *
  * TODO this needs major refactoring
  */
 public function sendNotificationToAttender(Calendar_Model_Attender $_attender, $_event, $_updater, $_action, $_notificationLevel, $_updates = NULL)
 {
     try {
         $organizer = $_event->resolveOrganizer();
         $organizerAccountId = $organizer->account_id;
         $attendee = $_attender->getResolvedUser();
         if ($attendee instanceof Addressbook_Model_List) {
             // don't send notification to lists as we already resolved the list members for individual mails
             if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
                 Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " Skip notification for list " . $attendee->name);
             }
             return;
         }
         $attendeeAccountId = $_attender->getUserAccountId();
         $prefUserId = $attendeeAccountId ? $attendeeAccountId : ($organizerAccountId ? $organizerAccountId : $_event->created_by);
         try {
             $prefUser = Tinebase_User::getInstance()->getFullUserById($prefUserId);
         } catch (Exception $e) {
             $prefUser = Tinebase_Core::getUser();
             $prefUserId = $prefUser->getId();
         }
         // get prefered language, timezone and notification level
         $locale = Tinebase_Translation::getLocale(Tinebase_Core::getPreference()->getValueForUser(Tinebase_Preference::LOCALE, $prefUserId));
         $timezone = Tinebase_Core::getPreference()->getValueForUser(Tinebase_Preference::TIMEZONE, $prefUserId);
         $translate = Tinebase_Translation::getTranslation('Calendar', $locale);
         $sendLevel = Tinebase_Core::getPreference('Calendar')->getValueForUser(Calendar_Preference::NOTIFICATION_LEVEL, $prefUserId);
         $sendOnOwnActions = Tinebase_Core::getPreference('Calendar')->getValueForUser(Calendar_Preference::SEND_NOTIFICATION_OF_OWN_ACTIONS, $prefUserId);
         $sendAlarms = Tinebase_Core::getPreference('Calendar')->getValueForUser(Calendar_Preference::SEND_ALARM_NOTIFICATIONS, $prefUserId);
         // external (non account) notification
         if (!$attendeeAccountId) {
             // external organizer needs status updates
             $sendLevel = is_object($organizer) && $_attender->getEmail() == $organizer->getPreferedEmailAddress() ? 40 : 30;
             $sendOnOwnActions = false;
             $sendAlarms = false;
         }
         $recipients = array($attendee);
         $this->_handleResourceEditors($_attender, $_notificationLevel, $recipients, $_action, $sendLevel, $_updates);
         // check if user wants this notification NOTE: organizer gets mails unless she set notificationlevel to NONE
         // NOTE prefUser is organizer for external notifications
         if ($attendeeAccountId == $_updater->getId() && !$sendOnOwnActions || $sendLevel < $_notificationLevel && (is_object($organizer) && method_exists($attendee, 'getPreferedEmailAddress') && $attendee->getPreferedEmailAddress() != $organizer->getPreferedEmailAddress() || is_object($organizer) && !method_exists($attendee, 'getPreferedEmailAddress') && $attendee->email != $organizer->getPreferedEmailAddress() || $sendLevel == self::NOTIFICATION_LEVEL_NONE)) {
             if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
                 Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " Preferred notification level not reached -> skipping notification for {$_attender->getEmail()}");
             }
             return;
         }
         if ($_action == 'alarm' && !$sendAlarms) {
             if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
                 Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " User does not want alarm mails -> skipping notification for {$_attender->getEmail()}");
             }
             return;
         }
         $method = NULL;
         // NOTE $method gets set in _getSubject as referenced param
         $messageSubject = $this->_getSubject($_event, $_notificationLevel, $_action, $_updates, $timezone, $locale, $translate, $method, $_attender);
         // we don't send iMIP parts to external attendee if config is active
         if (Calendar_Config::getInstance()->get(Calendar_Config::DISABLE_EXTERNAL_IMIP) && !$attendeeAccountId) {
             if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) {
                 Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . " External iMIP is disabled.");
             }
             $method = NULL;
         }
         $view = new Zend_View();
         $view->setScriptPath(dirname(__FILE__) . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'views');
         $view->translate = $translate;
         $view->timezone = $timezone;
         $view->event = $_event;
         $view->updater = $_updater;
         $view->updates = $_updates;
         $messageBody = $view->render('eventNotification.php');
         $calendarPart = null;
         $attachments = $this->_getAttachments($method, $_event, $_action, $_updater, $calendarPart);
         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, $recipients, $messageSubject, $messageBody, $calendarPart, $attachments);
     } catch (Exception $e) {
         Tinebase_Exception::log($e);
         return;
     }
 }
 /**
  * merges Recurrences of given events into the given event set
  * 
  * @param  Tinebase_Record_RecordSet    $_events
  * @param  Tinebase_DateTime                    $_from
  * @param  Tinebase_DateTime                    $_until
  * @return void
  */
 public static function mergeRecurrenceSet($_events, $_from, $_until)
 {
     if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) {
         Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . " from: {$_from} until: {$_until}");
     }
     //compute recurset
     $candidates = $_events->filter('rrule', "/^FREQ.*/", TRUE);
     foreach ($candidates as $candidate) {
         try {
             $exceptions = $_events->filter('recurid', "/^{$candidate->uid}-.*/", TRUE);
             $recurSet = Calendar_Model_Rrule::computeRecurrenceSet($candidate, $exceptions, $_from, $_until);
             foreach ($recurSet as $event) {
                 $_events->addRecord($event);
             }
             // check if candidate/baseEvent has an exception itself -> in this case remove baseEvent from set
             if (is_array($candidate->exdate) && in_array($candidate->dtstart, $candidate->exdate)) {
                 $_events->removeRecord($candidate);
             }
         } catch (Exception $e) {
             if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
                 Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " Could not compute recurSet of event: {$candidate->getId()}");
             }
             Tinebase_Exception::log($e);
             continue;
         }
     }
 }
 /**
  * get config for client registry
  * 
  * @return Tinebase_Config_Struct
  */
 public function getClientRegistryConfig()
 {
     // get all config names to be included in registry
     $clientProperties = new Tinebase_Config_Struct(array());
     $userApplications = Tinebase_Core::getUser()->getApplications(TRUE);
     foreach ($userApplications as $application) {
         $config = Tinebase_Config_Abstract::factory($application->name);
         if ($config) {
             $clientProperties[$application->name] = new Tinebase_Config_Struct(array());
             $properties = $config->getProperties();
             foreach ((array) $properties as $name => $definition) {
                 if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) {
                     Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' ' . print_r($definition, TRUE));
                 }
                 if ((isset($definition['clientRegistryInclude']) || array_key_exists('clientRegistryInclude', $definition)) && $definition['clientRegistryInclude'] === TRUE) {
                     // add definition here till we have a better place
                     try {
                         $configRegistryItem = new Tinebase_Config_Struct(array('value' => $config->{$name}, 'definition' => new Tinebase_Config_Struct($definition)));
                         if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) {
                             Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' ' . print_r($configRegistryItem->toArray(), TRUE));
                         }
                         $clientProperties[$application->name][$name] = $configRegistryItem;
                     } catch (Exception $e) {
                         Tinebase_Exception::log($e);
                     }
                 }
             }
             if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
                 Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Got ' . count($clientProperties[$application->name]) . ' config items for ' . $application->name . '.');
             }
         }
     }
     return $clientProperties;
 }