myexperiment-hackers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[myexperiment-hackers] [3079] trunk: switched authorisation to use scope


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)

Revision
3079
Author
dgc
Date
2012-08-07 11:12:00 +0000 (Tue, 07 Aug 2012)

Log Message

switched authorisation to use scoped and refactored the pivot code

Modified Paths

Diff

Modified: trunk/app/controllers/application_controller.rb (3078 => 3079)


--- 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

Modified: trunk/app/controllers/blobs_controller.rb (3078 => 3079)


--- 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'
 

Modified: trunk/app/controllers/content_controller.rb (3078 => 3079)


--- 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

Modified: trunk/app/controllers/packs_controller.rb (3078 => 3079)


--- 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'
 

Modified: trunk/app/controllers/search_controller.rb (3078 => 3079)


--- 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

Modified: trunk/app/controllers/services_controller.rb (3078 => 3079)


--- 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'
 

Modified: trunk/app/controllers/workflows_controller.rb (3078 => 3079)


--- 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
   

Modified: trunk/app/models/contribution.rb (3078 => 3079)


--- 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

Modified: trunk/app/views/content/_index.rhtml (3078 => 3079)


--- 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>

Modified: trunk/app/views/layouts/_paginate.rhtml (3078 => 3079)


--- 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>
 

Modified: trunk/config/default_settings.yml (3078 => 3079)


--- 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"]
+

Modified: trunk/lib/authorization.rb (3078 => 3079)


--- 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
 

Modified: trunk/lib/conf.rb (3078 => 3079)


--- 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)

reply via email to

[Prev in Thread] Current Thread [Next in Thread]