{
$messageToSend = $this->_getMessageData();
$messageToSend['headers'] = array_merge($messageToSend['headers'], $addtionalHeaders);
- $returned = $this->_json->saveMessage($messageToSend);
+ $this->_json->saveMessage($messageToSend);
$this->_foldersToClear = array('INBOX', $this->_account->sent_folder);
- // sleep for 2 secs because mailserver may be slower than expected
- sleep(2);
-
- $result = $this->_getMessages($folderName);
- $message = $this->_getMessageFromSearchResult($result, $messageToSend['subject']);
-
+ $i = 0;
+ while ($i < 5) {
+ $result = $this->_getMessages($folderName);
+ $message = $this->_getMessageFromSearchResult($result, $messageToSend['subject']);
+ if (! empty($message)) {
+ break;
+ }
+ // sleep for 1 sec because mailserver may be slower than expected
+ sleep(1);
+ $i++;
+ }
+
$this->assertTrue(! empty($message), 'Sent message not found.');
return $message;
$this->_uit->runNextScheduledImport();
$all = $cc->search($filter);
$this->assertEquals($seq, $all->getFirstRecord()->seq);
-
- // setting manual timestamp to force run again
- $record->timestamp = $record->timestamp->subHour(1)->subSecond(1);
-
- $this->_uit->update($record);
-
+
+ $this->_runAgain($record);
+
$this->_uit->runNextScheduledImport();
$all = $cc->search($filter);
$this->assertEquals(7, $all->count());
}
/**
+ * make import run again
+ *
+ * @param Tinebase_Model_Import|array $record
+ */
+ protected function _runAgain($record)
+ {
+ if (! $record instanceof Tinebase_Model_Import) {
+ $record = new Tinebase_Model_Import($record);
+ }
+
+ // setting manual timestamp to force run again
+ $record->timestamp = $record->timestamp->subHour(1)->subSecond(1);
+ $this->_uit->update($record);
+ }
+
+ /**
* @see 0011342: ics-scheduled import only imports 1 remote calendar
*/
public function testMultipleScheduledImports()
$this->assertEquals(0, count($result), 'no imports should be found: ' . print_r($result->toArray(), true));
}
+
+ /**
+ * @see 0012082: deactivate failing scheduled imports
+ */
+ public function testDeactivatingImport()
+ {
+ // create invalid import
+ $import1 = $this->createScheduledImport();
+
+ // run 5 (maxfailcount) times
+ for ($i = 1; $i <= Tinebase_Controller_ScheduledImport::MAXFAILCOUNT; $i++) {
+ $importRun = $this->_uit->runNextScheduledImport();
+ $this->assertTrue(isset($importRun['failcount']), 'failcount should exist (import run ' . $i . ')');
+ $this->assertEquals($i, $importRun['failcount'], 'failcount should increase: ' . print_r($importRun, true));
+ $this->_runAgain($importRun);
+ }
+
+ // check if import is deactivated
+ $importRun = $this->_uit->runNextScheduledImport();
+ $this->assertTrue($importRun === null, 'import should not run: ' . print_r($importRun, true));
+ }
}
),
'returns' => 'array'
), $smdArray['services']['Inventory.deleteInventoryItems']);
+
+ $this->assertEquals(array
+ (
+ 'envelope' => 'JSON-RPC-2.0',
+ 'transport' => 'POST',
+ 'parameters' => array
+ (
+ array
+ (
+ 'type' => 'array',
+ 'optional' => false,
+ 'name' => 'filter'
+ ),
+ array
+ (
+ 'type' => 'array',
+ 'optional' => false,
+ 'name' => 'paging'
+ )
+ ),
+ 'returns' => 'array'
+ ), $smdArray['services']['Inventory.searchInventoryItems']);
}
/**
foreach($this->_personas as $loginName => $persona) {
$this->_calendars[$loginName] = Tinebase_Container::getInstance()->getContainerById(Tinebase_Core::getPreference('Calendar')->getValueForUser(Calendar_Preference::DEFAULTCALENDAR, $persona->getId()));
- Tinebase_Container::getInstance()->addGrants($this->_calendars[$loginName]->getId(), 'user', $this->_personas['sclever']->getId(), $this->_secretaryGrants, true);
- Tinebase_Container::getInstance()->addGrants($this->_calendars[$loginName]->getId(), 'user', $this->_personas['rwright']->getId(), $this->_controllerGrants, true);
+ if (isset($this->_personas['sclever'])) {
+ Tinebase_Container::getInstance()->addGrants($this->_calendars[$loginName]->getId(), 'user', $this->_personas['sclever']->getId(), $this->_secretaryGrants, true);
+ }
+ if (isset($this->_personas['rwright'])) {
+ Tinebase_Container::getInstance()->addGrants($this->_calendars[$loginName]->getId(), 'user', $this->_personas['rwright']->getId(), $this->_controllerGrants, true);
+ }
}
}
$group = Tinebase_Group::getInstance()->getDefaultGroup();
Tinebase_Container::getInstance()->addGrants($this->sharedCalendar->getId(), 'group', $group->getId(), $this->_userGrants, true);
- Tinebase_Container::getInstance()->addGrants($this->sharedCalendar->getId(), 'user', $this->_personas['sclever']->getId(), $this->_secretaryGrants, true);
+ if (isset($this->_personas['sclever'])) {
+ Tinebase_Container::getInstance()->addGrants($this->sharedCalendar->getId(), 'user', $this->_personas['sclever']->getId(), $this->_secretaryGrants, true);
+ }
// create some resorces as well
$this->_ressources = array();
$tuesday = clone $this->_tuesday;
$wednesday = clone $this->_wednesday;
$thursday = clone $this->_thursday;
- $friday = clone $this->_friday;
$lastMonday = clone $this->_lastMonday;
$lastFriday = clone $this->_lastFriday;
$defaultData = array(
'container_id' => $this->sharedCalendar->getId(),
Tinebase_Model_Grants::GRANT_EDIT => true,
-
- 'attendee' => array(
- array_merge($defaultAttendeeData,
- array('user_id' => $this->_personas['pwulf']->toArray())
- ),
- array_merge($defaultAttendeeData,
- array('user_id' => $this->_personas['sclever']->toArray())
- ),
- array_merge($defaultAttendeeData,
- array('user_id' => $this->_personas['jsmith']->toArray())
- ),
- array_merge($defaultAttendeeData,
- array('user_id' => $this->_personas['jmcblack']->toArray())
- ),
- array_merge($defaultAttendeeData,
- array('user_id' => $this->_personas['rwright']->toArray())
- ),
- )
-
-
);
+ $defaultData['attendee'] = array();
+ foreach ($this->_personas as $persona) {
+ $defaultData['attendee'][] = array_merge($defaultAttendeeData,
+ array('user_id' => $persona->toArray())
+ );
+ }
+
$lastMonday->add(date_interval_create_from_date_string('20 weeks'));
$rruleUntilMondayMeeting = $lastMonday->format('d-m-Y') . ' 16:00:00';
array_merge_recursive($defaultData,
array(
'summary' => static::$_de ? 'Mittagspause' : 'lunchtime',
- 'description' => static::$_de ? '' : '',
+ 'description' => '',
'dtstart' => $monday->format('d-m-Y') . ' 12:00:00',
'dtend' => $monday->format('d-m-Y') . ' 13:00:00',
)),
array_merge_recursive($defaultEventData,
array(
'summary' => static::$_de ? 'Schwimmen gehen' : 'go swimming',
- 'description' => static::$_de ? '' : '',
+ 'description' => '',
'dtstart' => $thursday->format('d-m-Y') . ' 17:00:00',
'dtend' => $thursday->format('d-m-Y') . ' 18:00:00',
)
array_merge_recursive($defaultEventData,
array(
'summary' => static::$_de ? 'Auto aus der Werkstatt abholen' : 'fetch car from the garage',
- 'description' => static::$_de ? '' : '',
+ 'description' => '',
'dtstart' => $thursday->format('d-m-Y') . ' 15:00:00',
'dtend' => $thursday->format('d-m-Y') . ' 16:00:00',
)
array_merge_recursive($defaultEventData,
array(
'summary' => static::$_de ? 'Oper mit Lucy' : 'Got to the Opera with Lucy',
- 'description' => static::$_de ? 'Brighton Centre' : 'Brighton Centre',
+ 'description' => 'Brighton Centre',
'dtstart' => $sunday->format('d-m-Y') . ' 20:00:00',
'dtend' => $sunday->format('d-m-Y') . ' 21:30:00',
)
'color' => '#00CCFF'
), true));
- Tinebase_Container::getInstance()->addGrants($cal->getId(), 'user', $this->_personas['sclever']->getId(), $this->_secretaryGrants, true);
- Tinebase_Container::getInstance()->addGrants($cal->getId(), 'user', $this->_personas['rwright']->getId(), $this->_controllerGrants, true);
+ if (isset($this->_personas['sclever'])) {
+ Tinebase_Container::getInstance()->addGrants($cal->getId(), 'user', $this->_personas['sclever']->getId(), $this->_secretaryGrants, true);
+ }
+ if (isset($this->_personas['rwright'])) {
+ Tinebase_Container::getInstance()->addGrants($cal->getId(), 'user', $this->_personas['rwright']->getId(), $this->_controllerGrants, true);
+ }
$defaultEventData = array(
'container_id' => $cal->getId(),
array_merge_recursive($defaultEventData,
array(
'summary' => static::$_de ? 'Projektbesprechung Projekt Epsilon mit John' : 'Project Epsilon Meeting with John',
- 'description' => static::$_de ? '' : '',
+ 'description' => '',
'dtstart' => $monday->format('d-m-Y') . ' 08:00:00',
'dtend' => $monday->format('d-m-Y') . ' 09:30:00',
)
'color' => '#00CCFF'
), true));
- Tinebase_Container::getInstance()->addGrants($cal->getId(), 'user', $this->_personas['sclever']->getId(), $this->_secretaryGrants, true);
- Tinebase_Container::getInstance()->addGrants($cal->getId(), 'user', $this->_personas['rwright']->getId(), $this->_controllerGrants, true);
+ if (isset($this->_personas['sclever'])) {
+ Tinebase_Container::getInstance()->addGrants($cal->getId(), 'user', $this->_personas['sclever']->getId(), $this->_secretaryGrants, true);
+ }
+
+ if (isset($this->_personas['rwright'])) {
+ Tinebase_Container::getInstance()->addGrants($cal->getId(), 'user', $this->_personas['rwright']->getId(), $this->_controllerGrants, true);
+ }
$defaultEventData['container_id'] = $cal->getId();
$defaultEventData['attendee'][] = array(
'color' => '#00CCFF'
), true));
- Tinebase_Container::getInstance()->addGrants($cal->getId(), 'user', $this->_personas['sclever']->getId(), $this->_secretaryGrants, true);
+ if (isset($this->_personas['sclever'])) {
+ Tinebase_Container::getInstance()->addGrants($cal->getId(), 'user', $this->_personas['sclever']->getId(), $this->_secretaryGrants, true);
+ }
$defaultEventData = array(
'container_id' => $cal->getId(),
'color' => '#00CCFF'
), true));
- Tinebase_Container::getInstance()->addGrants($cal->getId(), 'user', $this->_personas['sclever']->getId(), $this->_secretaryGrants, true);
- Tinebase_Container::getInstance()->addGrants($cal->getId(), 'user', $this->_personas['rwright']->getId(), $this->_controllerGrants, true);
+ if (isset($this->_personas['sclever'])) {
+ Tinebase_Container::getInstance()->addGrants($cal->getId(), 'user', $this->_personas['sclever']->getId(), $this->_secretaryGrants, true);
+ }
+ if (isset($this->_personas['rwright'])) {
+ Tinebase_Container::getInstance()->addGrants($cal->getId(), 'user', $this->_personas['rwright']->getId(), $this->_controllerGrants, true);
+ }
$defaultEventData = array(
'container_id' => $cal->getId(),
onRecordUpdate: function() {
this.record.data.attachments = [];
var attachmentData = null;
+
+ var format = this.bodyCards.layout.activeItem.mimeType;
+ if (format.match(/^text/)) {
+ var editor = format == 'text/html' ? this.htmlEditor : this.textEditor;
+
+ this.record.set('content_type', format);
+ this.record.set('body', editor.getValue());
+ }
this.attachmentGrid.store.each(function(attachment) {
this.record.data.attachments.push(Ext.ux.file.Upload.file.getFileData(attachment));
return;
}
- var format = this.bodyCards.layout.activeItem.mimeType;
- if (format.match(/^text/)) {
- var editor = format == 'text/html' ? this.htmlEditor : this.textEditor;
-
- this.record.set('content_type', format);
- this.record.set('body', editor.getValue());
- }
-
Tine.log.debug('Tine.Felamimail.MessageEditDialog::doApplyChanges - call parent');
this.doApplyChanges(closeWindow);
if (mimeType == 'configured') {
var account = Tine.Tinebase.appMgr.get('Felamimail').getAccountStore().getById(message.get('account_id'));
- mimeType = account.get('display_format');
- if (! mimeType.match(/^text\//)) {
- mimeType = 'text/' + mimeType;
+ if (account) {
+ mimeType = account.get('display_format');
+ if (!mimeType.match(/^text\//)) {
+ mimeType = 'text/' + mimeType;
+ }
+ } else {
+ // no account found, might happen for .eml emails
+ mimeType = 'text/plain';
}
}
$customerRecords = new Tinebase_Record_RecordSet('Sales_Model_Customer');
foreach ($customers as $customer) {
- $customer['cpextern_id'] = $addresses->getByIndex($i)->getId();
+ $contactExtern = $addresses->getByIndex($i);
+ if ($contactExtern) {
+ $customer['cpextern_id'] = $contactExtern->getId();
+ }
$i++;
- $customer['cpintern_id'] = $addresses->getByIndex($i)->getId();
+ $contactIntern = $addresses->getByIndex($i);
+ if ($contactIntern) {
+ $customer['cpintern_id'] = $contactIntern->getId();
+ }
$i++;
$customer['iban'] = Tinebase_Record_Abstract::generateUID(20);
$customer['bic'] = Tinebase_Record_Abstract::generateUID(12);
} else {
try {
$containerController->deleteContainer($container, true);
- } catch (Tinebase_Exception_NotFound $e) {
+ } catch (Exception $e) {
}
}
}
$record->setKeyFieldRecordModel($_options['recordModel']);
}
- $record->setFromArray($_data);
+ if (is_array($_data)) {
+ $record->setFromArray($_data);
+ } else if (is_string($_data)) {
+ if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) Tinebase_Core::getLogger()->notice(__METHOD__ . '::'
+ . __LINE__ . ' Did not get an array to set keyfield config. Got this: ' . $_data);
+ }
return $record;
}
*/
public function getValue($id)
{
+ if (! $this->records instanceof Tinebase_Record_RecordSet) {
+ return '';
+ }
+
$record = $this->records->filter('id', $id)->getFirstRecord();
if (! $record) {
$record = $this->getKeyfieldDefault();
return $originRecord ? $originRecord->getId() : null;
}
-}
\ No newline at end of file
+}
* @var Tinebase_Controller_ScheduledImport
*/
private static $instance = null;
+
+ const MAXFAILCOUNT = 5;
/**
* the constructor
return $this->_doScheduledImport($record)->toArray();
}
- return NULL;
+ return null;
}
+ /**
+ * @return Tinebase_Model_ImportFilter
+ */
public function getScheduledImportFilter()
{
$timestampBefore = null;
$aWeekAgo->subWeek(1);
$filter = new Tinebase_Model_ImportFilter(array(array(
+ array('field' => 'failcount', 'operator' => 'greater', 'value' => 5),
+ ),
+ array(
'condition' => 'OR', 'filters' => array(
array('field' => 'timestamp', 'operator' => 'isnull', 'value' => null),
array('condition' => 'AND', 'filters' => array(
*
* @param interval
* @param recursive
- * @return Object
+ * @return Tinebase_Model_Import|null
*/
protected function _getNextScheduledImport()
{
// Always sort by timestamp to ensure first in first out
$pagination = new Tinebase_Model_Pagination(array(
- 'limit' => 1,
+ 'limit' => 50,
'sort' => 'timestamp',
'dir' => 'ASC'
));
- $record = $this->search($filter, $pagination)->getFirstRecord();
-
- if (! $record) {
- if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
- Tinebase_Core::getLogger()->debug(__METHOD__ . ' ' . __LINE__ . ' No ScheduledImport could be found.');
- }
+ $records = $this->search($filter, $pagination);
- return NULL;
+ foreach ($records as $record) {
+ // TODO add failcount to filter in getScheduledImportFilter as
+ // no more valid imports are run if we have 50+ failing imports
+ if ($record->failcount < self::MAXFAILCOUNT) {
+ return $record;
+ } else {
+ if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) {
+ Tinebase_Core::getLogger()->info(__METHOD__ . ' ' . __LINE__ . ' Too many failures, skipping import');
+ }
+ }
}
- return $record;
+
+ if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
+ Tinebase_Core::getLogger()->debug(__METHOD__ . ' ' . __LINE__ . ' No valid ScheduledImport could be found.');
+ }
+
+ return null;
}
/**
try {
$importer = new $importer($options);
$importer->import($toImport);
+ $record->failcount = 0;
} catch (Exception $e) {
if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) {
Tinebase_Core::getLogger()->notice(__METHOD__ . ' ' . __LINE__
. ' Import failed.');
}
- // TODO log failure message in import record
Tinebase_Exception::log($e);
+
+ $record->lastfail = $e->getMessage();
+ $record->failcount = $record->failcount + 1;
}
if ($record->interval === Tinebase_Model_Import::INTERVAL_ONCE || !$record->timestamp instanceof Tinebase_DateTime) {
break;
}
- // update record
$record = $this->update($record);
} else {
$registryData = array();
if (Tinebase_Core::getUser()) {
- $userApplications = Tinebase_Core::getUser()->getApplications(TRUE);
+ $userApplications = Tinebase_Core::getUser()->getApplications(/* $_anyRight */ TRUE);
$clientConfig = Tinebase_Config::getInstance()->getClientRegistryConfig();
if (Tinebase_Core::isLogLevel(Zend_Log::TRACE))
$appRegistry['customfields'] = $customfields->toArray();
// add preferences for app
- $prefRegistry = $this->_getAppPreferencesForRegistry($application);
- $appRegistry = array_merge_recursive($appRegistry, $prefRegistry);
+ try {
+ $prefRegistry = $this->_getAppPreferencesForRegistry($application);
+ $appRegistry = array_merge_recursive($appRegistry, $prefRegistry);
+ } catch (Tinebase_Exception_AccessDenied $tead) {
+ // do not add prefs if user has no run right
+ }
$customAppRegistry = $this->_getCustomAppRegistry($application);
if (empty($customAppRegistry)) {
try {
$transactionId = Tinebase_TransactionManager::getInstance()->startTransaction(Tinebase_Core::getDb());
-
- $this->_updatePrimaryGroupsOfUsers($groupIds);
-
+
$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);
*/
public function deleteGroupsInSqlBackend($groupIds)
{
+ $this->_updatePrimaryGroupsOfUsers($groupIds);
+
$where = $this->_db->quoteInto($this->_db->quoteIdentifier('group_id') . ' IN (?)', (array) $groupIds);
$this->groupMembersTable->delete($where);
$where = $this->_db->quoteInto($this->_db->quoteIdentifier('id') . ' IN (?)', (array) $groupIds);
'sourcetype' => array('presence' => 'required'),
'options' => array('allowEmpty' => true),
'source' => array('allowEmpty' => true),
+ 'failcount' => array('allowEmpty' => true, 'default' => 0),
+ 'lastfail' => array('allowEmpty' => true),
'created_by' => array('allowEmpty' => true),
'creation_time' => array('allowEmpty' => true),
'last_modified_by' => array('allowEmpty' => true),
)),
new Zend_Server_Method_Parameter(array(
'type' => 'array',
- 'name' => 'pagination',
+ 'name' => 'paging',
)),
),
'help' => 'Search for ' . $simpleModelName . 's matching given arguments',
$data
), true)
);
-
$group = Tinebase_Group::getInstance()->getDefaultGroup();
Tinebase_Container::getInstance()->addGrants($container->getId(), 'group', $group->getId(), $this->_userGrants, true);
- Tinebase_Container::getInstance()->addGrants($container->getId(), 'user', $this->_personas['sclever']->getId(), $this->_secretaryGrants, true);
- Tinebase_Container::getInstance()->addGrants($container->getId(), 'user', $this->_personas['pwulf']->getId(), $this->_adminGrants, true);
+ if (isset($this->_personas['sclever'])) {
+ Tinebase_Container::getInstance()->addGrants($container->getId(), 'user', $this->_personas['sclever']->getId(), $this->_secretaryGrants, true);
+ }
+ if (isset($this->_personas['pwulf'])) {
+ Tinebase_Container::getInstance()->addGrants($container->getId(), 'user', $this->_personas['pwulf']->getId(), $this->_adminGrants, true);
+ }
if ($setAsThisSharedContainer) {
$this->_sharedContainer = $container;
{
/**
* update to 9.1
- *
+ *
* @see 0011178: allow to lock preferences for individual users
*/
public function update_0()
// delete index unique-fields
try {
$this->_backend->dropIndex('relations', 'unique-fields');
- } catch (Exception $e) {}
+ } catch (Exception $e) {
+ }
$declaration = new Setup_Backend_Schema_Index_Xml('
<index>
<name>unique-fields</name>
$this->createTable('path', $declaration);
$this->setApplicationVersion('Tinebase', '9.7');
}
+
+ /**
+ * update to 9.8
+ *
+ * adds failcount+lastfail to scheduled imports
+ *
+ * @see 0012082: deactivate failing scheduled imports
+ */
+ public function update_7()
+ {
+ if ($this->getTableVersion('import') < 2) {
+ $declaration = new Setup_Backend_Schema_Field_Xml('<field>
+ <name>failcount</name>
+ <type>integer</type>
+ </field>');
+ $this->_backend->addCol('import', $declaration);
+
+ $declaration = new Setup_Backend_Schema_Field_Xml('<field>
+ <name>lastfail</name>
+ <type>text</type>
+ </field>');
+ $this->_backend->addCol('import', $declaration);
+ }
+
+ $this->setTableVersion('import', '2');
+ $this->setApplicationVersion('Tinebase', '9.8');
+ }
}
<?xml version="1.0" encoding="utf-8"?>
<application>
<name>Tinebase</name>
- <version>9.7</version>
+ <version>9.8</version>
<tables>
<table>
<name>applications</name>
</table>
<table>
<name>import</name>
- <version>1</version>
+ <version>2</version>
<declaration>
<field>
<name>id</name>
<name>options</name>
<type>text</type>
</field>
+ <field>
+ <name>failcount</name>
+ <type>integer</type>
+ </field>
+ <field>
+ <name>lastfail</name>
+ <type>text</type>
+ </field>
<index>
<name>id</name>
<primary>true</primary>