diff options
Diffstat (limited to 'models/model.php')
-rw-r--r-- | models/model.php | 937 |
1 files changed, 779 insertions, 158 deletions
diff --git a/models/model.php b/models/model.php index aa97bfddb..ba1393a8c 100644 --- a/models/model.php +++ b/models/model.php @@ -22,6 +22,22 @@ function event_calendar_get_event_for_edit($event_id) { } } +// converts to time in minutes since midnight +function event_calendar_convert_to_time($hour,$minute,$meridian) { + if ($meridian) { + if ($meridian == 'am') { + if ($hour == 12) { + $hour = 0; + } + } else { + if ($hour < 12) { + $hour += 12; + } + } + } + return 60*$hour+$minute; +} + // returns the event or FALSE function event_calendar_set_event_from_form($event_guid,$group_guid) { @@ -32,6 +48,8 @@ function event_calendar_set_event_from_form($event_guid,$group_guid) { $event_calendar_hide_end = elgg_get_plugin_setting('hide_end', 'event_calendar'); $event_calendar_more_required = elgg_get_plugin_setting('more_required', 'event_calendar'); $event_calendar_personal_manage = elgg_get_plugin_setting('personal_manage', 'event_calendar'); + $event_calendar_repeating_events = elgg_get_plugin_setting('repeating_events', 'event_calendar'); + $schedule_type = get_input('schedule_type'); if ($event_calendar_more_required == 'yes') { $required_fields = array('title','venue','start_date', @@ -54,7 +72,7 @@ function event_calendar_set_event_from_form($event_guid,$group_guid) { $required_fields[] = 'spots'; } } else { - $required_fields = array('title','venue','start_date'); + $required_fields = array('title'); } if ($event_guid) { @@ -78,36 +96,48 @@ function event_calendar_set_event_from_form($event_guid,$group_guid) { $event->title = get_input('title'); $event->description = get_input('description'); $event->venue = get_input('venue'); - // convert start date from current server time to GMT - $start_date = get_input('start_date'); - $start_date_text = date("Y-m-d",$start_date); - - $event->start_date = strtotime($start_date_text." ".date_default_timezone_get()); - $end_date = trim(get_input('end_date','')); - if ($end_date) { - $end_date_text = date("Y-m-d",$end_date); - $event->end_date = strtotime($end_date_text." ".date_default_timezone_get()); - } else { - $event->end_date = ''; - } - if ($event_calendar_times != 'no') { - $st = get_input('start_time',''); - if (is_numeric($st)) { - $event->start_time = $st; - } else { - $event->start_time = ''; - } - $et = get_input('end_time',''); - if (is_numeric($et)) { - $event->end_time = $et; + if ($schedule_type != 'poll') { + $start_date_text = trim(get_input('start_date')); + /*$event->original_start_date = get_input('start_date'); + //$end_date = trim(get_input('end_date','')); + // convert start date from current server time to GMT + $start_date_text = gmdate("Y-m-d",$start_date); + //$event->munged_start_date_string = $start_date_text." ".date_default_timezone_get();*/ + + // TODO: is the timezone bit necessary? + $event->start_date = strtotime($start_date_text." ".date_default_timezone_get()); + $end_date_text = trim(get_input('end_date','')); + //$event->original_end_date = get_input('end_date'); + if ($end_date_text) { + $event->end_date = strtotime($end_date_text." ".date_default_timezone_get()); + //$event->munged_end_date_string = $end_date_text." ".date_default_timezone_get(); } else { - $event->end_time = ''; + $event->end_date = ''; } - if (is_numeric($event->start_time)) { - // Set start date to the Unix start time, if set. - // This allows sorting by date *and* time. - $event->start_date += $event->start_time*60; + + if ($event_calendar_times != 'no') { + $hour = get_input('start_time_hour',''); + $minute = get_input('start_time_minute',''); + $meridian = get_input('start_time_meridian',''); + if (is_numeric($hour) && is_numeric($minute)) { + $event->start_time = event_calendar_convert_to_time($hour,$minute,$meridian); + } else { + $event->start_time = ''; + } + $hour = get_input('end_time_hour',''); + $minute = get_input('end_time_minute',''); + $meridian = get_input('end_time_meridian',''); + if (is_numeric($hour) && is_numeric($minute)) { + $event->end_time = event_calendar_convert_to_time($hour,$minute,$meridian); + } else { + $event->end_time = ''; + } + if (is_numeric($event->start_date) && is_numeric($event->start_time)) { + // Set start date to the Unix start time, if set. + // This allows sorting by date *and* time. + $event->start_date += $event->start_time*60; + } } } if ($event_calendar_spots_display == 'yes') { @@ -122,11 +152,29 @@ function event_calendar_set_event_from_form($event_guid,$group_guid) { if ($event_calendar_personal_manage == 'by_event') { $event->personal_manage = get_input('personal_manage'); } + + if ($event_calendar_repeating_events != 'no') { + $repeats = get_input('repeats'); + $event->repeats = $repeats; + if ($repeats == 'yes') { + $event->repeat_interval = get_input('repeat_interval'); + $dow = array('monday','tuesday','wednesday','thursday','friday','saturday','sunday'); + foreach ($dow as $w) { + $v = 'event-calendar-repeating-'.$w.'-value'; + $event->$v = get_input($v); + } + } + } $event->fees = get_input('fees'); $event->contact = get_input('contact'); $event->organiser = get_input('organiser'); $event->tags = string_to_tag_array(get_input('tags')); $event->long_description = get_input('long_description'); + $event->schedule_type = $schedule_type; + $event->send_reminder = get_input('send_reminder'); + $event->reminder_number = get_input('reminder_number'); + $event->reminder_interval = get_input('reminder_interval'); + $event->web_conference = get_input('web_conference'); $event->real_end_time = event_calendar_get_end_time($event); foreach ($required_fields as $fn) { if (!trim($event->$fn)) { @@ -135,6 +183,9 @@ function event_calendar_set_event_from_form($event_guid,$group_guid) { } } if ($event->save()) { + if (!$event_guid && $event->web_conference) { + event_calendar_create_bbb_conf($event); + } if ($group_guid && (elgg_get_plugin_setting('autogroup', 'event_calendar') == 'yes')) { event_calendar_add_personal_events_from_group($event->guid,$group_guid); } @@ -148,12 +199,12 @@ function event_calendar_set_event_from_form($event_guid,$group_guid) { event_calendar_add_personal_event($event->guid,$user_id); if (elgg_get_plugin_setting('add_users_notify', 'event_calendar') == 'yes') { notify_user($user_id, $CONFIG->site->guid, elgg_echo('event_calendar:add_users_notify:subject'), - sprintf( - elgg_echo('event_calendar:add_users_notify:body'), - $user->name, - $event->title, - $event->getURL() - ) + sprintf( + elgg_echo('event_calendar:add_users_notify:body'), + $user->name, + $event->title, + $event->getURL() + ) ); } } @@ -164,19 +215,142 @@ function event_calendar_set_event_from_form($event_guid,$group_guid) { return $event; } -function event_calendar_get_events_between($start_date,$end_date,$is_count,$limit=10,$offset=0,$container_guid=0,$region='-') { +function event_calendar_get_events_between($start_date,$end_date,$is_count=FALSE,$limit=10,$offset=0,$container_guid=0,$region='-') { + $polls_supported = elgg_is_active_plugin('event_poll'); if ($is_count) { $count = event_calendar_get_entities_from_metadata_between2('start_date','end_date', $start_date, $end_date, "object", "event_calendar", 0, $container_guid, $limit,$offset,"",0,false,true,$region); return $count; } else { $events = event_calendar_get_entities_from_metadata_between2('start_date','end_date', - $start_date, $end_date, "object", "event_calendar", 0, $container_guid, $limit,$offset,"",0,false,false,$region); - //return event_calendar_vsort($events,'start_date'); - return $events; + $start_date, $end_date, "object", "event_calendar", 0, $container_guid, $limit,$offset,"",0,false,false,$region); + $repeating_events = event_calendar_get_repeating_events_between($start_date,$end_date,$container_guid,$region); + $all_events = event_calendar_merge_repeating_events($events, $repeating_events); + if ($polls_supported) { + elgg_load_library('elgg:event_poll'); + $all_events = event_poll_merge_poll_events($all_events,$start_date,$end_date); + } + + return $all_events; } } +function event_calendar_merge_repeating_events($events, $repeating_events) { + $non_repeating_events = array(); + foreach($events as $e) { + if ($e->repeats != 'yes') { + $non_repeating_events[] = array('event' => $e,'data' => array(array('start_time' => $e->start_date, 'end_time' => $e->real_end_time))); + } + } + + return array_merge($non_repeating_events, $repeating_events); +} + +function event_calendar_get_repeating_events_between($start_date,$end_date,$container_guid,$region) { + // game plan: get all repeating events with start date <= $end_date and then generate all possible events + // sanity check + if ($start_date <= $end_date) { + $options = array( + 'type' => 'object', + 'subtype' => 'event_calendar', + 'limit' => 0, + 'metadata_name_value_pairs' => array( + array( + 'name' => 'start_date', + 'value' => $end_date, + 'operand' => '<=' + ), + array( + 'name' => 'repeats', + 'value' => 'yes' + ), + ) + ); + if ($container_guid) { + if (is_array($container_guid)) { + $options['container_guids'] = $container_guid; + } else { + $options['container_guid'] = $container_guid; + } + } + + if ($region && $region != '-') { + $options['metadata_name_value_pairs'][] = array( + 'name' => 'region', + 'value' => $region + ); + } + + $events = elgg_get_entities_from_metadata($options); + } + return event_calendar_get_repeating_event_structure($events, $start_date, $end_date); +} + + +function event_calendar_get_repeating_event_structure($events, $start_date, $end_date) { + $dow = array('monday','tuesday','wednesday','thursday','friday','saturday','sunday'); + $repeating_events = array(); + if ($events) { + $incs = array(); + foreach($events as $e) { + $repeat_data = array(); + $day_num = date('N',$e->start_date)-1; + for($d=0;$d<7;$d++) { + $fn = 'event-calendar-repeating-'.$dow[$d].'-value'; + if ($e->$fn) { + $increment = $d - $day_num; + $incs[] = $increment; + } + } + if ($incs) { + sort($incs); + + $repeat_interval = $e->repeat_interval; + $event_start_time = $e->start_date; + $event_end_time = $e->real_end_time; + $week = 0; + if ($event_start_time <= $event_end_time) { + $more_to_do = TRUE; + $cur_start_time = $event_start_time; + $cur_end_time = $event_end_time; + // keep generating events until after $end_date + // repeat_times is a sanity check to prevent infinite loops in case of bad data + $repeat_times = 0; + do { + foreach($incs as $inc) { + //$seconds = $inc*60*60*24; + if ($inc >=0) { + $tinc = "+ " . $inc; + } else { + $tinc = $inc; + } + $this_start_time = strtotime($tinc . " day", $cur_start_time); + $this_end_time = strtotime($tinc . " day", $cur_end_time); + if ($this_start_time > $end_date) { + $more_to_do = FALSE; + break; + } + if ($this_start_time >= $event_start_time) { + $repeat_data[] = array ( + 'start_time' => $this_start_time, + 'end_time' => $this_end_time, + ); + } + } + // repeat_interval weeks later + $week += $repeat_interval; + $cur_start_time = strtotime("+" . $week . " week", $event_start_time); + $cur_end_time = strtotime("+" . $week ." week", $event_end_time); + $repeat_times += 1; + } while ($repeat_times < 1000 && $more_to_do); + } + } + $repeating_events[] = array('event'=>$e,'data'=>$repeat_data); + } + } + return $repeating_events; +} + function event_calendar_get_open_events_between($start_date,$end_date, $is_count,$limit=10,$offset=0,$container_guid=0,$region='-', $meta_max = 'spots', $annotation_name = 'personal_event') { if ($is_count) { @@ -187,10 +361,73 @@ $is_count,$limit=10,$offset=0,$container_guid=0,$region='-', $meta_max = 'spots' $events = event_calendar_get_entities_from_metadata_between2('start_date','end_date', $start_date, $end_date, "object", "event_calendar", 0, $container_guid, $limit,$offset,"",0,false,false,$region,$meta_max,$annotation_name); //return event_calendar_vsort($events,'start_date'); - return $events; + $repeating_events = event_calendar_get_open_repeating_events_between($start_date,$end_date,$container_guid,$region); + $all_events = event_calendar_merge_repeating_events($events, $repeating_events); + return $all_events; } } +function event_calendar_get_open_repeating_events_between($start_date,$end_date,$container_guid,$region) { + $db_prefix = elgg_get_config('dbprefix'); + $meta_max = 'spots'; + $annotation_name = 'personal_event'; + $joins = array(); + $wheres = array(); + $meta_max_n = get_metastring_id($meta_max); + $ann_n = get_metastring_id($annotation_name); + if (!$meta_max_n || !$ann_n) { + if ($count) { + return 0; + } else { + return false; + } + } + + $joins[] = "LEFT JOIN {$dbprefix}metadata m4 ON (e.guid = m4.entity_guid AND m4.name_id=$meta_max_n) "; + $joins[] = "LEFT JOIN {$dbprefix}metastrings ms4 ON (m4.value_id = ms4.id) "; + $wheres[] = "((ms4.string is null) OR (ms4.string = \"\") OR (CONVERT(ms4.string,SIGNED) > (SELECT count(id) FROM {$dbprefix}annotations ann WHERE ann.entity_guid = e.guid AND name_id = $ann_n GROUP BY entity_guid)))"; + + // sanity check + if ($start_date <= $end_date) { + $options = array( + 'type' => 'object', + 'subtype' => 'event_calendar', + 'limit' => 0, + 'metadata_name_value_pairs' => array( + array( + 'name' => 'start_date', + 'value' => $end_date, + 'operand' => '<=' + ), + array( + 'name' => 'repeats', + 'value' => 'yes' + ), + ), + 'joins' => $joins, + 'wheres' => $wheres, + + ); + if ($container_guid) { + if (is_array($container_guid)) { + $options['container_guids'] = $container_guid; + } else { + $options['container_guid'] = $container_guid; + } + } + + if ($region && $region != '-') { + $options['metadata_name_value_pairs'][] = array( + 'name' => 'region', + 'value' => $region + ); + } + + $events = elgg_get_entities_from_metadata($options); + } + return event_calendar_get_repeating_event_structure($events, $start_date, $end_date); +} + function event_calendar_get_events_for_user_between($start_date,$end_date,$is_count,$limit=10,$offset=0,$user_guid,$container_guid=0,$region='-') { if ($is_count) { // old way @@ -244,14 +481,82 @@ function event_calendar_get_events_for_user_between2($start_date,$end_date,$is_c //print_r($options_new_way); $events_new_way = elgg_get_entities_from_relationship($options_new_way); //return event_calendar_vsort($events,'start_date'); - if (!$events_old_way) { - return $events_new_way; - } else if (!$events_new_way) { - return $events_old_way; + $repeating_events = event_calendar_get_repeating_events_for_user_between($user_guid,$start_date,$end_date,$container_guid,$region); + $all_events = event_calendar_merge_repeating_events(array_merge($events_old_way,$events_new_way), $repeating_events); + return $all_events; + } +} + +function event_calendar_get_repeating_events_for_user_between($user_guid,$start_date,$end_date,$container_guid,$region) { + $options = array( + 'type' => 'object', + 'subtype' => 'event_calendar', + 'relationship' => 'personal_event', + 'relationship_guid' => $user_guid, + 'metadata_name_value_pairs' => array( + array( + 'name' => 'start_date', + 'value' => $end_date, + 'operand' => '<=' + ), + array( + 'name' => 'repeats', + 'value' => 'yes' + ), + ) + ); + + if ($container_guid) { + if (is_array($container_guid)) { + $options['container_guids'] = $container_guid; + } else { + $options['container_guid'] = $container_guid; + } + } + + if ($region && $region != '-') { + $options['metadata_name_value_pairs'][] = array( + 'name' => 'region', + 'value' => $region + ); + } + + $events = elgg_get_entities_from_relationship($options); + return event_calendar_get_repeating_event_structure($events, $start_date, $end_date); +} + +function event_calendar_get_repeating_events_for_friends_between($user_guid,$friend_list,$start_date,$end_date,$container_guid=0,$region='-') { + + $db_prefix = elgg_get_config('dbprefix'); + $options = array( + 'type' => 'object', + 'subtype' => 'event_calendar', + 'metadata_name_value_pairs' => array( + array( 'name' => 'start_date', + 'value' => $end_date, + 'operand' => '<=' + ), + array( 'name' => 'repeats', + 'value' => 'yes' + ) + ), + 'joins' => array("JOIN {$db_prefix}entity_relationships r ON (r.guid_two = e.guid)"), + 'wheres' => array("r.relationship = 'personal_event'","r.guid_one IN ($friend_list)"), + ); + + if ($container_guid) { + if (is_array($container_guid)) { + $options['container_guids'] = $container_guid; } else { - return array_merge($events_old_way,$events_new_way); + $options['container_guid'] = $container_guid; } } + if ($region && $region != '-') { + $options['metadata_name_value_pairs'][] = array('name'=>'region','value'=>sanitize_string($region)); + } + + $events = elgg_get_entities_from_relationship($options); + return event_calendar_get_repeating_event_structure($events, $start_date, $end_date); } function event_calendar_get_events_for_friends_between($start_date,$end_date,$is_count,$limit=10,$offset=0,$user_guid,$container_guid=0,$region='-') { @@ -300,13 +605,9 @@ function event_calendar_get_events_for_friends_between($start_date,$end_date,$is $options_new_way['order_by_metadata'] = array(array('name'=>'start_date','direction'=>'ASC','as'=>'integer')); //print_r($options_new_way); $events_new_way = elgg_get_entities_from_metadata($options_new_way); - if (!$events_old_way) { - return $events_new_way; - } else if (!$events_new_way) { - return $events_old_way; - } else { - return array_merge($events_old_way,$events_new_way); - } + $repeating_events = event_calendar_get_repeating_events_for_friends_between($user_guid,$friend_list,$start_date,$end_date,$container_guid,$region); + $all_events = event_calendar_merge_repeating_events(array_merge($events_old_way,$events_new_way), $repeating_events); + return $all_events; } } } @@ -469,18 +770,19 @@ function event_calendar_get_entities_from_metadata_between($meta_start_name, $me $query .= ' and ' . get_access_sql_suffix("m"); // Add access controls $query .= ' and ' . get_access_sql_suffix("m2"); // Add access controls - - if (!$count) { - $query .= " order by $order_by limit $offset, $limit"; // Add order and limit + $query .= " order by $order_by"; + if ($limit) { + $query .= " limit $offset, $limit"; // Add order and limit + } $entities = get_data($query, "entity_row_to_elggstar"); if (elgg_get_plugin_setting('add_to_group_calendar', 'event_calendar') == 'yes') { if (get_entity($container_guid) instanceOf ElggGroup) { $entities = event_calendar_get_entities_from_metadata_between_related($meta_start_name, $meta_end_name, - $meta_start_value, $meta_end_value, $entity_type, - $entity_subtype, $owner_guid, $container_guid, - $limit = 10, $offset = 0, $order_by = "", $site_guid = 0, - $filter = false, $count = false, $region='-',$entities); + $meta_start_value, $meta_end_value, $entity_type, + $entity_subtype, $owner_guid, $container_guid, + 0, 0, "", 0, + false, false, '-',$entities); } } return $entities; @@ -557,6 +859,8 @@ $filter = false, $count = false, $region='-',$main_events) { * @param string $annotation_name annotation name to count * * @return int|array A list of entities, or a count if $count is set to true + * + * TODO: see if the new API is robust enough to avoid this custom query */ function event_calendar_get_entities_from_metadata_between2 ($meta_start_name, $meta_end_name, $meta_start_value, $meta_end_value, @@ -690,8 +994,21 @@ $count = false, $region='-', $meta_max = '', $annotation_name = '') $query .= ' AND ' . get_access_sql_suffix("m2"); // Add access controls if (!$count) { - $query .= " order by $order_by limit $offset, $limit"; // Add order and limit - return get_data($query, "entity_row_to_elggstar"); + $query .= " order by $order_by"; + if ($limit) { + $query .= " limit $offset, $limit"; // Add order and limit + } + $entities = get_data($query, "entity_row_to_elggstar"); + if (elgg_get_plugin_setting('add_to_group_calendar', 'event_calendar') == 'yes') { + if (get_entity($container_guid) instanceOf ElggGroup) { + $entities = event_calendar_get_entities_from_metadata_between_related($meta_start_name, $meta_end_name, + $meta_start_value, $meta_end_value, $entity_type, + $entity_subtype, $owner_guid, $container_guid, + 0, 0, "", 0, + false, false, '-',$entities); + } + } + return $entities; } else { if ($row = get_data_row($query)) return $row->total; @@ -784,7 +1101,7 @@ function event_calendar_get_personal_events_for_user($user_guid,$limit) { // the old way used annotations, and the new Elgg 1.8 way uses relationships // for now this version attempts to bridge the gap by using both methods for older sites -function event_calendar_get_users_for_event($event_guid,$limit,$offset,$is_count) { +function event_calendar_get_users_for_event($event_guid,$limit,$offset=0,$is_count=FALSE) { $options = array( 'type' => 'user', 'relationship' => 'personal_event', @@ -833,38 +1150,16 @@ function event_calendar_security_fields() { return "__elgg_token=$token&__elgg_ts=$ts"; } -function event_calendar_get_events_for_group($group_guid) { +function event_calendar_get_events_for_group($group_guid, $limit = 0) { $options = array( 'type' => 'object', 'subtype' => 'event_calendar', 'container_guid' => $group_guid, - 'limit' => 0, + 'limit' => $limit, ); return elgg_get_entities($options); } -function event_calendar_handle_join($event, $object_type, $object) { - $group = $object['group']; - $user = $object['user']; - $user_guid = $user->getGUID(); - $events = event_calendar_get_events_for_group($group->getGUID()); - foreach ($events as $event) { - $event_id = $event->getGUID(); - event_calendar_add_personal_event($event_id,$user_guid); - } -} - -function event_calendar_handle_leave($event, $object_type, $object) { - $group = $object['group']; - $user = $object['user']; - $user_guid = $user->getGUID(); - $events = event_calendar_get_events_for_group($group->getGUID()); - foreach ($events as $event) { - $event_id = $event->getGUID(); - event_calendar_remove_personal_event($event_id,$user_guid); - } -} - function event_calendar_convert_time($time) { $event_calendar_time_format = elgg_get_plugin_setting('timeformat','event_calendar'); if ($event_calendar_time_format == '12') { @@ -922,10 +1217,14 @@ function event_calendar_get_region($event) { function event_calendar_get_type($event) { $event_calendar_type_list_handles = elgg_get_plugin_setting('type_list_handles', 'event_calendar'); $type = trim($event->event_type); - if ($event_calendar_type_list_handles == 'yes') { - $type = elgg_echo('event_calendar:type:'.$type); - } - return htmlspecialchars($type); + if ($type) { + if ($event_calendar_type_list_handles == 'yes') { + $type = elgg_echo('event_calendar:type:'.$type); + } + return htmlspecialchars($type); + } else { + return $type; + } } function event_calendar_get_formatted_full_items($event) { @@ -933,10 +1232,12 @@ function event_calendar_get_formatted_full_items($event) { $event_calendar_region_display = elgg_get_plugin_setting('region_display', 'event_calendar'); $event_calendar_type_display = elgg_get_plugin_setting('type_display', 'event_calendar'); $event_items = array(); - $item = new stdClass(); - $item->title = elgg_echo('event_calendar:when_label'); - $item->value = $time_bit; - $event_items[] = $item; + if ($time_bit) { + $item = new stdClass(); + $item->title = elgg_echo('event_calendar:when_label'); + $item->value = $time_bit; + $event_items[] = $item; + } $item = new stdClass(); $item->title = elgg_echo('event_calendar:venue_label'); $item->value = htmlspecialchars($event->venue); @@ -948,10 +1249,13 @@ function event_calendar_get_formatted_full_items($event) { $event_items[] = $item; } if ($event_calendar_type_display == 'yes') { - $item = new stdClass(); - $item->title = elgg_echo('event_calendar:type_label'); - $item->value = event_calendar_get_type($event); - $event_items[] = $item; + $event_type = event_calendar_get_type($event); + if ($event_type) { + $item = new stdClass(); + $item->title = elgg_echo('event_calendar:type_label'); + $item->value = event_calendar_get_type($event); + $event_items[] = $item; + } } $item = new stdClass(); $item->title = elgg_echo('event_calendar:fees_label'); @@ -970,6 +1274,9 @@ function event_calendar_get_formatted_full_items($event) { } function event_calendar_get_formatted_time($event) { + if (!$event->start_date) { + return ''; + } $date_format = 'j M Y'; $event_calendar_times = elgg_get_plugin_setting('times', 'event_calendar') != 'no'; @@ -978,17 +1285,35 @@ function event_calendar_get_formatted_time($event) { $end_date = date($date_format,$event->end_date); } if ((!$event->end_date) || ($end_date == $start_date)) { - if ($event_calendar_times) { + if (!$event->all_day && $event_calendar_times) { $start_date = event_calendar_format_time($start_date,$event->start_time,$event->end_time); } $time_bit = $start_date; } else { - if ($event_calendar_times) { + if (!$event->all_day && $event_calendar_times) { $start_date = event_calendar_format_time($start_date,$event->start_time); $end_date = event_calendar_format_time($end_date,$event->end_time); } $time_bit = "$start_date - $end_date"; } + + if ($event->repeats == 'yes') { + $dow = array('monday','tuesday','wednesday','thursday','friday','saturday','sunday'); + $r = array(); + foreach ($dow as $w) { + $fn = 'event-calendar-repeating-'.$w.'-value'; + if ($event->$fn) { + $r[] = elgg_echo('event_calendar:dow:full:'.$w); + } + } + $week_bit = implode(", ",$r); + if ($event->repeat_interval > 1) { + $week_bit .= ' '.elgg_echo('event_calendar:repeated_event:week_interval',array($event->repeat_interval)); + } else { + $week_bit .= ' '.elgg_echo('event_calendar:repeated_event:week_single'); + } + $time_bit = elgg_echo('event_calendar:repeated_event:format',array($time_bit, $week_bit)); + } return $time_bit; } @@ -1156,18 +1481,9 @@ function event_calendar_get_page_content_list($page_type,$container_guid,$start_ elgg_push_context('groups'); elgg_set_page_owner_guid($container_guid); $user_guid = elgg_get_logged_in_user_guid(); - $group_calendar = elgg_get_plugin_setting('group_calendar', 'event_calendar'); - if (!$group_calendar || $group_calendar == 'members') { - if (elgg_get_page_owner_entity()->canWriteToContainer($user_guid)){ - elgg_register_menu_item('title', array( - 'name' => 'add', - 'href' => "event_calendar/add/".$container_guid, - 'text' => elgg_echo('event_calendar:add'), - 'class' => 'elgg-button elgg-button-action', - )); - } - } else if ($group_calendar == 'admin') { - if (elgg_is_admin_logged_in() || ($group->owner_guid == $user_guid)) { + // TODO - ideally avoid the check on the event_poll plugin, perhaps by having event_poll remove the menu item + if(event_calendar_can_add($container_guid)) { + if (!elgg_plugin_exists('event_poll')) { elgg_register_menu_item('title', array( 'name' => 'add', 'href' => "event_calendar/add/".$container_guid, @@ -1178,20 +1494,9 @@ function event_calendar_get_page_content_list($page_type,$container_guid,$start_ } } else { elgg_push_breadcrumb(elgg_echo('item:object:event_calendar')); - $site_calendar = elgg_get_plugin_setting('site_calendar', 'event_calendar'); - if (!$site_calendar || $site_calendar == 'admin') { - // only admins can post directly to the site-wide calendar - if (elgg_is_admin_logged_in()) { - elgg_register_menu_item('title', array( - 'name' => 'add', - 'href' => "event_calendar/add", - 'text' => elgg_echo('event_calendar:add'), - 'class' => 'elgg-button elgg-button-action', - )); - } - } else if ($site_calendar == 'loggedin') { - // any logged-in user can post to the site calendar - if (elgg_is_logged_in()) { + $user_guid = elgg_get_logged_in_user_guid(); + if(event_calendar_can_add($container_guid)) { + if (!elgg_plugin_exists('event_poll')) { elgg_register_menu_item('title', array( 'name' => 'add', 'href' => "event_calendar/add", @@ -1228,7 +1533,8 @@ function event_calendar_get_page_content_list($page_type,$container_guid,$start_ return elgg_view_page($title,$body); } -function event_calendar_get_page_content_edit($page_type,$guid) { +function event_calendar_get_page_content_edit($page_type,$guid,$start_date='') { + elgg_load_js('elgg.event_calendar'); $vars = array(); $vars['id'] = 'event-calendar-edit'; $vars['name'] = 'event_calendar_edit'; @@ -1242,12 +1548,15 @@ function event_calendar_get_page_content_edit($page_type,$guid) { $event = get_entity((int)$guid); if (elgg_instanceof($event, 'object', 'event_calendar') && $event->canEdit()) { $body_vars['event'] = $event; - $body_vars['form_data'] = event_calendar_prepare_edit_form_vars($event); + $body_vars['form_data'] = event_calendar_prepare_edit_form_vars($event,$page_type); + $event_container = get_entity($event->container_guid); if (elgg_instanceof($event_container, 'group')) { elgg_push_breadcrumb(elgg_echo('event_calendar:group_breadcrumb'), 'event_calendar/group/'.$event->container_guid); + $body_vars['group_guid'] = $event_container->guid; } else { elgg_push_breadcrumb(elgg_echo('event_calendar:show_events_title'),'event_calendar/list'); + $body_vars['group_guid'] = 0; } elgg_push_breadcrumb($event->title,$event->getURL()); elgg_push_breadcrumb(elgg_echo('event_calendar:manage_event_title')); @@ -1258,6 +1567,7 @@ function event_calendar_get_page_content_edit($page_type,$guid) { } } else { $title = elgg_echo('event_calendar:add_event_title'); + if ($guid) { // add to group $group = get_entity($guid); @@ -1265,16 +1575,17 @@ function event_calendar_get_page_content_edit($page_type,$guid) { $body_vars['group_guid'] = $guid; elgg_push_breadcrumb(elgg_echo('event_calendar:group_breadcrumb'), 'event_calendar/group/'.$guid); elgg_push_breadcrumb(elgg_echo('event_calendar:add_event_title')); - $body_vars['form_data'] = event_calendar_prepare_edit_form_vars(); + $body_vars['form_data'] = event_calendar_prepare_edit_form_vars(NULL,$page_type,$start_date); $content = elgg_view_form('event_calendar/edit', $vars, $body_vars); } else { $content = elgg_echo('event_calendar:no_group'); } } else { + $body_vars['group_guid'] = 0; elgg_push_breadcrumb(elgg_echo('event_calendar:show_events_title'),'event_calendar/list'); elgg_push_breadcrumb(elgg_echo('event_calendar:add_event_title')); - $body_vars['form_data'] = event_calendar_prepare_edit_form_vars(); + $body_vars['form_data'] = event_calendar_prepare_edit_form_vars(NULL,$page_type,$start_date); $content = elgg_view_form('event_calendar/edit', $vars, $body_vars); } @@ -1293,17 +1604,27 @@ function event_calendar_get_page_content_edit($page_type,$guid) { * @param ElggObject $event * @return array */ -function event_calendar_prepare_edit_form_vars($event = NULL) { +function event_calendar_prepare_edit_form_vars($event = NULL, $page_type = '', $start_date = '') { // input names => defaults + $now = time(); + $iso_date = date('Y-m-d',$now); + $now_midnight = strtotime($iso_date); + if ($start_date) { + $start_date = strtotime($start_date); + } else { + $start_date = $now+60*60; + } + $start_time = floor(($now-$now_midnight)/60) + 60; + $start_time = floor($start_time/5)*5; $values = array( 'title' => NULL, 'description' => NULL, 'venue' => NULL, - 'start_date' => NULL, - 'end_date' => NULL, - 'start_time' => NULL, - 'end_time' => NULL, + 'start_date' => $start_date, + 'end_date' => $start_date+60*60, + 'start_time' => $start_time, + 'end_time' => $start_time + 60, 'spots' => NULL, 'region' => '-', 'event_type' => '-', @@ -1311,11 +1632,30 @@ function event_calendar_prepare_edit_form_vars($event = NULL) { 'contact' => NULL, 'organiser' => NULL, 'tags' => NULL, - 'personal_manage' => NULL, + 'send_reminder' => NULL, + 'reminder_number' => 1, + 'reminder_interval' => 60, + 'repeats' => NULL, + 'repeat_interval' => 1, + 'event-calendar-repeating-monday-value' => 0, + 'event-calendar-repeating-tuesday-value' => 0, + 'event-calendar-repeating-wednesday-value' => 0, + 'event-calendar-repeating-thursday-value' => 0, + 'event-calendar-repeating-friday-value' => 0, + 'event-calendar-repeating-saturday-value' => 0, + 'event-calendar-repeating-sunday-value' => 0, + 'personal_manage' => 'open', + 'web_conference' => NULL, 'long_description' => NULL, 'access_id' => ACCESS_DEFAULT, 'group_guid' => NULL, ); + + if ($page_type == 'schedule') { + $values['schedule_type'] = 'poll'; + } else { + $values['schedule_type'] = 'fixed'; + } if ($event) { foreach (array_keys($values) as $field) { @@ -1466,6 +1806,7 @@ function event_calendar_generate_listing_params($page_type,$container_guid,$orig $filter = 'all'; } } + if ($filter == 'all') { $count = event_calendar_get_events_between($start_ts,$end_ts,true,$limit,$offset,$container_guid,$region); $events = event_calendar_get_events_between($start_ts,$end_ts,false,$limit,$offset,$container_guid,$region); @@ -1506,6 +1847,8 @@ function event_calendar_generate_listing_params($page_type,$container_guid,$orig if ($event_calendar_listing_format == 'paged') { $title = elgg_echo('event_calendar:upcoming_events_title'); + } else if ($event_calendar_listing_format == 'full') { + $title = elgg_echo('event_calendar:show_events_title'); } else if ($page_type == 'group') { $title = elgg_echo('event_calendar:group'). ' ('.$subtitle.')'; } else { @@ -1517,7 +1860,7 @@ function event_calendar_generate_listing_params($page_type,$container_guid,$orig return $params; } -function event_calendar_get_page_content_view($event_guid) { +function event_calendar_get_page_content_view($event_guid,$light_box = FALSE) { // add personal calendar button and links elgg_push_context('event_calendar:view'); $event = get_entity($event_guid); @@ -1547,12 +1890,16 @@ function event_calendar_get_page_content_view($event_guid) { $content .= elgg_view_comments($event); } } - - $params = array('title' => $title, 'content' => $content,'filter' => ''); - - $body = elgg_view_layout("content", $params); - - return elgg_view_page($title,$body); + + if ($light_box) { + return '<div class="event-calendar-lightbox">'.elgg_view_title($title).$content.'</div>'; + } else { + $params = array('title' => $title, 'content' => $content,'filter' => ''); + + $body = elgg_view_layout("content", $params); + + return elgg_view_page($title,$body); + } } function event_calendar_get_page_content_display_users($event_guid) { @@ -1744,28 +2091,302 @@ function getLastDayOfMonth($month,$year) { return idate('d', mktime(0, 0, 0, ($month + 1), 0, $year)); } -// TODO - this is not quite right across daylight savings time divides -// Possible solution: convert stored date to server date, do inc and then convert back to GMT - -function event_calendar_modify_full_calendar($event_guid,$day_delta,$minute_delta) { +function event_calendar_modify_full_calendar($event_guid,$day_delta,$minute_delta,$start_time,$resend,$minutes,$iso_date) { $event = get_entity($event_guid); if (elgg_instanceof($event,'object','event_calendar') && $event->canEdit()) { - $event->start_date = strtotime("$day_delta days",$event->start_date)+60*$minute_delta; - if ($event->end_date) { - $event->end_date = strtotime("$day_delta days",$event->end_date); + if ($event->is_event_poll) { + if (elgg_is_active_plugin('event_poll')) { + elgg_load_library('elgg:event_poll'); + return event_poll_change($event_guid,$day_delta,$minute_delta,$start_time,$resend,$minutes,$iso_date); + } else { + return FALSE; + } + } else { + $event->start_date = strtotime("$day_delta days",$event->start_date)+60*$minute_delta; + if ($event->end_date) { + $event->end_date = strtotime("$day_delta days",$event->end_date); + } + $times = elgg_get_plugin_setting('times','event_calendar'); + //$inc = 24*60*60*$day_delta+60*$minute_delta; + + //$event->real_end_time += $inc; + $event->real_end_time = strtotime("$day_delta days",$event->real_end_time)+60*$minute_delta; + if ($times != 'no') { + $event->start_time += $minute_delta; + if ($event->end_time) { + $event->end_time += $minute_delta; + } + } + return TRUE; } - $times = elgg_get_plugin_setting('times','event_calendar'); - //$inc = 24*60*60*$day_delta+60*$minute_delta; - - //$event->real_end_time += $inc; - $event->real_end_time = strtotime("$day_delta days",$event->real_end_time)+60*$minute_delta; - if ($times != 'no') { - $event->start_time += $minute_delta; - if ($event->end_time) { - $event->end_time += $minute_delta; + } + return FALSE; +} + +function event_calendar_get_page_content_fullcalendar_events($start_date,$end_date,$filter='all',$container_guid=0,$region='-') { + //print "$start_date - $end_date"; + $start_ts = strtotime($start_date); + $end_ts = strtotime($end_date); + if ($filter == 'all') { + $events = event_calendar_get_events_between($start_ts,$end_ts,false,0,0,$container_guid,$region); + } else if ($filter == 'open') { + $events = event_calendar_get_open_events_between($start_ts,$end_ts,false,0,0,$container_guid,$region); + } else if ($filter == 'friends') { + $user_guid = elgg_get_logged_in_user_guid(); + $events = event_calendar_get_events_for_friends_between($start_ts,$end_ts,false,0,0,$user_guid,$container_guid,$region); + } else if ($filter == 'mine') { + $user_guid = elgg_get_logged_in_user_guid(); + $events = event_calendar_get_events_for_user_between2($start_ts,$end_ts,false,0,0,$user_guid,$container_guid,$region); + } + $event_array = array(); + $times_supported = elgg_get_plugin_setting('times','event_calendar') != 'no'; + $polls_supported = elgg_is_active_plugin('event_poll'); + foreach($events as $e) { + $event = $e['event']; + $event_data = $e['data']; + $c = count($event_data); + foreach($event_data as $ed) { + $event_item = array( + 'guid' => $event->guid, + 'title' => $event->title, + 'start' => date('c',$ed['start_time']), + 'end' => date('c',$ed['end_time']), + ); + if (!$times_supported || ($event->schedule_type == 'all_day')) { + $event_item['allDay'] = TRUE; + } else { + $event_item['allDay'] = FALSE; } + + if ($polls_supported && isset($e['is_event_poll']) && $e['is_event_poll']) { + $event_item['className'] = 'event-poll-class'; + $event_item['title'] .= ' '.elgg_echo('event_calendar:poll_suffix'); + $event_item['is_event_poll'] = TRUE; + $event_item['url'] = elgg_get_site_url().'event_poll/vote/'.$event->guid; + $event_item['minutes'] = $ed['minutes']; + $event_item['iso_date'] = $ed['iso_date']; + } else { + $event_item['id'] = $event->guid; + $event_item['is_event_poll'] = FALSE; + $event_item['url'] = elgg_get_site_url().'event_calendar/view_light_box/'.$event->guid; + } + + $event_array[] = $event_item; + } + } + + $json_events_string = json_encode($event_array); + return $json_events_string; +} + +// right now this does not return repeated events in sorted order, so repeated events only really work properly for the full calendar +// TODO: find another solution for displaying repeated events + +function event_calendar_flatten_event_structure($events) { + $flattened = array(); + $guids = array(); + foreach($events as $e) { + $this_event = $e['event']; + $guid = $this_event->guid; + if (!in_array($guid,$guids)) { + $guids[] = $guid; + $flattened[] = $this_event; + } + } + return $flattened; +} + +function event_calendar_queue_reminders() { + // game plan - get all events up to 60 days ahead + // with no reminder sent + // compute reminder period + // if <= current time, set reminder_queued flag and queue the + // notification message using the message_queue plugin + if (elgg_plugin_exists('message_queue')) { + $now = time(); + // oops - this does not work for repeated events + // need extra stuff for that + /*$options = array( + 'type' => 'object', + 'subtype' => 'event_calendar', + 'metadata_name_value_pairs' => array( + array('name' => 'reminder_queued', 'value' => 'no'), + array('name' => 'send_reminder', 'value' => 1), + array('name' => 'start_date', 'value' => $now + 60*24*60*60, 'operand' => '>='), + ), + 'limit' => 0, + ); + $events = elgg_get_entities_from_metadata($options); + */ + $event_list = event_calendar_get_events_between($now,$now + 60*24*60*60,FALSE,0); + + foreach($event_list as $es) { + $e = $es['event']; + if ($e->send_reminder) { + $reminder_period = 60*$e->reminder_interval*$e->reminder_number; + if ($e->repeats) { + // repeated events require more complex handing + foreach($es['data'] as $d) { + // if event falls in the reminder period + if ($d->start_time - $reminder_period >= $now) { + // and the reminder has not already been queued + if (!event_calendar_repeat_reminder_logged($e,$d->start_time)) { + // set the reminder queued flag + event_calendar_repeat_reminder_log($e,$d->start_time); + // queue the reminder for sending + event_calendar_queue_reminder($e); + } + break; + } + } + } else { + // if this is just a normal non-repeated event, then we just need to set a flag and queue the reminder + if (($e->reminder_queued != 'yes') && ($e->start_date - $now <= $reminder_period)) { + $e->reminder_queued = 'yes'; + event_calendar_queue_reminder($e); + } + } + } } + } +} + +function event_calendar_repeat_reminder_log($e,$start) { + // this simple log just uses annotations on the event + // TODO - remove log entries for past events + create_annotation($e->guid, 'repeat_reminder_log_item', $start, '',0,ACCESS_PUBLIC); +} + +function event_calendar_repeat_reminder_logged($e,$start) { + $options = array( + 'guid' => $e->guid, + 'annotation_name' => 'repeat_reminder_log_item', + 'annotation_value' => $start, + 'limit' => 1 + ); + + if (elgg_get_annotations($options)) { return TRUE; + } else { + return FALSE; + } +} + +function event_calendar_queue_reminder($e) { + elgg_load_library('elgg:message_queue'); + $subject = elgg_echo('event_calendar:reminder:subject',array($e->title)); + $time_string = event_calendar_get_formatted_time($e); + $body = elgg_echo('event_calendar:reminder:body',array($e->title,$time_string,$e->getURL())); + $m = message_queue_create_message($subject,$body); + if ($m) { + $users = event_calendar_get_users_for_event($e->guid,0); + foreach($users as $u) { + message_queue_add($m->guid,$u->guid); + } + message_queue_set_for_sending($m->guid); + } +} + +function event_calendar_create_bbb_conf($event) { + $bbb_security_salt = elgg_get_plugin_setting('bbb_security_salt','event_calendar'); + $bbb_server_url = rtrim(elgg_get_plugin_setting('bbb_server_url','event_calendar'), '/') . '/'; + if ($bbb_security_salt) { + $day_in_minutes = 60*24; + $duration = (int)(($event->real_end_time-$event->start_date)/60)+$day_in_minutes; + $title = urlencode($event->title); + $params = "name=$title&meetingID={$event->guid}&duration=$duration"; + $checksum = sha1('create'.$params.$bbb_security_salt); + $params .= "&checksum=$checksum"; + + // create curl resource + $ch = curl_init(); + + // set url + curl_setopt($ch, CURLOPT_URL, $bbb_server_url.'api/create?'.$params); + + //return the transfer as a string + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + + // $output contains the output string + $output = curl_exec($ch); + + // close curl resource to free up system resources + curl_close($ch); + + /*error_log("BBB create request:"); + error_log($bbb_server_url.'api/create?'.$params); + + error_log("BBB create response:"); + error_log($output);*/ + + $xml = new SimpleXMLElement($output); + if ($xml->returncode == 'SUCCESS') { + $event->bbb_attendee_password = (string) $xml->attendeePW; + $event->bbb_moderator_password = (string) $xml->moderatorPW; + } else { + register_error(elgg_echo('event_calendar:bbb_create_error',array($xml->message))); + } + } else { + register_error(elgg_echo('event_calendar:bbb_settings_error')); + } +} + +function event_calendar_get_join_bbb_url($event) { + $bbb_security_salt = elgg_get_plugin_setting('bbb_security_salt','event_calendar'); + $bbb_server_url = rtrim(elgg_get_plugin_setting('bbb_server_url','event_calendar'), '/') . '/'; + $user = elgg_get_logged_in_user_entity(); + $full_name = urlencode($user->name); + if ($event->canEdit()) { + $password = urlencode($event->bbb_moderator_password); + } else { + $password = urlencode($event->bbb_attendee_password); + } + $params = "fullName=$full_name&meetingID={$event->guid}&userID={$user->username}&password=$password"; + $checksum = sha1('join'.$params.$bbb_security_salt); + $params .= "&checksum=$checksum"; + $url = $bbb_server_url.'api/join?'.$params; + return $url; +} + +// returns TRUE if the given user can add an event to the given calendar +// if group_guid is 0, this is assumed to be the site calendar +function event_calendar_can_add($group_guid=0,$user_guid=0) { + if (!$user_guid) { + if (elgg_is_logged_in()) { + $user_guid = elgg_get_logged_in_user_guid(); + } else { + return FALSE; + } } + if ($group_guid) { + if (!event_calendar_activated_for_group($group_guid)) { + return FALSE; + } + $group = get_entity($group_guid); + if (elgg_instanceof($group,'group')) { + $group_calendar = elgg_get_plugin_setting('group_calendar', 'event_calendar'); + if (!$group_calendar || $group_calendar == 'members') { + return $group->canWriteToContainer($user_guid); + } else if ($group_calendar == 'admin') { + if ($group->canEdit($user_guid)) { + return TRUE; + } else { + return FALSE; + } + } + } else { + return FALSE; + } + } else { + $site_calendar = elgg_get_plugin_setting('site_calendar', 'event_calendar'); + if (!$site_calendar || $site_calendar == 'admin') { + // only admins can post directly to the site-wide calendar + return elgg_is_admin_user($user_guid); + } else if ($site_calendar == 'loggedin') { + // any logged-in user can post to the site calendar + return TRUE; + } + } + return FALSE; } |