Example #1
0
 /**
  * Overwrite save to set the uri if it's not already set and recalculate the minutes.
  */
 public function save()
 {
     // Prevent http://jira.opensource.mayflower.de/jira/browse/PHPROJEKT-450
     if (is_null($this->notes)) {
         $this->notes = '';
     }
     if (empty($this->endTime)) {
         $this->minutes = null;
     } else {
         $start = new Datetime($this->startDatetime);
         $end = new Datetime(substr($this->startDatetime, 0, 11) . $this->endTime);
         $this->minutes = floor(($end->getTimestamp() - $start->getTimestamp()) / 60);
     }
     if (empty($this->uid)) {
         $this->uid = Phprojekt::generateUniqueIdentifier();
     }
     if (empty($this->uri)) {
         $this->uri = $this->uid;
     }
     if (!$this->projectId) {
         $this->projectId = 1;
     }
     return parent::save();
 }
Example #2
0
 /**
  * Overwrite save function. Writes the data in this object into the
  * database.
  *
  * @return int The id of the saved object
  */
 public function save()
 {
     if (!$this->recordValidate()) {
         $errors = $this->getError();
         $error = array_pop($errors);
         throw new Zend_Controller_Action_Exception($error['label'] . ': ' . $error['message'], 400);
     }
     if ($this->_isFirst) {
         $endOfLast = $this->getRruleHelper()->getUpperTimeBoundary();
         if ($endOfLast) {
             $this->lastEnd = $endOfLast->format('Y-m-d H:i:s');
         } else {
             // I hate to do this, but item casts null to '1970-01-01 00;00:00'.
             $this->_data['lastEnd'] = null;
         }
         if (!self::isValidVisibility($this->visibility)) {
             throw new Zend_Controller_Action_Exception("Invalid visibility {$this->visibility}", 400);
         }
         $this->_fetchParticipantData();
         // We need to check this before we call parent::save() as it will be
         // set after.
         $isNew = empty($this->_storedId);
         $now = new Datetime('now', new DateTimeZone('UTC'));
         $this->lastModified = $now->format('Y-m-d H:i:s');
         if (!$this->uri) {
             $this->uri = $this->uid;
         }
         $start = new Datetime('@' . Phprojekt_Converter_Time::userToUtc($this->start));
         // This is here to fix a special case where P6 interprets things different from iCalendar. Assume a event
         // starts on tuesdays, has bi-weekly recurrence and BYDAY monday and wednesday. P6 will have the tuesday,
         // the wednesday after that and monday on the next week, wednesday the week after that, etc. Caldav will
         // have one week pause and then monday and wednesday in the same week.
         // TODO: Remove this after we changed to a predicate-based generation of events.
         if (strpos($this->rrule, ';BYDAY=') && !strpos($this->rrule, ';WKST=')) {
             $this->rrule = $this->rrule . ';WKST=' . strtoupper(substr($start->format('D'), 0, 2));
         }
         parent::save();
         $this->_saveParticipantData();
         $this->_updateRights();
         // If the start time has changed, we have to adjust all the excluded
         // dates.
         if (!$isNew && $start != $this->_originalStart) {
             $delta = $this->_originalStart->diff($start);
             $db = $this->getAdapter();
             foreach ($this->getExcludedDates() as $date) {
                 $where = $db->quoteInto('calendar2_id = ?', $this->id);
                 $where .= $db->quoteInto('AND date = ?', $date->format('Y-m-d H:i:s'));
                 $date->add($delta);
                 $db->update('calendar2_excluded_dates', array('date' => $date->format('Y-m-d H:i:s')), $where);
             }
         }
     } else {
         // Split the series into two parts. $this will be the second part.
         $new = $this;
         $old = $this->create();
         $old->find($this->id);
         $splitDate = new Datetime('@' . Phprojekt_Converter_Time::userToUtc($new->start));
         $helper = $old->getRruleHelper();
         $rrules = $helper->splitRrule($splitDate);
         $old->rrule = $rrules['old'];
         // Only overwrite the new rrule if the user didn't change it
         if ($new->rrule == $old->rrule) {
             $new->rrule = $rrules['new'];
         }
         // Regenerate the uid if the new event has multiple occurrences, see
         // http://jira.opensource.mayflower.de/jira/browse/PHPROJEKT-298
         // As they don't belong together anymore, we also need to set a new uri.
         if ($new->rrule) {
             $this->uid = Phprojekt::generateUniqueIdentifier();
             $new->uri = $new->uid;
         }
         $old->save();
         $new->_saveToNewRow();
         // Update the excluded occurences
         $where = "id = {$old->id} ";
         $where .= "AND date >= '{$splitDate->format('Y-m-d H:i:s')}'";
         $this->getAdapter()->update('calendar2_excluded_dates', array('id' => $new->id), $where);
     }
     $this->_originalStart = new Datetime('@' . Phprojekt_Converter_Time::userToUtc($this->start));
     return $this->id;
 }
Example #3
0
 /**
  * Update a group of events with a common parent id
  */
 private function _updateSingleChangedEventGroup($events)
 {
     $parent = $this->_db->select()->from('calendar')->where('id = ?', $events[0]['parent_id'])->query()->fetch();
     $start = new Datetime($parent['start_datetime']);
     $duration = $start->diff(new Datetime($parent['end_datetime']));
     $helper = new Calendar2_Helper_Rrule($start, $duration, $parent['rrule']);
     $last = new Datetime($events[count($events) - 1]['end_datetime']);
     $occurrences = $helper->getDatesInPeriod($start, $last);
     $deleted = array();
     $added = array();
     while (!empty($events) && $events[0]['start_datetime'] == $parent['start_datetime']) {
         array_shift($events);
     }
     $addedTimes = array();
     $regularTimes = array();
     foreach ($events as $e) {
         // At this point we throw away confirmation information, mostly because I'm too tired and it's too
         // complicated to retrieve them.
         if ($e['participant_id'] != $parent['owner_id']) {
             continue;
         }
         if (empty($occurrences)) {
             $addedTimes[] = $e['start_datetime'];
             $added[] = $e;
             continue;
         }
         $cmp = $this->_compareDatetimeWithEvent($occurrences[0], $e);
         if ($cmp < 0) {
             // occurrence is before
             $deleted[] = array_shift($occurrences);
         } else {
             if ($cmp === 0) {
                 $regularTimes[] = array_shift($occurrences);
                 if ($this->_eventDataDiffers($parent, $e)) {
                     $addedTimes[] = $e['start_datetime'];
                     $deleted[] = new Datetime($e['start_datetime']);
                     $added[] = $e;
                 }
             } else {
                 // event is before occurrence
                 $added[] = $e;
             }
         }
     }
     $addedEventsParticipants = array();
     foreach ($events as $e) {
         if ($e['participant_id'] == $parent['owner_id']) {
             continue;
         }
         if (in_array($e['start_datetime'], $addedTimes)) {
             if (!array_key_exists($e['start_datetime'], $addedEventsParticipants)) {
                 $addedEventsParticipants[$e['start_datetime']] = array();
             }
             $addedEventsParticipants[$e['start_datetime']][] = array('id' => $e['participant_id'], 'status' => $e['status']);
         } else {
             if (!in_array($e['start_datetime'], $regularTimes)) {
                 // This event doesn't really belong here. We just create a new one for the user independent of $parent.
                 $uid = Phprojekt::generateUniqueIdentifier();
                 $this->_db->insert('calendar2', array('project_id' => $e['project_id'], 'summary' => $e['title'], 'description' => $e['notes'], 'location' => $e['place'], 'comments' => "", 'start' => $e['start_datetime'], 'last_end' => $e['end_datetime'], 'end' => $e['end_datetime'], 'owner_id' => $e['participant_id'], 'rrule' => '', 'visibility' => $e['visibility'] + 1, 'uri' => $uid, 'uid' => $uid));
                 $newCalendarId = $this->_db->lastInsertId();
                 $this->_db->insert('calendar2_user_relation', array('calendar2_id' => $newCalendarId, 'user_id' => $e['participant_id'], 'confirmation_status' => $e['status']));
             }
         }
     }
     if (!empty($deleted)) {
         $this->_deletedOccurrences($parent, $deleted);
     }
     if (!empty($added)) {
         $this->_addedOccurrences($parent, $added, $addedEventsParticipants);
     }
 }