@@ -10,28 +10,31 @@ class SearchExercises
1010 'number' => Publication . arel_table [ :number ] ,
1111 'version' => Publication . arel_table [ :version ] ,
1212 'title' => :title ,
13- 'created_at' => :created_at
13+ 'created_at' => :created_at ,
14+ 'updated_at' => :updated_at ,
15+ 'published_at' => Publication . arel_table [ :published_at ]
1416 }
1517
1618 protected
1719
1820 def exec ( params = { } , options = { } )
1921 params [ :ob ] ||= [ { number : :asc } , { version : :desc } ]
22+ relation = Exercise . visible_for ( options [ :user ] )
2023
21- # By default, only return the latest exercises.
24+ # By default, only return the latest exercises visible to the user .
2225 # If either versions or uids are specified, this "latest" condition is disabled.
23- latest_only = true
24- run ( :search , relation : Exercise . visible_for ( options [ :user ] ) . preloaded ,
26+ latest_scope = relation
27+
28+ run ( :search , relation : relation . preloaded ,
2529 sortable_fields : SORTABLE_FIELDS ,
2630 params : params ) do |with |
2731 with . default_keyword :content
2832
2933 with . keyword :id , :uid do |ids |
30- latest_only = false
31-
3234 ids . each do |id |
3335 sanitized_ids = to_string_array ( id ) . collect { |id | id . split ( '@' ) }
3436 next @items = @items . none if sanitized_ids . empty?
37+
3538 sanitized_numbers = sanitized_ids . collect { |sid | sid . first } . compact
3639 sanitized_versions = sanitized_ids . collect { |sid | sid . second } . compact
3740 if sanitized_numbers . empty?
@@ -42,31 +45,38 @@ def exec(params = {}, options = {})
4245 @items = @items . where ( publication : { number : sanitized_numbers ,
4346 version : sanitized_versions } )
4447 end
48+
49+ # Since we are returning specific uids, disable "latest"
50+ latest_scope = nil
4551 end
4652 end
4753
4854 with . keyword :number do |numbers |
4955 numbers . each do |number |
5056 sanitized_numbers = to_string_array ( numbers )
5157 next @items = @items . none if sanitized_numbers . empty?
58+
5259 @items = @items . where ( publication : { number : sanitized_versions } )
5360 end
5461 end
5562
5663 with . keyword :version do |versions |
57- latest_only = false
58-
5964 versions . each do |version |
6065 sanitized_versions = to_string_array ( version )
6166 next @items = @items . none if sanitized_versions . empty?
67+
6268 @items = @items . where ( publication : { version : sanitized_versions } )
69+
70+ # Since we are returning specific versions, disable "latest"
71+ latest_scope = nil
6372 end
6473 end
6574
6675 with . keyword :tag do |tags |
6776 tags . each do |tag |
6877 sanitized_tags = to_string_array ( tag ) . collect { |t | t . downcase }
6978 next @items = @items . none if sanitized_tags . empty?
79+
7080 @items = @items . joins ( :tags )
7181 . where ( tags : { name : sanitized_tags } )
7282 end
@@ -77,6 +87,7 @@ def exec(params = {}, options = {})
7787 sanitized_titles = to_string_array ( title , append_wildcard : true ,
7888 prepend_wildcard : true )
7989 next @items = @items . none if sanitized_titles . empty?
90+
8091 @items = @items . where { title . like_any sanitized_titles }
8192 end
8293 end
@@ -86,6 +97,7 @@ def exec(params = {}, options = {})
8697 sanitized_contents = to_string_array ( content , append_wildcard : true ,
8798 prepend_wildcard : true )
8899 next @items = @items . none if sanitized_contents . empty?
100+
89101 @items = @items . joins { [ questions . outer . stems . outer , questions . outer . answers . outer ] }
90102 . where {
91103 ( title . like_any sanitized_contents ) |\
@@ -102,6 +114,7 @@ def exec(params = {}, options = {})
102114 sanitized_solutions = to_string_array ( solution , append_wildcard : true ,
103115 prepend_wildcard : true )
104116 next @items = @items . none if sanitized_solutions . empty?
117+
105118 @items = @items . joins ( :solutions )
106119 . where { ( solutions . summary . like_any sanitized_solutions ) |\
107120 ( solutions . details . like_any sanitized_solutions ) }
@@ -112,6 +125,7 @@ def exec(params = {}, options = {})
112125 names . each do |name |
113126 sn = to_string_array ( name , append_wildcard : true )
114127 next @items = @items . none if sn . empty?
128+
115129 @items = @items . joins ( publication : { authors : { user : :account } } )
116130 . where {
117131 ( publication . authors . user . account . username . like_any sn ) |\
@@ -126,6 +140,7 @@ def exec(params = {}, options = {})
126140 names . each do |name |
127141 sn = to_string_array ( name , append_wildcard : true )
128142 next @items = @items . none if sn . empty?
143+
129144 @items = @items . joins ( publication : { copyright_holders : { user : :account } } )
130145 . where {
131146 ( publication . copyright_holders . user . account . username . like_any sn ) |\
@@ -140,6 +155,7 @@ def exec(params = {}, options = {})
140155 names . each do |name |
141156 sn = to_string_array ( name , append_wildcard : true )
142157 next @items = @items . none if sn . empty?
158+
143159 @items = @items . joins ( publication : { editors : { user : :account } } )
144160 . where {
145161 ( publication . editors . user . account . username . like_any sn ) |\
@@ -154,6 +170,7 @@ def exec(params = {}, options = {})
154170 names . each do |name |
155171 sn = to_string_array ( name , append_wildcard : true )
156172 next @items = @items . none if sn . empty?
173+
157174 @items = @items . joins { publication . outer . authors . outer . user . outer . account . outer }
158175 . joins { publication . outer . copyright_holders . outer . user . outer . account . outer }
159176 . joins { publication . outer . editors . outer . user . outer . account . outer }
@@ -173,10 +190,24 @@ def exec(params = {}, options = {})
173190 }
174191 end
175192 end
193+
194+ with . keyword :published_before do |published_befores |
195+ min_published_before = published_befores . flatten . collect do |str |
196+ DateTime . parse ( str ) rescue nil
197+ end . compact . min
198+ next @items = @items . none if min_published_before . nil?
199+
200+ @items = @items . where { publication . published_at < min_published_before }
201+
202+ # Latest now refers to results that happened before min_published_before
203+ latest_scope = latest_scope . where { publication . published_at < min_published_before } \
204+ unless latest_scope . nil?
205+ end
176206 end
177207
178- return unless latest_only
179- outputs [ :items ] = outputs [ :items ] . latest
208+ return if latest_scope . nil?
209+
210+ outputs [ :items ] = outputs [ :items ] . latest ( latest_scope )
180211 outputs [ :total_count ] = outputs [ :items ] . limit ( nil ) . offset ( nil ) . reorder ( nil ) . count
181212 end
182213end
0 commit comments