/** * Adds metabox to the page. * * @wp_hook admin_init * * @return void */ public function add_meta_box() { // Add the 'General Settings' meta box. add_meta_box('ai1ec-general-settings', Ai1ec_I18n::_x('General Settings', 'meta box'), array($this, 'display_meta_box'), $this->_registry->get('model.settings')->get('settings_page'), 'left', 'default'); // Add the 'Timely' meta box. add_meta_box('ai1ec-support', Ai1ec_I18n::_x('Timely', 'meta box', AI1EC_PLUGIN_NAME), array($this, 'support_meta_box'), $this->_registry->get('model.settings')->get('settings_page'), 'right', 'default'); }
/** * Adds metabox to the page. * * @wp_hook admin_init * * @return void */ public function add_meta_box() { // Add the 'ICS Import Settings' meta box. add_meta_box('ai1ec-feeds', Ai1ec_I18n::_x('Feed Subscriptions', 'meta box'), array($this, 'display_meta_box'), $this->_registry->get('model.settings')->get('feeds_page'), 'left', 'default'); }
/** * Returns timespan expression for the event. * * Properly handles: * - instantaneous events * - all-day events * - multi-day events * Display of start date can be hidden (non-all-day events only) or full * date. All-day status, if any, is enclosed in a span.ai1ec-allday-badge * element. * * @param Ai1ec_Event $event Rendered event. * @param string $start_date_display Can be one of 'hidden', 'short', * or 'long'. * * @return string Formatted timespan HTML element. */ public function get_timespan_html(Ai1ec_Event $event, $start_date_display = 'long') { // Makes no sense to hide start date for all-day events, so fix argument if ('hidden' === $start_date_display && $event->is_allday()) { $start_date_display = 'short'; } // Localize time. $start = $this->_registry->get('date.time', $event->get('start')); $end = $this->_registry->get('date.time', $event->get('end')); // All-day events need to have their end time shifted by 1 second less // to land on the correct day. $end_offset = 0; if ($event->is_allday()) { $end->set_time($end->format('H'), $end->format('i'), $end->format('s') - 1); } // Get timestamps of start & end dates without time component. $start_ts = $this->_registry->get('date.time', $start)->set_time(0, 0, 0)->format(); $end_ts = $this->_registry->get('date.time', $end)->set_time(0, 0, 0)->format(); $break_years = $start->format('Y') !== $end->format('Y'); $output = ''; // Display start date, depending on $start_date_display. switch ($start_date_display) { case 'hidden': break; case 'short': case 'long': $property = $start_date_display . '_date'; $output .= $this->{'get_' . $property}($start, $break_years); break; default: $start_date_display = 'long'; } // Output start time for non-all-day events. if (!$event->is_allday()) { if ('hidden' !== $start_date_display) { $output .= apply_filters('ai1ec_get_timespan_html_time_separator', Ai1ec_I18n::_x(' @ ', 'Event time separator')); } $output .= $this->get_short_time($start); } // Find out if we need to output the end time/date. Do not output it for // instantaneous events and all-day events lasting only one day. if (!($event->is_instant() || $event->is_allday() && $start_ts === $end_ts)) { $output .= apply_filters('ai1ec_get_timespan_html_date_separator', Ai1ec_I18n::_x(' – ', 'Event start/end separator')); // If event ends on a different day, output end date. if ($start_ts !== $end_ts) { // for short date, use short display type if ('short' === $start_date_display) { $output .= $this->get_short_date($end, $break_years); } else { $output .= $this->get_long_date($end); } } // Output end time for non-all-day events. if (!$event->is_allday()) { if ($start_ts !== $end_ts) { $output .= apply_filters('ai1ec_get_timespan_html_time_separator', Ai1ec_I18n::_x(' @ ', 'Event time separator')); } $output .= $this->get_short_time($end); } } $output = esc_html($output); // Add all-day label. if ($event->is_allday()) { $output .= apply_filters('ai1ec_get_timespan_html_allday_badge', ' <span class="ai1ec-allday-badge">' . Ai1ec_I18n::__('all-day') . '</span>'); } return apply_filters('ai1ec_get_timespan_html', $output, $event, $start_date_display); }
/** * _get_sentence_by function * * @internal * * @return void **/ protected function _get_sentence_by(&$txt, $freq, $rc) { global $wp_locale; switch ($freq) { case 'weekly': if ($rc->getByDay()) { if (count($rc->getByDay()) > 1) { // if there are more than 3 days // use days's abbr if (count($rc->getByDay()) > 2) { $_days = ''; foreach ($rc->getByDay() as $d) { $day = $this->get_weekday_by_id($d, true); $_days .= ' ' . $wp_locale->weekday_abbrev[$wp_locale->weekday[$day]] . ','; } // remove the last ' and' $_days = substr($_days, 0, -1); $txt .= ' ' . Ai1ec_I18n::_x('on', 'Recurrence editor - weekly tab') . $_days; } else { $_days = ''; foreach ($rc->getByDay() as $d) { $day = $this->get_weekday_by_id($d, true); $_days .= ' ' . $wp_locale->weekday[$day] . ' ' . Ai1ec_I18n::__('and'); } // remove the last ' and' $_days = substr($_days, 0, -4); $txt .= ' ' . Ai1ec_I18n::_x('on', 'Recurrence editor - weekly tab') . $_days; } } else { $_days = ''; foreach ($rc->getByDay() as $d) { $day = $this->get_weekday_by_id($d, true); $_days .= ' ' . $wp_locale->weekday[$day]; } $txt .= ' ' . Ai1ec_I18n::_x('on', 'Recurrence editor - weekly tab') . $_days; } } break; case 'monthly': if ($rc->getByMonthDay()) { // if there are more than 2 days if (count($rc->getByMonthDay()) > 2) { $_days = ''; foreach ($rc->getByMonthDay() as $m_day) { $_days .= ' ' . $this->_ordinal($m_day) . ','; } $_days = substr($_days, 0, -1); $txt .= ' ' . Ai1ec_I18n::_x('on', 'Recurrence editor - monthly tab') . $_days . ' ' . Ai1ec_I18n::__('of the month'); } else { if (count($rc->getByMonthDay()) > 1) { $_days = ''; foreach ($rc->getByMonthDay() as $m_day) { $_days .= ' ' . $this->_ordinal($m_day) . ' ' . Ai1ec_I18n::__('and'); } $_days = substr($_days, 0, -4); $txt .= ' ' . Ai1ec_I18n::_x('on', 'Recurrence editor - monthly tab') . $_days . ' ' . Ai1ec_I18n::__('of the month'); } else { $_days = ''; foreach ($rc->getByMonthDay() as $m_day) { $_days .= ' ' . $this->_ordinal($m_day); } $txt .= ' ' . Ai1ec_I18n::_x('on', 'Recurrence editor - monthly tab') . $_days . ' ' . Ai1ec_I18n::__('of the month'); } } } elseif ($rc->getByDay()) { $_days = ''; $dnum = ''; foreach ($rc->getByDay() as $d) { if (!preg_match('|^((-?)\\d+)([A-Z]{2})$|', $d, $matches)) { continue; } $_dnum = $matches[1]; $_day = $matches[3]; if ('-' === $matches[2]) { $dnum = ' ' . Ai1ec_I18n::__('last'); } else { $dnum = ' ' . $this->_registry->get('date.time', strtotime($_dnum . '-01-1998 12:00:00'))->format_i18n('jS'); } $day = $this->get_weekday_by_id($_day, true); $_days .= ' ' . $wp_locale->weekday[$day]; } $txt .= ' ' . Ai1ec_I18n::_x('on', 'Recurrence editor - monthly tab') . $dnum . $_days; } break; case 'yearly': if ($rc->getByMonth()) { // if there are more than 2 months if (count($rc->getByMonth()) > 2) { $_months = ''; foreach ($rc->getByMonth() as $_m) { $_m = $_m < 10 ? 0 . $_m : $_m; $_months .= ' ' . $wp_locale->month_abbrev[$wp_locale->month[$_m]] . ','; } $_months = substr($_months, 0, -1); $txt .= ' ' . Ai1ec_I18n::_x('on', 'Recurrence editor - yearly tab') . $_months; } else { if (count($rc->getByMonth()) > 1) { $_months = ''; foreach ($rc->getByMonth() as $_m) { $_m = $_m < 10 ? 0 . $_m : $_m; $_months .= ' ' . $wp_locale->month[$_m] . ' ' . Ai1ec_I18n::__('and'); } $_months = substr($_months, 0, -4); $txt .= ' ' . Ai1ec_I18n::_x('on', 'Recurrence editor - yearly tab') . $_months; } else { $_months = ''; foreach ($rc->getByMonth() as $_m) { $_m = $_m < 10 ? 0 . $_m : $_m; $_months .= ' ' . $wp_locale->month[$_m]; } $txt .= ' ' . Ai1ec_I18n::_x('on', 'Recurrence editor - yearly tab') . $_months; } } } break; } }
/** * Registers the custom post type. * * @wp-hook init */ public function register() { $settings = $this->_registry->get('model.settings'); // =============================== // = labels for custom post type = // =============================== $labels = array('name' => Ai1ec_I18n::_x('Events', 'Custom post type name'), 'singular_name' => Ai1ec_I18n::_x('Event', 'Custom post type name (singular)'), 'add_new' => Ai1ec_I18n::__('Add New'), 'add_new_item' => Ai1ec_I18n::__('Add New Event'), 'edit_item' => Ai1ec_I18n::__('Edit Event'), 'new_item' => Ai1ec_I18n::__('New Event'), 'view_item' => Ai1ec_I18n::__('View Event'), 'search_items' => Ai1ec_I18n::__('Search Events'), 'not_found' => Ai1ec_I18n::__('No Events found'), 'not_found_in_trash' => Ai1ec_I18n::__('No Events found in Trash'), 'parent_item_colon' => Ai1ec_I18n::__('Parent Event'), 'menu_name' => Ai1ec_I18n::__('Events'), 'all_items' => $this->get_all_items_name()); // ================================ // = support for custom post type = // ================================ $supports = array('title', 'editor', 'comments', 'custom-fields', 'thumbnail', 'author'); // ============================= // = args for custom post type = // ============================= $page_base = false; if ($settings->get('calendar_page_id')) { $page_base = get_page_uri($settings->get('calendar_page_id')); } $rewrite = array('slug' => Ai1ec_I18n::__('event')); $has_archive = true; if ($settings->get('calendar_base_url_for_permalinks') && $page_base) { $rewrite = array('slug' => $page_base); $has_archive = AI1EC_ALTERNATIVE_ARCHIVE_URL; } $args = array('labels' => $labels, 'public' => true, 'publicly_queryable' => true, 'show_ui' => true, 'show_in_menu' => true, 'query_var' => true, 'rewrite' => $rewrite, 'map_meta_cap' => true, 'capability_type' => 'ai1ec_event', 'has_archive' => $has_archive, 'hierarchical' => false, 'menu_position' => 5, 'supports' => $supports, 'exclude_from_search' => $settings->get('exclude_from_search')); // ======================================== // = labels for event categories taxonomy = // ======================================== $events_categories_labels = array('name' => Ai1ec_I18n::_x('Categories', 'Event categories taxonomy'), 'singular_name' => Ai1ec_I18n::_x('Category', 'Event categories taxonomy (singular)'), 'menu_name' => Ai1ec_I18n::_x('Organize', 'Event categories menu item')); // ================================== // = labels for event tags taxonomy = // ================================== $events_tags_labels = array('name' => Ai1ec_I18n::_x('Tags', 'Event tags taxonomy'), 'singular_name' => Ai1ec_I18n::_x('Tag', 'Event tags taxonomy (singular)')); // ================================== // = labels for event feeds taxonomy = // ================================== $events_feeds_labels = array('name' => Ai1ec_I18n::_x('Event Feeds', 'Event feeds taxonomy'), 'singular_name' => Ai1ec_I18n::_x('Event Feed', 'Event feed taxonomy (singular)')); // ====================================== // = args for event categories taxonomy = // ====================================== $events_categories_args = array('labels' => $events_categories_labels, 'hierarchical' => true, 'rewrite' => array('slug' => 'events_categories'), 'capabilities' => array('manage_terms' => 'manage_events_categories', 'edit_terms' => 'manage_events_categories', 'delete_terms' => 'manage_events_categories', 'assign_terms' => 'edit_ai1ec_events')); // ================================ // = args for event tags taxonomy = // ================================ $events_tags_args = array('labels' => $events_tags_labels, 'hierarchical' => false, 'rewrite' => array('slug' => 'events_tags'), 'show_ui' => true, 'capabilities' => array('manage_terms' => 'manage_events_categories', 'edit_terms' => 'manage_events_categories', 'delete_terms' => 'manage_events_categories', 'assign_terms' => 'edit_ai1ec_events')); // ================================ // = args for event feeds taxonomy = // ================================ $events_feeds_args = array('labels' => $events_feeds_labels, 'hierarchical' => false, 'rewrite' => array('slug' => 'events_feeds'), 'capabilities' => array('manage_terms' => 'manage_events_categories', 'edit_terms' => 'manage_events_categories', 'delete_terms' => 'manage_events_categories', 'assign_terms' => 'edit_ai1ec_events'), 'public' => false); // ====================================== // = register event categories taxonomy = // ====================================== register_taxonomy('events_categories', array(AI1EC_POST_TYPE), $events_categories_args); // ================================ // = register event tags taxonomy = // ================================ register_taxonomy('events_tags', array(AI1EC_POST_TYPE), $events_tags_args); // ================================ // = register event tags taxonomy = // ================================ register_taxonomy('events_feeds', array(AI1EC_POST_TYPE), $events_feeds_args); // ======================================== // = register custom post type for events = // ======================================== register_post_type(AI1EC_POST_TYPE, $args); // get event contributor if saved in the db $contributor = get_role('ai1ec_event_assistant'); // if it's present and has the wrong capability delete it. if ($contributor instanceof WP_Role && ($contributor->has_cap('publish_ai1ec_events') || !$contributor->has_cap('edit_published_ai1ec_events') || !$contributor->has_cap('delete_published_ai1ec_events'))) { remove_role('ai1ec_event_assistant'); $contributor = false; } // Create event contributor role with the same capabilities // as subscriber role, plus event managing capabilities // if we have not created it yet. if (!$contributor) { $caps = get_role('subscriber')->capabilities; $role = add_role('ai1ec_event_assistant', 'Event Contributor', $caps); $role->add_cap('edit_ai1ec_events'); $role->add_cap('read_ai1ec_events'); $role->add_cap('delete_ai1ec_events'); $role->add_cap('edit_published_ai1ec_events'); $role->add_cap('delete_published_ai1ec_events'); $role->add_cap('read'); unset($caps, $role); } // Add event managing capabilities to administrator, editor, author. // The last created capability is "manage_ai1ec_feeds", so check for // that one. $role = get_role('administrator'); if (is_object($role) && !$role->has_cap('manage_ai1ec_feeds')) { $role_list = array('administrator', 'editor', 'author'); foreach ($role_list as $role_name) { $role = get_role($role_name); if (null === $role || !$role instanceof WP_Role) { continue; } // Read events. $role->add_cap('read_ai1ec_event'); // Edit events. $role->add_cap('edit_ai1ec_event'); $role->add_cap('edit_ai1ec_events'); $role->add_cap('edit_others_ai1ec_events'); $role->add_cap('edit_private_ai1ec_events'); $role->add_cap('edit_published_ai1ec_events'); // Delete events. $role->add_cap('delete_ai1ec_event'); $role->add_cap('delete_ai1ec_events'); $role->add_cap('delete_others_ai1ec_events'); $role->add_cap('delete_published_ai1ec_events'); $role->add_cap('delete_private_ai1ec_events'); // Publish events. $role->add_cap('publish_ai1ec_events'); // Read private events. $role->add_cap('read_private_ai1ec_events'); // Manage categories & tags. $role->add_cap('manage_events_categories'); // Manage calendar feeds. $role->add_cap('manage_ai1ec_feeds'); if ('administrator' === $role_name) { // Change calendar themes & manage calendar options. $role->add_cap('switch_ai1ec_themes'); $role->add_cap('manage_ai1ec_options'); } } } }
/** * Add meta box for page. * * @wp_hook admin_init * * @return void */ public function add_meta_box() { // Add the 'General Settings' meta box. add_meta_box('ai1ec-less-variables-tabs', Ai1ec_I18n::_x('Calendar Theme Options', 'meta box'), array($this, 'display_meta_box'), $this->_registry->get('model.settings')->get('less_variables_page'), 'left', 'default'); }