Is it possible to Schedule Attachments in WordPress?

As it’s fairly well known, it is possible to schedule Posts in WordPress for publishing.

Also Attachments are actually Posts (in the more internal, technical meaning).

Read More

So the question that bothers me right now is: Is it possible to schedule attachments as well? Like for example that a Photo-Gallery grows over time?

Related posts

2 comments

  1. 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:

    Attachments date

    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 [gallery] 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.

  2. Create the complete gallery at once, use a custom shortcode handler for it.

    In your shortcode handler, just count the attachments for an advent calendar, or look up a post meta for the attachment. Replace the image with a placeholder or hide it completely, if it should not be seen yet.

    An attachment is public the moment is is uploaded, because WordPress is not involved in the direct file request.

Comments are closed.