/**
  * @covers EventRegistrationPurgeTask::purgeUnconfirmedRegistrations
  */
 public function testPurgeTaskCancelsUnconfirmedRegistrations()
 {
     $task = new EventRegistrationPurgeTask();
     $unconfirmed1 = $this->objFromFixture('EventRegistration', 'unconfirmed_1');
     $unconfirmed2 = $this->objFromFixture('EventRegistration', 'unconfirmed_2');
     $canceled = 'SELECT COUNT(*) FROM "EventRegistration" WHERE "Status" = \'Canceled\'';
     $update = 'UPDATE "EventRegistration" SET "Created" = \'%s\' WHERE "ID" = %d';
     ob_start();
     $task->run(null);
     $this->assertEquals(0, DB::query($canceled)->value());
     // Update the first task to be just shy of six hours less than the
     // created date.
     $created = strtotime($unconfirmed1->Created);
     $created = sfTime::subtract($created, 5, sfTime::HOUR);
     DB::query(sprintf($update, date('Y-m-d H:i:s', $created), $unconfirmed1->ID));
     $task->run(null);
     $this->assertEquals(0, DB::query($canceled)->value());
     // Now push it beyond six hours
     DB::query(sprintf($update, date('Y-m-d H:i:s', sfTime::subtract($created, 1, sfTime::HOUR)), $unconfirmed1->ID));
     $task->run(null);
     $this->assertEquals(1, DB::query($canceled)->value());
     // Now push the second one way back, and check it's also canceled
     $created = sfTime::subtract(time(), 1000, sfTime::DAY);
     DB::query(sprintf($update, date('Y-m-d H:i:s', $created), $unconfirmed2->ID));
     $task->run(null);
     $this->assertEquals(2, DB::query($canceled)->value());
     // Ensure the confirmed event is still there.
     $confirmed = DB::query('SELECT COUNT(*) FROM "EventRegistration" WHERE "Status" = \'Confirmed\'');
     $this->assertEquals(1, $confirmed->value());
     ob_end_clean();
 }
 /**
  * If the event times have changed, it checks to make sure that the resources
  * are still available. If not, it throws a validation exception.
  *
  * @throws ValiationException
  */
 public function onBeforeWrite()
 {
     $changed = $this->owner->getChangedFields();
     $check = array('StartDate', 'StartTime', 'EndDate', 'EndTime', 'is_all_day');
     if (!array_intersect_key(array_flip($check), $changed)) {
         return;
     }
     foreach ($this->owner->Resources() as $resource) {
         if ($resource->Type == 'Unlimited') {
             continue;
         }
         // If this is a recurring event, then check all other non-recurring
         // bookings for this resource to see if any conflict.
         if ($this->owner->Event()->Recursion) {
             $bookings = $resource->Events(sprintf('"CalendarEvent"."Recursion" = 0 AND "CalendarDateTime"."ID" <> %d', $this->owner->ID), null, 'INNER JOIN "CalendarEvent" ON "CalendarEvent"."ID" = "CalendarDateTime"."EventID"');
             foreach ($bookings as $booking) {
                 $counter = $booking->getStartTimestamp();
                 $end = $booking->getEndTimestamp();
                 // Loop through each day the other booking falls on, to see
                 // if it could cause a conflict.
                 while ($counter < $end) {
                     if ($this->owner->Event()->recursionHappensOn($counter)) {
                         $this->checkResourceAvailability($resource, $counter);
                     }
                     $counter = sfTime::add($counter, 1, sfTime::DAY);
                 }
             }
         } else {
             $this->checkResourceAvailability($resource);
         }
     }
 }
    public function bookings($request)
    {
        $start = (int) $request->getVar('start');
        $end = (int) $request->getVar('end');
        $result = array();
        // First load standard non-recurring events that fall between the start
        // and end date.
        $events = $this->parent->Events(sprintf('"CalendarEvent"."Recursion" = 0 AND (
					"StartDate" BETWEEN \'%1$s\' AND \'%2$s\'
					OR "EndDate" BETWEEN \'%1$s\' AND \'%2$s\'
					OR ("StartDate" < \'%1$s\' AND "EndDate" > \'%2$s\')
				)', date('Y-m-d', $start), date('Y-m-d', $end)), null, 'INNER JOIN "CalendarEvent" ON "CalendarEvent"."ID" = "CalendarDateTime"."EventID"');
        // Then load every recurring event and see if they fall between the start
        // and end.
        $recurring = $this->parent->Events(sprintf('"CalendarEvent"."Recursion" = 1
				AND ("EndDate" IS NULL OR "EndDate" > \'%s\')
				AND ("StartDate" IS NULL OR "StartDate" < \'%s\')', date('Y-m-d', $start), date('Y-m-d', $end)), null, 'INNER JOIN "CalendarEvent" ON "CalendarEvent"."ID" = "CalendarDateTime"."EventID"');
        // Now loop through each day in the specified date range, and check
        // each recurring date to see if it occurs on that day. Note that
        // recurring events always start and end on the same day.
        if ($recurring) {
            foreach ($recurring as $datetime) {
                $counter = $start;
                $days = 0;
                while ($counter <= $end) {
                    if ($counter > strtotime($datetime->EndDate)) {
                        break;
                    }
                    if ($datetime->Event()->recursionHappensOn($counter)) {
                        $_datetime = clone $datetime;
                        $_datetime->ID = -1;
                        $_datetime->StartDate = date('Y-m-d', $counter);
                        $_datetime->EndDate = date('Y-m-d', $counter);
                        $events->push($_datetime);
                    }
                    $counter = sfTime::add($counter, 1, sfTime::DAY);
                    $days++;
                }
            }
        }
        foreach ($events as $event) {
            $title = $event->EventTitle();
            if ($this->parent->Type != 'Single') {
                $title .= " ({$event->BookingQuantity} {$this->parent->Title})";
            }
            $result[] = array('id' => $event->ID, 'title' => $title, 'start' => $event->getStartTimestamp(), 'end' => $event->getEndTimestamp(), 'allDay' => (bool) $event->is_all_day, 'url' => Controller::join_links('admin/show', $event->EventID));
        }
        return Convert::array2json($result);
    }
 /**
  * If an email reminder is set, then this registers it in the queue.
  */
 protected function onBeforeWrite()
 {
     parent::onBeforeWrite();
     // If an email reminder has been set then register it with the queued
     // jobs module.
     if (class_exists('AbstractQueuedJob') && $this->EmailReminder) {
         $hasJob = $this->ReminderJobID;
         $changedStart = $this->isChanged('RemindDays');
         if ($hasJob) {
             if (!$changedStart) {
                 return;
             } else {
                 $this->ReminderJob()->delete();
             }
         }
         $start = $this->getStartDateTime()->getTimestamp();
         $start = sfTime::subtract($start, $this->RemindDays, sfTime::DAY);
         $job = new EventReminderEmailJob($this);
         $srv = singleton('QueuedJobService');
         $this->ReminderJobID = $srv->queueJob($job, date('Y-m-d H:i:s', $start));
     }
 }
Example #5
0
 /**
  * Returns the timestamp for the most recent (previous) occurance of [month].
  *
  * @param	timestamp
  * @param	int			the month of year
  * @return	timestamp
  */
 public static function previousMonth($ts = null, $month = sfTime::JANUARY)
 {
     // default to now
     if ($ts === null) {
         $ts = sfDateTimeToolkit::now();
     }
     // get offsets from january
     $offset1 = date('m', $ts);
     $offset2 = $month;
     // adjust if date wraps into last year
     $offset1 += $offset1 > $offset2 ? 0 : 12;
     return sfTime::subtractMonth($ts, $offset1 - $offset2);
 }
 /**
  * Calculates the timestamp for when this ticket stops going on sale for an
  * event date time.
  *
  * @param  RegistrableDateTime $datetime
  * @return int
  */
 public function getSaleEndForDateTime(RegistrableDateTime $datetime)
 {
     if ($this->EndType == 'Date') {
         return strtotime($this->EndDate);
     }
     $time = $datetime->getStartDateTime()->getTimestamp();
     $time = sfTime::subtract($time, $this->EndDays, sfTime::DAY);
     $time = sfTime::subtract($time, $this->EndHours, sfTime::HOUR);
     $time = sfTime::subtract($time, $this->EndMins, sfTime::MINUTE);
     return $time;
 }
    /**
     * Returns the number of this resource that are not booked during an event
     * time.
     *
     * @param  CalendarDateTime $time
     * @return bool|int
     */
    public function getAvailableForEvent($time)
    {
        if ($this->Type == 'Unlimited') {
            return true;
        }
        $start = $time->getStartTimestamp();
        $end = $time->getEndTimestamp();
        // First just get simple non-recurring bookings, often this will be
        // enough to check if a resource is available.
        $dateFilter = sprintf('"StartDate" BETWEEN \'%1$s\' AND \'%2$s\'
			OR "EndDate" BETWEEN \'%1$s\' AND \'%2$s\'
			OR ("StartDate" < \'%1$s\' AND "EndDate" > \'%2$s\')', date('Y-m-d', $start), date('Y-m-d', $end));
        $filter = "\"CalendarEvent\".\"Recursion\" = 0 AND \"CalendarDateTimeID\" <> {$time->ID} AND ({$dateFilter})";
        $bookings = $this->Events($filter, null, 'INNER JOIN "CalendarEvent" ON "CalendarEvent"."ID" = "CalendarDateTime"."EventID"');
        $bookings = $bookings->toArray('ID');
        // Since the event calendar doesn't use a proper date time storage, we
        // need to manually filter events again here.
        foreach ($bookings as $id => $booking) {
            if ($booking->getEndTimestamp() < $start || $booking->getStartTimestamp() > $end) {
                unset($bookings[$id]);
            }
        }
        if ($bookings && $this->Type == 'Single') {
            return false;
        }
        // Now also load all the recurring events, and check if they occur on
        // this day.
        $recurring = $this->Events(sprintf('"CalendarDateTimeID" <> %d
				AND "CalendarEvent"."Recursion" = 1
				AND ("EndDate" IS NULL OR "EndDate" > \'%s\')
				AND ("StartDate" IS NULL OR "StartDate" < \'%s\')', $time->ID, date('Y-m-d', $start), date('Y-m-d', $end)), null, 'INNER JOIN "CalendarEvent" ON "CalendarEvent"."ID" = "CalendarDateTime"."EventID"');
        // Now loop through each day this event runs on, and check if any of the
        // events fall on it. If they do just push them onto the bookings set.
        foreach ($recurring as $datetime) {
            $counter = $start;
            while ($counter <= $end) {
                if ($counter > strtotime($datetime->EndDate)) {
                    break;
                }
                if ($datetime->Event()->recursionHappensOn($counter)) {
                    $bookings[$datetime->ID] = $datetime;
                    break;
                }
                $counter = sfTime::add($counter, 1, sfTime::DAY);
            }
        }
        if ($bookings && $this->Type == 'Single') {
            return false;
        }
        if (!count($bookings)) {
            return $this->Type == 'Limited' ? (int) $this->Quantity : true;
        }
        $quantity = (int) $this->Quantity;
        foreach ($bookings as $booking) {
            $quantity -= $booking->BookingQuantity;
        }
        return $quantity > 0 ? $quantity : false;
    }