diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index e79432ac6..01ef84c76 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -10,9 +10,7 @@ class PostsController < ApplicationController format.html { redirect_to(@post) } end else - limit = params[:limit] || (params[:tags] =~ /(?:^|\s)limit:(\d+)(?:$|\s)/ && $1) || CurrentUser.user.per_page - @random = params[:random] || params[:tags] =~ /(?:^|\s)order:random(?:$|\s)/ - @post_set = PostSets::Post.new(tag_query, params[:page], limit, raw: params[:raw], random: @random, format: params[:format], read_only: params[:ro]) + @post_set = PostSets::Post.new(tag_query, params[:page], params[:limit], raw: params[:raw], random: params[:random], format: params[:format], read_only: params[:ro]) @posts = @post_set.posts respond_with(@posts) do |format| format.atom diff --git a/app/logical/post_sets/post.rb b/app/logical/post_sets/post.rb index 32faedcbe..6f8b359b5 100644 --- a/app/logical/post_sets/post.rb +++ b/app/logical/post_sets/post.rb @@ -1,12 +1,12 @@ module PostSets class Post < PostSets::Base - attr_reader :tag_array, :page, :per_page, :raw, :random, :post_count, :format, :read_only + MAX_PER_PAGE = 200 + attr_reader :tag_array, :page, :raw, :random, :post_count, :format, :read_only def initialize(tags, page = 1, per_page = nil, options = {}) @tag_array = Tag.scan_query(tags) @page = page - @per_page = (per_page || CurrentUser.per_page).to_i - @per_page = 200 if @per_page > 200 + @per_page = per_page @raw = options[:raw].present? @random = options[:random].present? @format = options[:format] || "html" @@ -102,6 +102,14 @@ module PostSets posts.select { |p| p.safeblocked? && !p.levelblocked? && !p.banblocked? } end + def per_page + (@per_page || Tag.has_metatag?(tag_array, :limit) || CurrentUser.user.per_page).to_i.clamp(0, MAX_PER_PAGE) + end + + def is_random? + random || Tag.has_metatag?(tag_array, :order) == "random" + end + def use_sequential_paginator? unknown_post_count? && !CurrentUser.is_gold? end @@ -129,7 +137,7 @@ module PostSets @posts ||= begin @post_count = get_post_count() - if random + if is_random? temp = get_random_posts() elsif raw temp = ::Post.raw_tag_match(tag_string).order("posts.id DESC").where("true /* PostSets::Post#posts:1 */").paginate(page, :count => post_count, :limit => per_page) diff --git a/app/models/tag.rb b/app/models/tag.rb index df31b9b4c..c563c8549 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -445,6 +445,13 @@ class Tag < ApplicationRecord tag.include?("*") end + def has_metatag?(tags, *metatags) + return nil if tags.blank? + + tags = scan_query(tags.to_str) if tags.respond_to?(:to_str) + tags.grep(/\A#{Regexp.union(metatags.map(&:to_s))}:(.+)\z/i) { $1 }.first + end + def parse_query(query, options = {}) q = {} diff --git a/app/views/posts/partials/index/_posts.html.erb b/app/views/posts/partials/index/_posts.html.erb index e3e014082..53a33e3f9 100644 --- a/app/views/posts/partials/index/_posts.html.erb +++ b/app/views/posts/partials/index/_posts.html.erb @@ -19,7 +19,7 @@ <% end %> - <% unless @random.present? %> + <% unless post_set.is_random? %> <%= numbered_paginator(post_set.posts) %> <% end %> diff --git a/test/functional/posts_controller_test.rb b/test/functional/posts_controller_test.rb index dad1b9d83..283fa3303 100644 --- a/test/functional/posts_controller_test.rb +++ b/test/functional/posts_controller_test.rb @@ -89,6 +89,16 @@ class PostsControllerTest < ActionDispatch::IntegrationTest assert_redirected_to(@post) end end + + context "with a random search" do + should "render" do + get posts_path, params: { tags: "order:random" } + assert_response :success + + get posts_path, params: { random: "1" } + assert_response :success + end + end end context "show_seq action" do diff --git a/test/unit/post_sets/post_test.rb b/test/unit/post_sets/post_test.rb index 1ddf6a62f..93db94d0e 100644 --- a/test/unit/post_sets/post_test.rb +++ b/test/unit/post_sets/post_test.rb @@ -161,6 +161,19 @@ module PostSets end end end + + context "#per_page method" do + should "take the limit from the params first, then the limit: metatag, then the account settings" do + set = PostSets::Post.new("a limit:23 b", 1, 42) + assert_equal(42, set.per_page) + + set = PostSets::Post.new("a limit:23 b", 1, nil) + assert_equal(23, set.per_page) + + set = PostSets::Post.new("a", 1, nil) + assert_equal(CurrentUser.user.per_page, set.per_page) + end + end end end end