Commit 4b01e9daf93043a619c73a863b445b4ba4adb104
Exists in
master
and in
28 other branches
Merge remote-tracking branch 'danielbucher/sub_organizations_improvements' into …
…sub_organizations_improvements
Showing
27 changed files
with
822 additions
and
35 deletions
Show diff stats
app/models/person.rb
@@ -43,7 +43,12 @@ class Person < Profile | @@ -43,7 +43,12 @@ class Person < Profile | ||
43 | alias_method_chain :has_permission?, :plugins | 43 | alias_method_chain :has_permission?, :plugins |
44 | 44 | ||
45 | def memberships | 45 | def memberships |
46 | - Profile.memberships_of(self) | 46 | + scopes = [] |
47 | + plugins_scopes = plugins.dispatch_scopes(:person_memberships, self) | ||
48 | + scopes = plugins_scopes unless plugins_scopes.first.blank? | ||
49 | + scopes << Profile.memberships_of(self) | ||
50 | + return scopes.first if scopes.size == 1 | ||
51 | + ScopeTool.union *scopes | ||
47 | end | 52 | end |
48 | 53 | ||
49 | def memberships_by_role(role) | 54 | def memberships_by_role(role) |
app/models/profile.rb
@@ -84,7 +84,8 @@ class Profile < ActiveRecord::Base | @@ -84,7 +84,8 @@ class Profile < ActiveRecord::Base | ||
84 | def members | 84 | def members |
85 | scopes = plugins.dispatch_scopes(:organization_members, self) | 85 | scopes = plugins.dispatch_scopes(:organization_members, self) |
86 | scopes << Person.members_of(self) | 86 | scopes << Person.members_of(self) |
87 | - scopes.size == 1 ? scopes.first : Person.or_scope(scopes) | 87 | + return scopes.first if scopes.size == 1 |
88 | + ScopeTool.union *scopes | ||
88 | end | 89 | end |
89 | 90 | ||
90 | def members_count | 91 | def members_count |
features/step_definitions/sub_organizations_block_steps.rb
0 → 100644
@@ -0,0 +1,6 @@ | @@ -0,0 +1,6 @@ | ||
1 | +Given /^"([^\"]*)" is a sub organization of "([^\"]*)"$/ do |child, parent| | ||
2 | + child = Organization.find_by_name(child) || Organization[child] | ||
3 | + parent = Organization.find_by_name(parent) || Organization[parent] | ||
4 | + | ||
5 | + SubOrganizationsPlugin::Relation.add_children(parent, child) | ||
6 | +end |
features/support/paths.rb
@@ -114,6 +114,13 @@ module NavigationHelpers | @@ -114,6 +114,13 @@ module NavigationHelpers | ||
114 | when /^(.+)'s members page/ | 114 | when /^(.+)'s members page/ |
115 | '/profile/%s/members' % profile_identifier($1) | 115 | '/profile/%s/members' % profile_identifier($1) |
116 | 116 | ||
117 | + when /^(.+)'s "(.+)" page from "(.*)" of "(.*)" plugin/ | ||
118 | + profile = $1 | ||
119 | + action = $2 | ||
120 | + plugin_name = $4.underscore | ||
121 | + controller_type = $3.constantize.superclass.to_s.underscore.gsub(/_controller/, "") | ||
122 | + "/#{controller_type}/#{profile}/plugin/#{plugin_name}/#{action}" | ||
123 | + | ||
117 | else | 124 | else |
118 | begin | 125 | begin |
119 | page_name =~ /the (.*) page/ | 126 | page_name =~ /the (.*) page/ |
lib/noosfero/plugin.rb
@@ -372,6 +372,13 @@ class Noosfero::Plugin | @@ -372,6 +372,13 @@ class Noosfero::Plugin | ||
372 | nil | 372 | nil |
373 | end | 373 | end |
374 | 374 | ||
375 | + # -> Extends person memberships list | ||
376 | + # returns = An instance of ActiveRecord::NamedScope::Scope retrived through | ||
377 | + # Person.memberships_of method. | ||
378 | + def person_memberships(person) | ||
379 | + nil | ||
380 | + end | ||
381 | + | ||
375 | # -> Extends person permission access | 382 | # -> Extends person permission access |
376 | # returns = boolean | 383 | # returns = boolean |
377 | def has_permission?(person, permission, target) | 384 | def has_permission?(person, permission, target) |
@@ -0,0 +1,15 @@ | @@ -0,0 +1,15 @@ | ||
1 | +module ScopeTool | ||
2 | + | ||
3 | + # Sum scope results by SQL, allowing post filtering of the group. | ||
4 | + def union(*scopes) | ||
5 | + model = scopes.first.class_name.constantize | ||
6 | + scopes = scopes.map &:to_sql | ||
7 | + model.from "(\n#{scopes.join("\nUNION\n")}\n) as #{model.table_name}" | ||
8 | + end | ||
9 | + | ||
10 | + class << self | ||
11 | + # Allows to use `ScopeTool.method()` anywhere. | ||
12 | + include ScopeTool | ||
13 | + end | ||
14 | + | ||
15 | +end |
plugins/sub_organizations/controllers/sub_organizations_plugin_profile_controller.rb
0 → 100644
@@ -0,0 +1,45 @@ | @@ -0,0 +1,45 @@ | ||
1 | +class SubOrganizationsPluginProfileController < ProfileController | ||
2 | + append_view_path File.join(File.dirname(__FILE__) + '/../views') | ||
3 | + | ||
4 | + before_filter :organizations_only | ||
5 | + | ||
6 | + def children | ||
7 | + children = SubOrganizationsPlugin::Relation.children(profile) | ||
8 | + family_relation(children) | ||
9 | + render 'related_organizations' | ||
10 | + end | ||
11 | + | ||
12 | + def parents | ||
13 | + parents = SubOrganizationsPlugin::Relation.parents(profile) | ||
14 | + family_relation(parents) | ||
15 | + render 'related_organizations' | ||
16 | + end | ||
17 | + | ||
18 | + private | ||
19 | + | ||
20 | + def family_relation(_profile) | ||
21 | + @communities = _profile.communities | ||
22 | + @enterprises = _profile.enterprises | ||
23 | + @full = true | ||
24 | + | ||
25 | + if !params[:type] and !params[:display] | ||
26 | + @communities = SubOrganizationsPlugin.limit(@communities) | ||
27 | + @enterprises = SubOrganizationsPlugin.limit(@enterprises) | ||
28 | + @full = false | ||
29 | + elsif !params[:type] | ||
30 | + @total = _profile | ||
31 | + @total = @total.paginate(:per_page => 2, :page => params[:npage]) | ||
32 | + if params[:display] == 'compact' | ||
33 | + @full = false | ||
34 | + end | ||
35 | + else | ||
36 | + @communities = @communities.paginate(:per_page => 2, :page => params[:npage]) | ||
37 | + @enterprises = @enterprises.paginate(:per_page => 2, :page => params[:npage]) | ||
38 | + end | ||
39 | + end | ||
40 | + | ||
41 | + def organizations_only | ||
42 | + render_not_found if !profile.organization? | ||
43 | + end | ||
44 | + | ||
45 | +end |
plugins/sub_organizations/features/sub_organizations_block.feature
0 → 100644
@@ -0,0 +1,62 @@ | @@ -0,0 +1,62 @@ | ||
1 | +Feature: related_organizations_block | ||
2 | + As a user | ||
3 | + I want my organizations to have blocks that lists it's related-organizations | ||
4 | + In order to have quick access to it's related-organizations | ||
5 | + | ||
6 | + Background: | ||
7 | + Given "SubOrganizations" plugin is enabled | ||
8 | + And the following users | ||
9 | + | login | name | | ||
10 | + | homer | Homer | | ||
11 | + And the following community | ||
12 | + | identifier | name | owner | | ||
13 | + | springfield | Springfield | homer | | ||
14 | + | moe | Moe's | homer | | ||
15 | + And the following enterprise | ||
16 | + | identifier | name | owner | | ||
17 | + | duff | Duff | homer | | ||
18 | + And "moe" is a sub organization of "springfield" | ||
19 | + And "duff" is a sub organization of "springfield" | ||
20 | + And I am logged in as "homer" | ||
21 | + And I go to springfield's control panel | ||
22 | + | ||
23 | + Scenario: display sub organizations block add option | ||
24 | + When I follow "Edit sideboxes" | ||
25 | + And I follow "Add a block" | ||
26 | + Then I should see "Related Organizations" | ||
27 | + | ||
28 | + Scenario: display both sub types on block | ||
29 | + When I follow "Edit sideboxes" | ||
30 | + And I follow "Add a block" | ||
31 | + And I choose "Related Organizations" | ||
32 | + And I press "Add" | ||
33 | + Then I should see "Moe's" within ".related-organizations-block" | ||
34 | + And I should see "Duff" within ".related-organizations-block" | ||
35 | + | ||
36 | + Scenario: display only sub-communities | ||
37 | + Given the following blocks | ||
38 | + | owner | type | | ||
39 | + | springfield | RelatedOrganizationsBlock | | ||
40 | + When I follow "Edit sideboxes" | ||
41 | + And I follow "Edit" within ".related-organizations-block" | ||
42 | + And I select "Community" from "block_organization_type" | ||
43 | + And I press "Save" | ||
44 | + Then I should see "Moe's" within ".related-organizations-block" | ||
45 | + And I should not see "Duff" within ".related-organizations-block" | ||
46 | + | ||
47 | + Scenario: display both sub types on sub-organizations page | ||
48 | + When I go to springfield's "children" page from "SubOrganizationsPluginProfileController" of "SubOrganizations" plugin | ||
49 | + Then I should see "Moe's" | ||
50 | + And I should see "Duff" | ||
51 | + | ||
52 | + Scenario: display only sub-communities on sub-organizations page | ||
53 | + Given the following blocks | ||
54 | + | owner | type | | ||
55 | + | springfield | RelatedOrganizationsBlock | | ||
56 | + When I follow "Edit sideboxes" | ||
57 | + And I follow "Edit" within ".related-organizations-block" | ||
58 | + And I select "Community" from "block_organization_type" | ||
59 | + And I press "Save" | ||
60 | + And I follow "View all" within ".related-organizations-block" | ||
61 | + Then I should see "Moe's" within ".profile-list" | ||
62 | + And I should not see "Duff" within ".profile-list" |
plugins/sub_organizations/features/sub_organizations_display.feature
0 → 100644
@@ -0,0 +1,80 @@ | @@ -0,0 +1,80 @@ | ||
1 | +Feature: sub_organizations_display | ||
2 | + As a user | ||
3 | + I want my organizations to have blocks that lists it's related-organizations | ||
4 | + In order to have quick access to it's related-organizations | ||
5 | + | ||
6 | + Background: | ||
7 | + Given "SubOrganizations" plugin is enabled | ||
8 | + And the following users | ||
9 | + | login | name | | ||
10 | + | nelson | Nelson | | ||
11 | + And feature "enterprise_registration" is enabled on environment | ||
12 | + And the following community | ||
13 | + | identifier | name | owner | description | city | state | | ||
14 | + | springfield | Springfield | nelson | Springfield description | Los Angeles | California | | ||
15 | + | moe | Moe | nelson | Moe description | Kansas | Texas | | ||
16 | + And the following enterprise | ||
17 | + | identifier | name | owner | description | city | state | | ||
18 | + | school | School | nelson | School description | Terra do Nunca | Billy Jean | | ||
19 | + And I am logged in as "nelson" | ||
20 | + And I go to springfield's control panel | ||
21 | + When I follow "Edit sideboxes" | ||
22 | + And I follow "Add a block" | ||
23 | + And I choose "Related Organizations" | ||
24 | + And I press "Add" | ||
25 | + | ||
26 | + @selenium | ||
27 | + Scenario: Display the sub organization block when there is a sub enterprise and communitys | ||
28 | + When I go to springfield's control panel | ||
29 | + And I follow "Manage sub-groups" | ||
30 | + And I follow "Register a new sub-enterprise" | ||
31 | + And I fill in "Name" with "Bart" | ||
32 | + And I press "Next" | ||
33 | + Then I should see "Enterprise registration completed" | ||
34 | + And I am logged in as admin | ||
35 | + And I go to admin_user's control panel | ||
36 | + When I follow "Tasks" within ".control-panel" | ||
37 | + Then I should see "Nelson wants to create enterprise Bart." | ||
38 | + And the first mail is to admin_user@example.com | ||
39 | + And I choose "Accept" | ||
40 | + And I press "Apply!" | ||
41 | + And I am logged in as "nelson" | ||
42 | + When I go to springfield's control panel | ||
43 | + And I follow "Manage sub-groups" | ||
44 | + And I follow "Create a new sub-community" | ||
45 | + And I fill in "Name" with "Homer" | ||
46 | + And I press "Create" | ||
47 | + When I go to springfield's "children" page from "SubOrganizationsPluginProfileController" of "SubOrganizations" plugin | ||
48 | + Then I should see "Homer" within ".related-organizations-block" | ||
49 | + And I should see "Bart" within ".related-organizations-block" | ||
50 | + | ||
51 | + Scenario: Display with compact mode | ||
52 | + Given "moe" is a sub organization of "springfield" | ||
53 | + And "school" is a sub organization of "springfield" | ||
54 | + When I go to springfield's homepage | ||
55 | + And I follow "View all" within ".related-organizations-block" | ||
56 | + Then I should see "Springfield's sub-communities" | ||
57 | + And I should see "Springfield's sub-enterprises" | ||
58 | + | ||
59 | + Scenario: Display with full mode for sub-communities | ||
60 | + Given "moe" is a sub organization of "springfield" | ||
61 | + When I go to springfield's homepage | ||
62 | + And I follow "View all" within ".related-organizations-block" | ||
63 | + Then I should see "Springfield's sub-communities" | ||
64 | + And I follow "Full" within ".search-customize-options" | ||
65 | + Then I should see "Moe description" within ".related-organizations-description" | ||
66 | + And I should see "Kansas, Texas" within ".related-organizations-region-name" | ||
67 | + | ||
68 | + Scenario: Display with full mode for sub-enterprises | ||
69 | + Given "school" is a sub organization of "springfield" | ||
70 | + When I go to springfield's homepage | ||
71 | + And I follow "View all" within ".related-organizations-block" | ||
72 | + And I should see "Springfield's sub-enterprises" | ||
73 | + And I follow "Full" within ".search-customize-options" | ||
74 | + Then I should see "School description" within ".related-organizations-description" | ||
75 | + And I should see "Terra do Nunca, Billy Jean" within ".related-organizations-region-name" | ||
76 | + | ||
77 | + Scenario: Display message when display full block are empty | ||
78 | + Given I follow "View all" within ".related-organizations-block" | ||
79 | + Then I should see "There are no sub-communities yet." | ||
80 | + And I should see "There are no sub-enterprises yet." |
plugins/sub_organizations/lib/related_organizations_block.rb
0 → 100644
@@ -0,0 +1,60 @@ | @@ -0,0 +1,60 @@ | ||
1 | +class RelatedOrganizationsBlock < ProfileListBlock | ||
2 | + | ||
3 | + settings_items :organization_type, :type => :string, :default => 'both' | ||
4 | + | ||
5 | + @display_type = {:title => 'related', :action => 'children' } | ||
6 | + | ||
7 | + def self.description | ||
8 | + __("#{@display_type[:title].capitalize} Organizations") | ||
9 | + end | ||
10 | + | ||
11 | + def default_title | ||
12 | + case organization_type | ||
13 | + when 'enterprise' | ||
14 | + n__("{#} #{@display_type[:title]} enterprise", "{#} #{@display_type[:title]} enterprises", profile_count) | ||
15 | + when 'community' | ||
16 | + n__("{#} #{@display_type[:title]} community", "{#} #{@display_type[:title]} communities", profile_count) | ||
17 | + else | ||
18 | + n__("{#} #{@display_type[:title]} organization", "{#} #{@display_type[:title]} organizations", profile_count) | ||
19 | + end | ||
20 | + end | ||
21 | + | ||
22 | + def help | ||
23 | + _("This block displays #{@display_type[:title]} organizations of this organization") | ||
24 | + end | ||
25 | + | ||
26 | + def profiles | ||
27 | + organizations = related_organizations | ||
28 | + case organization_type | ||
29 | + when 'enterprise' | ||
30 | + organizations.enterprises | ||
31 | + when 'community' | ||
32 | + organizations.communities | ||
33 | + else | ||
34 | + organizations | ||
35 | + end | ||
36 | + end | ||
37 | + | ||
38 | + def footer | ||
39 | + profile = self.owner | ||
40 | + type = self.organization_type | ||
41 | + params = {:profile => profile.identifier, :controller => 'sub_organizations_plugin_profile', :action => @display_type[:action]} | ||
42 | + params[:type] = type if type == 'enterprise' || type == 'community' | ||
43 | + lambda do | ||
44 | + link_to _('View all'), params.merge(params) | ||
45 | + end | ||
46 | + end | ||
47 | + | ||
48 | + def related_organizations | ||
49 | + profile = self.owner | ||
50 | + organizations = SubOrganizationsPlugin::Relation.parents(profile) | ||
51 | + | ||
52 | + if organizations.blank? | ||
53 | + @display_type = {:title => 'sub', :action => 'children'} | ||
54 | + organizations = SubOrganizationsPlugin::Relation.children(profile) | ||
55 | + else | ||
56 | + @display_type = {:title => 'parent', :action => 'parents' } | ||
57 | + organizations | ||
58 | + end | ||
59 | + end | ||
60 | +end |
plugins/sub_organizations/lib/sub_organizations_plugin.rb
1 | +require_dependency File.dirname(__FILE__) + '/related_organizations_block' | ||
2 | + | ||
3 | +class SubOrganizationsPlugin < Noosfero::Plugin; end; | ||
4 | + | ||
5 | +require_dependency 'sub_organizations_plugin/search_helper' | ||
6 | + | ||
1 | class SubOrganizationsPlugin < Noosfero::Plugin | 7 | class SubOrganizationsPlugin < Noosfero::Plugin |
2 | 8 | ||
9 | + include SearchHelper | ||
10 | + | ||
11 | + DISPLAY_LIMIT = 12 | ||
12 | + | ||
3 | def self.plugin_name | 13 | def self.plugin_name |
4 | _("Sub-groups") | 14 | _("Sub-groups") |
5 | end | 15 | end |
@@ -23,6 +33,10 @@ class SubOrganizationsPlugin < Noosfero::Plugin | @@ -23,6 +33,10 @@ class SubOrganizationsPlugin < Noosfero::Plugin | ||
23 | Person.members_of(children) if children.present? | 33 | Person.members_of(children) if children.present? |
24 | end | 34 | end |
25 | 35 | ||
36 | + def person_memberships(person) | ||
37 | + SubOrganizationsPlugin::Relation.parents(*Profile.memberships_of(person)) | ||
38 | + end | ||
39 | + | ||
26 | def has_permission?(person, permission, target) | 40 | def has_permission?(person, permission, target) |
27 | if !target.kind_of?(Environment) && target.organization? | 41 | if !target.kind_of?(Environment) && target.organization? |
28 | SubOrganizationsPlugin::Relation.parents(target).map do |parent| | 42 | SubOrganizationsPlugin::Relation.parents(target).map do |parent| |
@@ -40,4 +54,14 @@ class SubOrganizationsPlugin < Noosfero::Plugin | @@ -40,4 +54,14 @@ class SubOrganizationsPlugin < Noosfero::Plugin | ||
40 | parent_to_be = context.params[:sub_organizations_plugin_parent_to_be] | 54 | parent_to_be = context.params[:sub_organizations_plugin_parent_to_be] |
41 | {'sub_organizations_plugin_parent_to_be' => parent_to_be} if parent_to_be.present? | 55 | {'sub_organizations_plugin_parent_to_be' => parent_to_be} if parent_to_be.present? |
42 | end | 56 | end |
57 | + | ||
58 | + def self.limit(organizations) | ||
59 | + organizations.all(:limit => DISPLAY_LIMIT, :order => 'updated_at DESC').sort_by{ rand } | ||
60 | + end | ||
61 | + | ||
62 | + def self.extra_blocks | ||
63 | + { | ||
64 | + RelatedOrganizationsBlock => {:type => [Enterprise, Community], :position => ['1', '2', '3']} | ||
65 | + } | ||
66 | + end | ||
43 | end | 67 | end |
plugins/sub_organizations/lib/sub_organizations_plugin/relation.rb
@@ -33,11 +33,11 @@ class SubOrganizationsPlugin::Relation < Noosfero::Plugin::ActiveRecord | @@ -33,11 +33,11 @@ class SubOrganizationsPlugin::Relation < Noosfero::Plugin::ActiveRecord | ||
33 | ActiveRecord::NamedScope::Scope.new(Organization, options) | 33 | ActiveRecord::NamedScope::Scope.new(Organization, options) |
34 | end | 34 | end |
35 | 35 | ||
36 | - def parents(child) | 36 | + def parents(*children) |
37 | options = { | 37 | options = { |
38 | :select => "profiles.*", | 38 | :select => "profiles.*", |
39 | :joins => "inner join sub_organizations_plugin_relations as relations on profiles.id=relations.parent_id", | 39 | :joins => "inner join sub_organizations_plugin_relations as relations on profiles.id=relations.parent_id", |
40 | - :conditions => ["relations.child_id = ?", child.id] | 40 | + :conditions => ["relations.child_id in (?)", children.map(&:id)] |
41 | } | 41 | } |
42 | ActiveRecord::NamedScope::Scope.new(Organization, options) | 42 | ActiveRecord::NamedScope::Scope.new(Organization, options) |
43 | end | 43 | end |
plugins/sub_organizations/lib/sub_organizations_plugin/relation_helper.rb
0 → 100644
@@ -0,0 +1,9 @@ | @@ -0,0 +1,9 @@ | ||
1 | +module SubOrganizationsPlugin::RelationHelper | ||
2 | + def display_relation(organization,type,display_mode) | ||
3 | + if display_mode == 'full' | ||
4 | + render :partial => 'sub_organizations_plugin_profile/full_related_organizations', :locals => {:organizations => organization,:organization_type => type} | ||
5 | + else | ||
6 | + render :partial => 'sub_organizations_plugin_profile/related_organizations', :locals => {:organizations => organization, :organization_type => type} | ||
7 | + end | ||
8 | + end | ||
9 | +end | ||
0 | \ No newline at end of file | 10 | \ No newline at end of file |
plugins/sub_organizations/lib/sub_organizations_plugin/search_helper.rb
0 → 100644
@@ -0,0 +1,18 @@ | @@ -0,0 +1,18 @@ | ||
1 | +require_dependency 'search_helper' | ||
2 | + | ||
3 | +module SubOrganizationsPlugin::SearchHelper | ||
4 | + | ||
5 | + include SearchHelper | ||
6 | + | ||
7 | + def display_selectors(display, float = 'right') | ||
8 | + display = 'compact' if display.blank? | ||
9 | + compact_link = display == 'compact' ? _('Compact') : link_to(_('Compact'), params.merge(:display => 'compact')) | ||
10 | + full_link = display == 'full' ? _('Full') : link_to(_('Full'), params.merge(:display => 'full')) | ||
11 | + content_tag('div', | ||
12 | + content_tag('strong', _('Display')) + ': ' + [compact_link,full_link].compact.join(' | ').html_safe, | ||
13 | + :class => 'search-customize-options' | ||
14 | + ) | ||
15 | + end | ||
16 | + | ||
17 | + | ||
18 | +end |
plugins/sub_organizations/public/images/arrow-right-p.png
0 → 120000
plugins/sub_organizations/public/style.css
1 | #content .token-input-list { | 1 | #content .token-input-list { |
2 | margin-bottom: 30px; | 2 | margin-bottom: 30px; |
3 | } | 3 | } |
4 | + | ||
5 | +.related-organizations-button-bar { | ||
6 | + padding-top: 40px; | ||
7 | + clear: both; | ||
8 | +} | ||
9 | + | ||
10 | +.related-organizations-block .block-footer-content a { | ||
11 | + position: absolute; | ||
12 | + top: 2px; | ||
13 | + right: 0px; | ||
14 | + font-size: 11px; | ||
15 | + color: #000; | ||
16 | + text-decoration: none; | ||
17 | + padding-right: 15px; | ||
18 | + background: url(images/arrow-right-p.png) 100% 50% no-repeat; | ||
19 | +} | ||
20 | + | ||
21 | +.clearfix { | ||
22 | + clear: both; | ||
23 | +} | ||
24 | + | ||
25 | +.related-organizations-list-block .vcard{ | ||
26 | + margin-right: 10px; | ||
27 | + -webkit-border-radius: 0 !important; | ||
28 | + -moz-border-radius: 0!important; | ||
29 | + -o-border-radius: 0!important; | ||
30 | + border-radius: 0!important; | ||
31 | +} | ||
32 | +.related-organizations-item-column-right .search-result-title{ | ||
33 | + margin: 10px 0; | ||
34 | +} | ||
35 | + | ||
36 | +#main-content-wrapper-8 ul{ | ||
37 | + padding-left: 0; | ||
38 | +} | ||
39 | + | ||
40 | +.related-organizations-list-block ul li{ | ||
41 | + list-style: none; | ||
42 | + margin: 10px 0; | ||
43 | + border: 1px solid #ccc; | ||
44 | + /*padding: 10px 5px;*/ | ||
45 | +} | ||
46 | + | ||
47 | +.related-organizations-list-block ul li:hover{ | ||
48 | + border: 1px solid #999; | ||
49 | +} | ||
50 | + | ||
51 | +.related-organizations-list-block .profile_link{ | ||
52 | + height: auto !important; | ||
53 | + max-height: none !important; | ||
54 | + max-width: none !important; | ||
55 | + height: 150px; | ||
56 | + width: 150px; | ||
57 | +} | ||
58 | + | ||
59 | +.related-organizations-list-block .org { | ||
60 | + display: none !important; | ||
61 | +} | ||
62 | + | ||
63 | +.related-organizations-item .profile-image img{ | ||
64 | + max-height: 150px; | ||
65 | + max-width: 150px; | ||
66 | +} | ||
67 | + | ||
68 | + | ||
69 | +.menu-submenu-list>li{ | ||
70 | + border: 0!important; | ||
71 | +} | ||
72 | + | ||
73 | +.related-organizations-list-block .menu-submenu{ | ||
74 | + bottom: 147px; | ||
75 | + right: 5px; | ||
76 | +} | ||
77 | + | ||
78 | +.related-organizations-region-name{ | ||
79 | + line-height: 2em; | ||
80 | + font-weight: bold; | ||
81 | +} | ||
82 | + | ||
83 | +.related-organizations-description{ | ||
84 | + color: #333; | ||
85 | +} | ||
86 | + | ||
87 | + | ||
88 | +.related-organizations-list-block .vcard a{ | ||
89 | + padding: 0; | ||
90 | + margin: 0; | ||
91 | + border: 0; | ||
92 | +} | ||
93 | + | ||
94 | +.related-organizations-list-block .vcard img { | ||
95 | + opacity: 1; | ||
96 | + -webkit-transition: all 0.5s ease-out; | ||
97 | + -moz-transition: all 0.5s ease-out; | ||
98 | + -o-transition: all 0.5s ease-out; | ||
99 | + -ms-transition: all 0.5s ease-out; | ||
100 | + transition: all 0.5s ease-out; | ||
101 | +} | ||
102 | + | ||
103 | +.related-organizations-list-block .vcard img:hover { | ||
104 | + opacity: 0.5; | ||
105 | +} | ||
106 | + | ||
107 | +.related-organizations-item-column-right { | ||
108 | + float: right; | ||
109 | + position: relative; | ||
110 | + width: 65%; | ||
111 | +} | ||
112 | + | ||
113 | +.related-organizations-item-column-left { | ||
114 | +float: left; | ||
115 | +position: relative; | ||
116 | +width: 35%; | ||
117 | +} | ||
118 | + | ||
119 | +.related-organizations-block ul { | ||
120 | + min-width: 196px; | ||
121 | + width: 192px; | ||
122 | + margin: 0px 0px 0px -3px; | ||
123 | + padding: 0px; | ||
124 | +} |
plugins/sub_organizations/test/functional/sub_organizations_plugin_profile_controller_test.rb
0 → 100644
@@ -0,0 +1,59 @@ | @@ -0,0 +1,59 @@ | ||
1 | +require File.dirname(__FILE__) + '/../../../../test/test_helper' | ||
2 | +require File.dirname(__FILE__) + '/../../controllers/sub_organizations_plugin_profile_controller' | ||
3 | + | ||
4 | +# Re-raise errors caught by the controller. | ||
5 | +class SubOrganizationsPluginProfileController; def rescue_action(e) raise e end; end | ||
6 | + | ||
7 | +class SubOrganizationsPluginProfileControllerTest < ActionController::TestCase | ||
8 | + | ||
9 | + def setup | ||
10 | + @controller = SubOrganizationsPluginProfileController.new | ||
11 | + @request = ActionController::TestRequest.new | ||
12 | + @response = ActionController::TestResponse.new | ||
13 | + @organization = Organization.create!(:name => 'My Organization', :identifier => 'my-organization') | ||
14 | + @person = create_user('person').person | ||
15 | + @organization.add_admin(@person) | ||
16 | + login_as(@person.user.login) | ||
17 | + e = Environment.default | ||
18 | + e.enable_plugin('SubOrganizationsPlugin') | ||
19 | + e.save! | ||
20 | + @o1 = fast_create(Organization, :name => 'sample child organization 1') | ||
21 | + @o2 = fast_create(Community, :name => 'sample child community 1') | ||
22 | + @o3 = fast_create(Enterprise, :name => 'sample child enterprise 1') | ||
23 | + | ||
24 | + SubOrganizationsPlugin::Relation.add_children(@organization, @o2, @o3) | ||
25 | + end | ||
26 | + | ||
27 | + attr_accessor :person, :organization | ||
28 | + | ||
29 | + should 'display all children organizations' do | ||
30 | + get :children, :profile => @organization.identifier | ||
31 | + | ||
32 | + assert_no_match /#{@o1.name}/, @response.body | ||
33 | + assert_match /#{@o2.name}/, @response.body | ||
34 | + assert_match /#{@o3.name}/, @response.body | ||
35 | + end | ||
36 | + | ||
37 | + should 'display only communities' do | ||
38 | + get :children, :profile => @organization.identifier, :type => 'community' | ||
39 | + | ||
40 | + assert_no_match /#{@o1.name}/, @response.body | ||
41 | + assert_match /#{@o2.name}/, @response.body | ||
42 | + assert_no_match /#{@o3.name}/, @response.body | ||
43 | + end | ||
44 | + | ||
45 | + should 'display only enterprises' do | ||
46 | + get :children, :profile => @organization.identifier, :type => 'enterprise' | ||
47 | + | ||
48 | + assert_no_match /#{@o1.name}/, @response.body | ||
49 | + assert_no_match /#{@o2.name}/, @response.body | ||
50 | + assert_match /#{@o3.name}/, @response.body | ||
51 | + end | ||
52 | + | ||
53 | + should 'not respond to person profiles' do | ||
54 | + get :children, :profile => fast_create(Person, :name => 'Ze').identifier | ||
55 | + | ||
56 | + assert_response :missing | ||
57 | + end | ||
58 | + | ||
59 | +end |
plugins/sub_organizations/test/unit/related_organizations_block_test.rb
0 → 100644
@@ -0,0 +1,30 @@ | @@ -0,0 +1,30 @@ | ||
1 | +require File.dirname(__FILE__) + '/../../../../test/test_helper' | ||
2 | +require File.dirname(__FILE__) + '/../../lib/related_organizations_block' | ||
3 | + | ||
4 | +class RelatedOrganizationsBlockTest < ActiveSupport::TestCase | ||
5 | + | ||
6 | + def setup | ||
7 | + @block = RelatedOrganizationsBlock.new | ||
8 | + end | ||
9 | + | ||
10 | + attr_reader :block | ||
11 | + | ||
12 | + should 'have both as default organization_type' do | ||
13 | + assert_equal "both", block.organization_type | ||
14 | + end | ||
15 | + | ||
16 | + should 'return only children when the organization is a parent' do | ||
17 | + parent = fast_create(Organization, :name => 'I am your father', :identifier => 'i-am-your-father') | ||
18 | + child1 = fast_create(Organization, :name => 'Rebel Alliance') | ||
19 | + child2 = fast_create(Organization, :name => 'The Empire') | ||
20 | + org1 = fast_create(Organization, :name => 'Jedi Council') | ||
21 | + box = fast_create(Box, :owner_id => parent.id, :owner_type => 'Organization') | ||
22 | + @block.box = box | ||
23 | + @block.save! | ||
24 | + SubOrganizationsPlugin::Relation.add_children(parent, child1, child2) | ||
25 | + | ||
26 | + assert @block.related_organizations.include?(child1) | ||
27 | + assert @block.related_organizations.include?(child2) | ||
28 | + assert !@block.related_organizations.include?(org1) | ||
29 | + end | ||
30 | +end |
plugins/sub_organizations/test/unit/sub_organizations_plugin_test.rb
@@ -45,6 +45,35 @@ class SubOrganizationsTest < ActiveSupport::TestCase | @@ -45,6 +45,35 @@ class SubOrganizationsTest < ActiveSupport::TestCase | ||
45 | assert org3_members.blank? | 45 | assert org3_members.blank? |
46 | end | 46 | end |
47 | 47 | ||
48 | + should 'include parent-organizations in persons memberships' do | ||
49 | + org1 = fast_create(Organization) | ||
50 | + org2 = fast_create(Organization) | ||
51 | + org3 = fast_create(Organization) | ||
52 | + person1 = fast_create(Person) | ||
53 | + person2 = fast_create(Person) | ||
54 | + org1.add_member(person2) | ||
55 | + org2.add_member(person1) | ||
56 | + SubOrganizationsPlugin::Relation.create!(:parent => org1, :child => org2) | ||
57 | + SubOrganizationsPlugin::Relation.create!(:parent => org1, :child => org3) | ||
58 | + | ||
59 | + person1_memberships = plugin.person_memberships(person1) | ||
60 | + person2_memberships = plugin.person_memberships(person2) | ||
61 | + | ||
62 | + assert_equal ActiveRecord::NamedScope::Scope, person1_memberships.class | ||
63 | + assert_includes person1_memberships, org1 | ||
64 | + assert_not_includes person1_memberships, org2 | ||
65 | + assert_not_includes person1_memberships, org3 | ||
66 | + assert person2_memberships.blank? | ||
67 | + end | ||
68 | + | ||
69 | + should 'return blank for person memberships with no organization ' do | ||
70 | + person1 = fast_create(Person) | ||
71 | + | ||
72 | + person1_memberships = plugin.person_memberships(person1) | ||
73 | + | ||
74 | + assert person1_memberships.blank? | ||
75 | + end | ||
76 | + | ||
48 | should 'grant permission that user has on parent organizations over children orgnaizations' do | 77 | should 'grant permission that user has on parent organizations over children orgnaizations' do |
49 | person = create_user('admin-user').person | 78 | person = create_user('admin-user').person |
50 | org1 = fast_create(Organization) | 79 | org1 = fast_create(Organization) |
plugins/sub_organizations/views/box_organizer/_related_organizations_block.rhtml
0 → 100644
@@ -0,0 +1,7 @@ | @@ -0,0 +1,7 @@ | ||
1 | +<div id='edit-related-organizations-block'> | ||
2 | + <label for="block_organization_type"><%= _('Type of organizations to be displayed') %></label><br/> | ||
3 | + <%= select_tag('block[organization_type]', options_for_select([[_('Both'), 'both'], [_('Community'), 'community'], [_('Enterprise'), 'enterprise']], @block.organization_type)) %> | ||
4 | + <%= labelled_form_field _('Limit of items'), text_field(:block, :limit, :size => 3) %> | ||
5 | + <%= check_box(:block, :prioritize_profiles_with_image) %> | ||
6 | + <label for="block_prioritize_profiles_with_image"><%= _('Prioritize profiles with image') %></label> | ||
7 | +</div> |
plugins/sub_organizations/views/sub_organizations_plugin_profile/_full_related_organizations.rhtml
0 → 100644
@@ -0,0 +1,63 @@ | @@ -0,0 +1,63 @@ | ||
1 | +<% extend SubOrganizationsPlugin::SearchHelper %> | ||
2 | +<div class="related-organizations-list-block"> | ||
3 | + | ||
4 | + <h1><%= __("#{profile.name}'s sub-#{organization_type.pluralize}") %></h1> | ||
5 | + <ul> | ||
6 | + <% organizations.each do |organization| %> | ||
7 | + <li class="related-organizations-item"> | ||
8 | + <div class="related-organizations-item"> | ||
9 | + <div class="related-organizations-item-column-left"> | ||
10 | + <%= profile_image_link organization, :big, 'div' %> | ||
11 | + </div> | ||
12 | + <div class="related-organizations-item-column-right"> | ||
13 | + <%= link_to_homepage(organization.name, organization.identifier, :class => "search-result-title") %> | ||
14 | + <div class="related-organizations-description"> | ||
15 | + <% if organization.description %> | ||
16 | + <% body_stripped = strip_tags(organization.description) %> | ||
17 | + <% elsif organization.home_page and organization.home_page.body %> | ||
18 | + <% body_stripped = strip_tags(organization.home_page.body) %> | ||
19 | + <% end %> | ||
20 | + <%= excerpt(body_stripped, body_stripped.first(3), 200) if body_stripped %> | ||
21 | + </div> | ||
22 | + <div class="related-organizations-region"> | ||
23 | + <span class="related-organizations-region-label"><%= _("City") %></span> | ||
24 | + <% if organization.region %> | ||
25 | + <span class="related-organizations-region-name"><%= city_with_state(organization.region) %></span> | ||
26 | + <% elsif organization.city and organization.state %> | ||
27 | + <span class="related-organizations-region-name"><%= "#{organization.city}, #{organization.state}" %></span> | ||
28 | + <% end %> | ||
29 | + </div> | ||
30 | + | ||
31 | + <div class="related-organizations-categorization"> | ||
32 | + <% organization.top_level_categorization.each do |parent, children| %> | ||
33 | + <div class="related-organizations-category-<%=parent.id%> related-organizations-category"> | ||
34 | + <span class="related-organizations-categorization-parent"><%= parent.name %></span> | ||
35 | + <span class="related-organizations-categorization-children"> | ||
36 | + <%= children.collect(&:name).join(', ') %> | ||
37 | + </span> | ||
38 | + </div> | ||
39 | + <% end %> | ||
40 | + </div> | ||
41 | + </div> | ||
42 | + | ||
43 | + <br class="clearfix" /> | ||
44 | + | ||
45 | + </div> | ||
46 | + </li> | ||
47 | + <% end %> | ||
48 | + </ul> | ||
49 | + | ||
50 | + <div id='pagination-related-organizations'> | ||
51 | + <%= pagination_links(organizations, {:param_name => 'npage', :page_links => true}) %> | ||
52 | + </div> | ||
53 | + | ||
54 | + <% button_bar(:class => "related-organizations-button-bar") do %> | ||
55 | + <%= button :back, _('Go back'), { :controller => 'profile' } %> | ||
56 | + <%= button :add, __("Add a new #{organization_type}"), :controller => 'sub_organizations_plugin_myprofile', :action => 'index' if logged_in? && user.has_permission?(:edit_profile, profile) && !environment.enabled?("disable_asset_#{organization_type.pluralize}") %> | ||
57 | + | ||
58 | + <% if !@full %> | ||
59 | + <%= button :more, _('View all'), { :controller => 'sub_organizations_plugin_profile', :action => params[:action], :type => organization_type } %> | ||
60 | + <% end %> | ||
61 | + <% end %> | ||
62 | + | ||
63 | +</div> |
plugins/sub_organizations/views/sub_organizations_plugin_profile/_related_organizations.rhtml
0 → 100644
@@ -0,0 +1,27 @@ | @@ -0,0 +1,27 @@ | ||
1 | +<% extend SubOrganizationsPlugin::ApplicationHelper %> | ||
2 | +<div class="common-profile-list-block"> | ||
3 | + <h1><%= __("#{profile.name}'s sub-#{organization_type.pluralize}") %></h1> | ||
4 | + | ||
5 | + <ul class='profile-list'> | ||
6 | + <% organizations.each do |organization| %> | ||
7 | + <%= profile_image_link(organization)%> | ||
8 | + <% end %> | ||
9 | + </ul> | ||
10 | + <% if organizations.length == 0 %> | ||
11 | + <li><%= __("There are no sub-#{organization_type.pluralize} yet. " ) %></li> | ||
12 | + <% end %> | ||
13 | + <% button_bar(:class => "related-organizations-button-bar") do %> | ||
14 | + <%= button :back, _('Go back'), { :controller => 'profile' } %> | ||
15 | + <%= button :add, __("Add a new #{organization_type}"), :controller => 'sub_organizations_plugin_myprofile', :action => 'index' if logged_in? && user.has_permission?(:edit_profile, profile) && !environment.enabled?("disable_asset_#{organization_type.pluralize}") %> | ||
16 | + | ||
17 | + <% if !@full %> | ||
18 | + <%= button :more, _('View all'), { :controller => 'sub_organizations_plugin_profile', :action => params[:action], :type => organization_type } %> | ||
19 | + <% end %> | ||
20 | + <% end %> | ||
21 | +</div> | ||
22 | +<% if @full %> | ||
23 | + <div id='pagination-profiles'> | ||
24 | + <%= pagination_links(organizations, {:param_name => 'npage', :page_links => true}) %> | ||
25 | + </div> | ||
26 | +<% end %> | ||
27 | +<!-- fim class="common-profile-list-block" --> |
plugins/sub_organizations/views/sub_organizations_plugin_profile/related_organizations.rhtml
0 → 100644
@@ -0,0 +1,21 @@ | @@ -0,0 +1,21 @@ | ||
1 | +<% extend SubOrganizationsPlugin::SearchHelper %> | ||
2 | +<% extend SubOrganizationsPlugin::RelationHelper %> | ||
3 | + | ||
4 | +<div id="search-actions"> | ||
5 | + <%= display_selectors(params[:display]) %> | ||
6 | +</div> | ||
7 | + | ||
8 | +<% if params[:type] == 'community' %> | ||
9 | + <%= display_relation(@communities,params[:type],params[:display]) %> | ||
10 | +<% end %> | ||
11 | + | ||
12 | +<% if params[:type] == 'enterprise' %> | ||
13 | + <%= display_relation(@enterprises,params[:type],params[:display]) %> | ||
14 | +<% end %> | ||
15 | + | ||
16 | +<% if ["full"].include?(params[:display]) and !params[:type] %> | ||
17 | + <%= display_relation(@total,"organizations",params[:display]) %> | ||
18 | +<% elsif !params[:type] %> | ||
19 | + <%= display_relation(@communities,"community",params[:display]) %> | ||
20 | + <%= display_relation(@enterprises,"enterprise",params[:display]) %> | ||
21 | +<% end %> |
test/unit/person_test.rb
@@ -1413,4 +1413,37 @@ class PersonTest < ActiveSupport::TestCase | @@ -1413,4 +1413,37 @@ class PersonTest < ActiveSupport::TestCase | ||
1413 | person.reload | 1413 | person.reload |
1414 | assert_equal person.activities, [] | 1414 | assert_equal person.activities, [] |
1415 | end | 1415 | end |
1416 | + | ||
1417 | + should 'merge memberships of plugins to original memberships' do | ||
1418 | + class Plugin1 < Noosfero::Plugin | ||
1419 | + def person_memberships(person) | ||
1420 | + Profile.memberships_of(Person.find_by_identifier('person1')) | ||
1421 | + end | ||
1422 | + end | ||
1423 | + | ||
1424 | + class Plugin2 < Noosfero::Plugin | ||
1425 | + def person_memberships(person) | ||
1426 | + Profile.memberships_of(Person.find_by_identifier('person2')) | ||
1427 | + end | ||
1428 | + end | ||
1429 | + | ||
1430 | + Environment.default.enable_plugin(Plugin1) | ||
1431 | + Environment.default.enable_plugin(Plugin2) | ||
1432 | + | ||
1433 | + original_person = fast_create(Person) | ||
1434 | + person1 = fast_create(Person, :identifier => 'person1') | ||
1435 | + person2 = fast_create(Person, :identifier => 'person2') | ||
1436 | + original_cmm = fast_create(Community) | ||
1437 | + plugin1_cmm = fast_create(Community) | ||
1438 | + plugin2_cmm = fast_create(Community) | ||
1439 | + original_cmm.add_member(original_person) | ||
1440 | + plugin1_cmm.add_member(person1) | ||
1441 | + plugin2_cmm.add_member(person2) | ||
1442 | + | ||
1443 | + assert_includes original_person.memberships, original_cmm | ||
1444 | + assert_includes original_person.memberships, plugin1_cmm | ||
1445 | + assert_includes original_person.memberships, plugin2_cmm | ||
1446 | + assert 3, original_person.memberships.count | ||
1447 | + end | ||
1448 | + | ||
1416 | end | 1449 | end |
@@ -0,0 +1,31 @@ | @@ -0,0 +1,31 @@ | ||
1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
2 | + | ||
3 | +class ScopeToolTest < ActiveSupport::TestCase | ||
4 | + include ScopeTool | ||
5 | + | ||
6 | + should 'unite scopes' do | ||
7 | + cmm = fast_create Community | ||
8 | + ent = fast_create Enterprise | ||
9 | + orgs = union(Profile.communities, Profile.enterprises) | ||
10 | + assert orgs.include? cmm | ||
11 | + assert orgs.include? ent | ||
12 | + end | ||
13 | + | ||
14 | + should 'filter united scopes' do | ||
15 | + cmm1 = fast_create Community, :visible => true | ||
16 | + cmm2 = fast_create Community, :visible => false | ||
17 | + ent1 = fast_create Enterprise, :visible => true | ||
18 | + ent2 = fast_create Enterprise, :visible => false | ||
19 | + orgs = union(Profile.communities, Profile.enterprises) | ||
20 | + assert orgs.include? cmm1 | ||
21 | + assert orgs.include? cmm2 | ||
22 | + assert orgs.include? ent1 | ||
23 | + assert orgs.include? ent2 | ||
24 | + orgs = orgs.visible | ||
25 | + assert orgs.include? cmm1 | ||
26 | + assert !orgs.include?(cmm2) | ||
27 | + assert orgs.include? ent1 | ||
28 | + assert !orgs.include?(ent2) | ||
29 | + end | ||
30 | + | ||
31 | +end |
vendor/plugins/monkey_patches/methods_from_fake_arel/init.rb
@@ -19,14 +19,6 @@ module Rails3Finder | @@ -19,14 +19,6 @@ module Rails3Finder | ||
19 | named_scope :readonly, lambda {|readonly| {:readonly => readonly }} | 19 | named_scope :readonly, lambda {|readonly| {:readonly => readonly }} |
20 | named_scope :lock, lambda {|lock| {:lock => lock }} | 20 | named_scope :lock, lambda {|lock| {:lock => lock }} |
21 | 21 | ||
22 | - def self.select(value = Proc.new) | ||
23 | - if block_given? | ||
24 | - all.select {|*block_args| value.call(*block_args) } | ||
25 | - else | ||
26 | - self.scoped(:select => Array.wrap(value).join(',')) | ||
27 | - end | ||
28 | - end | ||
29 | - | ||
30 | __where_fn = lambda do |*where| | 22 | __where_fn = lambda do |*where| |
31 | if where.is_a?(Array) and where.size == 1 | 23 | if where.is_a?(Array) and where.size == 1 |
32 | {:conditions => where.first} | 24 | {:conditions => where.first} |
@@ -37,33 +29,66 @@ module Rails3Finder | @@ -37,33 +29,66 @@ module Rails3Finder | ||
37 | 29 | ||
38 | named_scope :where, __where_fn | 30 | named_scope :where, __where_fn |
39 | 31 | ||
40 | - # Use carefully this method! It might get lost with different classes | ||
41 | - # scopes or different types of joins. | ||
42 | - def self.or_scope(*scopes) | ||
43 | - where = [] | ||
44 | - joins = [] | ||
45 | - includes = [] | 32 | + class << self |
46 | 33 | ||
47 | - # for some reason, flatten is actually executing the scope | ||
48 | - scopes = scopes[0] if scopes.size == 1 | ||
49 | - scopes.each do |s| | ||
50 | - s = s.proxy_options | ||
51 | - begin | ||
52 | - where << merge_conditions(s[:conditions]) | ||
53 | - rescue NoMethodError | ||
54 | - # I am ActiveRecord::Base. Only my subclasses define merge_conditions: | ||
55 | - where << subclasses.first.merge_conditions(s[:conditions]) | 34 | + def select(value = Proc.new) |
35 | + if block_given? | ||
36 | + all.select {|*block_args| value.call(*block_args) } | ||
37 | + else | ||
38 | + self.scoped(:select => Array.wrap(value).join(',')) | ||
56 | end | 39 | end |
57 | - #where << merge_conditions(s[:conditions]) | ||
58 | - joins << s[:joins] unless s[:joins].nil? | ||
59 | - includes << s[:include] unless s[:include].nil? | ||
60 | end | 40 | end |
61 | - scoped = self | ||
62 | - scoped = scoped.select("DISTINCT #{self.table_name}.*") | ||
63 | - scoped = scoped.includes(includes.uniq.flatten) unless includes.blank? | ||
64 | - scoped = scoped.joins(joins.uniq.flatten) unless joins.blank? | ||
65 | - scoped.where(where.join(" OR ")) | 41 | + |
42 | + def to_sql | ||
43 | + join_dependency = JoinDependency.new(self, merge_includes(scope(:find, :include), nil), nil) | ||
44 | + scope = scope(:find) || {} | ||
45 | + options = current_scoped_methods || {} | ||
46 | + sql = "SELECT #{(scope && scope[:select]) || default_select(options[:joins] || (scope && scope[:joins]))} " | ||
47 | + sql << "FROM #{(scope && scope[:from]) || quoted_table_name} " | ||
48 | + sql << join_dependency.join_associations.collect{|join| join.association_join }.join | ||
49 | + | ||
50 | + add_joins!(sql, options[:joins], scope) | ||
51 | + add_conditions!(sql, options[:conditions], scope) | ||
52 | + add_limited_ids_condition!(sql, options, join_dependency) if !using_limitable_reflections?(join_dependency.reflections) && ((scope && scope[:limit]) || options[:limit]) | ||
53 | + | ||
54 | + add_group!(sql, options[:group], options[:having], scope) | ||
55 | + add_order!(sql, options[:order], scope) | ||
56 | + add_limit!(sql, options, scope) if using_limitable_reflections?(join_dependency.reflections) | ||
57 | + add_lock!(sql, options, scope) | ||
58 | + | ||
59 | + return sanitize_sql(sql) | ||
60 | + end | ||
61 | + | ||
62 | + # Use carefully this method! It might get lost with different classes | ||
63 | + # scopes or different types of joins. | ||
64 | + def or_scope(*scopes) | ||
65 | + where = [] | ||
66 | + joins = [] | ||
67 | + includes = [] | ||
68 | + | ||
69 | + # for some reason, flatten is actually executing the scope | ||
70 | + scopes = scopes[0] if scopes.size == 1 | ||
71 | + scopes.each do |s| | ||
72 | + s = s.proxy_options | ||
73 | + begin | ||
74 | + where << merge_conditions(s[:conditions]) | ||
75 | + rescue NoMethodError | ||
76 | + # I am ActiveRecord::Base. Only my subclasses define merge_conditions: | ||
77 | + where << subclasses.first.merge_conditions(s[:conditions]) | ||
78 | + end | ||
79 | + #where << merge_conditions(s[:conditions]) | ||
80 | + joins << s[:joins] unless s[:joins].nil? | ||
81 | + includes << s[:include] unless s[:include].nil? | ||
82 | + end | ||
83 | + scoped = self | ||
84 | + scoped = scoped.select("DISTINCT #{self.table_name}.*") | ||
85 | + scoped = scoped.includes(includes.uniq.flatten) unless includes.blank? | ||
86 | + scoped = scoped.joins(joins.uniq.flatten) unless joins.blank? | ||
87 | + scoped.where(where.join(" OR ")) | ||
88 | + end | ||
89 | + | ||
66 | end | 90 | end |
91 | + | ||
67 | end | 92 | end |
68 | end | 93 | end |
69 | end | 94 | end |