The problem with the plugin is it is querying for posts on the 'pre_get_posts'
hook, so this means that this plugin will run code that runs on the main post hooks twice.
Since it looks like this plugin is only meant to be looking for already-queried posts, I would recommend rewriting the mark_posts_as_read()
method to the following:
public function mark_posts_as_read($posts, $query) {
$headers = function_exists('getallheaders') ? getallheaders() : $this->get_headers();
if ($headers && isset($headers['X-Moz']) && $headers['X-Moz'] === 'prefetch') return $posts;
if ($this->posts_marked || $this->is_special_page() || ! $query->is_main_query()) return $posts;
$this->posts_marked = true;
$read_posts_ids = $this->get_read_posts_ids();
$update_cookie = false;
foreach ($posts as $post) {
$post_id = $post->ID;
if ($this->is_after_cookie_time($post) && !in_array($post_id, $read_posts_ids) || $this->is_test) {
$this->new_posts_displayed = true;
if ($this->options->mark_after !== MarkNewPosts_MarkAfter::OPENING_POST || is_single()) {
$read_posts_ids[] = $post_id;
$update_cookie = true;
}
}
}
if (!$update_cookie) return $posts;
array_unshift($read_posts_ids, $this->last_visit);
$this->set_cookie(join(self::COOKIE_DELIMITER, $read_posts_ids));
return $posts;
}
Then change your hook from 'pre_get_posts'
to 'the_posts'
:
add_filter('the_posts', array(&$this, 'mark_posts_as_read'), 10, 2);
I’m not 100% sure if this will break certain parts of your plugin, but hopefully it gives you an idea of where to optimize your code.