Advertisement
Guest User

Untitled

a guest
Dec 4th, 2014
335
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.49 KB | None | 0 0
  1. class Meta_Date_Archive {
  2.  
  3. public $start;
  4. public $end;
  5. public $dates;
  6. public $post_type;
  7. public $filters;
  8. public $orderby_key;
  9.  
  10.  
  11. function __construct() {
  12. add_action( 'wp_loaded', array( $this, 'setup' ) );
  13. }
  14.  
  15.  
  16. /**
  17. * Sets up properties for a meta date query.
  18. *
  19. * @since 1.0
  20. * @return void
  21. */
  22. public function setup() {
  23.  
  24. if ( is_admin() ) {
  25. return;
  26. }
  27.  
  28. $this->start = apply_filters( 'meta_date_archive_start', 'event_start_date' );
  29. $this->end = apply_filters( 'meta_date_archive_end', 'event_end_date' );
  30. $this->post_type = apply_filters( 'meta_date_archive_post_type', 'post' );
  31. $this->filters = "meta_date_archive";
  32.  
  33. add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ), 99 );
  34. add_filter( 'query_vars', array( $this, 'query_vars' ) );
  35. add_action( 'save_post', array( $this, 'save_post' ) );
  36. }
  37.  
  38.  
  39. /**
  40. * Meta date query.
  41. *
  42. * @since 1.0
  43. * @param object $query The WP_Query instance.
  44. * @return void
  45. */
  46. public function pre_get_posts( $query ) {
  47.  
  48. $this->dates = array();
  49.  
  50. $start_date = $query->get( 'meta_archive_start_date' );
  51. $end_date = $query->get( 'meta_archive_end_date' );
  52. $dates = array();
  53. $meta_date_query = false;
  54.  
  55. if ( $query->is_main_query() ) {
  56. // main queries
  57.  
  58. if ( is_date() ) {
  59. // main query for date archive
  60. $dates = meta_date_archive_dates();
  61. $meta_date_query = true;
  62. }
  63. } else {
  64. // external queries
  65.  
  66. if ( !empty( $start_date ) || !empty( $end_date ) ) {
  67. // one of the dates is provided
  68. $meta_date_query = true;
  69. }
  70.  
  71. if ( $meta_date_query ) {
  72. $dates = meta_date_archive_start_end_date( $start_date, $end_date );
  73. } else {
  74. // not the query we're looking for
  75. return;
  76. }
  77. }
  78.  
  79. // not a meta date query
  80. if ( !$meta_date_query ) {
  81. return;
  82. }
  83.  
  84. if ( isset( $query->query_vars['suppress_filters'] ) ) {
  85. $this->filters = $query->query_vars['suppress_filters'];
  86. }
  87.  
  88. // we need the filters for a meta date query
  89. unset( $query->query_vars['suppress_filters'] );
  90.  
  91. if ( empty( $dates ) ) {
  92. echo 'empty';
  93.  
  94. // return no posts found
  95. //
  96. // not a date archives main query
  97. // or an external query with dates where the dates didn't validate
  98. // or an external query where one of the dates is missing
  99.  
  100. $this->empty_query();
  101. $this->cleanup_query();
  102. return;
  103. }
  104.  
  105. $this->dates = $dates;
  106.  
  107. $reset_query_vars = array(
  108. 'second' , 'minute', 'hour',
  109. 'day', 'monthnum', 'year',
  110. 'w', 'm', 'meta_query'
  111. );
  112.  
  113. // reset date query vars
  114. foreach ( $reset_query_vars as $var ) {
  115. $query->set( $var, '' );
  116. }
  117.  
  118. $locale = get_query_var('lang');
  119. $query->set( 'lang', $locale );
  120.  
  121. $query->set( 'post_type', $this->post_type );
  122. $query->set( 'posts_per_page', get_option( 'posts_per_page' ) );
  123.  
  124. $query->set( 'meta_key', 'event_start_date' );
  125. $query->set( 'orderby', 'meta_value_num' );
  126. $query->set( 'order', 'ASC' );
  127.  
  128. $meta_query = array(
  129. 'relation' => 'AND',
  130.  
  131. // needs to be two meta key arrays
  132. array(
  133. 'key' => $this->start,
  134. 'compare' => '>=',
  135. 'value' => $this->dates['start_date'],
  136. 'type' => 'DATE'
  137. ),
  138. array(
  139. 'key' => $this->end,
  140. 'compare' => '<=',
  141. 'value' => $this->dates['end_date'],
  142. 'type' => 'DATE'
  143. ),
  144. );
  145.  
  146. $query->set( 'meta_query', $meta_query );
  147.  
  148. $this->orderby_key = $query->get( 'meta_key' );
  149.  
  150. // add the filter
  151. add_filter( 'get_meta_sql', array( $this, 'get_meta_sql' ), 10, 2 );
  152.  
  153. // remove the filters down the road
  154. $this->cleanup_query();
  155. }
  156.  
  157.  
  158. /**
  159. * Adds the end and start date variables to the public query variables.
  160. *
  161. * @since 1.0
  162. * @param array $query_vars The array of whitelisted query variables.
  163. * @return array The array of whitelisted query variables.
  164. */
  165. public function query_vars( $query_vars ) {
  166. $query_vars[] = 'meta_archive_start_date';
  167. $query_vars[] = 'meta_archive_end_date';
  168. return $query_vars;
  169. }
  170.  
  171.  
  172. /**
  173. * Returns meta date archive meta sql.
  174. *
  175. * @since 1.0
  176. * @param array $pieces Array containing the query's JOIN and WHERE clauses.
  177. * @param array $queries Array of meta queries.
  178. * @return array Array containing the query's JOIN and WHERE clauses.
  179. */
  180. public function get_meta_sql( $pieces, $queries ) {
  181. global $wpdb;
  182.  
  183. $start_date = $this->dates['start_date'];
  184. $end_date = $this->dates['end_date'];
  185. $where = "";
  186. $start_alias = "$wpdb->postmeta";
  187. $end_alias = "mt1";
  188. $join = " INNER JOIN $wpdb->postmeta ON ($wpdb->posts.ID = $wpdb->postmeta.post_id)
  189. INNER JOIN $wpdb->postmeta AS mt1 ON ( $wpdb->posts.ID = mt1.post_id )";
  190.  
  191.  
  192. if ( in_array( $this->orderby_key, array( $this->start, $this->end ) ) ) {
  193.  
  194. $where .= $wpdb->prepare( " AND ($wpdb->postmeta.meta_key = %s)", $this->orderby_key );
  195. $join .= " INNER JOIN $wpdb->postmeta AS mt2 ON ($wpdb->posts.ID = mt2.post_id)";
  196. $start_alias = "mt1";
  197. $end_alias = "mt2";
  198. }
  199.  
  200. $start_key = $wpdb->prepare( "{$start_alias}.meta_key = %s", $this->start );
  201. $end_key = $wpdb->prepare( "{$end_alias}.meta_key = %s", $this->end );
  202.  
  203. // after start date AND before end date
  204. $query = " AND ( (
  205. ( $start_key AND ( CAST($start_alias.meta_value AS DATE) >= %s) )
  206. AND ( $end_key AND ( CAST($end_alias.meta_value AS DATE) <= %s) )
  207. )";
  208. $where .= $wpdb->prepare( $query, $start_date, $end_date );
  209.  
  210. // OR before start date AND after end end date
  211. $query = " OR (
  212. ( $start_key AND ( CAST($start_alias.meta_value AS DATE) <= %s) )
  213. AND ( $end_key AND ( CAST($end_alias.meta_value AS DATE) >= %s) ))";
  214. $where .= $wpdb->prepare( $query, $start_date, $end_date );
  215.  
  216. // OR before start date AND (before end date AND end date after start date)
  217. $query = " OR (
  218. ( $start_key AND ( CAST($start_alias.meta_value AS DATE) <= %s) )
  219. AND ( $end_key
  220. AND ( CAST($end_alias.meta_value AS DATE) <= %s )
  221. AND ( CAST($end_alias.meta_value AS DATE) >= %s )
  222. ))";
  223. $where .= $wpdb->prepare( $query, $start_date, $end_date, $start_date );
  224.  
  225. // OR after end date AND (after start date AND start date before end date) )
  226. $query = "OR (
  227. ( $end_key AND ( CAST($end_alias.meta_value AS DATE) >= %s ) )
  228. AND ( $start_key AND ( CAST($start_alias.meta_value AS DATE) >= %s )
  229. AND ( CAST($start_alias.meta_value AS DATE) <= %s )
  230. )))";
  231. $where .= $wpdb->prepare( $query, $end_date, $start_date, $end_date );
  232.  
  233. $pieces['join'] = $join;
  234. $pieces['where'] = $where;
  235.  
  236. return $pieces;
  237. }
  238.  
  239.  
  240. /**
  241. * Adds a filter to 'the_posts' to remove filters used in pre_get_posts.
  242. *
  243. * @since 1.0
  244. * @param object $query The WP_Query instance.
  245. * @return [type] [description]
  246. */
  247. private function cleanup_query() {
  248. add_filter( 'the_posts', array( $this, 'the_posts' ), 99, 2 );
  249. }
  250.  
  251.  
  252. /**
  253. * Removes filters used in pre_get_posts.
  254. * Restores the suppress_filters parameter if it was used.
  255. *
  256. * @since 1.0
  257. * @param array $posts Array with post objects.
  258. * @return array Array with post objects.
  259. */
  260. public function the_posts( $posts, $_this ) {
  261.  
  262. if ( 'meta_date_archive' !== $this->filters ) {
  263. $_this->query_vars['suppress_filters'] = $this->filters;
  264. }
  265.  
  266. remove_filter( 'get_meta_sql', array( $this, 'get_meta_sql' ), 10, 2 );
  267. remove_filter( 'posts_where', array( $this, 'posts_where' ) );
  268. remove_filter( 'the_posts', array( $this, 'the_posts' ) );
  269. return $posts;
  270. }
  271.  
  272.  
  273. /**
  274. * Adds a filter to 'posts_where' to have the query return no posts.
  275. *
  276. * @since 1.0
  277. * @return void
  278. */
  279. private function empty_query() {
  280. add_filter( 'posts_where', array( $this, 'posts_where' ) );
  281. }
  282.  
  283.  
  284. /**
  285. * Adds 1=0 to the where clause to have the query return no posts.
  286. *
  287. * @since 1.0
  288. * @return void
  289. */
  290. public function posts_where( $where ) {
  291. return $where . 'AND 1 = 0';
  292. }
  293.  
  294.  
  295. /**
  296. * Adds the start date meta if only end date meta is provided when editing or publishing a post.
  297. *
  298. * @since 1.0
  299. * @return void
  300. */
  301. public function save_post( $post_id ) {
  302.  
  303. if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
  304. return $post_id;
  305. }
  306.  
  307. if ( !current_user_can( 'edit_post', $post_id ) ) {
  308. return $post_id;
  309. }
  310.  
  311. $post_type = ( isset( $_POST['post_type'] ) ) ? $_POST['post_type'] : '';
  312.  
  313. if ( $this->post_type !== $post_type ) {
  314. return $post_id;
  315. }
  316.  
  317. $end_date = get_post_meta( $post_id, $this->end, true );
  318. if ( !empty( $end_date ) ) {
  319. if ( !get_post_meta( $post_id, $this->start, true ) ) {
  320. update_post_meta( $post_id, $this->start, $end_date );
  321. }
  322. }
  323. }
  324.  
  325. }
  326.  
  327. $meta_date_archive = new Meta_Date_Archive();
  328.  
  329.  
  330. /**
  331. * Returns start and end dates for date archives.
  332. *
  333. * @since 1.0
  334. * @return array Array with start and end date.
  335. */
  336. function meta_date_archive_dates() {
  337. $year = $month = $day = $m = false;
  338. $start_date = $end_date = '';
  339.  
  340. // is date archives
  341. if ( is_date() ) {
  342. $m = ( get_query_var( 'm' ) ) ? get_query_var( 'm' ) : false;
  343. $year = ( get_query_var( 'year' ) ) ? get_query_var( 'year' ) : false;
  344. $month = ( get_query_var( 'monthnum' ) ) ? zeroise( get_query_var( 'monthnum' ), 2 ) : false;
  345. $day = ( get_query_var( 'day' ) ) ? get_query_var( 'day' ) : false;
  346. if ( $m ) {
  347. $dates = meta_date_archive_getdate( $m );
  348. $year = $dates['year'];
  349. $month = $dates['month'];
  350. $day = $dates['day'];
  351. }
  352. return meta_date_archive_validated_dates( $year, $month, $day );
  353. }
  354.  
  355. return array();
  356. }
  357.  
  358.  
  359. /**
  360. * Returns start and end dates.
  361. *
  362. * @since 1.0
  363. * @param int $start Date.
  364. * @param int $end Date.
  365. * @return array Array with start and end date.
  366. */
  367. function meta_date_archive_start_end_date( $start = '', $end = '' ) {
  368.  
  369. $year = $month = $day = $m = false;
  370. $start_date = $end_date = '';
  371.  
  372. $start = absint( $start ); // int
  373. $end = absint( $end ); // int
  374.  
  375. // if not both dates are provided
  376. if ( !( $start && $end ) ) {
  377. return array();
  378. }
  379.  
  380. $dates = meta_date_archive_getdate( $start );
  381. $dates = meta_date_archive_validated_dates( $dates['year'], $dates['month'], $dates['day'] );
  382. $start_date = isset( $dates['start_date'] ) ? $dates['start_date'] : '';
  383.  
  384. $dates = meta_date_archive_getdate( $end );
  385. $dates = meta_date_archive_validated_dates( $dates['year'], $dates['month'], $dates['day'] );
  386. $end_date = isset( $dates['end_date'] ) ? $dates['end_date'] : '';
  387.  
  388. if ( !empty( $start_date ) && !empty( $end_date ) ) {
  389. return compact( 'start_date', 'end_date' );
  390. }
  391.  
  392. return array();
  393. }
  394.  
  395.  
  396. /**
  397. * Returns year, month or day from date .
  398. *
  399. * @since 1.0
  400. * @param string $date Date.
  401. * @return array Array with year, month and day.
  402. */
  403. function meta_date_archive_getdate( $date = '' ) {
  404. $year = $month = $day = false;
  405. switch ( strlen( $date ) ) {
  406. case 4: // Yearly
  407. $year = substr( $date, 0, 4 );
  408. break;
  409. case 6: // Monthly
  410. $year = substr( $date, 0, 4 );
  411. $month = substr( $date, 4, 2 );
  412. break;
  413. case 8: // Daily
  414. $year = substr( $date, 0, 4 );
  415. $month = substr( $date, 4, 2 );
  416. $day = substr( $date, 6, 2 );
  417. break;
  418. }
  419.  
  420. return compact( 'year', 'month', 'day' );
  421. }
  422.  
  423.  
  424. /**
  425. * Returns full date validated.
  426. *
  427. * @since 1.0
  428. * @param integer $year Year
  429. * @param integer $month Month
  430. * @param integer $day Day
  431. * @return string Validated date.
  432. */
  433. function meta_date_archive_validated_dates( $year = 0, $month = 0, $day = 0 ) {
  434. $start_date = $end_date = '';
  435.  
  436. $year = absint( $year );
  437. $month = absint( $month );
  438. $day = absint( $day );
  439.  
  440. if ( $year ) {
  441. // check if date exists
  442. if ( checkdate( '01', '01', $year ) ) {
  443. $start_date = $year . '0101';
  444. $end_date = $year . '1231';
  445. }
  446. }
  447.  
  448. if ( $year && $month ) {
  449. $month = zeroise( $month, 2 );
  450. // check if date exists
  451. if ( checkdate( $month, '01', $year ) ) {
  452. $start_date = $year . $month . '01';
  453. $end_date = date( 'Ymt', mktime( 23, 59, 59, $month, 1, $year ) ); // 't' gets the last day
  454. }
  455. }
  456.  
  457. if ( $year && $month && $day ) {
  458. $month = zeroise( $month, 2 );
  459. $day = zeroise( $day, 2 );
  460. // check if date exists
  461. if ( checkdate( $month, $day, $year ) ) {
  462. $start_date = $year . $month . $day;
  463. $end_date = $start_date;
  464. }
  465. }
  466.  
  467. if ( empty( $start_date ) || empty( $end_date ) ) {
  468. return array();
  469. }
  470.  
  471. return compact( 'start_date', 'end_date' );
  472. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement