0

I am trying to implement a "content drip-style/time released content" subscription system using a WordPress query that filters and selects content from a custom post type using set parameters and displays them on a page template. An explanation, some examples, initial parameters for the query, and how the retailers (pages) and posts are structured are included below.

Is this possible with a WP query or would a plugin be required? I have looked into membership plugins, but they seem to be excessive for this level of customization.

<?php
/**
 * Pages that are defined as 'Retailers'.
 * Each retailer (page) will have a defined start date using an Advanced Custom Fields date picker field. This field is set manually by the site admin.

 * The retailer pages will display a defined number of posts from the 'sendouts' custom post type in a HTML dropdown (explained below).
 * The number of displayed posts is handled in part by the start date parameter.
 * A new post will be added every 14 days (2 weeks).

 * EXAMPLE 1: Retailer A has a start date of January 1, 2019. Counting up from that start date to the current date (January 7, 2020),
 * the retailer will have a total of 26 posts accessible from the HTML dropdown.

 * EXAMPLE 2: Retailer B has a start date of December 1, 2019. Counting up from that start date to the current date (January 7, 2020,
 * the retailer will have a total 2 posts accessible from the HTML dropdown.

 * EXAMPLE 3: Retailer C has a start date of January 1, 2020. As the start date is less than 14 days (two weeks) old, only one post will be displayed
 * and the HTML dropdown will not be displayed on the page.
 * 
 */

// Advanced Custom Fields date picker field assigned to each Retailer page
$startDate = get_field( 'sendout_start_date' );

// Set the timezone to America/Edmonton to localize date to region
date_default_timezone_set( 'America/Edmonton' );

// Grab the current date for the set timezone
$currentDate = date( 'm/d/Y h:i:s a', time() );

// Add fourteen days to the current date
// Use this variable in a loop to increment the total number of visible posts by one every 14 days
$datePlusFourteen = date_add( $currentDate, new DateInterval( 'P14D' ));

$args = array(
    'post_type' => 'sendouts',
    'cat' => '101',
    'order' => 'ASC',
    'orderby' => 'p',
    'meta_query' => array(
        array(
            'key' => 'sendout_start_date',
            'type' => 'NUMERIC',
            'value' => array( 'sendout_start_date', $currentDate ),
            'compare' => 'BETWEEN',
        ),
    ),
);
$query = new WP_Query( $args );

Update

Page sendout start date: October 18, 2019

Sendout post dates:

  • January 7
  • December 1
  • November 15
  • November 1
  • October 15
0

Use a meta query. Since ACF stores dates as Ymd you can just treat the value as a number:

$date_query = array(
    'key' => 'start_date', // ACF date field name
    'type' => 'NUMERIC',
    'value' => '20200101',
    'compare' => '<=', // All posts with start date before/on January 1st 2020
);

$args['meta_query'] = array( $date_query );

Any typical comparison e.g. =, !=, >, >=, <, <= can be used for the value of compare.

Or perhaps a date range is what you need e.g. to get all posts for December 2019:

$date_query = array(
    'key' => 'start_date',
    'type' => 'NUMERIC',
    'value' => array( '20191201' /* Start date */, '20191231' /* End date */ ),
    'compare' => 'BETWEEN',
);

Here's an (untested) example for your question:

// Grab the current date for the set timezone
$currentDate = new DateTimeImmutable( current_time( 'mysql', true /* GMT */ ), new DateTimeZone( 'America/Edmonton' ) );

// Add fourteen days to the current date
// Use this variable in a loop to increment the total number of visible posts by one every 14 days
$datePlusFourteen = $currentDate->add( new DateInterval( 'P14D' ) );

$args = array(
    'post_type' => 'sendouts',
    'cat' => '101',
    'order' => 'ASC',
    'orderby' => 'p',
    'meta_query' => array(
        array(
            'key' => 'sendout_start_date',
            'type' => 'NUMERIC',
            'value' => array( $currentDate->format( 'Ymd' ), $datePlusFourteen->format( 'Ymd' ) ),
            'compare' => 'BETWEEN',
        ),
    ),
);

$query = new WP_Query( $args );
  • A date range is heading in the right direction, but I need it to compare the page start date and the current date on the server for the set time zone. This comparison will also need to take into account the 14 day window and adding an additional post to the HTML dropdown every two weeks. I have update my code example with your suggestions. – Mike Hermary Jan 7 at 20:45
  • @MikeHermary See my update. – TheDeadMedic Jan 7 at 21:33
  • Thanks for the code. I have implemented it, but it is not working correctly. The query is not returning any posts. I have updated my question with the page sendout start date value and dates for the posts. Hopefully this sheds some light on the issue. – Mike Hermary Jan 8 at 3:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.