$post_types, 'post_status' => 'publish', 'numberposts' => max(1, (int) $limit), 'offset' => max(0, (int) $offset), 'orderby' => 'ID', 'order' => 'ASC', ]); } /** Every published title in scope, for the duplicate check. Titles only, so it stays light. */ public function published_titles(array $post_types) { global $wpdb; $types = array_values(array_filter(array_map('sanitize_key', $post_types))); if (!$types) { return []; } $in = implode(', ', array_fill(0, count($types), '%s')); // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders, WordPress.DB.DirectDatabaseQuery return $wpdb->get_col($wpdb->prepare("SELECT post_title FROM {$wpdb->posts} WHERE post_status = 'publish' AND post_type IN ($in)", $types)); } /** Record that a post has been looked at, so a later feature can find what went stale. */ public function mark_scanned($post_id, $when) { update_post_meta((int) $post_id, Postlint_Scanner::SCAN_META, $when); } public function read_report() { $report = get_option(POSTLINT_OPTION_REPORT, []); return is_array($report) ? $report : []; } /** * Written with autoload off on purpose: the report can grow to the size of the whole site and * has no business being loaded into memory on every front-end request. */ public function write_report(array $report) { update_option(POSTLINT_OPTION_REPORT, $report, false); } public function now() { return current_time('mysql', true); } public function timestamp() { return time(); } }