1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
# Redmine - project management software
# Copyright (C) 2006-2017 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
module Redmine
class SortCriteria < Array
def initialize(arg=nil)
super()
if arg.is_a?(Array)
replace arg
elsif arg.is_a?(String)
replace arg.split(',').collect {|s| s.split(':')[0..1]}
elsif arg.respond_to?(:values)
replace arg.values
elsif arg
raise ArgumentError.new("SortCriteria#new takes an Array, String or Hash, not a #{arg.class.name}.")
end
normalize!
end
def to_param
self.collect {|k,o| k + (o == 'desc' ? ':desc' : '')}.join(',')
end
def to_a
Array.new(self)
end
def add!(key, asc)
key = key.to_s
delete_if {|k,o| k == key}
prepend([key, asc])
normalize!
end
def add(*args)
self.class.new(self).add!(*args)
end
def first_key
first.try(:first)
end
def first_asc?
first.try(:last) == 'asc'
end
def key_at(arg)
self[arg].try(:first)
end
def order_at(arg)
self[arg].try(:last)
end
def order_for(key)
detect {|k, order| key.to_s == k}.try(:last)
end
def sort_clause(sortable_columns)
if sortable_columns.is_a?(Array)
sortable_columns = sortable_columns.inject({}) {|h,k| h[k]=k; h}
end
sql = self.collect do |k,o|
if s = sortable_columns[k]
s = [s] unless s.is_a?(Array)
s.collect {|c| append_order(c, o)}
end
end.flatten.compact
sql.blank? ? nil : sql
end
private
def normalize!
self.reject! {|s| s.first.blank? }
self.collect! {|s| s = Array(s); [s.first, (s.last == false || s.last.to_s == 'desc') ? 'desc' : 'asc']}
self.replace self.first(3)
end
# Appends ASC/DESC to the sort criterion unless it has a fixed order
def append_order(criterion, order)
if criterion =~ / (asc|desc)$/i
criterion
else
Arel.sql "#{criterion} #{order.to_s.upcase}"
end
end
end
end
|