setup(); } return self::$instance; } /** * Register actions and filters * * @uses add_action * @uses add_filter * @return null */ private function setup() { add_action( 'init', array( $this, 'action_init' ) ); add_action( 'pre_get_posts', array( $this, 'action_pre_get_posts' ) ); add_action( 'admin_enqueue_scripts', array( $this, 'action_admin_enqueue_scripts' ) ); add_action( 'add_meta_boxes_' . $this->post_type, array( $this, 'action_add_meta_boxes' ) ); add_action( 'save_post', array( $this, 'action_save_post' ) ); add_filter( 'manage_' . $this->post_type . '_posts_columns', array( $this, 'filter_list_table_columns' ) ); add_action( 'manage_' . $this->post_type . '_posts_custom_column', array( $this, 'do_list_table_columns' ), 10, 2 ); add_filter( 'enter_title_here', array( $this, 'filter_editor_title_prompt' ), 10, 2 ); } /** * Register post type and shortcode * * @uses register_post_type * @uses add_shortcode * @action init * @return null */ public function action_init() { register_post_type( $this->post_type, array( 'label' => __( 'Timeline', 'eth-timeline' ), 'labels' => array( 'name' => __( 'Timeline', 'eth-timeline' ), 'singular_name' => __( 'Timeline', 'eth-timeline' ), 'menu_name' => __( 'Timeline', 'eth-timeline' ), 'all_items' => __( 'All Entries', 'eth-timeline' ), 'add_new' => __( 'Add New', 'eth-timeline' ), 'add_new_item' => __( 'Add New', 'eth-timeline' ), 'edit_item' => __( 'Edit Entry', 'eth-timeline' ), 'new_item' => __( 'New Entry', 'eth-timeline' ), 'view_item' => __( 'View Entry', 'eth-timeline' ), 'items_archive' => __( 'Entries List', 'eth-timeline' ), 'search_items' => __( 'Search Timeline Entries', 'eth-timeline' ), 'not_found' => __( 'No entries found', 'eth-timeline' ), 'not_found_in_trash' => __( 'No trashed entries', 'eth-timeline' ), 'parent_item_colon' => __( 'Entries:', 'eth-timeline' ), ), 'public' => true, 'has_archive' => false, 'exclude_from_search' => true, 'show_in_nav_menus' => false, 'show_in_admin_bar' => true, 'rewrite' => false, 'supports' => array( 'title', 'editor', 'author', ) ) ); add_shortcode( 'eth-timeline', array( $this, 'do_shortcode' ) ); } /** * Force all timeline queries to be sorted by start date. * Doesn't interfere with admin list table sorting. * * @param object $query * @uses is_admin * @action pre_get_posts * @return null */ public function action_pre_get_posts( $query ) { if ( $query->is_main_query() && $this->post_type == $query->get( 'post_type' ) ) { if ( is_admin() && isset( $_GET['orderby'] ) ) { return; } $query->set( 'orderby', 'meta_value_num' ); $query->set( 'meta_key', $this->meta_start ); } } /** ** ADMINISTRATION */ /** * Enqueue admin assets * * @uses get_current_screen * @uses is_wp_error * @uses wp_enqueue_script * @uses plugins_url * @uses wp_enqueue_style * @action admin_enqueue_scripts * @return null */ public function action_admin_enqueue_scripts() { $screen = get_current_screen(); if ( is_object( $screen ) && ! is_wp_error( $screen ) && $this->post_type === $screen->post_type && 'post' === $screen->base ) { wp_enqueue_script( 'eth-timeline-admin', plugins_url( 'js/admin.js', __FILE__ ), array( 'jquery', 'jquery-ui-datepicker' ), 20130721, false ); wp_enqueue_style( 'eth-timeline-admin', plugins_url( 'css/smoothness.min.css', __FILE__ ), array(), 20130721, 'screen' ); } } /** * Register custom date metabox * * @uses add_meta_box * @action add_meta_boxes * @return null */ public function action_add_meta_boxes() { add_meta_box( 'eth-timeline-dates', __( 'Dates', 'eth-timeline' ), array( $this, 'meta_box_dates' ), $this->post_type, 'normal', 'high' ); } /** * Render dates metabox * * @param object $post * @uses get_post_meta * @uses _e * @uses wp_nonce_field * @uses ths::get_field_name * @uses this::get_nonce_name * @action add_meta_boxes_{$this->post_type} * @return string */ public function meta_box_dates( $post ) { $times = $this->get_times( $post->ID ); ?>
get_field_name( 'date' ), $this->get_nonce_name( 'date' ), false ); } /** * Save custom dates * * @param int $post_id * @uses get_post_type * @uses this::get_nonce_name * @uses this::get_field_name * @uses update_post_meta * @uses delete_post_meta * @action save_post * @return null */ public function action_save_post( $post_id ) { if ( $this->post_type != get_post_type( $post_id ) ) { return; } if ( isset( $_POST[ $this->get_nonce_name( 'date' ) ] ) && wp_verify_nonce( $_POST[ $this->get_nonce_name( 'date' ) ], $this->get_field_name( 'date' ) ) ) { $dates = isset( $_POST['eth-timeline'] ) ? $_POST['eth-timeline'] : array(); if ( empty( $dates ) ) { return; } foreach ( $dates as $key => $date ) { if ( ! in_array( $key, array( 'start', 'end' ) ) ) { continue; } // Timestamp comes from JS if ( empty( $date ) ) { $timestamp = false; } else { $timestamp = strtotime( $date ); } if ( $timestamp ) { update_post_meta( $post_id, $this->{'meta_' . $key}, $timestamp ); } else { delete_post_meta( $post_id, $this->{'meta_' . $key} ); } } } } /** * Add new date columns to list table * * @param array $columns * @uses __ * @filter manage_{$this->post_type}_posts_columns * @return array */ public function filter_list_table_columns( $columns ) { $after = array_splice( $columns, 2 ); $new_columns = array( 'eth_timeline_start' => __( 'Start Date', 'eth-timeline' ), 'eth_timeline_end' => __( 'End Date (Optional)', 'eth-timeline' ), ); $columns = $columns + $new_columns + $after; return $columns; } /** * Display start and end dates in the post list table * * @param string $column * @param int $post_id * @uses get_post_meta * @uses get_option * @action manage_{$this->post_type}_posts_custom_column * @return string or null */ public function do_list_table_columns( $column, $post_id ) { if ( in_array( $column, array( 'eth_timeline_start', 'eth_timeline_end' ) ) ) { $key = str_replace( 'eth_timeline_', '', $column ); $date = get_post_meta( $post_id, $this->{'meta_' . $key}, true ); if ( is_numeric( $date ) ) { echo date( get_option( 'date_format', 'F j, Y' ), $date ); } } } /** ** PRESENTATION */ /** * Render list of timeline entries * * @global $post * @param mixed $atts * @uses shortcode_atts * @uses WP_Query * @uses this::get_times * @uses the_ID * @uses this::format_date * @uses get_the_ID * @uses the_title * @uses get_the_content * @uses remove_filter * @uses the_content * @uses add_filter * @uses wp_reset_query * @return string or null */ public function do_shortcode( $atts ) { // Parse and sanitize atts $atts = shortcode_atts( array( 'posts_per_page' => 100, 'order' => 'DESC', 'year' => null, ), $atts ); $atts['posts_per_page'] = min( 200, max( (int) $atts['posts_per_page'], -1 ) ); $atts['order'] = 'ASC' == $atts['order'] ? 'ASC' : 'DESC'; $atts['year'] = is_numeric( $atts['year'] ) ? (int) $atts['year'] : null; // Build query $query = array( 'post_type' => $this->post_type, 'posts_per_page' => $atts['posts_per_page'], 'post_status' => 'publish', 'order' => $atts['order'], 'orderby' => 'meta_value_num', 'meta_key' => $this->meta_start ); if ( $atts['year'] ) { $query['meta_query'] = array( array( 'key' => $this->meta_start, 'value' => array( strtotime( $atts['year'] . '-01-01 00:00:00' ), strtotime( $atts['year'] . '-12-31 23:59:59' ) ), 'type' => 'numeric', 'compare' => 'BETWEEN' ) ); } // Run query and build output, if possible $query = new WP_Query( $query ); if ( $query->have_posts() ) { ob_start(); global $post; echo '