Restores object count and adds offset/limit attributes to API responses for paginated collections (#6140).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@4489 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
parent
67f1131a20
commit
00d50157d3
|
@ -349,6 +349,23 @@ class ApplicationController < ActionController::Base
|
|||
per_page
|
||||
end
|
||||
|
||||
def api_offset_and_limit
|
||||
offset = nil
|
||||
if params[:offset].present?
|
||||
offset = params[:offset].to_i
|
||||
if offset < 0
|
||||
offset = 0
|
||||
end
|
||||
end
|
||||
limit = params[:limit].to_i
|
||||
if limit < 1
|
||||
limit = 25
|
||||
elsif limit > 100
|
||||
limit = 100
|
||||
end
|
||||
[offset, limit]
|
||||
end
|
||||
|
||||
# qvalues http header parser
|
||||
# code taken from webrick
|
||||
def parse_qvalues(value)
|
||||
|
|
|
@ -65,21 +65,24 @@ class IssuesController < ApplicationController
|
|||
sort_update(@query.sortable_columns)
|
||||
|
||||
if @query.valid?
|
||||
limit = case params[:format]
|
||||
case params[:format]
|
||||
when 'csv', 'pdf'
|
||||
Setting.issues_export_limit.to_i
|
||||
@limit = Setting.issues_export_limit.to_i
|
||||
when 'atom'
|
||||
Setting.feeds_limit.to_i
|
||||
@limit = Setting.feeds_limit.to_i
|
||||
when 'xml', 'json'
|
||||
@offset, @limit = api_offset_and_limit
|
||||
else
|
||||
per_page_option
|
||||
@limit = per_page_option
|
||||
end
|
||||
|
||||
@issue_count = @query.issue_count
|
||||
@issue_pages = Paginator.new self, @issue_count, limit, params['page']
|
||||
@issue_pages = Paginator.new self, @issue_count, @limit, params['page']
|
||||
@offset ||= @issue_pages.current.offset
|
||||
@issues = @query.issues(:include => [:assigned_to, :tracker, :priority, :category, :fixed_version],
|
||||
:order => sort_clause,
|
||||
:offset => @issue_pages.current.offset,
|
||||
:limit => limit)
|
||||
:offset => @offset,
|
||||
:limit => @limit)
|
||||
@issue_count_by_group = @query.issue_count_by_group
|
||||
|
||||
respond_to do |format|
|
||||
|
|
|
@ -30,6 +30,13 @@ class UsersController < ApplicationController
|
|||
sort_init 'login', 'asc'
|
||||
sort_update %w(login firstname lastname mail admin created_on last_login_on)
|
||||
|
||||
case params[:format]
|
||||
when 'xml', 'json'
|
||||
@offset, @limit = api_offset_and_limit
|
||||
else
|
||||
@limit = per_page_option
|
||||
end
|
||||
|
||||
@status = params[:status] ? params[:status].to_i : 1
|
||||
c = ARCondition.new(@status == 0 ? "status <> 0" : ["status = ?", @status])
|
||||
|
||||
|
@ -39,13 +46,13 @@ class UsersController < ApplicationController
|
|||
end
|
||||
|
||||
@user_count = User.count(:conditions => c.conditions)
|
||||
@user_pages = Paginator.new self, @user_count,
|
||||
per_page_option,
|
||||
params['page']
|
||||
@users = User.find :all,:order => sort_clause,
|
||||
@user_pages = Paginator.new self, @user_count, @limit, params['page']
|
||||
@offset ||= @user_pages.current.offset
|
||||
@users = User.find :all,
|
||||
:order => sort_clause,
|
||||
:conditions => c.conditions,
|
||||
:limit => @user_pages.items_per_page,
|
||||
:offset => @user_pages.current.offset
|
||||
:limit => @limit,
|
||||
:offset => @offset
|
||||
|
||||
respond_to do |format|
|
||||
format.html { render :layout => !request.xhr? }
|
||||
|
|
|
@ -877,6 +877,18 @@ module ApplicationHelper
|
|||
@included_in_api_response.include?(arg.to_s)
|
||||
end
|
||||
|
||||
# Returns options or nil if nometa param or X-Redmine-Nometa header
|
||||
# was set in the request
|
||||
def api_meta(options)
|
||||
if params[:nometa].present? || request.headers['X-Redmine-Nometa']
|
||||
# compatibility mode for activeresource clients that raise
|
||||
# an error when unserializing an array with attributes
|
||||
nil
|
||||
else
|
||||
options
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def wiki_helper
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
api.array :issues do
|
||||
api.array :issues, api_meta(:total_count => @issue_count, :offset => @offset, :limit => @limit) do
|
||||
@issues.each do |issue|
|
||||
api.issue do
|
||||
api.id issue.id
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
api.array :users do
|
||||
api.array :users, api_meta(:total_count => @user_count, :offset => @offset, :limit => @limit) do
|
||||
@users.each do |user|
|
||||
api.user do
|
||||
api.id user.id
|
||||
|
|
|
@ -25,11 +25,12 @@ module Redmine
|
|||
@struct = [{}]
|
||||
end
|
||||
|
||||
def array(tag, &block)
|
||||
def array(tag, options={}, &block)
|
||||
@struct << []
|
||||
block.call(self)
|
||||
ret = @struct.pop
|
||||
@struct.last[tag] = ret
|
||||
@struct.last.merge!(options) if options
|
||||
end
|
||||
|
||||
def method_missing(sym, *args, &block)
|
||||
|
|
|
@ -37,7 +37,7 @@ module Redmine
|
|||
end
|
||||
|
||||
def array(name, options={}, &block)
|
||||
__send__ name, options.merge(:type => 'array'), &block
|
||||
__send__ name, (options || {}).merge(:type => 'array'), &block
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -46,10 +46,60 @@ class ApiTest::IssuesTest < ActionController::IntegrationTest
|
|||
Setting.rest_api_enabled = '1'
|
||||
end
|
||||
|
||||
# Use a private project to make sure auth is really working and not just
|
||||
# only showing public issues.
|
||||
context "/index.xml" do
|
||||
# Use a private project to make sure auth is really working and not just
|
||||
# only showing public issues.
|
||||
should_allow_api_authentication(:get, "/projects/private-child/issues.xml")
|
||||
|
||||
should "contain metadata" do
|
||||
get '/issues.xml'
|
||||
|
||||
assert_tag :tag => 'issues',
|
||||
:attributes => {
|
||||
:type => 'array',
|
||||
:total_count => assigns(:issue_count),
|
||||
:limit => 25,
|
||||
:offset => 0
|
||||
}
|
||||
end
|
||||
|
||||
context "with offset and limit" do
|
||||
should "use the params" do
|
||||
get '/issues.xml?offset=2&limit=3'
|
||||
|
||||
assert_equal 3, assigns(:limit)
|
||||
assert_equal 2, assigns(:offset)
|
||||
assert_tag :tag => 'issues', :children => {:count => 3, :only => {:tag => 'issue'}}
|
||||
end
|
||||
end
|
||||
|
||||
context "with nometa param" do
|
||||
should "not contain metadata" do
|
||||
get '/issues.xml?nometa=1'
|
||||
|
||||
assert_tag :tag => 'issues',
|
||||
:attributes => {
|
||||
:type => 'array',
|
||||
:total_count => nil,
|
||||
:limit => nil,
|
||||
:offset => nil
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
context "with nometa header" do
|
||||
should "not contain metadata" do
|
||||
get '/issues.xml', {}, {'X-Redmine-Nometa' => '1'}
|
||||
|
||||
assert_tag :tag => 'issues',
|
||||
:attributes => {
|
||||
:type => 'array',
|
||||
:total_count => nil,
|
||||
:limit => nil,
|
||||
:offset => nil
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "/index.json" do
|
||||
|
|
Loading…
Reference in New Issue