menu

Web制作のTipsとかアレコレ。

[WordPress]一定期間後に投稿ステータスを自動的に「非表示」にする

2014.09.17

ワードプレスで構築したあるクライアントさんのご要望に沿って作成しました。
前提として、ここはショッピングサイトではなく、店頭で陳列販売をしているショップさんです。
サイト上に掲載している商品が売れたら、「販売済み」のチェックボックスにチェックを入れ、その際出現するデートピッカーで販売日を入力する、という仕様。
何故そういう仕様になっているかというと、
「商品が売れた日から一週間の間は「Sold Out」のタグと一緒に表示しておいて、その後一覧から表示を消す」
ためでした。

当初は商品一覧ページでget_postsで商品一覧から全ての商品データを取得して、条件分岐で処理してました。

$args = array( 'numberposts' => -1,
               'post_type' => 'products');
$posts = get_posts( $args );

if( !empty( $posts ) ):

  $new_posts = array();

  foreach( $posts as $post ):
    
    // 販売済みにチェックのないものはそのまま(ACFを使ってます)
    if ( ! get_field('products_sold', $post->ID ) ) {
      $new_posts[] = $post;
    } else {
    // 現在時刻をタイムスタンプで取得し、
    // 販売日(カスタムフィールドで入力)のタイムスタンプとの差を取得
    // その差が604800(1週間)未満の$postを
       $new_posts[] = $post;
    // として配列new_postsに格納していく
    }
  endforeach;

endif;

if( !empty( $new_posts ) ):
  // 出力処理

こんな感じですね。
ただ、当然ですが、毎回全記事を取得して条件判別なんてしてたら1年もしないうちに激重サイトになることは確実。

ということで、
・販売済みから一週間経った記事は、ステータス(公開状態)を非表示にして、フロント表示時に取得しないようにする。
・管理画面は毎日開くので、admin_initにフックする。
というのを実装しました。

参考にしたのは /wp-includes/post.phpの[wp_publish_post]という関数です。
これを改変して、1週間経ったことを判別する条件分岐でくくります。

// 販売日から一週間以上のproducts投稿ステータスを「非表示(private)」にする
// 管理画面は毎日開くので、ここにフックする
add_action('admin_init', 'set_private_post');
function set_private_post() {

  $args = array(
    'numberposts' => -1,
    'post_type' => 'products' // カスタム投稿タイプproducts
    );
  $posts = get_posts( $args );

if( !empty($posts) ):
  foreach( $posts as $post ):

    if( get_field('products_sold', $post->ID ) === true ){ // カスタムフィールド(ACF)で、販売されたらチェックを入れる(true)もの
      $sold_date = strtotime( get_field('products_sold_date', $post->ID ) ); // 販売済みのチェックが入ったらこの項目に日付が入る
      $gap = time() - $sold_date;
      if( $gap < 604800 ){ // 604800秒 = 1週間
        continue;
      } else {

        global $wpdb;

        if ( ! $post = get_post( $post ) )
          continue;

        if ( 'private' == $post->post_status )
          continue;

        $wpdb->update( $wpdb->posts, array( 'post_status' => 'private' ), array( 'ID' => $post->ID ) );

        clean_post_cache( $post->ID );

        $old_status = $post->post_status;
        $post->post_status = 'private';
        wp_transition_post_status( 'private', $old_status, $post );

        /** This action is documented in wp-includes/post.php */
        do_action( 'edit_post', $post->ID, $post );
        /** This action is documented in wp-includes/post.php */
        do_action( "save_post_{$post->post_type}", $post->ID, $post, true );
        /** This action is documented in wp-includes/post.php */
        do_action( 'save_post', $post->ID, $post, true );
    }
  }
  endforeach; endif;
}

デフォルトでは「非表示」のポストを取得しないので、これで激重サイト化を回避です。

最下部の3つのアクションフックは・・・よく分からんのでとりあえずそのままにしてます・・・
ほんとはもう一つ、insert_postがあったんですけど、それは明らかに関係ないので削除しましたが。
ここの部分、誰かご教授を・・・。

Comments

please leave your comment...

▲ Page Top