/** * adds a new personal tag * * @param array $tag * @return array */ public function saveTag($tag) { $inTag = new Tinebase_Model_Tag($tag); if (strlen($inTag->getId()) < 40) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' creating tag: ' . print_r($inTag->toArray(), true)); } $outTag = Tinebase_Tags::getInstance()->createTag($inTag); } else { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' updating tag: ' . print_r($inTag->toArray(), true)); } $outTag = Tinebase_Tags::getInstance()->updateTag($inTag); } return $outTag->toArray(); }
/** * test resolving tag names to Tinebase_Model_Tag */ public function testResolveTagNames() { $sharedTag = $this->_createSharedTag(); $resolvedTags = Tinebase_Model_Tag::resolveTagNameToTag($sharedTag->name, 'Addressbook'); $this->assertContains($sharedTag->name, $resolvedTags->name); }
/** * converts vcard to Addressbook_Model_Contact * * @param \Sabre\VObject\Component|resource|string $blob the vcard to parse * @param Tinebase_Record_Abstract $_record update existing contact * @param array $options array of options * @return Addressbook_Model_Contact */ public function toTine20Model($blob, Tinebase_Record_Abstract $_record = null, $options = array()) { $vcard = self::getVObject($blob); if ($_record instanceof Addressbook_Model_Contact) { $contact = $_record; } else { $contact = new Addressbook_Model_Contact(null, false); } $data = $this->_emptyArray; /** @var \Sabre\VObject\Property $property */ foreach ($vcard->children() as $property) { switch ($property->name) { case 'VERSION': case 'PRODID': case 'UID': // do nothing break; case 'ADR': $type = null; foreach ($property['TYPE'] as $typeProperty) { $typeProperty = strtolower($typeProperty); if (in_array($typeProperty, array('home', 'work'))) { $type = $typeProperty; break; } } $parts = $property->getParts(); if ($type == 'home') { // home address $data['adr_two_street2'] = $parts[1]; $data['adr_two_street'] = $parts[2]; $data['adr_two_locality'] = $parts[3]; $data['adr_two_region'] = $parts[4]; $data['adr_two_postalcode'] = $parts[5]; $data['adr_two_countryname'] = $parts[6]; } elseif ($type == 'work') { // work address $data['adr_one_street2'] = $parts[1]; $data['adr_one_street'] = $parts[2]; $data['adr_one_locality'] = $parts[3]; $data['adr_one_region'] = $parts[4]; $data['adr_one_postalcode'] = $parts[5]; $data['adr_one_countryname'] = $parts[6]; } break; case 'CATEGORIES': $tags = Tinebase_Model_Tag::resolveTagNameToTag($property->getParts(), 'Addressbook'); if (!isset($data['tags'])) { $data['tags'] = $tags; } else { $data['tags']->merge($tags); } break; case 'EMAIL': $this->_toTine20ModelParseEmail($data, $property, $vcard); break; case 'FN': $data['n_fn'] = $property->getValue(); break; case 'N': $parts = $property->getParts(); $data['n_family'] = $parts[0]; $data['n_given'] = isset($parts[1]) ? $parts[1] : null; $data['n_middle'] = isset($parts[2]) ? $parts[2] : null; $data['n_prefix'] = isset($parts[3]) ? $parts[3] : null; $data['n_suffix'] = isset($parts[4]) ? $parts[4] : null; break; case 'NOTE': $data['note'] = $property->getValue(); break; case 'ORG': $parts = $property->getParts(); $data['org_name'] = $parts[0]; $data['org_unit'] = isset($parts[1]) ? $parts[1] : null; break; case 'PHOTO': $jpegphoto = $property->getValue(); break; case 'TEL': $this->_toTine20ModelParseTel($data, $property); break; case 'URL': switch (strtoupper($property['TYPE'])) { case 'HOME': $data['url_home'] = $property->getValue(); break; case 'WORK': default: $data['url'] = $property->getValue(); break; } break; case 'TITLE': $data['title'] = $property->getValue(); break; case 'BDAY': $this->_toTine20ModelParseBday($data, $property); break; default: if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' cardData ' . $property->name); } break; } } if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' data ' . print_r($data, true)); } // Some email clients will only set a contact with FN (formatted name) without surname if (empty($data['n_family']) && empty($data['org_name']) && !empty($data['n_fn'])) { if (strpos($data['n_fn'], ",") > 0) { list($lastname, $firstname) = explode(",", $data['n_fn'], 2); $data['n_family'] = trim($lastname); $data['n_given'] = trim($firstname); } elseif (strpos($data['n_fn'], " ") > 0) { list($firstname, $lastname) = explode(" ", $data['n_fn'], 2); $data['n_family'] = trim($lastname); $data['n_given'] = trim($firstname); } else { $data['n_family'] = empty($data['n_fn']) ? 'VCARD (imported)' : $data['n_fn']; } } $contact->setFromArray($data); if (isset($jpegphoto)) { $contact->setSmallContactImage($jpegphoto, $this->_maxPhotoSize); } if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' data ' . print_r($contact->toArray(), true)); } if (isset($options[self::OPTION_USE_SERVER_MODLOG]) && $options[self::OPTION_USE_SERVER_MODLOG] === true) { $contact->creation_time = $_record->creation_time; $contact->last_modified_time = $_record->last_modified_time; $contact->seq = $_record->seq; } return $contact; }
/** * update tag occurrrence * * @param Tinebase_Model_Tag|string $tag * @param integer $toAddOrRemove */ protected function _updateOccurrence($tag, $toAddOrRemove) { if ($toAddOrRemove == 0) { return; } $tagId = $tag instanceof Tinebase_Model_Tag ? $tag->getId() : $tag; if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " de/increasing tag occurrence of {$tagId} by {$toAddOrRemove}"); } $quotedIdentifier = $this->_db->quoteIdentifier('occurrence'); if ($toAddOrRemove > 0) { $toAdd = (int) $toAddOrRemove; $data = array('occurrence' => new Zend_Db_Expr($quotedIdentifier . ' + ' . $toAdd)); } else { $toRemove = abs((int) $toAddOrRemove); $data = array('occurrence' => new Zend_Db_Expr('(CASE WHEN (' . $quotedIdentifier . ' - ' . $toRemove . ') > 0 THEN ' . $quotedIdentifier . ' - ' . $toRemove . ' ELSE 0 END)')); } $this->_db->update(SQL_TABLE_PREFIX . 'tags', $data, $this->_db->quoteInto($this->_db->quoteIdentifier('id') . ' = ?', $tagId)); }
public function __construct($_data = NULL, $_bypassFilters = false, $_convertDates = true) { $this->_validators['rights'] = array('allowEmpty' => true); $this->_validators['contexts'] = array('allowEmpty' => true); parent::__construct($_data, $_bypassFilters, $_convertDates); }
/** * parse VEVENT part of VCALENDAR * * @param \Sabre\VObject\Component\VEvent $vevent the VEVENT to parse * @param Calendar_Model_Event $event the Tine 2.0 event to update * @param array $options */ protected function _convertVevent(\Sabre\VObject\Component\VEvent $vevent, Calendar_Model_Event $event, $options) { if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' vevent ' . $vevent->serialize()); } $newAttendees = array(); $attachments = new Tinebase_Record_RecordSet('Tinebase_Model_Tree_Node'); $event->alarms = new Tinebase_Record_RecordSet('Tinebase_Model_Alarm'); $skipFieldsIfOnlyBasicData = array('ATTENDEE', 'UID', 'ORGANIZER', 'VALARM', 'ATTACH', 'CATEGORIES'); foreach ($vevent->children() as $property) { if (isset($this->_options['onlyBasicData']) && $this->_options['onlyBasicData'] && in_array((string) $property->name, $skipFieldsIfOnlyBasicData)) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Skipping ' . $property->name . ' (using option onlyBasicData)'); } continue; } switch ($property->name) { case 'CREATED': case 'DTSTAMP': if (!isset($options[self::OPTION_USE_SERVER_MODLOG]) || $options[self::OPTION_USE_SERVER_MODLOG] !== true) { $event->{$property->name == 'CREATED' ? 'creation_time' : 'last_modified_time'} = $this->_convertToTinebaseDateTime($property); } break; case 'LAST-MODIFIED': $event->last_modified_time = new Tinebase_DateTime($property->getValue()); break; case 'ATTENDEE': $newAttendee = $this->_getAttendee($property); if ($newAttendee) { $newAttendees[] = $newAttendee; } break; case 'CLASS': if (in_array($property->getValue(), array(Calendar_Model_Event::CLASS_PRIVATE, Calendar_Model_Event::CLASS_PUBLIC))) { $event->class = $property->getValue(); } else { $event->class = Calendar_Model_Event::CLASS_PUBLIC; } break; case 'STATUS': if (in_array($property->getValue(), array(Calendar_Model_Event::STATUS_CONFIRMED, Calendar_Model_Event::STATUS_TENTATIVE, Calendar_Model_Event::STATUS_CANCELED))) { $event->status = $property->getValue(); } else { if ($property->getValue() == 'CANCELLED') { $event->status = Calendar_Model_Event::STATUS_CANCELED; } else { $event->status = Calendar_Model_Event::STATUS_CONFIRMED; } } break; case 'DTEND': if (isset($property['VALUE']) && strtoupper($property['VALUE']) == 'DATE') { // all day event $event->is_all_day_event = true; $dtend = $this->_convertToTinebaseDateTime($property, TRUE); // whole day events ends at 23:59:59 in Tine 2.0 but 00:00 the next day in vcalendar $dtend->subSecond(1); } else { $event->is_all_day_event = false; $dtend = $this->_convertToTinebaseDateTime($property); } $event->dtend = $dtend; break; case 'DTSTART': if (isset($property['VALUE']) && strtoupper($property['VALUE']) == 'DATE') { // all day event $event->is_all_day_event = true; $dtstart = $this->_convertToTinebaseDateTime($property, TRUE); } else { $event->is_all_day_event = false; $dtstart = $this->_convertToTinebaseDateTime($property); } $event->originator_tz = $dtstart->getTimezone()->getName(); $event->dtstart = $dtstart; break; case 'SEQUENCE': if (!isset($options[self::OPTION_USE_SERVER_MODLOG]) || $options[self::OPTION_USE_SERVER_MODLOG] !== true) { $event->seq = $property->getValue(); } // iMIP only $event->external_seq = $property->getValue(); break; case 'DESCRIPTION': case 'LOCATION': case 'SUMMARY': $key = strtolower($property->name); $value = $property->getValue(); $event->{$key} = $value; break; case 'ORGANIZER': $email = null; if (!empty($property['EMAIL'])) { $email = $property['EMAIL']; } elseif (preg_match('/mailto:(?P<email>.*)/i', $property->getValue(), $matches)) { $email = $matches['email']; } if ($email !== null) { // it's not possible to change the organizer by spec if (empty($event->organizer)) { $name = isset($property['CN']) ? $property['CN']->getValue() : $email; $contact = Calendar_Model_Attender::resolveEmailToContact(array('email' => $email, 'lastName' => $name)); $event->organizer = $contact->getId(); } // Lightning attaches organizer ATTENDEE properties to ORGANIZER property and does not add an ATTENDEE for the organizer if (isset($property['PARTSTAT'])) { $newAttendees[] = $this->_getAttendee($property); } } break; case 'RECURRENCE-ID': // original start of the event $event->recurid = $this->_convertToTinebaseDateTime($property); // convert recurrence id to utc $event->recurid->setTimezone('UTC'); break; case 'RRULE': $rruleString = $property->getValue(); // convert date format $rruleString = preg_replace_callback('/UNTIL=([\\dTZ]+)(?=;?)/', function ($matches) { $dtUntil = Calendar_Convert_Event_VCalendar_Abstract::getUTCDateFromStringInUsertime($matches[1]); return 'UNTIL=' . $dtUntil->format(Tinebase_Record_Abstract::ISO8601LONG); }, $rruleString); // remove additional days from BYMONTHDAY property (BYMONTHDAY=11,15 => BYMONTHDAY=11) $rruleString = preg_replace('/(BYMONTHDAY=)([\\d]+),([,\\d]+)/', '$1$2', $rruleString); $event->rrule = $rruleString; // process exceptions if (isset($vevent->EXDATE)) { $exdates = new Tinebase_Record_RecordSet('Calendar_Model_Event'); foreach ($vevent->EXDATE as $exdate) { foreach ($exdate->getDateTimes() as $exception) { if (isset($exdate['VALUE']) && strtoupper($exdate['VALUE']) == 'DATE') { $recurid = new Tinebase_DateTime($exception->format(Tinebase_Record_Abstract::ISO8601LONG), (string) Tinebase_Core::getUserTimezone()); } else { $recurid = new Tinebase_DateTime($exception->format(Tinebase_Record_Abstract::ISO8601LONG), $exception->getTimezone()); } $recurid->setTimezone(new DateTimeZone('UTC')); $eventException = new Calendar_Model_Event(array('recurid' => $recurid, 'is_deleted' => true)); $exdates->addRecord($eventException); } } $event->exdate = $exdates; } break; case 'TRANSP': if (in_array($property->getValue(), array(Calendar_Model_Event::TRANSP_OPAQUE, Calendar_Model_Event::TRANSP_TRANSP))) { $event->transp = $property->getValue(); } else { $event->transp = Calendar_Model_Event::TRANSP_TRANSP; } break; case 'UID': // it's not possible to change the uid by spec if (!empty($event->uid)) { continue; } $event->uid = $property->getValue(); break; case 'VALARM': $this->_parseAlarm($event, $property, $vevent); break; case 'CATEGORIES': $tags = Tinebase_Model_Tag::resolveTagNameToTag($property->getParts(), 'Calendar'); if (!isset($event->tags)) { $event->tags = $tags; } else { $event->tags->merge($tags); } break; case 'ATTACH': $name = (string) $property['FILENAME']; $managedId = (string) $property['MANAGED-ID']; $value = (string) $property['VALUE']; $attachment = NULL; $readFromURL = false; $url = ''; if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) { Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' attachment found: ' . $name . ' ' . $managedId); } if ($managedId) { $attachment = $event->attachments instanceof Tinebase_Record_RecordSet ? $event->attachments->filter('hash', $property['MANAGED-ID'])->getFirstRecord() : NULL; // NOTE: we might miss a attachment here for the following reasons // 1. client reuses a managed id (we are server): // We havn't observerd this yet. iCal client reuse manged id's // from base events in exceptions but this is covered as we // initialize new exceptions with base event attachments // // When a client reuses a managed id it's not clear yet if // this managed id needs to be in the same series/calendar/server // // As we use the object hash the managed id might be used in the // same files with different names. We need to evaluate the name // (if attached) in this case as well. // // 2. server send his managed id (we are client) // * we need to download the attachment (here?) // * we need to have a mapping externalid / internalid (where?) if (!$attachment) { $readFromURL = true; $url = $property->getValue(); } else { $attachments->addRecord($attachment); } } elseif ('URI' === $value) { /* * ATTACH;VALUE=URI:https://server.com/calendars/__uids__/0AA0 3A3B-F7B6-459A-AB3E-4726E53637D0/dropbox/4971F93F-8657-412B-841A-A0FD913 9CD61.dropbox/Canada.png */ $url = $property->getValue(); $urlParts = parse_url($url); $host = $urlParts['host']; $name = pathinfo($urlParts['path'], PATHINFO_BASENAME); // iCal 10.7 places URI before uploading if (parse_url(Tinebase_Core::getHostname(), PHP_URL_HOST) != $host) { $readFromURL = true; } } else { // @TODO: implement (check if add / update / update is needed) if (Tinebase_Core::isLogLevel(Zend_Log::WARN)) { Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' attachment found that could not be imported due to missing managed id'); } } if ($readFromURL) { if (preg_match('#^(https?://)(.*)$#', str_replace(array("\n", "\r"), '', $url), $matches)) { // we are client and found an external hosted attachment that we need to import $userCredentialCache = Tinebase_Core::getUserCredentialCache(); $url = $matches[1] . $userCredentialCache->username . ':' . $userCredentialCache->password . '@' . $matches[2]; $attachmentInfo = $matches[1] . $matches[2] . ' ' . $name . ' ' . $managedId; if (Tinebase_Helper::urlExists($url)) { if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) { Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' Downloading attachment: ' . $attachmentInfo); } $stream = fopen($url, 'r'); $attachment = new Tinebase_Model_Tree_Node(array('name' => rawurldecode($name), 'type' => Tinebase_Model_Tree_Node::TYPE_FILE, 'contenttype' => (string) $property['FMTTYPE'], 'tempFile' => $stream), true); $attachments->addRecord($attachment); } else { if (Tinebase_Core::isLogLevel(Zend_Log::WARN)) { Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' Url not found (got 404): ' . $attachmentInfo . ' - Skipping attachment'); } } } else { if (Tinebase_Core::isLogLevel(Zend_Log::WARN)) { Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' Attachment found with malformed url: ' . $url); } } } break; case 'X-MOZ-LASTACK': $lastAck = $this->_convertToTinebaseDateTime($property); break; case 'X-MOZ-SNOOZE-TIME': $snoozeTime = $this->_convertToTinebaseDateTime($property); break; default: // thunderbird saves snooze time for recurring event occurrences in properties with names like this - // we just assume that the event/recur series has only one snooze time if (preg_match('/^X-MOZ-SNOOZE-TIME-[0-9]+$/', $property->name)) { $snoozeTime = $this->_convertToTinebaseDateTime($property); if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Found snooze time for recur occurrence: ' . $snoozeTime->toString()); } } break; } } // NOTE: X-CALENDARSERVER-ACCESS overwrites CLASS if (isset($vevent->{'X-CALENDARSERVER-ACCESS'})) { $event->class = $vevent->{'X-CALENDARSERVER-ACCESS'} == 'PUBLIC' ? Calendar_Model_Event::CLASS_PUBLIC : Calendar_Model_Event::CLASS_PRIVATE; } if (isset($lastAck)) { Calendar_Controller_Alarm::setAcknowledgeTime($event->alarms, $lastAck); } if (isset($snoozeTime)) { Calendar_Controller_Alarm::setSnoozeTime($event->alarms, $snoozeTime); } // merge old and new attendee Calendar_Model_Attender::emailsToAttendee($event, $newAttendees); if (empty($event->seq)) { $event->seq = 1; } if (empty($event->class)) { $event->class = Calendar_Model_Event::CLASS_PUBLIC; } $this->_manageAttachmentsFromClient($event, $attachments); if (empty($event->dtend)) { if (empty($event->dtstart)) { throw new Tinebase_Exception_UnexpectedValue("Got event without dtstart and dtend"); } // TODO find out duration (see TRIGGER DURATION) // if (isset($vevent->DURATION)) { // } if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) { Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__ . ' Got event without dtend. Assuming 30 minutes duration'); } $event->dtend = clone $event->dtstart; $event->dtend->addMinute(30); } $this->_manageAttachmentsFromClient($event, $attachments); // convert all datetime fields to UTC $event->setTimezone('UTC'); }
/** * parse VTODO part of VCALENDAR * * @param \Sabre\VObject\Component\VTodo $_vevent the VTODO to parse * @param Tasks_Model_Task $_vtodo the Tine 2.0 event to update */ protected function _convertVtodo(\Sabre\VObject\Component\VTodo $_vtodo, Tasks_Model_Task $_task, $options) { if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' vtodo ' . $_vtodo->serialize()); } $task = $_task; $task->alarms = new Tinebase_Record_RecordSet('Tinebase_Model_Alarm'); $task->priority = 'NORMAL'; $task->status = 'NEEDS-ACTION'; foreach ($_vtodo->children() as $property) { switch ($property->name) { case 'CREATED': case 'DTSTAMP': // do nothing break; case 'LAST-MODIFIED': $task->last_modified_time = new Tinebase_DateTime($property->getValue()); break; case 'CLASS': if (in_array($property->getValue(), array(Tasks_Model_Task::CLASS_PRIVATE, Tasks_Model_Task::CLASS_PUBLIC))) { $task->class = $property->getValue(); } else { $task->class = Tasks_Model_Task::CLASS_PUBLIC; } break; case 'COMPLETED': if (isset($property['VALUE']) && strtoupper($property['VALUE']) == 'DATE') { // all day event //$task->is_all_day_event = true; $dtend = $this->_convertToTinebaseDateTime($property, TRUE); // whole day events ends at 23:59:59 in Tine 2.0 but 00:00 the next day in vcalendar $dtend->subSecond(1); } else { //$task->is_all_day_event = false; $dtend = $this->_convertToTinebaseDateTime($property); } $task->completed = $dtend; break; case 'DUE': if (isset($property['VALUE']) && strtoupper($property['VALUE']) == 'DATE') { // all day event //$task->is_all_day_event = true; $due = $this->_convertToTinebaseDateTime($property, TRUE); } else { //$task->is_all_day_event = false; $due = $this->_convertToTinebaseDateTime($property); } $task->originator_tz = $due->getTimezone()->getName(); $task->due = $due; break; case 'DTSTART': if (isset($property['VALUE']) && strtoupper($property['VALUE']) == 'DATE') { // all day event //$task->is_all_day_event = true; $dtstart = $this->_convertToTinebaseDateTime($property, TRUE); // whole day events ends at 23:59:59 in Tine 2.0 but 00:00 the next day in vcalendar $dtstart->subSecond(1); } else { //$task->is_all_day_event = false; $dtstart = $this->_convertToTinebaseDateTime($property); } $task->originator_tz = $dtstart->getTimezone()->getName(); $task->dtstart = $dtstart; break; case 'STATUS': $task->status = $property->getValue(); break; case 'PERCENT-COMPLETE': $task->percent = $property->getValue(); break; case 'SEQUENCE': if (!isset($options[self::OPTION_USE_SERVER_MODLOG]) || $options[self::OPTION_USE_SERVER_MODLOG] !== true) { $task->seq = $property->getValue(); } break; case 'PRIORITY': if (is_numeric($property->getValue())) { switch ($property->getValue()) { case '0': $task->priority = 'NORMAL'; break; case '1': $task->priority = 'HIGH'; break; case '9': $task->priority = 'LOW'; break; } } else { $task->priority = $property->getValue(); } break; case 'DESCRIPTION': case 'LOCATION': case 'SUMMARY': $key = strtolower($property->name); //$task->$key = empty($property->getValue()) ? "With aout summary" : $property->getValue(); $task->{$key} = $property->getValue(); break; case 'ORGANIZER': if (preg_match('/mailto:(?P<email>.*)/i', $property->getValue(), $matches)) { // it's not possible to change the organizer by spec if (empty($task->organizer)) { $user = Tinebase_User::getInstance()->getUserByPropertyFromSqlBackend('accountEmailAddress', $matches['email']); $task->organizer = $user ? $user->getId() : Tinebase_Core::getUser()->getId(); } } break; case 'UID': // it's not possible to change the uid by spec if (!empty($task->uid)) { continue; } $task->uid = $property->getValue(); break; case 'VALARM': $this->_parseAlarm($task, $property, $_vtodo); break; case 'CATEGORIES': $tags = Tinebase_Model_Tag::resolveTagNameToTag($property->getParts(), 'Tasks'); if (!isset($task->tags)) { $task->tags = $tags; } else { $task->tags->merge($tags); } break; case 'X-MOZ-LASTACK': $lastAck = $this->_convertToTinebaseDateTime($property); break; case 'X-MOZ-SNOOZE-TIME': $snoozeTime = $this->_convertToTinebaseDateTime($property); break; default: break; } } if (empty($task->percent)) { $task->percent = 0; } if (empty($task->class)) { $task->class = Tasks_Model_Task::CLASS_PUBLIC; } // convert all datetime fields to UTC $task->setTimezone('UTC'); }
/** * Creates missing tags on the fly and returns complete list of tags the current * user has use rights for. * Allways respects the current acl of the current user! * * @param array|Tinebase_Record_RecordSet set of string|array|Tinebase_Model_Tag with existing and non-existing tags * @return Tinebase_Record_RecordSet set of all tags * @throws Tinebase_Exception_UnexpectedValue */ protected function _createTagsOnTheFly($_mixedTags) { if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' Creating tags on the fly: ' . print_r($_mixedTags, true)); } $tagIds = array(); foreach ($_mixedTags as $tag) { if (is_string($tag)) { $tagIds[] = $tag; continue; } else { if (is_array($tag)) { if (!isset($tag['name']) || empty($tag['name'])) { if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) { Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__ . ' Do not create tag without a name.'); } continue; } $tag = new Tinebase_Model_Tag($tag); } elseif (!$tag instanceof Tinebase_Model_Tag) { throw new Tinebase_Exception_UnexpectedValue('Tag could not be identified.'); } if (!$tag->getId()) { $tag->type = Tinebase_Model_Tag::TYPE_PERSONAL; $tag = $this->createTag($tag); } $tagIds[] = $tag->getId(); } } return $this->getTagsById($tagIds, Tinebase_Model_TagRight::USE_RIGHT); }