/** * converts record into raw data for adapter * * @param Tinebase_Record_Interface $_record * @return array */ protected function _recordToRawData(Tinebase_Record_Interface $_record) { if (is_object($_record->filters)) { $_record->filters->removeId(); } $rawData = $_record->toArray(); $rawData['filters'] = Zend_Json::encode($rawData['filters']); return $rawData; }
/** * checks cleared state and sets the date to the current date, also sets all billables billed * * @param Tinebase_Record_Interface $record * @param Tinebase_Record_Interface $oldRecord */ protected function _checkCleared(Tinebase_Record_Interface &$record, Tinebase_Record_Interface $oldRecord = NULL) { $foundCustomer = NULL; if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' Invoice: ' . print_r($record->toArray(), true)); } if (is_array($record->relations)) { foreach ($record->relations as $relation) { if ($relation['related_model'] == 'Sales_Model_Customer') { $foundCustomer = $relation['related_record']; break; } if ($relation['related_model'] == 'Sales_Model_Contract') { $foundContractRecord = Sales_Controller_Contract::getInstance()->get($relation['related_record']['id']); if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' Contract: ' . print_r($foundContractRecord->toArray(), true)); } foreach ($foundContractRecord->relations as $relation) { if ($relation['related_model'] == 'Sales_Model_Customer') { $foundCustomer = $relation['related_record']; break; } } } } } if (empty($record->address_id) && $foundCustomer) { $json = new Sales_Frontend_Json(); $resolved = $json->getCustomer($foundCustomer->getId()); if (!empty($resolved['billing'])) { $record->address_id = $resolved['billing'][0]['id']; } else { throw new Tinebase_Exception_Data('You have to set a billing address!'); } } // if the record hasn't been cleared before, clear billables if ($record->cleared == 'CLEARED' && (!$oldRecord || $oldRecord->cleared != 'CLEARED')) { if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) { Tinebase_Core::getLogger()->log(__METHOD__ . '::' . __LINE__ . ' Clearing Invoice ' . print_r($record->toArray(), 1), Zend_Log::INFO); } if (!$record->date) { $record->date = new Tinebase_DateTime(); } $this->_setNextNumber($record, isset($oldRecord)); $address = Sales_Controller_Address::getInstance()->get(is_string($record->address_id) ? $record->address_id : $record->address_id . id); $string = $foundCustomer['name'] . PHP_EOL; $string .= $address->prefix1 ? $address->prefix1 . "\n" : ''; $string .= $address->prefix2 ? $address->prefix2 . "\n" : ''; $string .= $address->pobox ? $address->pobox . "\n" : ''; $string .= $address->street ? $address->street . "\n" : ''; $poloc = $address->postalcode ? $address->postalcode . " " : ''; $poloc .= $address->locality ? $address->locality : ''; if (!empty($poloc)) { $string .= $poloc . PHP_EOL; } $string .= $address->countryname ? $address->countryname : ''; $record->fixed_address = $string; // clear all billables if (!empty($record->relations)) { foreach ($record->relations as $relation) { if (in_array('Sales_Model_Accountable_Interface', class_implements($relation['related_model']))) { if (is_array($relation['related_record'])) { $rr = new $relation['related_model']($relation['related_record']); } else { $rr = $relation['related_record']; } $rr->clearBillables($record); if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) { Tinebase_Core::getLogger()->log(__METHOD__ . '::' . __LINE__ . ' Clearing billables ' . print_r($rr->toArray(), 1), Zend_Log::INFO); } } } } } }
/** * Creates new entry * * @param Tinebase_Record_Interface $_record * @return Tinebase_Record_Interface * @throws Tinebase_Exception_InvalidArgument * @throws Tinebase_Exception_UnexpectedValue * * @todo remove autoincremental ids later */ public function create(Tinebase_Record_Interface $_record) { $folder = $_record->toArray(); $return = $this->get($this->encodeFolderUid($folder['globalname'], $folder['account_id'])); return $return; }
/** * Creates new entry * * @param Tinebase_Record_Interface $_record * @return Tinebase_Record_Interface * @throws Tinebase_Exception_InvalidArgument * @throws Tinebase_Exception_UnexpectedValue * * @todo remove autoincremental ids later */ public function create(Tinebase_Record_Interface $_record) { $folder = $_record->toArray(); $return = $this->get($this->encodeFolderUid(Expressomail_Model_Folder::encodeFolderName($folder['globalname']), $folder['account_id']), FALSE); return $return; }
/** * set relations / tags / alarms * * @param Tinebase_Record_Interface $updatedRecord the just updated record * @param Tinebase_Record_Interface $record the update record * @param boolean $returnUpdatedRelatedData * @return Tinebase_Record_Interface */ protected function _setRelatedData($updatedRecord, $record, $returnUpdatedRelatedData = FALSE) { if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' Update record: ' . print_r($record->toArray(), true)); } // relations won't be touched if the property is set to NULL // an empty array on the relations property will remove all relations if ($record->has('relations') && isset($record->relations) && is_array($record->relations)) { $type = $this->_getBackendType(); Tinebase_Relations::getInstance()->setRelations($this->_modelName, $type, $updatedRecord->getId(), $record->relations, FALSE, $this->_inspectRelatedRecords); } if ($record->has('tags') && isset($record->tags) && (is_array($record->tags) || $record->tags instanceof Tinebase_Record_RecordSet)) { $updatedRecord->tags = $record->tags; Tinebase_Tags::getInstance()->setTagsOfRecord($updatedRecord); } if ($record->has('alarms') && isset($record->alarms)) { $this->_saveAlarms($record); } if ($record->has('attachments') && isset($record->attachments) && Tinebase_Core::isFilesystemAvailable()) { $updatedRecord->attachments = $record->attachments; Tinebase_FileSystem_RecordAttachments::getInstance()->setRecordAttachments($updatedRecord); } if ($returnUpdatedRelatedData) { $this->_getRelatedData($updatedRecord); } return $updatedRecord; }
/** * merges changes made to local storage on concurrent updates into the new record * * @param Tinebase_Record_Interface $_newRecord record from user data * @param Tinebase_Record_Interface $_curRecord record from storage * @return Tinebase_Record_RecordSet with resolved concurrent updates (Tinebase_Model_ModificationLog records) */ public function manageConcurrentUpdates(Tinebase_Record_Interface $_newRecord, Tinebase_Record_Interface $_curRecord, $_model, $_backend, $_id) { list($appName, $i, $modelName) = explode('_', $_model); $resolved = new Tinebase_Record_RecordSet('Tinebase_Model_ModificationLog'); // handle concurrent updates on unmodified records if (!$_newRecord->last_modified_time instanceof DateTime) { if ($_curRecord->creation_time instanceof DateTime) { $_newRecord->last_modified_time = clone $_curRecord->creation_time; } else { Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' Something went wrong! No creation_time was set in current record: ' . print_r($_curRecord->toArray(), TRUE)); return $resolved; } } if ($_curRecord->last_modified_time instanceof DateTime && !$_curRecord->last_modified_time->equals($_newRecord->last_modified_time)) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " concurrent updates: current record last updated '" . $_curRecord->last_modified_time . "' where record to be updated was last updated '" . $_newRecord->last_modified_time . "'"); } $loggedMods = $this->getModifications($appName, $_id, $_model, $_backend, $_newRecord->last_modified_time, $_curRecord->last_modified_time); // effective modifications made to the record after current user got his record $diffs = $this->computeDiff($loggedMods); if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " during the concurrent update, the following changes have been made: " . print_r($diffs->toArray(), true)); } // we loop over the diffs! -> changes over fields which have no diff in storage are not in the loop! foreach ($diffs as $diff) { if (isset($_newRecord[$diff->modified_attribute]) && $_newRecord[$diff->modified_attribute] instanceof Tinebase_DateTime) { Tinebase_Core::getLogger()->err(__METHOD__ . '::' . __LINE__ . " we can't deal with dates yet -> non resolvable conflict!"); throw new Tinebase_Timemachine_Exception_ConcurrencyConflict('concurrency conflict!'); } if (isset($_newRecord[$diff->modified_attribute]) && $_newRecord[$diff->modified_attribute] == $diff->new_value) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " user updated to same value for field '" . $diff->modified_attribute . "', nothing to do."); } $resolved->addRecord($diff); } elseif (!isset($_newRecord[$diff->modified_attribute]) || $_newRecord[$diff->modified_attribute] == $diff->old_value) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " merge current value into update data, as it was not changed in update request."); } $_newRecord[$diff->modified_attribute] = $diff->new_value; $resolved->addRecord($diff); } else { Tinebase_Core::getLogger()->err(__METHOD__ . '::' . __LINE__ . " non resolvable conflict!"); throw new Tinebase_Timemachine_Exception_ConcurrencyConflict('concurrency conflict!'); } } } return $resolved; }
/** * inspect before create/update * * @param Tinebase_Record_Interface $_record the record to inspect */ protected function _inspectTask($_record) { $_record->uid = $_record->uid ? $_record->uid : Tinebase_Record_Abstract::generateUID(); $_record->organizer = $_record->organizer ? $_record->organizer : Tinebase_Core::getUser()->getId(); if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . " Inspected Task: " . print_r($_record->toArray(), true)); } }
/** * set relations / tags / alarms * * @param Tinebase_Record_Interface $updatedRecord the just updated record * @param Tinebase_Record_Interface $record the update record * @param Tinebase_Record_Interface $currentRecord the original record if one exists * @param boolean $returnUpdatedRelatedData * @return Tinebase_Record_Interface */ protected function _setRelatedData(Tinebase_Record_Interface $updatedRecord, Tinebase_Record_Interface $record, Tinebase_Record_Interface $currentRecord = null, $returnUpdatedRelatedData = FALSE) { if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' Update record: ' . print_r($record->toArray(), true)); } $pathPartChanged = false; $relationsTouched = false; // relations won't be touched if the property is set to NULL // an empty array on the relations property will remove all relations if ($record->has('relations') && isset($record->relations) && is_array($record->relations)) { $type = $this->_getBackendType(); Tinebase_Relations::getInstance()->setRelations($this->_modelName, $type, $updatedRecord->getId(), $record->relations, FALSE, $this->_inspectRelatedRecords, $this->_doRelatedCreateUpdateCheck); $relationsTouched = true; } elseif (null === $currentRecord || $this->_getPathPart($currentRecord) !== $this->_getPathPart($updatedRecord)) { $pathPartChanged = true; } // rebuild paths if relations where set or if pathPart changed if (true === $this->_useRecordPaths && (true === $pathPartChanged || true === $relationsTouched)) { $this->_rebuildRelationPaths($updatedRecord, $record, $currentRecord, $relationsTouched); } if ($record->has('tags') && isset($record->tags) && (is_array($record->tags) || $record->tags instanceof Tinebase_Record_RecordSet)) { $updatedRecord->tags = $record->tags; Tinebase_Tags::getInstance()->setTagsOfRecord($updatedRecord); } if ($record->has('alarms') && isset($record->alarms)) { $this->_saveAlarms($record); } if ($record->has('attachments') && isset($record->attachments) && Tinebase_Core::isFilesystemAvailable()) { $updatedRecord->attachments = $record->attachments; Tinebase_FileSystem_RecordAttachments::getInstance()->setRecordAttachments($updatedRecord); } if ($returnUpdatedRelatedData) { $this->_getRelatedData($updatedRecord); } return $updatedRecord; }
/** * delete linked objects (notes, relations, ...) of record * * @param Tinebase_Record_Interface $_record */ protected function _deleteLinkedObjects(Tinebase_Record_Interface $_record) { try { Tinebase_Container::getInstance()->deleteContainer($_record->container_id, true); } catch (Tinebase_Exception_NotFound $tenf) { Tinebase_Exception::log($tenf, false, $_record->toArray()); } return parent::_deleteLinkedObjects($_record); }
/** * computes changes of records and writes them to the logbook * * NOTE: expects last_modified_by and last_modified_time to be set * properly in the $_newRecord * * @param Tinebase_Record_Interface $_newRecord record from user data * @param Tinebase_Record_Interface $_curRecord record from storage * @param string $_model * @param string $_backend * @param string $_id * @return Tinebase_Record_RecordSet RecordSet of Tinebase_Model_ModificationLog */ public function writeModLog($_newRecord, $_curRecord, $_model, $_backend, $_id) { $commonModLog = $this->_getCommonModlog($_model, $_backend, array('last_modified_time' => $_newRecord->last_modified_time, 'last_modified_by' => $_newRecord->last_modified_by, 'seq' => $_newRecord->has('seq') ? $_newRecord->seq : 0), $_id); $diffs = $_curRecord->diff($_newRecord)->diff; if (!empty($diffs) && Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' Diffs: ' . print_r($diffs, TRUE)); } if (!empty($diffs) && Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' CurRecord: ' . print_r($_curRecord->toArray(), TRUE)); } if (!empty($diffs) && Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' NewRecord: ' . print_r($_newRecord->toArray(), TRUE)); } if (!empty($commonModLog) && Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' Common modlog: ' . print_r($commonModLog->toArray(), TRUE)); } $modifications = new Tinebase_Record_RecordSet('Tinebase_Model_ModificationLog'); $this->_loopModifications($diffs, $commonModLog, $modifications, $_curRecord->toArray(), $_curRecord->getModlogOmitFields()); if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Logged ' . count($modifications) . ' modifications.'); } return $modifications; }
/** * inspect update of one record (before update) * * @param Tinebase_Record_Interface $_record the update record * @param Tinebase_Record_Interface $_oldRecord the current persistent record * @return void */ protected function _inspectBeforeUpdate($_record, $_oldRecord) { foreach (array_keys($_record->toArray()) as $property) { if (!in_array($property, array('id', 'name', 'description', 'relations', 'customfields', 'tags', 'notes', 'object_id'))) { unset($_record->{$property}); } } }
/** * converts record into raw data for adapter * * @param Tinebase_Record_Interface $_record * @return array */ protected function _recordToRawData(Tinebase_Record_Interface $_record) { $data = $_record->toArray(); if (is_object($data['definition']) && method_exists($data['definition'], 'toArray')) { $data['definition'] = $data['definition']->toArray(); } if (is_array($data['definition'])) { $data['definition'] = Zend_Json::encode($data['definition']); } return $data; }
/** * 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()) { if (isset($_additionalData['alarm'])) { $_alarm = $_additionalData['alarm']; } else { $_alarm = null; } // we only send notifications to attendee if (!$_event->attendee instanceof Tinebase_Record_RecordSet) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " Event has no attendee"); } return; } if ($_event->dtend === NULL) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " " . print_r($_event->toArray(), TRUE)); } throw new Tinebase_Exception_UnexpectedValue('no dtend set in event'); } if (Tinebase_DateTime::now()->subHour(1)->isLater($_event->dtend)) { if ($_action == 'alarm' || !($_event->isRecurException() || $_event->rrule)) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " Skip notifications to past events"); } return; } } $notificationPeriodConfig = Calendar_Config::getInstance()->get(Calendar_Config::MAX_NOTIFICATION_PERIOD_FROM); if (Tinebase_DateTime::now()->subWeek($notificationPeriodConfig)->isLater($_event->dtend)) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " Skip notifications to past events (MAX_NOTIFICATION_PERIOD_FROM: " . $notificationPeriodConfig . " week(s))"); } return; } // lets resolve attendee once as batch to fill cache $attendee = clone $_event->attendee; Calendar_Model_Attender::resolveAttendee($attendee); if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . " " . print_r($_event->toArray(), true)); } if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " Notification action: " . $_action); } switch ($_action) { case 'alarm': foreach ($_event->attendee as $attender) { if (Calendar_Model_Attender::isAlarmForAttendee($attender, $_alarm)) { $this->sendNotificationToAttender($attender, $_event, $_updater, $_action, self::NOTIFICATION_LEVEL_NONE); } } break; case 'booked': case 'created': case 'deleted': foreach ($_event->attendee as $attender) { $this->sendNotificationToAttender($attender, $_event, $_updater, $_action, self::NOTIFICATION_LEVEL_INVITE_CANCEL); } break; case 'changed': $attendeeMigration = Calendar_Model_Attender::getMigration($_oldEvent->attendee, $_event->attendee); foreach ($attendeeMigration['toCreate'] as $attender) { $this->sendNotificationToAttender($attender, $_event, $_updater, 'created', self::NOTIFICATION_LEVEL_INVITE_CANCEL); } foreach ($attendeeMigration['toDelete'] as $attender) { $this->sendNotificationToAttender($attender, $_oldEvent, $_updater, 'deleted', self::NOTIFICATION_LEVEL_INVITE_CANCEL); } // NOTE: toUpdate are all attendee to be notified if (count($attendeeMigration['toUpdate']) > 0) { $updates = $this->_getUpdates($_event, $_oldEvent); if (empty($updates)) { Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . " empty update, nothing to notify about"); return; } // compute change type if (count(array_intersect(array('dtstart', 'dtend'), array_keys($updates))) > 0) { $notificationLevel = self::NOTIFICATION_LEVEL_EVENT_RESCHEDULE; } else { if (count(array_diff(array_keys($updates), array('attendee'))) > 0) { $notificationLevel = self::NOTIFICATION_LEVEL_EVENT_UPDATE; } else { $notificationLevel = self::NOTIFICATION_LEVEL_ATTENDEE_STATUS_UPDATE; } } // send notifications foreach ($attendeeMigration['toUpdate'] as $attender) { $this->sendNotificationToAttender($attender, $_event, $_updater, 'changed', $notificationLevel, $updates); } } break; default: if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " unknown action '{$_action}'"); } break; } // SEND REPLY/COUNTER to external organizer if ($_event->organizer && !$_event->resolveOrganizer()->account_id && count($_event->attendee) == 1) { $updates = array('attendee' => array('toUpdate' => $_event->attendee)); $organizer = new Calendar_Model_Attender(array('user_type' => Calendar_Model_Attender::USERTYPE_USER, 'user_id' => $_event->resolveOrganizer())); $this->sendNotificationToAttender($organizer, $_event, $_updater, 'changed', self::NOTIFICATION_LEVEL_ATTENDEE_STATUS_UPDATE, $updates); } }
/** * Upates an existing persistent record * * @param Tinebase_Record_Interface $_contact * * @return Tinebase_Record_Interface|NULL */ public function update(Tinebase_Record_Interface $_record) { $allData = $_record->toArray(); $samAccount = new Tinebase_Model_SAMUser($allData, true); $samAccount->acctFlags = '[W ]'; $posixAccount = new Tinebase_Model_FullUser($allData, true); $posixAccount->sambaSAM = $samAccount; $posixAccount = $this->_ldap->updateUserInSyncBackend($posixAccount); return $this->get($posixAccount->getId()); }
/** * converts record into raw data for adapter * * @param Tinebase_Record_Interface $_record * @return array */ protected function _recordToRawData(Tinebase_Record_Interface $_record) { $_record->runConvertToData(); $readOnlyFields = $_record->getReadOnlyFields(); $raw = $_record->toArray(FALSE); foreach ($raw as $key => $value) { if ($value instanceof Tinebase_Record_Interface) { $raw[$key] = $value->getId(); } if (in_array($key, $readOnlyFields)) { unset($raw[$key]); } } return $raw; }
/** * update one record * * @param Tinebase_Record_Interface $_record * @param boolean $_duplicateCheck * @return Tinebase_Record_Interface * @throws Tinebase_Exception_AccessDenied * * @todo fix duplicate check on update / merge needs to remove the changed record / ux discussion */ public function update(Tinebase_Record_Interface $_record, $_duplicateCheck = TRUE) { if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' ' . ' Record to update: ' . print_r($_record->toArray(), TRUE)); } if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) { Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' Update ' . $this->_modelName); } try { $db = $this->_backend->getAdapter(); $transactionId = Tinebase_TransactionManager::getInstance()->startTransaction($db); $_record->isValid(TRUE); $currentRecord = $this->get($_record->getId()); if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' Current record: ' . print_r($currentRecord->toArray(), TRUE)); } $this->_updateACLCheck($_record, $currentRecord); $this->_concurrencyManagement($_record, $currentRecord); $this->_inspectBeforeUpdate($_record, $currentRecord); // NOTE removed the duplicate check because we can not remove the changed record yet // if ($_duplicateCheck) { // $this->_duplicateCheck($_record); // } $updatedRecord = $this->_backend->update($_record); if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' Updated record: ' . print_r($updatedRecord->toArray(), TRUE)); } $this->_inspectAfterUpdate($updatedRecord, $_record); $this->_setRelatedData($updatedRecord, $_record); $updatedRecordWithRelatedData = $this->get($_record->getId()); if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' Updated record with related data: ' . print_r($updatedRecordWithRelatedData->toArray(), TRUE)); } $currentMods = $this->_writeModLog($updatedRecordWithRelatedData, $currentRecord); $this->_setNotes($updatedRecordWithRelatedData, $_record, Tinebase_Model_Note::SYSTEM_NOTE_NAME_CHANGED, $currentMods); if ($this->_sendNotifications && count($currentMods) > 0) { $this->doSendNotifications($updatedRecordWithRelatedData, $this->_currentAccount, 'changed', $currentRecord); } if ($_record->has('container_id') && $currentRecord->container_id !== $updatedRecord->container_id) { $this->_increaseContainerContentSequence($currentRecord, Tinebase_Model_ContainerContent::ACTION_DELETE); $this->_increaseContainerContentSequence($updatedRecord, Tinebase_Model_ContainerContent::ACTION_CREATE); } else { $this->_increaseContainerContentSequence($updatedRecord, Tinebase_Model_ContainerContent::ACTION_UPDATE); } Tinebase_TransactionManager::getInstance()->commitTransaction($transactionId); } catch (Exception $e) { $this->_handleRecordCreateOrUpdateException($e); } return $this->get($updatedRecord->getId()); }
/** * inspect update of one record (before update) * * @param Tinebase_Record_Interface $_record the update record * @param Tinebase_Record_Interface $_oldRecord the current persistent record * @return void */ protected function _inspectBeforeUpdate($_record, $_oldRecord) { // protect against file object spoofing foreach (array_keys($_record->toArray()) as $property) { if (!in_array($property, array('name', 'description', 'relations', 'customfields', 'tags', 'notes'))) { $_record->{$property} = $_oldRecord->{$property}; } } }
/** * set file attachments of a record * * @param Tinebase_Record_Interface $record */ public function setRecordAttachments(Tinebase_Record_Interface $record) { if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' Record: ' . print_r($record->toArray(), TRUE)); } $currentAttachments = $record->getId() ? $this->getRecordAttachments(clone $record) : new Tinebase_Record_RecordSet('Tinebase_Model_Tree_Node'); $attachmentsToSet = $record->attachments instanceof Tinebase_Record_RecordSet ? $record->attachments : new Tinebase_Record_RecordSet('Tinebase_Model_Tree_Node', (array) $record->attachments, TRUE); $attachmentDiff = $currentAttachments->diff($attachmentsToSet); foreach ($attachmentDiff->added as $added) { try { $this->addRecordAttachment($record, $added->name, $added); } catch (Tinebase_Exception_InvalidArgument $teia) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Could not add new attachment ' . print_r($added->toArray(), TRUE) . ' to record: ' . print_r($record->toArray(), TRUE)); } Tinebase_Exception::log($teia); } catch (Tinebase_Exception_NotFound $tenf) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Could not add new attachment ' . print_r($added->toArray(), TRUE) . ' to record: ' . print_r($record->toArray(), TRUE)); } Tinebase_Exception::log($tenf); } } foreach ($attachmentDiff->removed as $removed) { $this->_fsController->deleteFileNode($removed); } foreach ($attachmentDiff->modified as $modified) { $this->_fsController->update($attachmentsToSet->getById($modified->getId())); } }