/** * implement logic for each controller in this function * * @param Tinebase_Event_Abstract $_eventObject */ public static function handleEvent(Tinebase_Event_Abstract $_eventObject) { if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . ' (' . __LINE__ . ') handle event of type ' . get_class($_eventObject)); } switch (get_class($_eventObject)) { case 'Admin_Event_AddAccount': $data = array('user' => $_eventObject->account->toArray(), 'action' => 'create'); break; /* case 'Admin_Event_DeleteAccount': break; case 'Admin_Event_UpdateGroup': break; case 'Admin_Event_AddGroupMember': break; case 'Admin_Event_RemoveGroupMember': break; case 'Tinebase_Event_Container_BeforeCreate': break; */ /* case 'Admin_Event_DeleteAccount': break; case 'Admin_Event_UpdateGroup': break; case 'Admin_Event_AddGroupMember': break; case 'Admin_Event_RemoveGroupMember': break; case 'Tinebase_Event_Container_BeforeCreate': break; */ default: // do nothing return; } if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . ' (' . __LINE__ . ') Push to Redis queue: ' . print_r($data, TRUE)); } Tinebase_ActionQueue::getInstance()->send($data); }
/** * event handler function * * all events get routed through this function * * @param Tinebase_Event_Abstract $_eventObject the eventObject */ protected function _handleEvent(Tinebase_Event_Abstract $_eventObject) { if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . ' (' . __LINE__ . ') handle event of type ' . get_class($_eventObject)); } switch (get_class($_eventObject)) { case 'Admin_Event_AddAccount': //$this->createPersonalFolder($_eventObject->account); Tinebase_Core::getPreference('Calendar')->getValueForUser(Calendar_Preference::DEFAULTCALENDAR, $_eventObject->account->getId()); break; case 'Admin_Event_DeleteAccount': // not a good idea, as it could be the originaters container for invitations // we need to move all contained events first //$this->deletePersonalFolder($_eventObject->account); break; case 'Admin_Event_UpdateGroup': if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . ' (' . __LINE__ . ') updated group ' . $_eventObject->group->name); } Tinebase_ActionQueue::getInstance()->queueAction('Calendar.onUpdateGroup', $_eventObject->group->getId()); break; case 'Admin_Event_AddGroupMember': if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . ' (' . __LINE__ . ') add groupmember ' . (string) $_eventObject->userId . ' to group ' . (string) $_eventObject->groupId); } Tinebase_ActionQueue::getInstance()->queueAction('Calendar.onUpdateGroup', $_eventObject->groupId); break; case 'Admin_Event_RemoveGroupMember': if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . ' (' . __LINE__ . ') removed groupmember ' . (string) $_eventObject->userId . ' from group ' . (string) $_eventObject->groupId); } Tinebase_ActionQueue::getInstance()->queueAction('Calendar.onUpdateGroup', $_eventObject->groupId); break; case 'Tinebase_Event_Container_BeforeCreate': $this->_handleContainerBeforeCreateEvent($_eventObject); break; } }
/** * process all jobs in queue */ public function processQueue() { // loop over all jobs while ($jobId = Tinebase_ActionQueue::getInstance()->waitForJob()) { $job = $this->receive($jobId); $this->executeAction($job); $this->delete($jobId); } }
/** * flush mailer (send all remaining mails first) */ public static function flushMailer() { // make sure all messages are sent if queue is activated if (isset(Tinebase_Core::getConfig()->actionqueue)) { Tinebase_ActionQueue::getInstance()->processQueue(10000); } self::getMailer()->flush(); }
/** * process given queue job * --message json encoded task * * @TODO rework user management, jobs should be executed as the right user in future * * @param Zend_Console_Getopt $_opts * @return boolean success */ public function executeQueueJob($_opts) { try { $cronuser = Tinebase_User::getInstance()->getFullUserByLoginName($_opts->username); } catch (Tinebase_Exception_NotFound $tenf) { $cronuser = $this->_getCronuserFromConfigOrCreateOnTheFly(); } Tinebase_Core::set(Tinebase_Core::USER, $cronuser); $args = $_opts->getRemainingArgs(); $message = preg_replace('/^message=/', '', $args[0]); if (!$message) { throw new Tinebase_Exception_InvalidArgument('mandatory parameter "message" is missing'); } Tinebase_ActionQueue::getInstance()->executeAction($message); return TRUE; }
/** * create user * * @return Tinebase_Model_FullUser */ protected function _createUser() { return Tinebase_ActionQueue::getInstance()->queueAction(array('key' => 'value')); }
/** * execute the action * * @param string $job * @todo make self::EXECUTION_METHOD_EXEC_CLI working */ protected function _executeAction($job) { // execute in subprocess if ($this->_getConfig()->tine20->executionMethod === self::EXECUTION_METHOD_EXEC_CLI) { $output = system('php $paths ./../../tine20.php --method Tinebase.executeQueueJob message=' . escapeshellarg($job), $exitCode); if (exitCode != 0) { throw new Exception('Problem during execution with shell: ' . $output); } // execute in same process } else { Tinebase_Core::initFramework(); Tinebase_Core::set(Tinebase_Core::USER, Tinebase_User::getInstance()->getFullUserById($job['account_id'])); Tinebase_ActionQueue::getInstance()->executeAction($job); } }
/** * testContainerNotification */ public function testContainerNotification() { // prepare smtp transport $smtpConfig = Tinebase_Config::getInstance()->get(Tinebase_Config::SMTP, new Tinebase_Config_Struct())->toArray(); if (empty($smtpConfig)) { $this->markTestSkipped('No SMTP config found: this is needed to send notifications.'); } $mailer = Tinebase_Smtp::getDefaultTransport(); // make sure all messages are sent if queue is activated if (isset(Tinebase_Core::getConfig()->actionqueue)) { Tinebase_ActionQueue::getInstance()->processQueue(100); } $mailer->flush(); // create and update container $container = $this->_saveContainer(); $container['type'] = Tinebase_Model_Container::TYPE_PERSONAL; $container['note'] = 'changed to personal'; $container['account_grants'] = $this->_getContainerGrants(); $containerUpdated = $this->_json->saveContainer($container); // make sure messages are sent if queue is activated if (isset(Tinebase_Core::getConfig()->actionqueue)) { Tinebase_ActionQueue::getInstance()->processQueue(); } // check notification message $messages = $mailer->getMessages(); $this->assertGreaterThan(0, count($messages)); $notification = $messages[0]; $translate = Tinebase_Translation::getTranslation('Admin'); $body = quoted_printable_decode($notification->getBodyText(TRUE)); $this->assertContains($container['note'], $body, $body); $subject = $notification->getSubject(); if (strpos($subject, 'UTF-8') !== FALSE) { $this->assertEquals(iconv_mime_encode('Subject', $translate->_('Your container has been changed'), array('scheme' => 'Q', 'line-length' => 500)), 'Subject: ' . $subject); } else { $this->assertEquals($translate->_('Your container has been changed'), $subject); } $this->assertTrue(in_array(Tinebase_Core::getUser()->accountEmailAddress, $notification->getRecipients())); }
/** * testInternalInvitationReplyAutoProcess * * an internal reply does not need to be processed of course */ public function testInternalInvitationReplyAutoProcess() { // flush mailer if (isset(Tinebase_Core::getConfig()->actionqueue)) { Tinebase_ActionQueue::getInstance()->processQueue(10000); } Tinebase_Smtp::getDefaultTransport()->flush(); $iMIP = $this->_getiMIP('REPLY', TRUE); $event = $iMIP->getEvent(); try { $this->_iMIPFrontend->autoProcess($iMIP); } catch (Exception $e) { $this->assertContains('TOPROCESS', $e->getMessage()); return; } $this->fail("autoProcess did not throw TOPROCESS Exception {$e}"); }
/** * Send a message to the queue * * @param mixed $message Message to send to the active queue * @return Zend_Queue_Message */ public function send($message) { Tinebase_ActionQueue::getInstance()->executeAction($message); }
/** * testAttendeeGroupMembersRecurringAddUser * * FIXME 0007352: fix Calendar_Controller_EventTests::testAttendeeGroupMembersRecurringAddUser */ public function testAttendeeGroupMembersRecurringAddUser() { $this->markTestIncomplete('test fails sometimes / needs fixing'); try { // cleanup if exists $cleanupUser = Tinebase_User::getInstance()->getFullUserByLoginName('testAttendeeGroupMembersAddUser'); Tinebase_User::getInstance()->deleteUser($cleanupUser); } catch (Exception $e) { // do nothing } $defaultGroup = Tinebase_Group::getInstance()->getDefaultGroup(); // create event and invite admin group $event = $this->_getEvent(); $event->rrule = 'FREQ=DAILY;INTERVAL=1'; $event->attendee = $this->_getAttendee(); $event->attendee[1] = new Calendar_Model_Attender(array('user_id' => $defaultGroup->getId(), 'user_type' => Calendar_Model_Attender::USERTYPE_GROUP, 'role' => Calendar_Model_Attender::ROLE_REQUIRED)); $persistentEvent = $this->_controller->create($event); // create a new user $newUser = Admin_Controller_User::getInstance()->create(new Tinebase_Model_FullUser(array('accountLoginName' => 'testAttendeeGroupMembersAddUser', 'accountStatus' => 'enabled', 'accountExpires' => NULL, 'accountPrimaryGroup' => $defaultGroup->getId(), 'accountLastName' => 'Tine 2.0', 'accountFirstName' => 'PHPUnit', 'accountEmailAddress' => '*****@*****.**')), Zend_Registry::get('testConfig')->password, Zend_Registry::get('testConfig')->password); if (isset(Tinebase_Core::getConfig()->actionqueue)) { Tinebase_ActionQueue::getInstance()->processQueue(10000); } $events = $this->_backend->search(new Calendar_Model_EventFilter(array(array('field' => 'container_id', 'operator' => 'in', 'value' => $this->_getTestCalendars()->getId()))), new Tinebase_Model_Pagination(array())); $oldSeries = $events->filter('rrule_until', '/.+/', TRUE)->getFirstRecord(); $newSeries = $events->filter('rrule_until', '/^$/', TRUE)->getFirstRecord(); $this->assertEquals(2, $events->count(), 'recur event must be splitted ' . print_r($events->toArray(), TRUE)); // check if this user was added to event $this->_controller->get($persistentEvent->getId()); $user = $oldSeries->attendee->filter('user_type', Calendar_Model_Attender::USERTYPE_GROUPMEMBER)->filter('user_id', $newUser->contact_id); $this->assertEquals(0, count($user), 'added user is attender of old event, but should not be'); $user = $newSeries->attendee->filter('user_type', Calendar_Model_Attender::USERTYPE_GROUPMEMBER)->filter('user_id', $newUser->contact_id); $this->assertEquals(1, count($user), 'added user is not attender of new event, but should be'); // cleanup user Admin_Controller_User::getInstance()->delete($newUser->getId()); if (isset(Tinebase_Core::getConfig()->actionqueue)) { Tinebase_ActionQueue::getInstance()->processQueue(10000); } $events = $this->_backend->search(new Calendar_Model_EventFilter(array(array('field' => 'container_id', 'operator' => 'in', 'value' => $this->_getTestCalendars()->getId()))), new Tinebase_Model_Pagination(array())); $newSeries = $events->filter('rrule_until', '/^$/', TRUE)->getFirstRecord(); // check if this user was deleted from event $user = $newSeries->attendee->filter('user_type', Calendar_Model_Attender::USERTYPE_GROUPMEMBER)->filter('user_id', $newUser->contact_id); $this->assertEquals(0, count($user), 'deleted user is attender of new event, but should not be'); }
/** * testActionQueueTriggeredByScheduler */ public function testActionQueueTriggeredByScheduler() { if (!isset(Tinebase_Core::getConfig()->actionqueue)) { return; } $user = Tinebase_Core::getUser(); $result1 = Tinebase_Container::getInstance()->getPersonalContainer($user, 'Addressbook', $user, '', TRUE); $scheduler = Tinebase_Core::getScheduler(); Tinebase_Scheduler_Task::addQueueTask($scheduler); Tinebase_ActionQueue::getInstance()->queueAction('Addressbook.createPersonalFolder', $user); $scheduler->run(); // check if user has 1 more personal folders now $result2 = Tinebase_Container::getInstance()->getPersonalContainer($user, 'Addressbook', $user, '', TRUE); $this->assertGreaterThan(count($result1), count($result2)); $migration = $result2->getMigration($result1->getArrayOfIds()); Tinebase_Container::getInstance()->delete($migration['toDeleteIds']); }
/** * send notifications * * @param Calendar_Model_Event $_event * @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) { Tinebase_ActionQueue::getInstance()->queueAction('Calendar.sendEventNotifications', $_event, $_updater, $_action, $_oldEvent ? $_oldEvent : NULL); }
/** * test number of children must not exceed configured maxChilds */ public function testMaxChildren() { $maxCilds = $this->_defaultConfig['maxChildren']; for ($i = 0; $i < $maxCilds + 1; $i++) { $filepath = $filepaths[] = tempnam("/tmp", __METHOD__); Tinebase_ActionQueue::getInstance()->queueAction('Tinebase.testSpy', $filepath, 10); } sleep(5); // collect states after 5 seconds of execution foreach ($filepaths as $i => $filepath) { $counter[$i] = (int) file_get_contents($filepath); } // wait for children to finish sleep(20); $daemonLog = file_get_contents($this->_daemonLog); foreach ($filepaths as $i => $filepath) { unlink($filepath); if ($i < $maxCilds) { $this->assertEquals(1, $counter[$i], "{$i} was not executed but should be \n{$daemonLog}"); } else { $this->assertEquals(0, $counter[$i], "{$i} was executed but shouldn't \n{$daemonLog}"); } } }
/** * send notifications * * @param Tinebase_Record_Interface $_event * @param Tinebase_Model_FullUser $_updater * @param String $_action * @param Tinebase_Record_Interface $_oldEvent * @param Array $_additionalData */ public function doSendNotifications(Tinebase_Record_Interface $_event, Tinebase_Model_FullUser $_updater, $_action, Tinebase_Record_Interface $_oldEvent = NULL, array $_additionalData = array()) { Tinebase_ActionQueue::getInstance()->queueAction('Calendar.sendEventNotifications', $_event, $_updater, $_action, $_oldEvent ? $_oldEvent : NULL); }
/** * process queue tasks (simple queue processing, intended to be executed from system cron job) * optional --numtasks param * * @param Zend_Console_Getopt $_opts * @return boolean success */ public function processQueue($_opts) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Start a worker for action queye from CLI.'); } try { $cronuser = Tinebase_User::getInstance()->getFullUserByLoginName($_opts->username); } catch (Tinebase_Exception_NotFound $tenf) { $cronuser = $this->_getCronuserFromConfigOrCreateOnTheFly(); } Tinebase_Core::set(Tinebase_Core::USER, $cronuser); $actionQueue = Tinebase_ActionQueue::getInstance(); $r = $_opts->numtasks ? $actionQueue->processQueue($_opts->numtasks) : $actionQueue->processQueue(); return TRUE; }