/**
  * Create the html element used as the UI control for the datepicker button.
  * The href must keep only active filters.
  *
  * @param array           $args         Populated args for the view
  * @param int|string|null $initial_date The datepicker's initially set date
  * @return Ai1ec_Generic_Html_Tag
  */
 public static function create_datepicker_link(array $args, $initial_date = null)
 {
     global $ai1ec_settings, $ai1ec_view_helper;
     $link = Ai1ec_Helper_Factory::create_generic_html_tag('a');
     $date_format_pattern = Ai1ec_Time_Utility::get_date_pattern_by_key($ai1ec_settings->input_date_format);
     if ($initial_date == null) {
         // If exact_date argument was provided, use its value to initialize
         // datepicker.
         if (isset($args['exact_date']) && $args['exact_date'] !== false && $args['exact_date'] !== null) {
             $initial_date = $args['exact_date'];
         } else {
             $initial_date = Ai1ec_Time_Utility::gmt_to_local(Ai1ec_Time_Utility::current_time());
         }
     }
     // Convert initial date to formatted date if required.
     if (Ai1ec_Validation_Utility::is_valid_time_stamp($initial_date)) {
         $initial_date = Ai1ec_Time_Utility::format_date(Ai1ec_Time_Utility::gmt_to_local($initial_date), $ai1ec_settings->input_date_format);
     }
     $link->add_class('ai1ec-minical-trigger btn');
     $link->set_attribute('data-date', $initial_date);
     $link->set_attribute('data-date-format', $date_format_pattern);
     $link->set_attribute('data-date-weekstart', $ai1ec_settings->week_start_day);
     $link->set_attribute_expr($args['data_type']);
     $text = '<img src="' . esc_attr($ai1ec_view_helper->get_theme_img_url('date-icon.png')) . '" class="ai1ec-icon-datepicker" />';
     $link->set_text($text);
     $href_args = array('action' => $args['action'], 'cat_ids' => $args['cat_ids'], 'tag_ids' => $args['tag_ids'], 'exact_date' => "__DATE__");
     $data_href = self::create_href_helper_instance($href_args);
     $link->set_attribute('data-href', $data_href->generate_href());
     $link->set_attribute('href', '#');
     return $link;
 }
 /**
  * Creates the output of the RSS feed.
  * 
  * @param boolean $comment ( ignored )
  */
 public function create_feed_output($comment)
 {
     global $ai1ec_calendar_helper, $ai1ec_view_helper, $ai1ec_events_helper, $ai1ec_settings;
     $number_of_posts = Ai1ec_Meta::get_option('posts_per_rss');
     // Get the request parser
     $request = new Ai1ec_Arguments_Parser(NULL, 'ai1ec_' . $ai1ec_settings->default_calendar_view);
     $request->parse();
     // Create the filter
     $filter = array('cat_ids' => $request->get('cat_ids'), 'tag_ids' => $request->get('tag_ids'), 'post_ids' => $request->get('post_ids'));
     $event_results = $ai1ec_calendar_helper->get_events_relative_to($ai1ec_events_helper->gmt_to_local(Ai1ec_Time_Utility::current_time()), $number_of_posts, 0, $filter, 0);
     require_once AI1EC_VIEW_PATH . '/event-feed-rss2.php';
 }
 /**
  * Breaks down the given ordered array of event objects into dates, and
  * outputs an ordered array of two-element associative arrays in the
  * following format:
  *	key: localized UNIX timestamp of date
  *	value:
  *		['events'] => two-element associatative array broken down thus:
  *			['allday'] => all-day events occurring on this day
  *			['notallday'] => all other events occurring on this day
  *		['today'] => whether or not this date is today
  *
  * @param array                     $events Event results
  * @param Ai1ec_Abstract_Query|null $query  Current calendar page request, if
  *                                          any (null for widget)
  *
  * @return array
  */
 function get_agenda_like_date_array($events, Ai1ec_Abstract_Query $query = null)
 {
     global $ai1ec_events_helper, $ai1ec_settings;
     $dates = array();
     // Classify each event into a date/allday category
     foreach ($events as $event) {
         if (!empty($query)) {
             $event->set_request($query);
         }
         $date = $ai1ec_events_helper->gmt_to_local($event->start);
         $date = $ai1ec_events_helper->gmgetdate($date);
         $timestamp = gmmktime(0, 0, 0, $date['mon'], $date['mday'], $date['year']);
         $exact_date = Ai1ec_Time_Utility::format_date_for_url($timestamp, $ai1ec_settings->input_date_format);
         $href_for_date = $this->create_link_for_day_view($exact_date);
         // Ensure all-day & non all-day categories are created in correct order.
         if (!isset($dates[$timestamp]['events'])) {
             $dates[$timestamp]['events'] = array('allday' => array(), 'notallday' => array());
         }
         // Add the event.
         $category = $event->allday ? 'allday' : 'notallday';
         $dates[$timestamp]['events'][$category][] = $event;
         $dates[$timestamp]['href'] = $href_for_date;
     }
     // Flag today
     $today = $ai1ec_events_helper->gmt_to_local(Ai1ec_Time_Utility::current_time());
     $today = $ai1ec_events_helper->gmgetdate($today);
     $today = gmmktime(0, 0, 0, $today['mon'], $today['mday'], $today['year']);
     if (isset($dates[$today])) {
         $dates[$today]['today'] = true;
     }
     return $dates;
 }
 /**
  * export_events function
  *
  * Export events
  *
  * @return void
  **/
 function export_events()
 {
     global $ai1ec_events_helper, $ai1ec_exporter_helper, $ai1ec_localization_helper;
     $ai1ec_cat_ids = !empty($_REQUEST['ai1ec_cat_ids']) ? $_REQUEST['ai1ec_cat_ids'] : false;
     $ai1ec_tag_ids = !empty($_REQUEST['ai1ec_tag_ids']) ? $_REQUEST['ai1ec_tag_ids'] : false;
     $ai1ec_post_ids = !empty($_REQUEST['ai1ec_post_ids']) ? $_REQUEST['ai1ec_post_ids'] : false;
     if (!empty($_REQUEST['lang'])) {
         $ai1ec_localization_helper->set_language($_REQUEST['lang']);
     }
     $filter = array();
     if ($ai1ec_cat_ids) {
         $filter['cat_ids'] = explode(',', $ai1ec_cat_ids);
     }
     if ($ai1ec_tag_ids) {
         $filter['tag_ids'] = explode(',', $ai1ec_tag_ids);
     }
     if ($ai1ec_post_ids) {
         $filter['post_ids'] = explode(',', $ai1ec_post_ids);
     }
     // when exporting events by post_id, do not look up the event's start/end date/time
     $start = $ai1ec_post_ids !== false ? false : Ai1ec_Time_Utility::current_time(true) - 24 * 60 * 60;
     // Include any events ending today
     $end = false;
     $c = new vcalendar();
     $c->setProperty('calscale', 'GREGORIAN');
     $c->setProperty('method', 'PUBLISH');
     $c->setProperty('X-WR-CALNAME', get_bloginfo('name'));
     $c->setProperty('X-WR-CALDESC', get_bloginfo('description'));
     $c->setProperty('X-FROM-URL', home_url());
     // Timezone setup
     $tz = Ai1ec_Meta::get_option('timezone_string');
     if ($tz) {
         $c->setProperty('X-WR-TIMEZONE', $tz);
         $tz_xprops = array('X-LIC-LOCATION' => $tz);
         iCalUtilityFunctions::createTimezone($c, $tz, $tz_xprops);
     }
     $events = $ai1ec_events_helper->get_matching_events($start, $end, $filter);
     foreach ($events as $event) {
         $ai1ec_exporter_helper->insert_event_in_calendar($event, $c, $export = true);
     }
     $str = ltrim($c->createCalendar());
     header('Content-type: text/calendar; charset=utf-8');
     echo $str;
     exit;
 }
 /**
  * Return the current timestamp to make correct queries using restrictions
  * for starting time.
  *
  * This works as follows, it takes the time on the current server. Imagine
  * i'm at 22.30 on GMT + 2.
  * Facebook treats this as Pacific Time so i calculate the offset between
  * PST and UTC ( -7 ), i take into account the offset from GMT ( that's 2 i
  * subtract from -7 so i get -9) and then i subtract the offset of the
  * server from my starting time.
  *
  * @return number
  */
 public static function get_facebook_actual_time($timestamp = NULL)
 {
     if ($timestamp === NULL) {
         $timestamp = Ai1ec_Time_Utility::current_time();
     }
     global $ai1ec_events_helper;
     $offset = $ai1ec_events_helper->get_timezone_offset('UTC', 'PST', $timestamp);
     $offset -= $ai1ec_events_helper->get_gmt_offset() * 3600;
     return $timestamp - $offset;
 }
 /**
  * Refreshes the events from facebook for the currently loaded ids
  *
  * @throws WP_FacebookApiException if something goes wrong with the Facebook calls
  *
  * @return array an array with the results.
  */
 public function refresh_events()
 {
     $timestamp = Ai1ec_Time_Utility::current_time();
     // I use the strategy pattern for this, the common interface assure us that this method is present.
     try {
         $events = $this->_query_events_strategy->query_events($this->_facebook, $this->_ids, $timestamp);
     } catch (WP_FacebookApiException $e) {
         throw $e;
     }
     $result = $this->save_events($events, $timestamp);
     return $result;
 }
 /**
  * install_u_cron function
  *
  * This function sets up the cron job that checks for available updates
  *
  * @return void
  **/
 function install_u_cron()
 {
     // If existing CRON version is not consistent with current plugin's version,
     // or does not exist, then create/update cron using
     if (Ai1ec_Meta::get_option('ai1ec_u_cron_version') != AI1EC_U_CRON_VERSION) {
         // delete our scheduled crons
         wp_clear_scheduled_hook('ai1ec_u_cron');
         // reset flags
         update_option('ai1ec_update_available', 0);
         update_option('ai1ec_update_message', '');
         update_option('ai1ec_package_url', '');
         // set the new cron
         wp_schedule_event(Ai1ec_Time_Utility::current_time(), AI1EC_U_CRON_FREQ, 'ai1ec_u_cron');
         // update the cron version
         update_option('ai1ec_u_cron_version', AI1EC_U_CRON_VERSION);
     }
 }
 /**
  * Return the embedded day view of the calendar, optionally filtered by
  * event categories and tags.
  *
  * @param array $args     associative array with any of these elements:
  *   int oneday_offset  => specifies which day to display relative to the
  *                        current day
  *   array cat_ids     => restrict events returned to the given set of
  *                        event category slugs
  *   array tag_ids     => restrict events returned to the given set of
  *                        event tag names
  *   array post_ids    => restrict events returned to the given set of
  *                        post IDs
  *
  * @return string	        returns string of view output
  */
 function get_oneday_view($args)
 {
     global $ai1ec_view_helper, $ai1ec_events_helper, $ai1ec_calendar_helper, $ai1ec_settings;
     $defaults = array('oneday_offset' => 0, 'cat_ids' => array(), 'tag_ids' => array(), 'post_ids' => array(), 'exact_date' => Ai1ec_Time_Utility::current_time());
     $args = wp_parse_args($args, $defaults);
     // Localize requested date and get components.
     $local_date = Ai1ec_Time_Utility::gmt_to_local($args['exact_date']);
     $bits = Ai1ec_Time_Utility::gmgetdate($local_date);
     // Apply day offset.
     $day_shift = 0 + $args['oneday_offset'];
     // Now align date to start of day (midnight).
     $local_date = gmmktime(0, 0, 0, $bits['mon'], $bits['mday'] + $day_shift, $bits['year']);
     $cell_array = $ai1ec_calendar_helper->get_oneday_cell_array($local_date, array('cat_ids' => $args['cat_ids'], 'tag_ids' => $args['tag_ids'], 'post_ids' => $args['post_ids']));
     // Create pagination links.
     $pagination_links = $ai1ec_calendar_helper->get_oneday_pagination_links($args);
     $pagination_links = $ai1ec_view_helper->get_theme_view('pagination.php', array('links' => $pagination_links, 'data_type' => $args['data_type']));
     $date_format = Ai1ec_Meta::get_option('date_format', 'l, M j, Y');
     $title = Ai1ec_Time_Utility::date_i18n($date_format, $local_date, true);
     $time_format = Ai1ec_Meta::get_option('time_format', 'g a');
     // Calculate today marker's position.
     $now = Ai1ec_Time_Utility::current_time();
     $now = Ai1ec_Time_Utility::gmt_to_local($now);
     $now_text = $ai1ec_events_helper->get_short_time($now, false);
     $now = Ai1ec_Time_Utility::gmgetdate($now);
     $now = $now['hours'] * 60 + $now['minutes'];
     $view_args = array('title' => $title, 'type' => 'oneday', 'cell_array' => $cell_array, 'show_location_in_title' => $ai1ec_settings->show_location_in_title, 'now_top' => $now, 'now_text' => $now_text, 'pagination_links' => $pagination_links, 'post_ids' => join(',', $args['post_ids']), 'time_format' => $time_format, 'done_allday_label' => false, 'done_grid' => false, 'data_type' => $args['data_type'], 'data_type_events' => '');
     if ($ai1ec_settings->ajaxify_events_in_web_widget) {
         $view_args['data_type_events'] = $args['data_type'];
     }
     // Add navigation if requested.
     $view_args['navigation'] = $args['no_navigation'] ? '' : $ai1ec_view_helper->get_theme_view('navigation.php', $view_args);
     return apply_filters('ai1ec_get_oneday_view', $ai1ec_view_helper->get_theme_view('oneday.php', $view_args), $view_args);
 }
 /**
  * Create the array needed for translation and passing other settings to JS.
  *
  * @return $data array the dynamic data array
  */
 private function get_translation_data()
 {
     global $ai1ec_importer_plugin_helper;
     $force_ssl_admin = force_ssl_admin();
     if ($force_ssl_admin && !is_ssl()) {
         force_ssl_admin(false);
     }
     $ajax_url = admin_url('admin-ajax.php');
     force_ssl_admin($force_ssl_admin);
     $data = array('select_one_option' => __('Select at least one user/group/page to subscribe to.', AI1EC_PLUGIN_NAME), 'is_calendar_page' => isset($_GET[self::IS_CALENDAR_PAGE]) && $_GET[self::IS_CALENDAR_PAGE] === self::TRUE_PARAM, 'error_no_response' => __('An unexpected error occurred. Try reloading the page.', AI1EC_PLUGIN_NAME), 'no_more_subscription' => __('No subscriptions yet!', AI1EC_PLUGIN_NAME), 'no_more_than_ten' => __('Please select no more than ten users/groups/pages at a time to avoid overloading Facebook requests.', AI1EC_PLUGIN_NAME), 'duplicate_feed_message' => esc_html__('This feed is already being imported.', AI1EC_PLUGIN_NAME), 'invalid_url_message' => esc_html__('Please enter a valid iCalendar URL.', AI1EC_PLUGIN_NAME), 'invalid_email_message' => esc_html__('Please enter a valid e-mail address.', AI1EC_PLUGIN_NAME), 'now' => $this->events_helper->gmt_to_local(Ai1ec_Time_Utility::current_time()), 'date_format' => $this->settings->input_date_format, 'month_names' => $this->ai1ec_locale->get_localized_month_names(), 'day_names' => $this->ai1ec_locale->get_localized_week_names(), 'week_start_day' => $this->settings->week_start_day, 'twentyfour_hour' => $this->settings->input_24h_time, 'region' => $this->settings->geo_region_biasing ? $this->events_helper->get_region() : '', 'disable_autocompletion' => $this->settings->disable_autocompletion, 'error_message_not_valid_lat' => __('Please enter a valid latitude. A valid latitude is comprised between +90 and -90.', AI1EC_PLUGIN_NAME), 'error_message_not_valid_long' => __('Please enter a valid longitude. A valid longitude is comprised between +180 and -180.', AI1EC_PLUGIN_NAME), 'error_message_not_entered_lat' => __('When the "Input coordinates" checkbox is checked, "Latitude" is a required field.', AI1EC_PLUGIN_NAME), 'error_message_not_entered_long' => __('When the "Input coordinates" checkbox is checked, "Longitude" is a required field.', AI1EC_PLUGIN_NAME), 'language' => $this->events_helper->get_lang(), 'page' => '', 'page_on_front_description' => __('This setting cannot be changed in Event Platform mode.', AI1EC_PLUGIN_NAME), 'strict_mode' => $this->settings->event_platform_strict, 'platform_active' => $this->settings->event_platform_active, 'facebook_logged_in' => $ai1ec_importer_plugin_helper->check_if_we_have_a_valid_facebook_access_token(), 'app_id_and_secret_are_required' => __('You must specify both an app ID and app secret to connect to Facebook.', AI1EC_PLUGIN_NAME), 'file_upload_required' => __('You must specify a valid file to upload or paste your data into the text field.', AI1EC_PLUGIN_NAME), 'file_upload_not_permitted' => __('Only .ics and .csv files are supported.', AI1EC_PLUGIN_NAME), 'ajax_url' => $ajax_url, 'url_not_valid' => __('The URL you have entered seems to be invalid. Please remember that URLs must start with either "http://" or "https://".', AI1EC_PLUGIN_NAME), 'mail_url_required' => __('Both the <em>calendar URL</em> and <em>e-mail address</em> fields are required.', AI1EC_PLUGIN_NAME), 'confirm_reset_theme' => __('Are you sure you want to reset your theme options to their default values?', AI1EC_PLUGIN_NAME), 'license_key' => $this->settings->get_license_key(), 'reset_saved_filter_text' => __('Save this filter as default', AI1EC_PLUGIN_NAME), 'clear_saved_filter_text' => __('Remove default filter', AI1EC_PLUGIN_NAME), 'save_filter_text_ok' => __('The active filter has been saved as your default for this calendar.', AI1EC_PLUGIN_NAME), 'remove_filter_text_ok' => __('Your default calendar filter has been removed.', AI1EC_PLUGIN_NAME), 'size_less_variable_not_ok' => __('The value you have entered is not a valid CSS length.', AI1EC_PLUGIN_NAME), 'week_view_starts_at' => $this->settings->week_view_starts_at, 'week_view_ends_at' => $this->settings->week_view_ends_at, 'end_must_be_after_start' => __('The end date can\'t be earlier than the start date.', AI1EC_PLUGIN_NAME), 'show_at_least_six_hours' => __('For week and day view, you must select an interval of at least 6 hours.', AI1EC_PLUGIN_NAME), 'label_buy_tickets_url' => __('Buy tickets URL (optional)', AI1EC_PLUGIN_NAME), 'label_rsvp_url' => __('Registration URL (optional)', AI1EC_PLUGIN_NAME), 'label_a_buy_tickets_url' => __('Buy Tickets URL:', AI1EC_PLUGIN_NAME), 'label_a_rsvp_url' => __('Registration URL:', AI1EC_PLUGIN_NAME), 'event_price_not_entered' => __('Please enter an event cost, or mark the event as free.', AI1EC_PLUGIN_NAME), 'blog_timezone' => Ai1ec_Meta::get_option('gmt_offset'), 'use_select2' => $this->settings->use_select2_widgets, 'require_desclaimer' => __('If you choose to require a disclaimer on the front-end event creation form, you must provide the disclaimer text (HTML allowed) in the appropriate field.', AI1EC_PLUGIN_NAME));
     return $data;
 }
 /**
  * get_repeat_box function
  *
  * @return string
  **/
 function get_repeat_box()
 {
     global $ai1ec_view_helper;
     $repeat = (int) $_REQUEST["repeat"];
     $repeat = $repeat == 1 ? 1 : 0;
     $post_id = (int) $_REQUEST["post_id"];
     $count = 100;
     $end = null;
     $until = Ai1ec_Time_Utility::current_time(true);
     // try getting the event
     try {
         $event = new Ai1ec_Event($post_id);
         $rule = '';
         if ($repeat) {
             $rule = empty($event->recurrence_rules) ? '' : $event->recurrence_rules;
         } else {
             $rule = empty($event->exception_rules) ? '' : $event->exception_rules;
         }
         $rc = new SG_iCal_Recurrence(new SG_iCal_Line('RRULE:' . $rule));
         if ($until = $rc->getUntil()) {
             $until = is_numeric($until) ? $until : strtotime($until);
         } else {
             if ($count = $rc->getCount()) {
                 $count = is_numeric($count) ? $count : 100;
             }
         }
     } catch (Ai1ec_Event_Not_Found $e) {
         /* event wasn't found, keep defaults */
     }
     $args = array('row_daily' => $this->row_daily(), 'row_weekly' => $this->row_weekly(), 'row_monthly' => $this->row_monthly(), 'row_yearly' => $this->row_yearly(), 'count' => $this->create_count_input('ai1ec_count', $count) . __('times', AI1EC_PLUGIN_NAME), 'end' => $this->create_end_dropdown($end), 'until' => $until, 'repeat' => $repeat);
     $output = array("error" => false, "message" => $ai1ec_view_helper->get_admin_view('box_repeat.php', $args), "repeat" => $repeat);
     echo json_encode($output);
     exit;
 }
 /**
  * Create the array needed for translation and passing other settings to JS.
  *
  * @return $data array the dynamic data array
  */
 private function get_translation_data()
 {
     global $ai1ec_importer_plugin_helper;
     $lang = $this->events_helper->get_lang();
     $data = array('select_one_option' => __('Select at least one user/group/page to subscribe to.', AI1EC_PLUGIN_NAME), 'error_no_response' => __('An unexpected error occurred. Try reloading the page.', AI1EC_PLUGIN_NAME), 'no_more_subscription' => __('No subscriptions yet!', AI1EC_PLUGIN_NAME), 'no_more_than_ten' => __('Please select no more than ten users/groups/pages at a time to avoid overloading Facebook requests.', AI1EC_PLUGIN_NAME), 'duplicate_feed_message' => esc_html__('This feed is already being imported.', AI1EC_PLUGIN_NAME), 'invalid_url_message' => esc_html__('Please enter a valid iCalendar URL.', AI1EC_PLUGIN_NAME), 'invalid_email_message' => esc_html__('Please enter a valid e-mail address.', AI1EC_PLUGIN_NAME), 'now' => $this->events_helper->gmt_to_local(Ai1ec_Time_Utility::current_time()), 'date_format' => $this->settings->input_date_format, 'month_names' => $this->ai1ec_locale->get_localized_month_names(), 'day_names' => $this->ai1ec_locale->get_localized_week_names(), 'week_start_day' => $this->settings->week_start_day, 'twentyfour_hour' => $this->settings->input_24h_time, 'region' => $this->settings->geo_region_biasing ? $this->events_helper->get_region() : '', 'disable_autocompletion' => $this->settings->disable_autocompletion, 'error_message_not_valid_lat' => __('Please enter a valid latitude. A valid latitude is comprised between +90 and -90.', AI1EC_PLUGIN_NAME), 'error_message_not_valid_long' => __('Please enter a valid longitude. A valid longitude is comprised between +180 and -180.', AI1EC_PLUGIN_NAME), 'error_message_not_entered_lat' => __('When the "Input coordinates" checkbox is checked, "Latitude" is a required field.', AI1EC_PLUGIN_NAME), 'error_message_not_entered_long' => __('When the "Input coordinates" checkbox is checked, "Longitude" is a required field.', AI1EC_PLUGIN_NAME), 'language' => $lang, 'page' => '', 'page_on_front_description' => __('This setting cannot be changed in Event Platform mode.', AI1EC_PLUGIN_NAME), 'strict_mode' => $this->settings->event_platform_strict, 'platform_active' => $this->settings->event_platform_active, 'facebook_logged_in' => $ai1ec_importer_plugin_helper->check_if_we_have_a_valid_facebook_access_token(), 'app_id_and_secret_are_required' => __("You must specify both an app ID and app secret to connect to Facebook.", AI1EC_PLUGIN_NAME), 'ajax_url' => admin_url('admin-ajax.php'), 'url_not_valid' => __("The URL you have entered seems to be invalid. Please remember that URLs must start with either 'http://' or 'https://'.", AI1EC_PLUGIN_NAME), 'mail_url_required' => __("Both the <em>calendar URL</em> and <em>e-mail address</em> fields are required.", AI1EC_PLUGIN_NAME), 'confirm_reset_theme' => __("Are you sure you want to reset your theme options to their default values?", AI1EC_PLUGIN_NAME));
     return $data;
 }
 /**
  * Save the compile time to the db so that we can use it to build the link
  */
 private function save_less_parse_time()
 {
     $this->db_adapter->write_data_to_config(self::GET_VARIBALE_NAME, Ai1ec_Time_Utility::current_time());
 }
 /**
  * install_schedule method
  *
  * Update/install, if necessary CRON.
  * Return name of CRON action (hook) executed.
  *
  * @return string Name of CRON action
  */
 public function install_schedule()
 {
     $cron_key = 'ai1ec_logging_cron';
     $optn_key = $cron_key . '_version';
     if (Ai1ec_Meta::get_option($optn_key) != self::CRON_VERSION) {
         wp_clear_scheduled_hook($cron_key);
         wp_schedule_event(Ai1ec_Time_Utility::current_time(), 'daily', $cron_key);
         update_option($optn_key, self::CRON_VERSION);
     }
     return $cron_key;
 }
 /**
  * widget function
  *
  * Outputs the given instance of the widget to the front-end.
  *
  * @param array $args Display arguments passed to the widget
  * @param array $instance The settings for this widget instance
  */
 function widget($args, $instance)
 {
     global $ai1ec_view_helper, $ai1ec_events_helper, $ai1ec_calendar_helper, $ai1ec_settings, $ai1ec_themes_controller, $ai1ec_requirejs_controller;
     if ($ai1ec_themes_controller->frontend_outdated_themes_notice()) {
         return;
     }
     $ai1ec_requirejs_controller->add_link_to_render_js(Ai1ec_Requirejs_Controller::LOAD_ONLY_FRONTEND_SCRIPTS, false);
     $defaults = array('hide_on_calendar_page' => true, 'event_cat_ids' => array(), 'event_tag_ids' => array(), 'event_post_ids' => array(), 'events_per_page' => 10, 'days_per_page' => 10, 'events_seek_type' => 'events');
     $instance = wp_parse_args($instance, $defaults);
     if ($instance['hide_on_calendar_page'] && is_page($ai1ec_settings->calendar_page_id)) {
         return;
     }
     // Add params to the subscribe_url for filtering by Limits (category, tag)
     $subscribe_filter = '';
     $subscribe_filter .= $instance['event_cat_ids'] ? '&ai1ec_cat_ids=' . join(',', $instance['event_cat_ids']) : '';
     $subscribe_filter .= $instance['event_tag_ids'] ? '&ai1ec_tag_ids=' . join(',', $instance['event_tag_ids']) : '';
     $subscribe_filter .= $instance['event_post_ids'] ? '&ai1ec_post_ids=' . join(',', $instance['event_post_ids']) : '';
     // Get localized time
     $timestamp = $ai1ec_events_helper->gmt_to_local(Ai1ec_Time_Utility::current_time());
     // Set $limit to the specified category/tag
     $limit = array('cat_ids' => $instance['event_cat_ids'], 'tag_ids' => $instance['event_tag_ids'], 'post_ids' => $instance['event_post_ids']);
     // Get events, then classify into date array
     // JB: apply seek check here
     $seek_days = 'days' === $instance['events_seek_type'];
     $seek_count = $instance['events_per_page'];
     $last_day = false;
     if ($seek_days) {
         $seek_count = $instance['days_per_page'] * 5;
         $last_day = strtotime('+' . $instance['days_per_page'] . ' days');
     }
     $event_results = $ai1ec_calendar_helper->get_events_relative_to($timestamp, $seek_count, 0, $limit);
     if ($seek_days) {
         foreach ($event_results['events'] as $ek => $event) {
             if ($event->start >= $last_day) {
                 unset($event_results['events'][$ek]);
             }
         }
     }
     $dates = $ai1ec_calendar_helper->get_agenda_like_date_array($event_results['events']);
     $args['title'] = $instance['title'];
     $args['show_subscribe_buttons'] = $instance['show_subscribe_buttons'];
     $args['show_calendar_button'] = $instance['show_calendar_button'];
     $args['dates'] = $dates;
     $args['show_location_in_title'] = $ai1ec_settings->show_location_in_title;
     $args['show_year_in_agenda_dates'] = $ai1ec_settings->show_year_in_agenda_dates;
     $args['calendar_url'] = $ai1ec_calendar_helper->get_calendar_url($limit);
     $args['subscribe_url'] = AI1EC_EXPORT_URL . $subscribe_filter;
     $args['is_ticket_button_enabled'] = $ai1ec_calendar_helper->is_buy_ticket_enabled_for_view('agenda');
     $ai1ec_view_helper->display_theme('agenda-widget.php', $args);
 }
 /**
  * This function tells if less than the notification interval is missing from the event start time
  *
  * @param Ai1ec_Event $event
  * @return boolean
  */
 public function check_if_notification_should_be_sent_for_event(Ai1ec_Event $event)
 {
     $how_much_before_event_start = $event->start - Ai1ec_Time_Utility::current_time(true);
     if ($how_much_before_event_start < self::NOTIFICATION_INTERVAL) {
         return true;
     }
     return false;
 }
 /**
  * Run designated hook in background thread
  *
  * So far it is just re-scheduling the hook to be run at earliest
  * time possible.
  *
  * @param string $hook Name of registered schedulable hook
  *
  * @return void Method does not return
  */
 public function background($hook)
 {
     return $this->_install($hook, Ai1ec_Time_Utility::current_time());
 }