|
From: | noreply |
Subject: | [myexperiment-hackers] [3079] trunk: switched authorisation to use scoped and refactored the pivot code |
Date: | Tue, 7 Aug 2012 11:12:00 +0000 (UTC) |
switched authorisation to use scoped and refactored the pivot code
--- trunk/app/controllers/application_controller.rb 2012-08-07 09:26:10 UTC (rev 3078)
+++ trunk/app/controllers/application_controller.rb 2012-08-07 11:12:00 UTC (rev 3079)
@@ -408,200 +408,26 @@
end
# Pivot code
-
- def pivot_options
- {
- :order =>
- [
- {
- :option => 'rank',
- :label => 'Rank',
- :order => 'contributions.rank DESC'
- },
-
- {
- :option => 'title',
- :label => 'Title',
- :order => 'contributions.label, contributions.rank DESC'
- },
- {
- :option => 'latest',
- :label => 'Latest',
- :order => 'contributions.created_at DESC, contributions.rank DESC'
- },
+ def calculate_pivot(opts = {})
- {
- :option => 'last_updated',
- :label => 'Last updated',
- :order => 'contributions.updated_at DESC, contributions.rank DESC'
- },
+ begin
+ expr = parse_filter_expression(opts[:params]["filter"], opts[:pivot_options], :active_filters => opts[:active_filters])
+ rescue Exception => ex
+ problem = "Problem with query _expression_: #{ex}"
+ end
- {
- :option => 'member',
- :label => 'User',
- :joins => [ :users ],
- :order => 'users.name, contributions.rank DESC'
- },
+ pivot = contributions_list(opts[:params], opts[:user], opts[:pivot_options],
+ :model => opts[:model],
+ :active_filters => opts[:active_filters],
+ :lock_filter => opts[:locked_filters],
+ :search_models => opts[:search_models],
+ :search_limit => opts[:search_limit],
+ :filters => expr)
- {
- :option => 'rating',
- :label => 'Community rating',
- :order => 'contributions.rating DESC, contributions.rank DESC'
- },
-
- {
- :option => 'viewings',
- :label => 'Most viewed',
- :order => 'contributions.site_viewings_count DESC, contributions.rank DESC'
- },
-
- {
- :option => 'downloads',
- :label => 'Most downloaded',
- :order => 'contributions.site_downloads_count DESC, contributions.rank DESC'
- },
-
- {
- :option => 'type',
- :label => 'Type',
- :joins => [ :content_types ],
- :order => 'content_types.title, contributions.rank DESC'
- },
-
- {
- :option => 'licence',
- :label => 'Licence',
- :joins => [ :licences ],
- :order => 'licenses.title, contributions.rank DESC'
- },
-
- {
- :option => 'topic',
- :label => 'Topic',
- :joins => [ :topic_workflow_map ],
- :order => 'topic_workflow_map.probability, rank DESC'
- }
- ],
-
- :num_options => ['10', '20', '25', '50', '100'],
-
- :filters =>
- [
- {
- :title => 'category',
- :query_option => 'CATEGORY',
- :id_column => :auth_type,
- :label_column => :auth_type,
- :visible_name => true
- },
-
- {
- :title => 'type',
- :query_option => 'TYPE_ID',
- :id_column => 'content_types.id',
- :label_column => 'content_types.title',
- :joins => [ :content_types ],
- :not_null => true
- },
-
- {
- :title => 'tag',
- :query_option => 'TAG_ID',
- :id_column => 'tags.id',
- :label_column => 'tags.name',
- :joins => [ :taggings, :tags ]
- },
-
- {
- :title => 'user',
- :query_option => 'USER_ID',
- :id_column => 'users.id',
- :label_column => 'users.name',
- :joins => [ :users ]
- },
-
- {
- :title => 'licence',
- :query_option => 'LICENSE_ID',
- :id_column => 'licenses.id',
- :label_column => 'licenses.unique_name',
- :joins => [ :licences ],
- :not_null => true
- },
-
- {
- :title => 'group',
- :query_option => 'GROUP_ID',
- :id_column => 'networks.id',
- :label_column => 'networks.title',
- :joins => [ :networks ]
- },
-
- {
- :title => 'wsdl',
- :query_option => 'WSDL_ENDPOINT',
- :id_column => 'workflow_processors.wsdl',
- :label_column => 'workflow_processors.wsdl',
- :joins => [ :workflow_processors ],
- :not_null => true
- },
-
- {
- :title => 'curation',
- :query_option => 'CURATION_EVENT',
- :id_column => 'curation_events.category',
- :label_column => 'curation_events.category',
- :joins => [ :curation_events ],
- :capitalize => true
- },
-
- {
- :title => 'provider',
- :query_option => 'SERVICE_PROVIDER',
- :id_column => 'service_providers.id',
- :label_column => 'service_providers.name',
- :joins => [ :services, :service_providers ]
- },
-
- {
- :title => 'country',
- :query_option => 'SERVICE_COUNTRY',
- :id_column => 'services.country',
- :label_column => 'services.country',
- :joins => [ :services ]
- },
-
- {
- :title => 'service status',
- :query_option => 'SERVICE_STATUS',
- :id_column => 'services.monitor_label',
- :label_column => 'services.monitor_label',
- :joins => [ :services ]
- },
-
-
- ],
-
- :joins =>
- {
- :content_types => "LEFT OUTER JOIN content_types ON contributions.content_type_id = content_types.id",
- :licences => "LEFT OUTER JOIN licenses ON contributions.license_id = licenses.id",
- :users => "INNER JOIN users ON contributions.contributor_type = 'User' AND contributions.contributor_id = users.id",
- :taggings => "LEFT OUTER JOIN taggings ON AUTH_TYPE = taggings.taggable_type AND AUTH_ID = taggings.taggable_id",
- :tags => "INNER JOIN tags ON taggings.tag_id = tags.id",
- :networks => "INNER JOIN networks ON permissions.contributor_type = 'Network' AND permissions.contributor_id = networks.id",
- :credits => "INNER JOIN creditations ON creditations.creditable_type = AUTH_TYPE AND creditations.creditable_id = AUTH_ID",
- :curation_events => "INNER JOIN curation_events ON curation_events.object_type = AUTH_TYPE AND curation_events.object_id = AUTH_ID",
- :workflow_processors => "INNER JOIN workflow_processors ON AUTH_TYPE = 'Workflow' AND workflow_processors.workflow_id = AUTH_ID",
- :search => "RIGHT OUTER JOIN search_results ON search_results.result_type = AUTH_TYPE AND search_results.result_id = AUTH_ID",
- :topic_workflow_map => "INNER JOIN topic_workflow_map ON contributions.id = topic_workflow_map.workflow_id",
- :services => "INNER JOIN services ON AUTH_TYPE = 'Service' AND AUTH_ID = services.id",
- :service_providers => "INNER JOIN service_providers ON AUTH_TYPE = 'Service' AND service_providers.uri = services.provider_uri",
- }
- }
+ [pivot, problem]
end
-
+
TOKEN_UNKNOWN = 0x0000
TOKEN_AND = 0x0001
TOKEN_OR = 0x0002
@@ -620,12 +446,14 @@
STATE_EXPECT_END = 0x0400
STATE_COMPLETE = 0x0500
- def parse_filter_expression(expr)
+ def parse_filter_expression(expr, pivot_options, opts = {})
def unescape_string(str)
str.match(/^"(.*)"$/)[1].gsub(/\\"/, '"')
end
+ return nil if expr.nil?
+
state = STATE_INITIAL
data = ""
@@ -674,7 +502,8 @@
# validate and reduce expressions to current capabilities
- valid_filters = pivot_options[:filters].map do |f| f[:query_option] end
+ valid_filters = pivot_options["filters"].map do |f| f["query_option"] end
+ valid_filters = valid_filters.select do |f| opts[:active_filters].include?(f) end
data.each do |category|
case category
@@ -714,22 +543,22 @@
data
end
- def contributions_list(klass = nil, params = nil, user = nil, opts = {})
+ def contributions_list(params = nil, user = nil, pivot_options = nil, opts = {})
def escape_sql(str)
str.gsub(/\\/, '\&\&').gsub(/'/, "''")
end
- def build_url(params, opts, expr, parts, extra = {})
+ def build_url(params, opts, expr, parts, pivot_options, extra = {})
query = {}
if parts.include?(:filter)
bits = []
- pivot_options[:filters].each do |filter|
- if !opts[:lock_filter] || opts[:lock_filter][filter[:query_option]].nil?
- if find_filter(expr, filter[:query_option])
- bits << filter[:query_option] + "(\"" + find_filter(expr, filter[:query_option])[:expr][:terms].map do |t| t.gsub(/"/, '\"') end.join("\" OR \"") + "\")"
+ pivot_options["filters"].each do |filter|
+ if !opts[:lock_filter] || opts[:lock_filter][filter["query_option"]].nil?
+ if find_filter(expr, filter["query_option"])
+ bits << filter["query_option"] + "(\"" + find_filter(expr, filter["query_option"])[:expr][:terms].map do |t| t.gsub(/"/, '\"') end.join("\" OR \"") + "\")"
end
end
end
@@ -756,18 +585,18 @@
end
end
- def create_search_results_table(search_query, models)
+ def create_search_results_table(search_query, opts)
begin
- solr_results = models.first.multi_solr_search(search_query,
- :models => models,
- :results_format => :ids,
- :limit => Conf.max_search_size)
+ solr_results = opts[:search_models].first.multi_solr_search(search_query,
+ :models => opts[:search_models],
+ :limit => opts[:search_limit],
+ :results_format => :ids)
rescue
return false
end
- conn = ActiveRecord::Base.connection
+ conn = ActiveRecord::Base.connection
conn.execute("CREATE TEMPORARY TABLE search_results (id INT AUTO_INCREMENT UNIQUE KEY, result_type VARCHAR(255), result_id INT)")
@@ -793,14 +622,14 @@
ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS search_results")
end
- def calculate_having_clause(filter, opts)
+ def calculate_having_clause(filter, pivot_options, opts)
having_bits = []
- pivot_options[:filters].each do |f|
+ pivot_options["filters"].each do |f|
if f != filter
-# if opts[:filters][f[:query_option]] && opts[:filters]["and_#{f[:query_option]}"] == "yes"
-# having_bits << "(GROUP_CONCAT(DISTINCT #{f[:id_column]} ORDER BY #{f[:id_column]}) = '#{escape_sql(opts[:filters][f[:query_option]])}')"
+# if opts[:filters][f["query_option"]] && opts[:filters]["and_#{f["query_option"]}"] == "yes"
+# having_bits << "(GROUP_CONCAT(DISTINCT #{f["id_column"]} ORDER BY #{f["id_column"]}) = '#{escape_sql(opts[:filters][f["query_option"]])}')"
# end
end
end
@@ -822,27 +651,27 @@
end
end
- def calculate_filter(params, filter, user, opts = {})
+ def calculate_filter(collection, params, filter, pivot_options, user, opts = {})
# apply all the joins and conditions except for the current filter
joins = []
conditions = []
- pivot_options[:filters].each do |other_filter|
- if filter_list = find_filter(opts[:filters], other_filter[:query_option])
+ pivot_options["filters"].each do |other_filter|
+ if filter_list = find_filter(opts[:filters], other_filter["query_option"])
unless opts[:inhibit_other_conditions]
- conditions << comparison(column(other_filter[:id_column], opts), filter_list[:expr][:terms]) unless other_filter == filter
+ conditions << comparison(column(other_filter["id_column"], opts), filter_list[:expr][:terms]) unless other_filter == filter
end
- joins += other_filter[:joins] if other_filter[:joins]
+ joins += other_filter["joins"] if other_filter["joins"]
end
end
- filter_id_column = column(filter[:id_column], opts)
- filter_label_column = column(filter[:label_column], opts)
+ filter_id_column = column(filter["id_column"], opts)
+ filter_label_column = column(filter["label_column"], opts)
- joins += filter[:joins] if filter[:joins]
- conditions << "#{filter_id_column} IS NOT NULL" if filter[:not_null]
+ joins += filter["joins"] if filter["joins"]
+ conditions << "#{filter_id_column} IS NOT NULL" if filter["not_null"]
unless opts[:inhibit_filter_query]
if params[:filter_query]
@@ -850,10 +679,8 @@
end
end
- joins.push(:search) if params[:query] && !opts[:arbitrary_models]
+ current = find_filter(opts[:filters], filter["query_option"]) ? find_filter(opts[:filters], filter["query_option"])[:expr][:terms] : []
- current = find_filter(opts[:filters], filter[:query_option]) ? find_filter(opts[:filters], filter[:query_option])[:expr][:terms] : []
-
if opts[:ids].nil?
limit = 10
else
@@ -869,19 +696,14 @@
count_expr = "COUNT(DISTINCT contributions.contributable_type, contributions.contributable_id)"
end
- objects = Authorization.authorised_index(params[:query] && opts[:arbitrary_models] ? SearchResult : Contribution,
+ objects = collection.find(
:all,
- :include_permissions => true,
:select => "#{filter_id_column} AS filter_id, #{filter_label_column} AS filter_label, #{count_expr} AS filter_count",
- :arbitrary_models => opts[:arbitrary_models],
- :auth_type => opts[:auth_type],
- :auth_id => opts[:auth_id],
- :joins => merge_joins(joins, :auth_type => opts[:auth_type], :auth_id => opts[:auth_id]),
+ :joins => merge_joins(joins, pivot_options, :auth_type => opts[:auth_type], :auth_id => opts[:auth_id]),
:conditions => conditions,
- :group => "#{filter_id_column} #{calculate_having_clause(filter, opts)}",
+ :group => "#{filter_id_column} #{calculate_having_clause(filter, pivot_options, opts)}",
:limit => limit,
- :order => "#{count_expr} DESC, #{filter_label_column}",
- :authorised_user => user)
+ :order => "#{count_expr} DESC, #{filter_label_column}")
objects = objects.select do |x| !x[:filter_id].nil? end
@@ -891,15 +713,15 @@
selected = current.include?(value)
label_expr = deep_clone(opts[:filters])
- label_expr -= [find_filter(label_expr, filter[:query_option])] if find_filter(label_expr, filter[:query_option])
+ label_expr -= [find_filter(label_expr, filter["query_option"])] if find_filter(label_expr, filter["query_option"])
unless selected && current.length == 1
- label_expr << { :name => filter[:query_option], :expr => { :terms => [value] } }
+ label_expr << { :name => filter["query_option"], :expr => { :terms => [value] } }
end
checkbox_expr = deep_clone(opts[:filters])
- if expr_filter = find_filter(checkbox_expr, filter[:query_option])
+ if expr_filter = find_filter(checkbox_expr, filter["query_option"])
if selected
expr_filter[:expr][:terms] -= [value]
@@ -910,16 +732,16 @@
checkbox_expr -= [expr_filter] if expr_filter[:expr][:terms].empty?
else
- checkbox_expr << { :name => filter[:query_option], :expr => { :terms => [value] } }
+ checkbox_expr << { :name => filter["query_option"], :expr => { :terms => [value] } }
end
- label_uri = build_url(params, opts, label_expr, [:filter, :order], "page" => nil)
+ label_uri = build_url(params, opts, label_expr, [:filter, :order], pivot_options, "page" => nil)
- checkbox_uri = build_url(params, opts, checkbox_expr, [:filter, :order], "page" => nil)
+ checkbox_uri = build_url(params, opts, checkbox_expr, [:filter, :order], pivot_options, "page" => nil)
label = object.filter_label.clone
- label = visible_name(label) if filter[:visible_name]
- label = label.capitalize if filter[:capitalize]
+ label = visible_name(label) if filter["visible_name"]
+ label = label.capitalize if filter["capitalize"]
plain_label = object.filter_label
@@ -942,18 +764,18 @@
[current, objects]
end
- def calculate_filters(params, opts, user)
+ def calculate_filters(collection, params, opts, pivot_options, user)
# produce the filter list
- filters = pivot_options[:filters].clone
+ filters = pivot_options["filters"].clone
cancel_filter_query_url = nil
filters.each do |filter|
# calculate the top n items of the list
- filter[:current], filter[:objects] = calculate_filter(params, filter, user, opts)
+ filter[:current], filter[:objects] = calculate_filter(collection, params, filter, pivot_options, user, opts)
# calculate which active filters are missing (because they weren't in the
# top part of the list or have a count of zero)
@@ -961,7 +783,7 @@
missing_filter_ids = filter[:current] - filter[:objects].map do |ob| ob[:value] end
if missing_filter_ids.length > 0
- filter[:objects] += calculate_filter(params, filter, user, opts.merge(:ids => missing_filter_ids))[1]
+ filter[:objects] += calculate_filter(collection, params, filter, pivot_options, user, opts.merge(:ids => missing_filter_ids))[1]
end
# calculate which active filters are still missing (because they have a
@@ -970,7 +792,7 @@
missing_filter_ids = filter[:current] - filter[:objects].map do |ob| ob[:value] end
if missing_filter_ids.length > 0
- zero_list = calculate_filter(params, filter, user, opts.merge(:ids => missing_filter_ids, :inhibit_other_conditions => true))[1]
+ zero_list = calculate_filter(collection, params, filter, pivot_options, user, opts.merge(:ids => missing_filter_ids, :inhibit_other_conditions => true))[1]
zero_list.each do |x| x[:count] = 0 end
@@ -989,23 +811,23 @@
end
end
- def merge_joins(joins, opts = {})
-
- opts[:auth_type] ||= 'contributions.contributable_type'
- opts[:auth_id] ||= 'contributions.contributable_id'
-
+ def merge_joins(joins, pivot_options, opts = {})
if joins.length.zero?
nil
else
joins.uniq.map do |j|
- text = pivot_options[:joins][j]
- text.gsub!(/AUTH_TYPE/, opts[:auth_type])
- text.gsub!(/AUTH_ID/, opts[:auth_id])
+ text = pivot_options["joins"][j].clone
+ text.gsub!(/RESULT_TYPE/, opts[:auth_type])
+ text.gsub!(/RESULT_ID/, opts[:auth_id])
text
end.join(" ")
end
end
+ pivot_options["filters"] = pivot_options["filters"].select do |f|
+ opts[:active_filters].include?(f["query_option"])
+ end
+
joins = []
conditions = []
@@ -1032,52 +854,50 @@
# perform search if requested
- group_by = "contributions.contributable_type, contributions.contributable_id"
-
query_problem = false
if params["query"]
drop_search_results_table
- if create_search_results_table(params["query"], [Workflow, Blob, Pack, User, Network, Service])
- joins.push(:search) unless opts[:arbitrary_models]
- else
+ if !create_search_results_table(params["query"], opts)
params["query"] = nil
query_problem = true
end
end
- if opts[:arbitrary_models] && params[:query]
- klass = SearchResult
- contribution_records = false
+ if params[:query]
+ klass = SearchResult
auth_type = "search_results.result_type"
auth_id = "search_results.result_id"
group_by = "search_results.result_type, search_results.result_id"
else
- contribution_records = true
+ klass = opts[:model] || Contribution
+ auth_type = opts[:auth_type] || "contributions.contributable_type"
+ auth_id = opts[:auth_id] || "contributions.contributable_id"
+ group_by = opts[:group_by] || "contributions.contributable_type, contributions.contributable_id"
end
# determine joins, conditions and order for the main results
- pivot_options[:filters].each do |filter|
- if filter_list = find_filter(opts[:filters], filter[:query_option])
- conditions << comparison(column(filter[:id_column], opts.merge( { :auth_type => auth_type, :auth_id => auth_id } )), filter_list[:expr][:terms])
- joins += filter[:joins] if filter[:joins]
+ pivot_options["filters"].each do |filter|
+ if filter_list = find_filter(opts[:filters], filter["query_option"])
+ conditions << comparison(column(filter["id_column"], opts.merge( { :auth_type => auth_type, :auth_id => auth_id } )), filter_list[:expr][:terms])
+ joins += filter["joins"] if filter["joins"]
end
end
- order_options = pivot_options[:order].find do |x|
- x[:option] == params[:order]
+ order_options = pivot_options["order"].find do |x|
+ x["option"] == params[:order]
end
- order_options ||= pivot_options[:order].first
+ order_options ||= pivot_options["order"].first
- joins += order_options[:joins] if order_options[:joins]
+ joins += order_options["joins"] if order_options["joins"]
having_bits = []
-# pivot_options[:filters].each do |filter|
-# if params["and_#{filter[:query_option]}"]
-# having_bits << "GROUP_CONCAT(DISTINCT #{filter[:id_column]} ORDER BY #{filter[:id_column]}) = \"#{escape_sql(opts[:filters][filter[:query_option]])}\""
+# pivot_options["filters"].each do |filter|
+# if params["and_#{filter["query_option"]}"]
+# having_bits << "GROUP_CONCAT(DISTINCT #{filter["id_column"]} ORDER BY #{filter["id_column"]}) = \"#{escape_sql(opts[:filters][filter["query_option"]])}\""
# end
# end
@@ -1089,28 +909,28 @@
# perform the results query
- results = Authorization.authorised_index(klass,
- :all,
+ collection = Authorization.scoped(klass,
:authorised_user => user,
:include_permissions => true,
- :contribution_records => contribution_records,
- :arbitrary_models => opts[:arbitrary_models],
:auth_type => auth_type,
- :auth_id => auth_id,
+ :auth_id => auth_id)
+
+ results = collection.find(
+ :all,
:page => { :size => params["num"] ? params["num"].to_i : nil, :current => params["page"] },
- :joins => merge_joins(joins, :auth_type => auth_type, :auth_id => auth_id),
+ :joins => merge_joins(joins, pivot_options, :auth_type => auth_type, :auth_id => auth_id),
:conditions => conditions.length.zero? ? nil : conditions.join(" AND "),
:group => "#{group_by} #{having_clause}",
- :order => order_options[:order])
-
+ :order => order_options["order"])
+
# produce a query hash to match the current filters
opts[:filter_params] = {}
- pivot_options[:filters].each do |filter|
- if params[filter[:query_option]]
- next if opts[:lock_filter] && opts[:lock_filter][filter[:query_option]]
- opts[:filter_params][filter[:query_option]] = params[filter[:query_option]]
+ pivot_options["filters"].each do |filter|
+ if params[filter["query_option"]]
+ next if opts[:lock_filter] && opts[:lock_filter][filter["query_option"]]
+ opts[:filter_params][filter["query_option"]] = params[filter["query_option"]]
end
end
@@ -1119,13 +939,13 @@
opts_for_filter_query = opts.merge( { :auth_type => auth_type,
:auth_id => auth_id, :group_by => group_by } )
- filters, cancel_filter_query_url = calculate_filters(params, opts_for_filter_query, user)
+ filters, cancel_filter_query_url = calculate_filters(collection, params, opts_for_filter_query, pivot_options, user)
# produce the summary. If a filter query is specified, then we need to
# recalculate the filters without the query to get all of them.
if params[:filter_query]
- filters2 = calculate_filters(params, opts_for_filter_query.merge( { :inhibit_filter_query => true } ), user)[0]
+ filters2 = calculate_filters(collection, params, opts_for_filter_query.merge( { :inhibit_filter_query => true } ), pivot_options, user)[0]
else
filters2 = filters
end
@@ -1134,7 +954,7 @@
filters2.select do |filter|
- next if opts[:lock_filter] && opts[:lock_filter][filter[:query_option]]
+ next if opts[:lock_filter] && opts[:lock_filter][filter["query_option"]]
selected = filter[:objects].select do |x| x[:selected] end
current = selected.map do |x| x[:value] end
@@ -1144,29 +964,29 @@
expr = deep_clone(opts[:filters])
- f = find_filter(expr, filter[:query_option])
+ f = find_filter(expr, filter["query_option"])
expr -= f[:expr][:terms] -= [x[:value]]
expr -= [f] if f[:expr][:terms].empty?
x[:plain_label] + ' <a href="" + url_for(build_url(params, opts, expr,
- [:filter, :filter_query, :order])) +
+ [:filter, :filter_query, :order], pivot_options)) +
'">' + " <img src='' /></a>"
end
bits = selected_labels.map do |label| label end.join(" <i>or</i> ")
- summary << '<span class="filter-in-use"><b>' + filter[:title].capitalize + "</b>: " + bits + "</span> "
+ summary << '<span class="filter-in-use"><b>' + filter["title"].capitalize + "</b>: " + bits + "</span> "
end
end
if params[:filter_query]
- cancel_filter_query_url = build_url(params, opts, opts[:filters], [:filter, :order])
+ cancel_filter_query_url = build_url(params, opts, opts[:filters], [:filter, :order], pivot_options)
end
if include_reset_url
- reset_filters_url = build_url(params, opts, opts[:filters], [:order])
+ reset_filters_url = build_url(params, opts, opts[:filters], [:order], pivot_options)
end
# remove filters that do not help in narrowing down the result set
@@ -1174,7 +994,7 @@
filters = filters.select do |filter|
if filter[:objects].empty?
false
- elsif opts[:lock_filter] && opts[:lock_filter][filter[:query_option]]
+ elsif opts[:lock_filter] && opts[:lock_filter][filter["query_option"]]
false
else
true
@@ -1186,8 +1006,9 @@
:filters => filters,
:reset_filters_url => reset_filters_url,
:cancel_filter_query_url => cancel_filter_query_url,
- :filter_query_url => build_url(params, opts, opts[:filters], [:filter]),
+ :filter_query_url => build_url(params, opts, opts[:filters], [:filter], pivot_options),
:summary => summary,
+ :pivot_options => pivot_options,
:query_problem => query_problem
}
end
--- trunk/app/controllers/blobs_controller.rb 2012-08-07 09:26:10 UTC (rev 3078)
+++ trunk/app/controllers/blobs_controller.rb 2012-08-07 11:12:00 UTC (rev 3079)
@@ -67,20 +67,24 @@
def index
respond_to do |format|
format.html {
- @pivot_options = pivot_options
- begin
- expr = parse_filter_expression(params["filter"]) if params["filter"]
- rescue Exception => ex
- puts "ex = #{ex.inspect}"
- flash.now[:error] = "Problem with query _expression_: #{ex}"
- expr = nil
- end
+ @pivot, problem = calculate_pivot(
- @pivot = contributions_list(Contribution, params, current_user,
- :lock_filter => { 'CATEGORY' => 'Blob' },
- :filters => expr)
+ :pivot_options => Conf.pivot_options,
+ :params => params,
+ :user => current_user,
+ :search_models => [Blob],
+ :search_limit => Conf.max_search_size,
+ :locked_filters => { 'CATEGORY' => 'Blob' },
+
+ :active_filters => ["CATEGORY", "TYPE_ID", "TAG_ID", "USER_ID",
+ "LICENSE_ID", "GROUP_ID", "WSDL_ENDPOINT",
+ "CURATION_EVENT", "SERVICE_PROVIDER",
+ "SERVICE_COUNTRY", "SERVICE_STATUS"])
+
+ flash.now[:error] = problem if problem
+
@query = params[:query]
@query_type = 'files'
--- trunk/app/controllers/content_controller.rb 2012-08-07 09:26:10 UTC (rev 3078)
+++ trunk/app/controllers/content_controller.rb 2012-08-07 11:12:00 UTC (rev 3079)
@@ -10,19 +10,22 @@
def index
respond_to do |format|
format.html do
- @pivot_options = pivot_options
- begin
- expr = parse_filter_expression(params["filter"]) if params["filter"]
- rescue Exception => ex
- puts "ex = #{ex.inspect}"
- flash.now[:error] = "Problem with query _expression_: #{ex}"
- expr = nil
- end
+ @pivot, problem = calculate_pivot(
- @pivot = contributions_list(Contribution, params, current_user,
- :filters => expr, :arbitrary_models => true)
+ :pivot_options => Conf.pivot_options,
+ :params => params,
+ :user => current_user,
+ :search_models => [Workflow, Blob, Pack, Service],
+ :search_limit => Conf.max_search_size,
+ :active_filters => ["CATEGORY", "TYPE_ID", "TAG_ID", "USER_ID",
+ "LICENSE_ID", "GROUP_ID", "WSDL_ENDPOINT",
+ "CURATION_EVENT", "SERVICE_PROVIDER",
+ "SERVICE_COUNTRY", "SERVICE_STATUS"])
+
+ flash.now[:error] = problem if problem
+
@query = params[:query]
# index.rhtml
--- trunk/app/controllers/packs_controller.rb 2012-08-07 09:26:10 UTC (rev 3078)
+++ trunk/app/controllers/packs_controller.rb 2012-08-07 11:12:00 UTC (rev 3079)
@@ -29,20 +29,24 @@
def index
respond_to do |format|
format.html {
- @pivot_options = pivot_options
- begin
- expr = parse_filter_expression(params["filter"]) if params["filter"]
- rescue Exception => ex
- puts "ex = #{ex.inspect}"
- flash.now[:error] = "Problem with query _expression_: #{ex}"
- expr = nil
- end
+ @pivot, problem = calculate_pivot(
- @pivot = contributions_list(Contribution, params, current_user,
- :lock_filter => { 'CATEGORY' => 'Pack' },
- :filters => expr)
+ :pivot_options => Conf.pivot_options,
+ :params => params,
+ :user => current_user,
+ :search_models => [Pack],
+ :search_limit => Conf.max_search_size,
+ :locked_filters => { 'CATEGORY' => 'Pack' },
+
+ :active_filters => ["CATEGORY", "TYPE_ID", "TAG_ID", "USER_ID",
+ "LICENSE_ID", "GROUP_ID", "WSDL_ENDPOINT",
+ "CURATION_EVENT", "SERVICE_PROVIDER",
+ "SERVICE_COUNTRY", "SERVICE_STATUS"])
+
+ flash.now[:error] = problem if problem
+
@query = params[:query]
@query_type = 'packs'
--- trunk/app/controllers/search_controller.rb 2012-08-07 09:26:10 UTC (rev 3078)
+++ trunk/app/controllers/search_controller.rb 2012-08-07 11:12:00 UTC (rev 3079)
@@ -186,19 +186,20 @@
@query = params[:query]
- @pivot_options = pivot_options
+ @pivot, problem = calculate_pivot(
- begin
- expr = parse_filter_expression(params["filter"]) if params["filter"]
- rescue Exception => ex
- puts "ex = #{ex.inspect}"
- flash.now[:error] = "Problem with query _expression_: #{ex}"
- expr = nil
- end
+ :pivot_options => Conf.pivot_options,
+ :params => params,
+ :user => current_user,
+ :search_models => [Workflow, Blob, Pack, User, Network, Service],
+ :search_limit => Conf.max_search_size,
- @pivot = contributions_list(Contribution, params, current_user,
- :filters => expr, :arbitrary_models => true)
+ :active_filters => ["CATEGORY", "TYPE_ID", "TAG_ID", "USER_ID",
+ "LICENSE_ID", "GROUP_ID", "WSDL_ENDPOINT",
+ "CURATION_EVENT", "SERVICE_PROVIDER",
+ "SERVICE_COUNTRY", "SERVICE_STATUS"])
+ flash.now[:error] = problem if problem
end
def search_model
--- trunk/app/controllers/services_controller.rb 2012-08-07 09:26:10 UTC (rev 3078)
+++ trunk/app/controllers/services_controller.rb 2012-08-07 11:12:00 UTC (rev 3079)
@@ -27,20 +27,24 @@
def index
respond_to do |format|
format.html {
- @pivot_options = pivot_options
- begin
- expr = parse_filter_expression(params["filter"]) if params["filter"]
- rescue Exception => ex
- puts "ex = #{ex.inspect}"
- flash.now[:error] = "Problem with query _expression_: #{ex}"
- expr = nil
- end
+ @pivot, problem = calculate_pivot(
- @pivot = contributions_list(Contribution, params, current_user,
- :lock_filter => { 'CATEGORY' => 'Service' },
- :filters => expr)
+ :pivot_options => Conf.pivot_options,
+ :params => params,
+ :user => current_user,
+ :search_models => [Service],
+ :search_limit => Conf.max_search_size,
+ :locked_filters => { 'CATEGORY' => 'Service' },
+
+ :active_filters => ["CATEGORY", "TYPE_ID", "TAG_ID", "USER_ID",
+ "LICENSE_ID", "GROUP_ID", "WSDL_ENDPOINT",
+ "CURATION_EVENT", "SERVICE_PROVIDER",
+ "SERVICE_COUNTRY", "SERVICE_STATUS"])
+
+ flash.now[:error] = problem if problem
+
@query = params[:query]
@query_type = 'services'
--- trunk/app/controllers/workflows_controller.rb 2012-08-07 09:26:10 UTC (rev 3078)
+++ trunk/app/controllers/workflows_controller.rb 2012-08-07 11:12:00 UTC (rev 3079)
@@ -199,20 +199,24 @@
def index
respond_to do |format|
format.html do
- @pivot_options = pivot_options
- begin
- expr = parse_filter_expression(params["filter"]) if params["filter"]
- rescue Exception => ex
- puts "ex = #{ex.inspect}"
- flash.now[:error] = "Problem with query _expression_: #{ex}"
- expr = nil
- end
+ @pivot, problem = calculate_pivot(
- @pivot = contributions_list(Contribution, params, current_user,
- :lock_filter => { 'CATEGORY' => 'Workflow' },
- :filters => expr)
+ :pivot_options => Conf.pivot_options,
+ :params => params,
+ :user => current_user,
+ :search_models => [Workflow],
+ :search_limit => Conf.max_search_size,
+ :locked_filters => { 'CATEGORY' => 'Workflow' },
+
+ :active_filters => ["CATEGORY", "TYPE_ID", "TAG_ID", "USER_ID",
+ "LICENSE_ID", "GROUP_ID", "WSDL_ENDPOINT",
+ "CURATION_EVENT", "SERVICE_PROVIDER",
+ "SERVICE_COUNTRY", "SERVICE_STATUS"])
+
+ flash.now[:error] = problem if problem
+
@query = params[:query]
@query_type = 'workflows'
@@ -687,7 +691,7 @@
def find_workflows_rss
# Only carry out if request is for RSS
if params[:format] and params[:format].downcase == 'rss'
- @rss_workflows = Authorization.authorised_index(Workflow, :all, :limit => 30, :order => 'updated_at DESC', :authorised_user => current_user)
+ @rss_workflows = Authorization.scoped(Workflow, :authorised_user => current_user).find(:all, :limit => 30, :order => 'updated_at DESC')
end
end
--- trunk/app/models/contribution.rb 2012-08-07 09:26:10 UTC (rev 3078)
+++ trunk/app/models/contribution.rb 2012-08-07 11:12:00 UTC (rev 3079)
@@ -47,13 +47,15 @@
# returns the 'most recent' Contributions
# the maximum number of results is set by #limit#
def self.most_recent(limit = 10, klass = 'Contribution')
- Authorization.authorised_index(Object.const_get(klass), :all, :contribution_records => true, :limit => limit, :order => 'created_at DESC')
+ conditions = ['contributions.contributable_type = ?', klass] if klass != 'Contribution'
+ Authorization.scoped(Contribution).find(:all, :conditions => conditions, :limit => limit, :order => 'created_at DESC')
end
# returns the 'last updated' Contributions
# the maximum number of results is set by #limit#
def self.last_updated(limit = 10, klass = 'Contribution')
- Authorization.authorised_index(Object.const_get(klass), :all, :contribution_records => true, :limit => limit, :order => 'updated_at DESC')
+ conditions = ['contributions.contributable_type = ?', klass] if klass != 'Contribution'
+ Authorization.scoped(Contribution).find(:all, :conditions => conditions, :limit => limit, :order => 'updated_at DESC')
end
# returns the 'most favourited' Contributions
--- trunk/app/views/content/_index.rhtml 2012-08-07 09:26:10 UTC (rev 3078)
+++ trunk/app/views/content/_index.rhtml 2012-08-07 11:12:00 UTC (rev 3079)
@@ -24,7 +24,7 @@
<% if @pivot[:cancel_filter_query_url] %>
<div class="category"><%= filter[:title].capitalize -%> results</div>
<% else %>
- <div class="category">Filter by <%= filter[:title] -%></div>
+ <div class="category">Filter by <%= filter["title"] -%></div>
<% end %>
<div id="<%= query_name -%>" style="display: <%= @pivot[:cancel_filter_query_url] ? "block" : "none" -%>">
</div>
@@ -53,9 +53,9 @@
<div class="sort">
Sort by:
<select = this.options[this.selectedIndex].value;">
- <% @pivot_options[:order].each do |args| %>
- <option value="<%= url_for(request.query_parameters.merge("order" => args[:option])) -%>"
- <% if params[:order] == args[:option] -%> selected="selected"<% end -%>><%= args[:label] -%></option>
+ <% @pivot[:pivot_options]["order"].each do |args| %>
+ <option value="<%= url_for(request.query_parameters.merge("order" => args["option"])) -%>"
+ <% if params[:order] == args["option"] -%> selected="selected"<% end -%>><%= args["label"] -%></option>
<% end %>
</select>
</div>
@@ -114,7 +114,7 @@
</div>
<% end %>
<div>
- <%= render :partial => "layouts/paginate", :locals => { :collection => @pivot[:results], :sort_by => @pivot_options[:order], :num_options => @pivot_options[:num_options] } %>
+ <%= render :partial => "layouts/paginate", :locals => { :collection => @pivot[:results], :sort_by => @pivot[:pivot_options]["order"], :num_options => @pivot[:pivot_options]["num_options"] } %>
</div>
</div>
</div>
--- trunk/app/views/layouts/_paginate.rhtml 2012-08-07 09:26:10 UTC (rev 3078)
+++ trunk/app/views/layouts/_paginate.rhtml 2012-08-07 11:12:00 UTC (rev 3079)
@@ -3,7 +3,7 @@
Sort by:
<select = this.options[this.selectedIndex].value;">
<% sort_by.each do |args| %>
- <option value="<%= url_for(request.query_parameters.merge("order" => args[:option])) -%>" <% if params[:order] == args[:option] -%> selected="selected"<% end -%>><%= args[:label] -%></option>
+ <option value="<%= url_for(request.query_parameters.merge("order" => args["option"])) -%>" <% if params[:order] == args["option"] -%> selected="selected"<% end -%>><%= args["label"] -%></option>
<% end %>
</select>
--- trunk/config/default_settings.yml 2012-08-07 09:26:10 UTC (rev 3078)
+++ trunk/config/default_settings.yml 2012-08-07 11:12:00 UTC (rev 3079)
@@ -525,3 +525,147 @@
email:
- "[0-9]{2,address@hidden"
+# pivot_options - These control the joins, ordering and filtering of the pivot
+# views.
+
+pivot_options:
+
+ joins:
+
+ workflow_processors: INNER JOIN workflow_processors ON RESULT_TYPE = 'Workflow' AND workflow_processors.workflow_id = RESULT_ID
+ taggings: LEFT OUTER JOIN taggings ON RESULT_TYPE = taggings.taggable_type AND RESULT_ID = taggings.taggable_id
+ services: INNER JOIN services ON RESULT_TYPE = 'Service' AND RESULT_ID = services.id
+ curation_events: INNER JOIN curation_events ON curation_events.object_type = RESULT_TYPE AND curation_events.object_id = RESULT_ID
+ service_providers: INNER JOIN service_providers ON RESULT_TYPE = 'Service' AND service_providers.uri = services.provider_uri
+ tags: INNER JOIN tags ON taggings.tag_id = tags.id
+ content_types: LEFT OUTER JOIN content_types ON contributions.content_type_id = content_types.id
+ credits: INNER JOIN creditations ON creditations.creditable_type = RESULT_TYPE AND creditations.creditable_id = RESULT_ID
+ networks: INNER JOIN networks ON permissions.contributor_type = 'Network' AND permissions.contributor_id = networks.id
+ topic_workflow_map: INNER JOIN topic_workflow_map ON contributions.id = topic_workflow_map.workflow_id
+ users: INNER JOIN users ON contributions.contributor_type = 'User' AND contributions.contributor_id = users.id
+ licences: LEFT OUTER JOIN licenses ON contributions.license_id = licenses.id
+
+ order:
+
+ - option: rank
+ order: contributions.rank DESC
+ label: Rank
+
+ - option: title
+ order: contributions.label, contributions.rank DESC
+ label: Title
+
+ - option: latest
+ order: contributions.created_at DESC, contributions.rank DESC
+ label: Latest
+
+ - option: last_updated
+ order: contributions.updated_at DESC, contributions.rank DESC
+ label: Last updated
+
+ - option: member
+ joins: [users]
+ order: users.name, contributions.rank DESC
+ label: User
+
+ - option: rating
+ order: contributions.rating DESC, contributions.rank DESC
+ label: Community rating
+
+ - option: viewings
+ order: contributions.site_viewings_count DESC, contributions.rank DESC
+ label: Most viewed
+
+ - option: downloads
+ order: contributions.site_downloads_count DESC, contributions.rank DESC
+ label: Most downloaded
+
+ - option: type
+ joins: [content_types]
+ order: content_types.title, contributions.rank DESC
+ label: Type
+
+ - option: licence
+ joins: [licences]
+ order: licenses.title, contributions.rank DESC
+ label: Licence
+
+ - option: topic
+ joins: [topic_workflow_map]
+ order: topic_workflow_map.probability, rank DESC
+ label: Topic
+
+ filters:
+
+ - query_option: CATEGORY
+ title: category
+ id_column: :auth_type
+ label_column: :auth_type
+ visible_name: true
+
+ - query_option: TYPE_ID
+ title: type
+ id_column: content_types.id
+ label_column: content_types.title
+ joins: [content_types]
+ not_null: true
+
+ - query_option: TAG_ID
+ title: tag
+ id_column: tags.id
+ label_column: tags.name
+ joins: [taggings, tags]
+
+ - query_option: USER_ID
+ title: user
+ id_column: users.id
+ label_column: users.name
+ joins: [users]
+
+ - query_option: LICENSE_ID
+ title: licence
+ id_column: licenses.id
+ label_column: licenses.unique_name
+ joins: [licences]
+ not_null: true
+
+ - query_option: GROUP_ID
+ title: group
+ id_column: networks.id
+ label_column: networks.title
+ joins: [networks]
+
+ - query_option: WSDL_ENDPOINT
+ title: wsdl
+ id_column: workflow_processors.wsdl
+ label_column: workflow_processors.wsdl
+ joins: [workflow_processors]
+ not_null: true
+
+ - query_option: CURATION_EVENT
+ title: curation
+ id_column: curation_events.category
+ label_column: curation_events.category
+ joins: [curation_events]
+ capitalize: true
+
+ - query_option: SERVICE_PROVIDER
+ title: provider
+ id_column: service_providers.id
+ label_column: service_providers.name
+ joins: [services, service_providers]
+
+ - query_option: SERVICE_COUNTRY
+ title: country
+ id_column: services.country
+ label_column: services.country
+ joins: [services]
+
+ - query_option: SERVICE_STATUS
+ title: service status
+ id_column: services.monitor_label
+ label_column: services.monitor_label
+ joins: [services]
+
+ num_options: ["10", "20", "25", "50", "100"]
+
--- trunk/lib/authorization.rb 2012-08-07 09:26:10 UTC (rev 3078)
+++ trunk/lib/authorization.rb 2012-08-07 11:12:00 UTC (rev 3079)
@@ -894,9 +894,9 @@
end
end
- def self.authorised_index(model, *args)
+ def self.scoped(model, opts = {})
- def self.view_conditions(user_id = nil, friends = nil, networks = nil)
+ def self.view_conditions(user_id, friends, networks)
return "((contributions.id IS NULL) OR (share_mode = 0 OR share_mode = 1 OR share_mode = 2))" if user_id.nil?
@@ -909,7 +909,7 @@
"((contributions.id IS NULL) OR (#{policy_part} OR #{permission_part(['view', 'download', 'edit'], user_id, networks)}))"
end
- def self.download_conditions(user_id = nil, friends = nil, networks = nil)
+ def self.download_conditions(user_id, friends, networks)
return "((contributions.id IS NULL) OR (share_mode = 0))" if user_id.nil?
@@ -922,7 +922,7 @@
"((contributions.id IS NULL) OR (#{policy_part} OR #{permission_part(['download', 'edit'], user_id, networks)}))"
end
- def self.edit_conditions(user_id = nil, friends = nil, networks = nil)
+ def self.edit_conditions(user_id, friends, networks)
return "((contributions.id IS NULL) OR (share_mode = 0 AND update_mode = 0))" if user_id.nil?
@@ -944,15 +944,8 @@
(permissions.contributor_type = 'Network' AND permissions.contributor_id IN #{networks})))"
end
- # extract the opts hash
-
- opts = args.last.class == Hash ? args.pop.clone : {}
-
user = opts.delete(:authorised_user)
- joins = []
- conditions = []
-
if (user != 0) && (user != nil)
user_id = user.id
@@ -966,71 +959,44 @@
networks = network_ids.empty? ? "(-1)" : "(#{network_ids.join(",")})"
end
- # filtering
+ # By default, the objects to authorize are the actual objects that the
+ # association returns. However you can specify an alternate type/id if
+ # this is different.
+ #
+ # For example, the association might return Taggings but Tagging objects do
+ # not support authorization in themselves but by association with the
+ # taggable association.
+ #
+ # In thie case, :auth_type would be "taggings.taggable_type" and :auth_id
+ # authorize would be "taggings.taggable_id".
auth_id = opts.delete(:auth_id) || "#{model.table_name}.id"
auth_type = opts.delete(:auth_type) || "'#{model.name}'"
- conditions.push(view_conditions(user_id, friends, networks))
- conditions.push("contributions.contributable_type = #{auth_type}") if !opts.delete(:arbitrary_models) && model != Contribution
+ # Joins
- # result model
+ joins = []
- if opts.delete(:contribution_records)
- model = Contribution
- end
-
- if model != Contribution
- joins.push("LEFT OUTER JOIN contributions ON contributions.contributable_id = #{auth_id} AND contributions.contributable_type = #{auth_type}")
- end
-
- # selection
-
- opts[:select] = "#{model.table_name}.*" unless opts[:select]
-
- # add in the extra joins needed for the authorisation checks
-
+ joins.push("LEFT OUTER JOIN contributions ON contributions.contributable_id = #{auth_id} AND contributions.contributable_type = #{auth_type}") if model != Contribution
joins.push("LEFT OUTER JOIN policies ON contributions.policy_id = policies.id")
- joins.push("LEFT OUTER JOIN permissions ON policies.id = permissions.policy_id") if user_id || opts[:include_permissions]
+ joins.push("LEFT OUTER JOIN permissions ON policies.id = permissions.policy_id")
- # include the effective permissions in the result?
+ # Include the effective permissions in the result?
if opts.delete(:include_permissions)
+ opts[:select] = "#{model.table_name}.*"
+
opts[:select] << ", BIT_OR(#{view_conditions(user_id, friends, networks)}) AS view_permission"
opts[:select] << ", BIT_OR(#{download_conditions(user_id, friends, networks)}) AS download_permission"
opts[:select] << ", BIT_OR(#{edit_conditions(user_id, friends, networks)}) AS edit_permission"
end
- # merge the joins
-
- if joins.length > 0
- opts[:joins] = [] unless opts[:joins]
- opts[:joins] = [opts[:joins]] unless opts[:joins].class == Array
- opts[:joins] = joins + opts[:joins]
- opts[:joins] = opts[:joins].join(" ") # Rails 1 does not support arrays here
- end
-
- # merge the conditions
-
- if conditions.length > 0
-
- conditions = conditions.map do |c| "(#{c})" end
-
- case opts[:conditions].class.name
- when "Array"; opts[:conditions][0] = "(#{([opts[:conditions][0]] + conditions).join(') AND (')})"
- when "String"; opts[:conditions] = "(#{([opts[:conditions]] + conditions).join(') AND (')})"
- else; opts[:conditions] = "(#{conditions.join(') AND (')})"
- end
- end
-
- # default to grouping by contributable type and id
-
+ opts[:conditions] = view_conditions(user_id, friends, networks)
opts[:group] ||= 'contributions.contributable_type, contributions.contributable_id'
+ opts[:joins] = joins
- # do it
-
- model.find(*args + [opts])
+ model.scoped(opts)
end
end
--- trunk/lib/conf.rb 2012-08-07 09:26:10 UTC (rev 3078)
+++ trunk/lib/conf.rb 2012-08-07 11:12:00 UTC (rev 3079)
@@ -198,6 +198,10 @@
self.fetch_entry('site_integrations',{})
end
+ def self.pivot_options
+ self.fetch_entry('pivot_options', {})
+ end
+
# This method is required to create an administrator in the test fixtures
def self.admins=(value)
[Prev in Thread] | Current Thread | [Next in Thread] |