Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class Meta_Date_Archive {
- public $start;
- public $end;
- public $dates;
- public $post_type;
- public $filters;
- public $orderby_key;
- function __construct() {
- add_action( 'wp_loaded', array( $this, 'setup' ) );
- }
- /**
- * Sets up properties for a meta date query.
- *
- * @since 1.0
- * @return void
- */
- public function setup() {
- if ( is_admin() ) {
- return;
- }
- $this->start = apply_filters( 'meta_date_archive_start', 'event_start_date' );
- $this->end = apply_filters( 'meta_date_archive_end', 'event_end_date' );
- $this->post_type = apply_filters( 'meta_date_archive_post_type', 'post' );
- $this->filters = "meta_date_archive";
- add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ), 99 );
- add_filter( 'query_vars', array( $this, 'query_vars' ) );
- add_action( 'save_post', array( $this, 'save_post' ) );
- }
- /**
- * Meta date query.
- *
- * @since 1.0
- * @param object $query The WP_Query instance.
- * @return void
- */
- public function pre_get_posts( $query ) {
- $this->dates = array();
- $start_date = $query->get( 'meta_archive_start_date' );
- $end_date = $query->get( 'meta_archive_end_date' );
- $dates = array();
- $meta_date_query = false;
- if ( $query->is_main_query() ) {
- // main queries
- if ( is_date() ) {
- // main query for date archive
- $dates = meta_date_archive_dates();
- $meta_date_query = true;
- }
- } else {
- // external queries
- if ( !empty( $start_date ) || !empty( $end_date ) ) {
- // one of the dates is provided
- $meta_date_query = true;
- }
- if ( $meta_date_query ) {
- $dates = meta_date_archive_start_end_date( $start_date, $end_date );
- } else {
- // not the query we're looking for
- return;
- }
- }
- // not a meta date query
- if ( !$meta_date_query ) {
- return;
- }
- if ( isset( $query->query_vars['suppress_filters'] ) ) {
- $this->filters = $query->query_vars['suppress_filters'];
- }
- // we need the filters for a meta date query
- unset( $query->query_vars['suppress_filters'] );
- if ( empty( $dates ) ) {
- echo 'empty';
- // return no posts found
- //
- // not a date archives main query
- // or an external query with dates where the dates didn't validate
- // or an external query where one of the dates is missing
- $this->empty_query();
- $this->cleanup_query();
- return;
- }
- $this->dates = $dates;
- $reset_query_vars = array(
- 'second' , 'minute', 'hour',
- 'day', 'monthnum', 'year',
- 'w', 'm', 'meta_query'
- );
- // reset date query vars
- foreach ( $reset_query_vars as $var ) {
- $query->set( $var, '' );
- }
- $locale = get_query_var('lang');
- $query->set( 'lang', $locale );
- $query->set( 'post_type', $this->post_type );
- $query->set( 'posts_per_page', get_option( 'posts_per_page' ) );
- $query->set( 'meta_key', 'event_start_date' );
- $query->set( 'orderby', 'meta_value_num' );
- $query->set( 'order', 'ASC' );
- $meta_query = array(
- 'relation' => 'AND',
- // needs to be two meta key arrays
- array(
- 'key' => $this->start,
- 'compare' => '>=',
- 'value' => $this->dates['start_date'],
- 'type' => 'DATE'
- ),
- array(
- 'key' => $this->end,
- 'compare' => '<=',
- 'value' => $this->dates['end_date'],
- 'type' => 'DATE'
- ),
- );
- $query->set( 'meta_query', $meta_query );
- $this->orderby_key = $query->get( 'meta_key' );
- // add the filter
- add_filter( 'get_meta_sql', array( $this, 'get_meta_sql' ), 10, 2 );
- // remove the filters down the road
- $this->cleanup_query();
- }
- /**
- * Adds the end and start date variables to the public query variables.
- *
- * @since 1.0
- * @param array $query_vars The array of whitelisted query variables.
- * @return array The array of whitelisted query variables.
- */
- public function query_vars( $query_vars ) {
- $query_vars[] = 'meta_archive_start_date';
- $query_vars[] = 'meta_archive_end_date';
- return $query_vars;
- }
- /**
- * Returns meta date archive meta sql.
- *
- * @since 1.0
- * @param array $pieces Array containing the query's JOIN and WHERE clauses.
- * @param array $queries Array of meta queries.
- * @return array Array containing the query's JOIN and WHERE clauses.
- */
- public function get_meta_sql( $pieces, $queries ) {
- global $wpdb;
- $start_date = $this->dates['start_date'];
- $end_date = $this->dates['end_date'];
- $where = "";
- $start_alias = "$wpdb->postmeta";
- $end_alias = "mt1";
- $join = " INNER JOIN $wpdb->postmeta ON ($wpdb->posts.ID = $wpdb->postmeta.post_id)
- INNER JOIN $wpdb->postmeta AS mt1 ON ( $wpdb->posts.ID = mt1.post_id )";
- if ( in_array( $this->orderby_key, array( $this->start, $this->end ) ) ) {
- $where .= $wpdb->prepare( " AND ($wpdb->postmeta.meta_key = %s)", $this->orderby_key );
- $join .= " INNER JOIN $wpdb->postmeta AS mt2 ON ($wpdb->posts.ID = mt2.post_id)";
- $start_alias = "mt1";
- $end_alias = "mt2";
- }
- $start_key = $wpdb->prepare( "{$start_alias}.meta_key = %s", $this->start );
- $end_key = $wpdb->prepare( "{$end_alias}.meta_key = %s", $this->end );
- // after start date AND before end date
- $query = " AND ( (
- ( $start_key AND ( CAST($start_alias.meta_value AS DATE) >= %s) )
- AND ( $end_key AND ( CAST($end_alias.meta_value AS DATE) <= %s) )
- )";
- $where .= $wpdb->prepare( $query, $start_date, $end_date );
- // OR before start date AND after end end date
- $query = " OR (
- ( $start_key AND ( CAST($start_alias.meta_value AS DATE) <= %s) )
- AND ( $end_key AND ( CAST($end_alias.meta_value AS DATE) >= %s) ))";
- $where .= $wpdb->prepare( $query, $start_date, $end_date );
- // OR before start date AND (before end date AND end date after start date)
- $query = " OR (
- ( $start_key AND ( CAST($start_alias.meta_value AS DATE) <= %s) )
- AND ( $end_key
- AND ( CAST($end_alias.meta_value AS DATE) <= %s )
- AND ( CAST($end_alias.meta_value AS DATE) >= %s )
- ))";
- $where .= $wpdb->prepare( $query, $start_date, $end_date, $start_date );
- // OR after end date AND (after start date AND start date before end date) )
- $query = "OR (
- ( $end_key AND ( CAST($end_alias.meta_value AS DATE) >= %s ) )
- AND ( $start_key AND ( CAST($start_alias.meta_value AS DATE) >= %s )
- AND ( CAST($start_alias.meta_value AS DATE) <= %s )
- )))";
- $where .= $wpdb->prepare( $query, $end_date, $start_date, $end_date );
- $pieces['join'] = $join;
- $pieces['where'] = $where;
- return $pieces;
- }
- /**
- * Adds a filter to 'the_posts' to remove filters used in pre_get_posts.
- *
- * @since 1.0
- * @param object $query The WP_Query instance.
- * @return [type] [description]
- */
- private function cleanup_query() {
- add_filter( 'the_posts', array( $this, 'the_posts' ), 99, 2 );
- }
- /**
- * Removes filters used in pre_get_posts.
- * Restores the suppress_filters parameter if it was used.
- *
- * @since 1.0
- * @param array $posts Array with post objects.
- * @return array Array with post objects.
- */
- public function the_posts( $posts, $_this ) {
- if ( 'meta_date_archive' !== $this->filters ) {
- $_this->query_vars['suppress_filters'] = $this->filters;
- }
- remove_filter( 'get_meta_sql', array( $this, 'get_meta_sql' ), 10, 2 );
- remove_filter( 'posts_where', array( $this, 'posts_where' ) );
- remove_filter( 'the_posts', array( $this, 'the_posts' ) );
- return $posts;
- }
- /**
- * Adds a filter to 'posts_where' to have the query return no posts.
- *
- * @since 1.0
- * @return void
- */
- private function empty_query() {
- add_filter( 'posts_where', array( $this, 'posts_where' ) );
- }
- /**
- * Adds 1=0 to the where clause to have the query return no posts.
- *
- * @since 1.0
- * @return void
- */
- public function posts_where( $where ) {
- return $where . 'AND 1 = 0';
- }
- /**
- * Adds the start date meta if only end date meta is provided when editing or publishing a post.
- *
- * @since 1.0
- * @return void
- */
- public function save_post( $post_id ) {
- if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
- return $post_id;
- }
- if ( !current_user_can( 'edit_post', $post_id ) ) {
- return $post_id;
- }
- $post_type = ( isset( $_POST['post_type'] ) ) ? $_POST['post_type'] : '';
- if ( $this->post_type !== $post_type ) {
- return $post_id;
- }
- $end_date = get_post_meta( $post_id, $this->end, true );
- if ( !empty( $end_date ) ) {
- if ( !get_post_meta( $post_id, $this->start, true ) ) {
- update_post_meta( $post_id, $this->start, $end_date );
- }
- }
- }
- }
- $meta_date_archive = new Meta_Date_Archive();
- /**
- * Returns start and end dates for date archives.
- *
- * @since 1.0
- * @return array Array with start and end date.
- */
- function meta_date_archive_dates() {
- $year = $month = $day = $m = false;
- $start_date = $end_date = '';
- // is date archives
- if ( is_date() ) {
- $m = ( get_query_var( 'm' ) ) ? get_query_var( 'm' ) : false;
- $year = ( get_query_var( 'year' ) ) ? get_query_var( 'year' ) : false;
- $month = ( get_query_var( 'monthnum' ) ) ? zeroise( get_query_var( 'monthnum' ), 2 ) : false;
- $day = ( get_query_var( 'day' ) ) ? get_query_var( 'day' ) : false;
- if ( $m ) {
- $dates = meta_date_archive_getdate( $m );
- $year = $dates['year'];
- $month = $dates['month'];
- $day = $dates['day'];
- }
- return meta_date_archive_validated_dates( $year, $month, $day );
- }
- return array();
- }
- /**
- * Returns start and end dates.
- *
- * @since 1.0
- * @param int $start Date.
- * @param int $end Date.
- * @return array Array with start and end date.
- */
- function meta_date_archive_start_end_date( $start = '', $end = '' ) {
- $year = $month = $day = $m = false;
- $start_date = $end_date = '';
- $start = absint( $start ); // int
- $end = absint( $end ); // int
- // if not both dates are provided
- if ( !( $start && $end ) ) {
- return array();
- }
- $dates = meta_date_archive_getdate( $start );
- $dates = meta_date_archive_validated_dates( $dates['year'], $dates['month'], $dates['day'] );
- $start_date = isset( $dates['start_date'] ) ? $dates['start_date'] : '';
- $dates = meta_date_archive_getdate( $end );
- $dates = meta_date_archive_validated_dates( $dates['year'], $dates['month'], $dates['day'] );
- $end_date = isset( $dates['end_date'] ) ? $dates['end_date'] : '';
- if ( !empty( $start_date ) && !empty( $end_date ) ) {
- return compact( 'start_date', 'end_date' );
- }
- return array();
- }
- /**
- * Returns year, month or day from date .
- *
- * @since 1.0
- * @param string $date Date.
- * @return array Array with year, month and day.
- */
- function meta_date_archive_getdate( $date = '' ) {
- $year = $month = $day = false;
- switch ( strlen( $date ) ) {
- case 4: // Yearly
- $year = substr( $date, 0, 4 );
- break;
- case 6: // Monthly
- $year = substr( $date, 0, 4 );
- $month = substr( $date, 4, 2 );
- break;
- case 8: // Daily
- $year = substr( $date, 0, 4 );
- $month = substr( $date, 4, 2 );
- $day = substr( $date, 6, 2 );
- break;
- }
- return compact( 'year', 'month', 'day' );
- }
- /**
- * Returns full date validated.
- *
- * @since 1.0
- * @param integer $year Year
- * @param integer $month Month
- * @param integer $day Day
- * @return string Validated date.
- */
- function meta_date_archive_validated_dates( $year = 0, $month = 0, $day = 0 ) {
- $start_date = $end_date = '';
- $year = absint( $year );
- $month = absint( $month );
- $day = absint( $day );
- if ( $year ) {
- // check if date exists
- if ( checkdate( '01', '01', $year ) ) {
- $start_date = $year . '0101';
- $end_date = $year . '1231';
- }
- }
- if ( $year && $month ) {
- $month = zeroise( $month, 2 );
- // check if date exists
- if ( checkdate( $month, '01', $year ) ) {
- $start_date = $year . $month . '01';
- $end_date = date( 'Ymt', mktime( 23, 59, 59, $month, 1, $year ) ); // 't' gets the last day
- }
- }
- if ( $year && $month && $day ) {
- $month = zeroise( $month, 2 );
- $day = zeroise( $day, 2 );
- // check if date exists
- if ( checkdate( $month, $day, $year ) ) {
- $start_date = $year . $month . $day;
- $end_date = $start_date;
- }
- }
- if ( empty( $start_date ) || empty( $end_date ) ) {
- return array();
- }
- return compact( 'start_date', 'end_date' );
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement