プロジェクトでは、私はウェブサイトに最新の投稿を10件だけ残して、他のすべての投稿を自動削除する必要があります。それで私はポストパブリッシュ/アップデートでトリガーするこの関数を思いつきました、そして私は最新の10アイテムを除外するためにoffset
パラメータを使いました。
function wpse_auto_delete_posts( $post_ID ) {
global $post;
$delete_posts = get_posts( array( 'post_type' => 'post', 'offset' => 10, 'posts_per_page' => -1 ) );
foreach ( $delete_posts as $delete_post ) : setup_postdata( $delete_post );
wp_delete_post( $delete_post->ID, true );
endforeach;
wp_reset_postdata();
}
add_action( 'publish_post', 'wpse_auto_delete_posts' );
しかし、offset
は'posts_per_page' => -1
ではここでは機能せず、すべての投稿を削除し続けます。日付クエリを使用することを考えましたが、新しい投稿が頻繁に作成されるため、それも機能しません。
最新の10または5以外のすべての投稿を選択する方法はありますか。したがって、WordPressはそれらを処理して最新のX投稿を保持できます。
offset
パラメーターは、posts_per_page
で-1
がWP_Query
に設定されていると無視されます。 WP_Query
クラスのソースコードを見ると、posts_per_page=-1
はnopaging
をtrueに設定します。
if ( !isset($q['nopaging']) ) {
if ( $q['posts_per_page'] == -1 ) {
$q['nopaging'] = true;
} else {
$q['nopaging'] = false;
}
}
これはSQLクエリにLIMIT
を追加しません(empty($q['nopaging'] === false
これは条件文に失敗します)。つまり、ページ区切り/オフセット全体は無視され、すべての投稿が返されます。
if ( empty($q['nopaging']) && !$this->is_singular ) {
$page = absint($q['paged']);
if ( !$page )
$page = 1;
if ( empty($q['offset']) ) {
$pgstrt = absint( ( $page - 1 ) * $q['posts_per_page'] ) . ', ';
} else { // we're ignoring $page and using 'offset'
$q['offset'] = absint($q['offset']);
$pgstrt = $q['offset'] . ', ';
}
$limits = 'LIMIT ' . $pgstrt . $q['posts_per_page'];
}
私はここで最もよい回避策はすべての投稿を得た後に通常のPHP(array_slice()
)を利用することであると思います。 wp_delete_post
は実行するのが非常に高価で実際には投稿IDのみが必要なので、ここでは投稿IDのみを取得したいので、他の投稿情報は必要ありません。
つまり、クエリは次のようになります。(NOTE:これはすべてテストされておらず、PHP 5.4+)
add_action( 'publish_post', function ( $post_ID )
{
$args = [
'nopaging' => true,
'fields' => 'ids'
];
$posts_array = get_posts( $args );
// Make sure that we have post ID's returned
if ( $posts_array ) {
// Get all post ids after the 10th post using array_slice
$delete_posts = array_slice( $posts_array, 10 );
// Make sure that we actually have post ID's in the $delete_posts array
if ( $delete_posts ) {
foreach ( $delete_posts as $delete_post )
wp_delete_post( $delete_post, true );
}
}
});
_編集_
忘れる直前に、posts_per_page
の代わりに-1
をあり得ない整数値として定義することもできます。これはoffset
パラメータを設定したコードでも動作します。
'nopaging' => true
と'posts_per_page' => -1
が同じ動作をするという事実。このパラメータはあなたのWPによってなされたMySQLリクエストのLIMIT
節をキャンセルしています。
offset(int) - 移動または通過するポストの数警告:offsetパラメータを設定すると、ページングされたパラメータが上書きされて無視され、ページ付けが中断されます(回避策についてはここをクリックしてください)。 'posts_per_page' => - 1(すべての投稿を表示)が使用されている場合、 'offset'パラメータは無視されます。
MySQLのドキュメント およびそれらの推奨事項を考慮すると、offsetをそのままにして、posts_per_page
パラメータに多数の値を使用できます。
特定のオフセットから結果セットの最後までのすべての行を取得するには、2番目のパラメータに大きな数を使用できます。このステートメントは、96行目から最後までのすべての行を取得します。
SELECT * FROM tbl LIMIT 95,18446744073709551615;