@@ -349,6 +349,23 class ApplicationController < ActionController::Base | |||||
349 | per_page |
|
349 | per_page | |
350 | end |
|
350 | end | |
351 |
|
351 | |||
|
352 | def api_offset_and_limit | |||
|
353 | offset = nil | |||
|
354 | if params[:offset].present? | |||
|
355 | offset = params[:offset].to_i | |||
|
356 | if offset < 0 | |||
|
357 | offset = 0 | |||
|
358 | end | |||
|
359 | end | |||
|
360 | limit = params[:limit].to_i | |||
|
361 | if limit < 1 | |||
|
362 | limit = 25 | |||
|
363 | elsif limit > 100 | |||
|
364 | limit = 100 | |||
|
365 | end | |||
|
366 | [offset, limit] | |||
|
367 | end | |||
|
368 | ||||
352 | # qvalues http header parser |
|
369 | # qvalues http header parser | |
353 | # code taken from webrick |
|
370 | # code taken from webrick | |
354 | def parse_qvalues(value) |
|
371 | def parse_qvalues(value) |
@@ -65,21 +65,24 class IssuesController < ApplicationController | |||||
65 | sort_update(@query.sortable_columns) |
|
65 | sort_update(@query.sortable_columns) | |
66 |
|
66 | |||
67 | if @query.valid? |
|
67 | if @query.valid? | |
68 |
|
|
68 | case params[:format] | |
69 | when 'csv', 'pdf' |
|
69 | when 'csv', 'pdf' | |
70 | Setting.issues_export_limit.to_i |
|
70 | @limit = Setting.issues_export_limit.to_i | |
71 | when 'atom' |
|
71 | when 'atom' | |
72 | Setting.feeds_limit.to_i |
|
72 | @limit = Setting.feeds_limit.to_i | |
|
73 | when 'xml', 'json' | |||
|
74 | @offset, @limit = api_offset_and_limit | |||
73 | else |
|
75 | else | |
74 | per_page_option |
|
76 | @limit = per_page_option | |
75 | end |
|
77 | end | |
76 |
|
78 | |||
77 | @issue_count = @query.issue_count |
|
79 | @issue_count = @query.issue_count | |
78 | @issue_pages = Paginator.new self, @issue_count, limit, params['page'] |
|
80 | @issue_pages = Paginator.new self, @issue_count, @limit, params['page'] | |
|
81 | @offset ||= @issue_pages.current.offset | |||
79 | @issues = @query.issues(:include => [:assigned_to, :tracker, :priority, :category, :fixed_version], |
|
82 | @issues = @query.issues(:include => [:assigned_to, :tracker, :priority, :category, :fixed_version], | |
80 | :order => sort_clause, |
|
83 | :order => sort_clause, | |
81 |
:offset => @ |
|
84 | :offset => @offset, | |
82 | :limit => limit) |
|
85 | :limit => @limit) | |
83 | @issue_count_by_group = @query.issue_count_by_group |
|
86 | @issue_count_by_group = @query.issue_count_by_group | |
84 |
|
87 | |||
85 | respond_to do |format| |
|
88 | respond_to do |format| |
@@ -30,6 +30,13 class UsersController < ApplicationController | |||||
30 | sort_init 'login', 'asc' |
|
30 | sort_init 'login', 'asc' | |
31 | sort_update %w(login firstname lastname mail admin created_on last_login_on) |
|
31 | sort_update %w(login firstname lastname mail admin created_on last_login_on) | |
32 |
|
32 | |||
|
33 | case params[:format] | |||
|
34 | when 'xml', 'json' | |||
|
35 | @offset, @limit = api_offset_and_limit | |||
|
36 | else | |||
|
37 | @limit = per_page_option | |||
|
38 | end | |||
|
39 | ||||
33 | @status = params[:status] ? params[:status].to_i : 1 |
|
40 | @status = params[:status] ? params[:status].to_i : 1 | |
34 | c = ARCondition.new(@status == 0 ? "status <> 0" : ["status = ?", @status]) |
|
41 | c = ARCondition.new(@status == 0 ? "status <> 0" : ["status = ?", @status]) | |
35 |
|
42 | |||
@@ -39,13 +46,13 class UsersController < ApplicationController | |||||
39 | end |
|
46 | end | |
40 |
|
47 | |||
41 | @user_count = User.count(:conditions => c.conditions) |
|
48 | @user_count = User.count(:conditions => c.conditions) | |
42 | @user_pages = Paginator.new self, @user_count, |
|
49 | @user_pages = Paginator.new self, @user_count, @limit, params['page'] | |
43 | per_page_option, |
|
50 | @offset ||= @user_pages.current.offset | |
44 | params['page'] |
|
51 | @users = User.find :all, | |
45 | @users = User.find :all,:order => sort_clause, |
|
52 | :order => sort_clause, | |
46 | :conditions => c.conditions, |
|
53 | :conditions => c.conditions, | |
47 | :limit => @user_pages.items_per_page, |
|
54 | :limit => @limit, | |
48 | :offset => @user_pages.current.offset |
|
55 | :offset => @offset | |
49 |
|
56 | |||
50 | respond_to do |format| |
|
57 | respond_to do |format| | |
51 | format.html { render :layout => !request.xhr? } |
|
58 | format.html { render :layout => !request.xhr? } |
@@ -877,6 +877,18 module ApplicationHelper | |||||
877 | @included_in_api_response.include?(arg.to_s) |
|
877 | @included_in_api_response.include?(arg.to_s) | |
878 | end |
|
878 | end | |
879 |
|
879 | |||
|
880 | # Returns options or nil if nometa param or X-Redmine-Nometa header | |||
|
881 | # was set in the request | |||
|
882 | def api_meta(options) | |||
|
883 | if params[:nometa].present? || request.headers['X-Redmine-Nometa'] | |||
|
884 | # compatibility mode for activeresource clients that raise | |||
|
885 | # an error when unserializing an array with attributes | |||
|
886 | nil | |||
|
887 | else | |||
|
888 | options | |||
|
889 | end | |||
|
890 | end | |||
|
891 | ||||
880 | private |
|
892 | private | |
881 |
|
893 | |||
882 | def wiki_helper |
|
894 | def wiki_helper |
@@ -1,4 +1,4 | |||||
1 | api.array :issues do |
|
1 | api.array :issues, api_meta(:total_count => @issue_count, :offset => @offset, :limit => @limit) do | |
2 | @issues.each do |issue| |
|
2 | @issues.each do |issue| | |
3 | api.issue do |
|
3 | api.issue do | |
4 | api.id issue.id |
|
4 | api.id issue.id |
@@ -1,4 +1,4 | |||||
1 | api.array :users do |
|
1 | api.array :users, api_meta(:total_count => @user_count, :offset => @offset, :limit => @limit) do | |
2 | @users.each do |user| |
|
2 | @users.each do |user| | |
3 | api.user do |
|
3 | api.user do | |
4 | api.id user.id |
|
4 | api.id user.id |
@@ -25,11 +25,12 module Redmine | |||||
25 | @struct = [{}] |
|
25 | @struct = [{}] | |
26 | end |
|
26 | end | |
27 |
|
27 | |||
28 | def array(tag, &block) |
|
28 | def array(tag, options={}, &block) | |
29 | @struct << [] |
|
29 | @struct << [] | |
30 | block.call(self) |
|
30 | block.call(self) | |
31 | ret = @struct.pop |
|
31 | ret = @struct.pop | |
32 | @struct.last[tag] = ret |
|
32 | @struct.last[tag] = ret | |
|
33 | @struct.last.merge!(options) if options | |||
33 | end |
|
34 | end | |
34 |
|
35 | |||
35 | def method_missing(sym, *args, &block) |
|
36 | def method_missing(sym, *args, &block) |
@@ -37,7 +37,7 module Redmine | |||||
37 | end |
|
37 | end | |
38 |
|
38 | |||
39 | def array(name, options={}, &block) |
|
39 | def array(name, options={}, &block) | |
40 | __send__ name, options.merge(:type => 'array'), &block |
|
40 | __send__ name, (options || {}).merge(:type => 'array'), &block | |
41 | end |
|
41 | end | |
42 | end |
|
42 | end | |
43 | end |
|
43 | end |
@@ -46,10 +46,60 class ApiTest::IssuesTest < ActionController::IntegrationTest | |||||
46 | Setting.rest_api_enabled = '1' |
|
46 | Setting.rest_api_enabled = '1' | |
47 | end |
|
47 | end | |
48 |
|
48 | |||
|
49 | context "/index.xml" do | |||
49 | # Use a private project to make sure auth is really working and not just |
|
50 | # Use a private project to make sure auth is really working and not just | |
50 | # only showing public issues. |
|
51 | # only showing public issues. | |
51 | context "/index.xml" do |
|
|||
52 | should_allow_api_authentication(:get, "/projects/private-child/issues.xml") |
|
52 | should_allow_api_authentication(:get, "/projects/private-child/issues.xml") | |
|
53 | ||||
|
54 | should "contain metadata" do | |||
|
55 | get '/issues.xml' | |||
|
56 | ||||
|
57 | assert_tag :tag => 'issues', | |||
|
58 | :attributes => { | |||
|
59 | :type => 'array', | |||
|
60 | :total_count => assigns(:issue_count), | |||
|
61 | :limit => 25, | |||
|
62 | :offset => 0 | |||
|
63 | } | |||
|
64 | end | |||
|
65 | ||||
|
66 | context "with offset and limit" do | |||
|
67 | should "use the params" do | |||
|
68 | get '/issues.xml?offset=2&limit=3' | |||
|
69 | ||||
|
70 | assert_equal 3, assigns(:limit) | |||
|
71 | assert_equal 2, assigns(:offset) | |||
|
72 | assert_tag :tag => 'issues', :children => {:count => 3, :only => {:tag => 'issue'}} | |||
|
73 | end | |||
|
74 | end | |||
|
75 | ||||
|
76 | context "with nometa param" do | |||
|
77 | should "not contain metadata" do | |||
|
78 | get '/issues.xml?nometa=1' | |||
|
79 | ||||
|
80 | assert_tag :tag => 'issues', | |||
|
81 | :attributes => { | |||
|
82 | :type => 'array', | |||
|
83 | :total_count => nil, | |||
|
84 | :limit => nil, | |||
|
85 | :offset => nil | |||
|
86 | } | |||
|
87 | end | |||
|
88 | end | |||
|
89 | ||||
|
90 | context "with nometa header" do | |||
|
91 | should "not contain metadata" do | |||
|
92 | get '/issues.xml', {}, {'X-Redmine-Nometa' => '1'} | |||
|
93 | ||||
|
94 | assert_tag :tag => 'issues', | |||
|
95 | :attributes => { | |||
|
96 | :type => 'array', | |||
|
97 | :total_count => nil, | |||
|
98 | :limit => nil, | |||
|
99 | :offset => nil | |||
|
100 | } | |||
|
101 | end | |||
|
102 | end | |||
53 | end |
|
103 | end | |
54 |
|
104 | |||
55 | context "/index.json" do |
|
105 | context "/index.json" do |
General Comments 0
You need to be logged in to leave comments.
Login now