public function testIsValidStartTime() { $this->event->repeat_frequency = Util::FREQUENCY_MONTHLY; $this->event->repeat_monthly_by = Util::REPEAT_MONTHLY_BY_DATE; $this->event->start_timestamp = 1424952000; // Thursday, 26-Feb-15 12:00:00 UTC $this->event->end_timestamp = 1424955600; $this->event->end_delta = 3600; // 1 hour $this->event->repeat_weekly_days = array(Util::MONDAY, Util::FRIDAY, Util::SUNDAY); $this->event->repeat = true; $valid = 1430049600; // Sunday, 26-Apr-15 12:00:00 UTC $invalid = 1430049660; $this->assertTrue($this->event->isValidStartTime($valid)); $this->assertFalse($this->event->isValidStartTime($invalid)); }
/** * Send reminder notifications to users based on their notification settings * @todo if there are a *lot* of recipients we should somehow break this off into parallel threads * * @param Event $event Event * @return void */ function send_event_reminder($event, $remindertime = null) { $force_send = true; if ($remindertime === null) { $remindertime = time(); $force_send = false; // default cron send } $dbprefix = elgg_get_config('dbprefix'); $options = array('type' => 'object', 'subtype' => 'calendar', 'relationship' => Calendar::EVENT_CALENDAR_RELATIONSHIP, 'relationship_guid' => $event->guid, 'joins' => array("JOIN {$dbprefix}users_entity ue ON e.container_guid = ue.guid"), 'limit' => false); $calendars = new ElggBatch('elgg_get_entities_from_relationship', $options); $starttimestamp = $event->getNextOccurrence($remindertime); $endtimestamp = $starttimestamp + $event->delta; // prevent sending if it was in the past, unless this is a forced reminder if (!$force_send && $starttimestamp < strtotime('-10 minutes')) { return true; } $owner = $event->getOwnerEntity(); $owner_link = elgg_view('output/url', array('text' => $owner->name, 'href' => $owner->getURL())); $in_group = ''; $in_group_link = ''; $container = $event->getContainerEntity(); $container_link = elgg_view('output/url', array('text' => $container->name, 'href' => $container->getURL())); if ($container instanceof \ElggGroup) { $in_group = elgg_echo('events:notify:subject:ingroup', array($container->name)); $in_group_link = elgg_echo('events:notify:subject:ingroup', array($container_link)); } $event_link = elgg_view('output/url', array('text' => $event->title, 'href' => $event->getURL())); $notified = array(); // users could have multiple calendars foreach ($calendars as $calendar) { $user = $calendar->getContainerEntity(); if (in_array($user->guid, $notified)) { continue; } $ia = elgg_set_ignore_access(false); if (!has_access_to_entity($event, $user)) { error_log($user->username . ' does not have access to ' . $event->guid); // the user can't see it, lets not notify them $notified[] = $user->guid; elgg_set_ignore_access($ia); continue; } elgg_set_ignore_access($ia); $notify_self = false; // support for notify self if (is_callable('notify_self_should_notify')) { $notify_self = notify_self_should_notify($user); } if (elgg_get_logged_in_user_guid() == $user->guid && !$notify_self) { $notified[] = $user->guid; continue; } $methods = get_calendar_notification_methods($user, 'eventreminder'); if (!$methods) { $notified[] = $user->guid; continue; } $timezone = Util::getClientTimezone($user); $dt = new DateTime(null, new DateTimeZone($timezone)); $dt->modify("{$event->start_date} {$event->start_time}"); $original_subject = elgg_echo('event:notify:eventreminder:subject', array($event->title, $in_group, $dt->format('D, F j g:ia T'))); $original_message = elgg_echo('event:notify:eventreminder:message', array($event_link, $in_group_link, elgg_view('output/events_ui/date_range', array('start' => $starttimestamp, 'end' => $endtimestamp, 'timezone' => $timezone)), $event->location, $event->description)); $params = array('event' => $event, 'entity' => $event, 'calendar' => $calendar, 'user' => $user, 'starttime' => $starttimestamp, 'endtime' => $endtimestamp); $subject = elgg_trigger_plugin_hook('events_ui', 'subject:eventreminder', $params, $original_subject); $message = elgg_trigger_plugin_hook('events_ui', 'message:eventreminder', $params, $original_message); notify_user($user->guid, $event->container_guid, $subject, $message, array(), $methods); $notified[] = $user->guid; } }
function event_calendar_migration() { $ia = elgg_set_ignore_access(true); // don't want to send notifications for these events elgg_unregister_event_handler('events_api', 'add_to_calendar', __NAMESPACE__ . '\\add_to_calendar'); $dbprefix = elgg_get_config('dbprefix'); $options = array('type' => 'object', 'subtype' => 'event_calendar', 'limit' => false); $old_events = new \ElggBatch('elgg_get_entities', $options, null, 25, false); foreach ($old_events as $old_event) { elgg_set_plugin_setting('migration_process', time(), 'events_ui'); $container = $old_event->getContainerEntity(); if (!$container) { // nothing we can do about this $old_event->delete(); continue; } $tza = DateTimeZone::listAbbreviations(); $tzlist = array(); foreach ($tza as $zone) { foreach ($zone as $item) { if (is_string($item['timezone_id']) && $item['timezone_id'] != '') { $tzlist[] = $item['timezone_id']; } } } // a list of all valid timezones $tzlist = array_unique($tzlist); $event = new Event(); $event->owner_guid = $old_event->owner_guid; $event->container_guid = $old_event->container_guid; $event->access_id = $old_event->access_id; $event->title = $old_event->title; $event->description = $old_event->long_description ? $old_event->long_description : $old_event->description; $event->location = $old_event->location; $event->tags = $old_event->tags; // date and time $start_date = $old_event->start_date ? date('Y-m-d', $old_event->start_date) : date('Y-m-d', $old_event->time_created); $event->start_date = $start_date; $end_date = $old_event->end_date ? date('Y-m-d', $old_event->end_date) : $start_date; $event->end_date = $end_date; if ($old_event->start_time !== '') { $hr = floor((int) $old_event->start_time / 15 / 4); $min = (int) $old_event->start_time / 15 % 4 * 15; $am = $hr < 12 ? 'am' : 'pm'; if ($hr > 12) { $hr -= 12; } if ($hr == 0) { $hr = 12; } if (!$min) { $min = '00'; } $start_time = $hr . ":" . $min . $am; } else { $start_time = '12:00am'; $end_time = '1:00am'; } if ($old_event->end_time !== '') { $hr = floor((int) $old_event->end_time / 15 / 4); $min = (int) $old_event->end_time / 15 % 4 * 15; $am = $hr < 12 ? 'am' : 'pm'; if ($hr > 12) { $hr -= 12; } if ($hr == 0) { $hr = 12; } if (!$min) { $min = '00'; } $end_time = $hr . ":" . $min . $am; } else { if (!$end_time) { $hr++; $am = $hr < 12 ? 'am' : 'pm'; if ($hr > 12) { $hr -= 12; } if ($hr == 0) { $hr = 12; } $end_time = $hr . ":" . $min . $am; } } $event->start_time = $start_time; $event->end_time = $end_time; $timezone = in_array($old_event->time_zone, $tzlist) ? $old_event->time_zone : 'America/New_York'; // event calendar used some invalid timezones... // default to UTC if it fails try { $dt = new DateTime(null, new DateTimeZone($timezone)); } catch (Exception $exc) { $dt = new DateTime(null, new DateTimeZone('America/New_York')); $timezone = 'America/New_York'; // good as any, and requested by client } $start_timestamp = $dt->modify("{$start_date} {$start_time}")->getTimestamp(); $start_timestamp_iso = $dt->format('c'); $end_timestamp = $dt->modify("{$end_date} {$end_time}")->getTimestamp(); $end_timestamp_iso = $dt->format('c'); $event->start_timestamp = $start_timestamp; $event->end_timestamp = $end_timestamp; $event->start_timestamp_iso = $start_timestamp_iso; $event->end_timestamp_iso = $end_timestamp_iso; $event->timezone = $timezone; $event->all_day = 0; $event->end_delta = abs($end_timestamp - $start_timestamp); $event->repeat = 0; if (!$event->save()) { // something went wrong continue; } $event->repeat_end_timestamp = $event->calculateRepeatEndTimestamp(); $event->time_created = $old_event->time_created; // might as well preserve this $event->save(); // time_created can only be updated, not set on creation // now we need to add the event to calendars // first add to the container calendar $calendar = Calendar::getPublicCalendar($container); $calendar->addEvent($event); // now add to any other calendars $user_options = array('type' => 'user', 'joins' => array("JOIN {$dbprefix}entity_relationships r ON r.guid_one = e.guid"), 'wheres' => array("r.relationship = 'personal_event' AND r.guid_two = {$old_event->guid}"), 'limit' => false); $users = new \ElggBatch('elgg_get_entities', $user_options); foreach ($users as $u) { $ucal = Calendar::getPublicCalendar($u); $ucal->addEvent($event); } // all done, lets kill the old event $old_event->delete(); } elgg_set_plugin_setting('migration_process', 0, 'events_ui'); elgg_set_ignore_access($ia); }
if (!$container->canWriteToContainer($user->guid, 'object', Event::SUBTYPE)) { register_error(elgg_echo('events:error:container_permissions')); forward(REFERER); } if (!get_input('title')) { register_error(elgg_echo('events:error:empty_title')); forward(REFERER); } $calendar_guid = get_input('calendar'); $calendar = get_entity($calendar_guid); if (!$calendar instanceof Calendar) { $calendar = Calendar::getPublicCalendar($user); } $editing = true; if (!$event instanceof Event) { $event = new Event(); $event->owner_guid = $user->guid; $event->container_guid = $container->guid; $editing = false; } $title = strip_tags(get_input('title', elgg_echo('events:edit:title:placeholder'))); $location = get_input('location'); $description = get_input('description'); $start_date = get_input('start_date'); $end_date = get_input('end_date', $start_date); $timezone = get_input('timezone', Util::UTC); $start_time = get_input('start_time', '12:00am'); $start_time_ts = strtotime($start_time); $end_time = get_input('end_time', date('g:ia', $start_time + Util::SECONDS_IN_AN_HOUR)); $repeat = get_input('repeat', false); $repeat_end_after = get_input('repeat_end_after');