public function updateCard($moduleName, $record, $card) { $this->log->debug(__CLASS__ . '::' . __METHOD__ . ' | Start CRM ID:' . $record['crmid']); $vcard = Sabre\VObject\Reader::read($card['carddata']); $vcard->PRODID = self::PRODID; unset($vcard->TEL); unset($vcard->EMAIL); unset($vcard->REV); if ($moduleName == 'Contacts') { $name = $record['firstname'] . ' ' . $record['lastname']; $vcard->N = [$record['lastname'], $record['firstname']]; $org = Vtiger_Functions::getCRMRecordLabel($record['parentid']); if ($org != '') { $vcard->ORG = $org; } } if ($moduleName == 'OSSEmployees') { $name = $record['name'] . ' ' . $record['last_name']; $vcard->N = [$record['last_name'], $record['name']]; $vcard->ORG = Vtiger_CompanyDetails_Model::getInstanceById()->get('organizationname'); } $vcard->FN = $name; foreach ($this->telFields[$moduleName] as $key => $val) { if ($record[$key] != '') { $vcard->add('TEL', $record[$key], ['type' => explode(',', $val)]); } } foreach ($this->mailFields[$moduleName] as $key => $val) { if ($record[$key] != '') { $vcard->add('EMAIL', $record[$key], ['type' => explode(',', $val)]); } } $cardData = Sabre\DAV\StringUtil::ensureUTF8($vcard->serialize()); $etag = md5($cardData); $modifiedtime = strtotime($record['modifiedtime']); $stmt = $this->pdo->prepare('UPDATE dav_cards SET carddata = ?, lastmodified = ?, size = ?, etag = ?, crmid = ? WHERE id = ?;'); $stmt->execute([$cardData, $modifiedtime, strlen($cardData), $etag, $record['crmid'], $card['id']]); $this->addChange($card['uri'], 2); $this->log->debug(__CLASS__ . '::' . __METHOD__ . ' | End'); }
/** * Updates the VCard-formatted object * * @param string $cardData * @return void */ public function put($cardData) { Calendar_Controller_MSEventFacade::getInstance()->assertEventFacadeParams($this->_container); if (get_class($this->_getConverter()) == 'Calendar_Convert_Event_VCalendar_Generic') { if (Tinebase_Core::isLogLevel(Zend_Log::WARN)) { Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . " update by generic client not allowed. See Calendar_Convert_Event_VCalendar_Factory for supported clients."); } throw new Sabre\DAV\Exception\Forbidden('write access denied for unknown client'); } $this->_vevent = null; if (is_resource($cardData)) { $cardData = stream_get_contents($cardData); } // Converting to UTF-8, if needed $cardData = Sabre\DAV\StringUtil::ensureUTF8($cardData); #Sabre_CalDAV_ICalendarUtil::validateICalendarObject($cardData, array('VEVENT', 'VFREEBUSY')); $vobject = Calendar_Convert_Event_VCalendar_Abstract::getVObject($cardData); foreach ($vobject->children() as $component) { if (isset($component->{'X-TINE20-CONTAINER'})) { $xTine20Container = $component->{'X-TINE20-CONTAINER'}; break; } } // keep old record for reference $recordBeforeUpdate = clone $this->getRecord(); // concurrency management is based on etag in CalDAV $event = $this->_getConverter()->toTine20Model($vobject, $this->getRecord(), array(Calendar_Convert_Event_VCalendar_Abstract::OPTION_USE_SERVER_MODLOG => true)); if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " " . print_r($event->toArray(), true)); } $currentEvent = $this->getRecord(); $currentContainer = Tinebase_Container::getInstance()->getContainerById($currentEvent->container_id); // client sends CalDAV event -> handle a container move if (isset($xTine20Container)) { if ($xTine20Container->getValue() == $currentContainer->getId()) { $event->container_id = $this->_container->getId(); } else { // @TODO allow organizer to move original cal when he edits the displaycal event? if ($this->_container->type == Tinebase_Model_Container::TYPE_PERSONAL) { Calendar_Controller_MSEventFacade::getInstance()->setDisplaycontainer($event, $this->_container->getId()); } } } else { if ($currentEvent->created_by == Tinebase_Core::getUser()->getId()) { $event->container_id = $this->_container->getId(); } else { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " X-TINE20-CONTAINER not present -> restrict container moves"); } if ($this->_container->type == Tinebase_Model_Container::TYPE_PERSONAL) { Calendar_Controller_MSEventFacade::getInstance()->setDisplaycontainer($event, $this->_container->getId()); } } } if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " " . print_r($event->toArray(), true)); } $this->update($event, $cardData); return $this->getETag(); }
/** * Updates the VCard-formatted object * * @param string $cardData * @return void */ public function put($cardData) { if (get_class($this->_converter) == 'Tasks_Convert_Task_VCalendar_Generic') { if (Tinebase_Core::isLogLevel(Zend_Log::WARN)) { Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . " update by generic client not allowed. See Tasks_Convert_Task_VCalendar_Factory for supported clients."); } throw new Sabre\DAV\Exception\Forbidden('Update denied for unknow client'); } if (is_resource($cardData)) { $cardData = stream_get_contents($cardData); } // Converting to UTF-8, if needed $cardData = Sabre\DAV\StringUtil::ensureUTF8($cardData); #Sabre_CalDAV_ICalendarUtil::validateICalendarObject($cardData, array('VTODO', 'VFREEBUSY')); $vobject = Tasks_Convert_Task_VCalendar_Abstract::getVObject($cardData); foreach ($vobject->children() as $component) { if (isset($component->{'X-TINE20-CONTAINER'})) { $xContainerId = $component->{'X-TINE20-CONTAINER'}; break; } } // keep old record for reference $recordBeforeUpdate = clone $this->getRecord(); $task = $this->_converter->toTine20Model($vobject, $this->getRecord(), array(Tasks_Convert_Task_VCalendar_Abstract::OPTION_USE_SERVER_MODLOG => true)); // iCal does sends back an old value, because it does not refresh the vcalendar after // update. Therefor we must reapply the value of last_modified_time after the convert $task->last_modified_time = $recordBeforeUpdate->last_modified_time; $currentContainer = Tinebase_Container::getInstance()->getContainerById($this->getRecord()->container_id); //$ownAttendee = Calendar_Model_Attender::getOwnAttender($this->getRecord()->attendee); // task 'belongs' current user -> allow container move if ($currentContainer->isPersonalOf(Tinebase_Core::getUser())) { $task->container_id = $this->_container->getId(); } // client sends CalDAV task -> handle a container move /*else if (isset($xContainerId)) { if ($xContainerId == $currentContainer->getId()) { $task->container_id = $this->_container->getId(); } else { // @TODO allow organizer to move original cal when he edits the displaycal task? if ($ownAttendee && $this->_container->type == Tinebase_Model_Container::TYPE_PERSONAL) { $ownAttendee->displaycontainer_id = $this->_container->getId(); } } } */ // client sends task from iMIP invitation -> only allow displaycontainer move /*else { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " X-TINE20-CONTAINER not present -> restrict container moves"); if ($ownAttendee && $this->_container->type == Tinebase_Model_Container::TYPE_PERSONAL) { if ($ownAttendee->displaycontainer_id == $currentContainer->getId()) { $task->container_id = $this->_container->getId(); } $ownAttendee->displaycontainer_id = $this->_container->getId(); } }*/ self::enforceEventParameters($task); // don't allow update of alarms for non organizer if oganizer is Tine 2.0 user if ($task->organizer !== Tinebase_Core::getUser()->getId()) { $organizerContact = Addressbook_Controller_Contact::getInstance()->getContactByUserId($task->organizer, TRUE); // reset alarms if organizer is Tine 2.0 user if (!empty($organizerContact->account_id)) { $this->_resetAlarms($task, $recordBeforeUpdate); } } if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " " . print_r($task->toArray(), true)); } try { $this->_task = Tasks_Controller_Task::getInstance()->update($task); } catch (Tinebase_Timemachine_Exception_ConcurrencyConflict $ttecc) { throw new Sabre\DAV\Exception\PreconditionFailed('An If-Match header was specified, but none of the specified the ETags matched.', 'If-Match'); } catch (Tinebase_Exception_AccessDenied $tead) { throw new Sabre\DAV\Exception\Forbidden('forbidden update'); } catch (Tinebase_Exception_NotFound $tenf) { throw new Sabre\DAV\Exception\PreconditionFailed('not found'); } catch (Exception $e) { Tinebase_Core::getLogger()->err(__METHOD__ . '::' . __LINE__ . " " . $e); Tinebase_Core::getLogger()->err(__METHOD__ . '::' . __LINE__ . " " . $cardData); Tinebase_Core::getLogger()->err(__METHOD__ . '::' . __LINE__ . " " . print_r($task->toArray(), true)); throw new Sabre\DAV\Exception\PreconditionFailed($e->getMessage()); } return $this->getETag(); }