My idea is that you can setup a post date for the attachments. This can be done using attachment_fields_to_edit
to show the UI (is possible use the touch_time
internal function).
After that, you can filter all the attachments query to show only the attachments with a past or current date.
So
add_action('load-post.php', 'setup_attachment_fields');
function setup_attachment_fields() {
$scr = get_current_screen();
if ( $scr->post_type === 'attachment' ) {
add_filter("attachment_fields_to_edit", "add_date_to_attachments", null, 2);
}
}
function add_date_to_attachments( $form_fields, $post = NULL ) {
printf('<label for="content"><strong>%s</strong></label>', __('Date'));
touch_time( 1, 1, 0, 1 );
return $form_fields;
}
Now on the attachment page you’ll see something like:
Now let’s set post date on attachment save:
add_filter("attachment_fields_to_save", "save_date_to_attachments");
function save_date_to_attachments( $post ) {
foreach ( array('mm', 'jj', 'aa', 'hh', 'mn') as $f ) {
$$f = (int) filter_input(INPUT_POST, $f, FILTER_SANITIZE_NUMBER_INT);
}
if ( ! checkdate ( $mm, $jj, $aa ) ) return; // bad data, man
if ( ($hh < 0 || $hh > 24) ) $hh = 0;
if ( ($mn < 0 || $mn > 60) ) $mn = 0;
$ts = mktime($hh, $mn, 0, $mm, $jj, $aa);
$date = date( 'Y-m-d H:i:s', $ts );
$date_gmt = date( 'Y-m-d H:i:s', ( $ts + ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ) ) );
$modified = current_time( 'mysql');
$modified_gmt = current_time( 'mysql', true);
global $wpdb;
$data = array(
'post_date' => $date,
'post_date_gmt' => $date_gmt,
'post_modified' => $modified,
'post_modified_gmt' => $modified_gmt,
);
$wpdb->update( $wpdb->posts, $data, array( 'ID' => $post['ID'] ), '%s', '%d' );
}
When attachment is saved, the post date is set to whatever you set on date fields.
However, attachments are all visible, no matter the date, because WordPress does not check the date on attachments queries. Let’s add a filter to where clause for that:
add_filter( 'posts_where', 'not_future_attachment', 9999, 2 );
function not_future_attachment( $where, $query ) {
if ( is_admin() ) return $where;
if ( $query->get('post_type') === 'attachment' ) {
global $wpdb;
$where .= $wpdb->prepare(
" AND ($wpdb->posts.post_date <= %s)", current_time( 'mysql')
);
}
return $where;
}
Now in a shortcode for gallery (or wherever you want) be sure to use WP_Query
setting up the post type argument to 'attachment'
.
On standard shortcode this will not work because it uses
get_children
where query filters are suppressed, so you have to create a custom shortcode or overwrite the default.