trusty-cms 7.0.2 → 7.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +0 -1
- data/Gemfile +2 -2
- data/Gemfile.lock +89 -102
- data/INSTALL.md +8 -6
- data/README.md +16 -11
- data/app/assets/stylesheets/admin/partials/_forms.scss +13 -0
- data/app/controllers/admin/configuration_controller.rb +1 -1
- data/app/controllers/admin/extensions_controller.rb +1 -0
- data/app/controllers/admin/layouts_controller.rb +2 -1
- data/app/controllers/admin/resource_controller.rb +10 -1
- data/app/controllers/admin/sites_controller.rb +1 -0
- data/app/controllers/admin/snippets_controller.rb +2 -1
- data/app/controllers/admin/users_controller.rb +2 -1
- data/app/helpers/admin/users_helper.rb +2 -1
- data/app/models/admins_site.rb +6 -0
- data/app/models/site.rb +2 -0
- data/app/models/trusty_cms/config.rb +2 -1
- data/app/models/user.rb +15 -4
- data/app/views/admin/layouts/_choose_site.html.haml +5 -3
- data/app/views/admin/layouts/_site_chooser.html.haml +2 -2
- data/app/views/admin/pages/_fields.html.haml +4 -3
- data/app/views/admin/pages/_node.html.haml +1 -1
- data/app/views/admin/snippets/_choose_site.html.haml +2 -1
- data/app/views/admin/users/_choose_site.html.haml +2 -1
- data/app/views/admin/users/_form.html.haml +3 -1
- data/bin/rails +2 -2
- data/config/application.rb +1 -0
- data/config/locales/en.yml +10 -8
- data/db/migrate/20241108172942_create_site_users.rb +8 -0
- data/lib/login_system.rb +15 -15
- data/lib/trusty_cms/version.rb +1 -1
- data/spec/dummy/config/application.rb +2 -0
- data/spec/dummy/db/schema.rb +8 -1
- data/spec/factories/snippet.rb +10 -0
- data/spec/factories/user.rb +11 -11
- data/spec/models/snippets_spec.rb +29 -0
- data/spec/models/user_spec.rb +46 -0
- data/trusty_cms.gemspec +1 -1
- data/vendor/extensions/multi-site-extension/lib/multi_site/scoped_model.rb +17 -11
- data/vendor/extensions/multi-site-extension/lib/multi_site/site_chooser_helper.rb +10 -10
- metadata +12 -5
- data/app/users/_choose_site.html.haml +0 -4
@@ -2,7 +2,8 @@ module Admin::UsersHelper
|
|
2
2
|
def roles(user)
|
3
3
|
roles = []
|
4
4
|
roles << I18n.t('admin') if user.admin?
|
5
|
-
roles << I18n.t('
|
5
|
+
roles << I18n.t('editor') if user.editor?
|
6
|
+
roles << I18n.t('content_editor') if user.content_editor?
|
6
7
|
roles.join(', ')
|
7
8
|
end
|
8
9
|
end
|
data/app/models/site.rb
CHANGED
@@ -7,6 +7,8 @@ class Site < ActiveRecord::Base
|
|
7
7
|
belongs_to :created_by, class_name: 'User'
|
8
8
|
belongs_to :updated_by, class_name: 'User'
|
9
9
|
belongs_to :production_homepage, class_name: 'ProductionPage'
|
10
|
+
has_many :admins_sites
|
11
|
+
has_many :admins, through: :admins_sites, class_name: 'User'
|
10
12
|
|
11
13
|
default_scope { order('position ASC') }
|
12
14
|
|
@@ -81,7 +81,8 @@ module TrustyCms
|
|
81
81
|
TrustyCms::Config.initialize_cache
|
82
82
|
end
|
83
83
|
TrustyCms::Config.initialize_cache if TrustyCms::Config.stale_cache?
|
84
|
-
Rails.cache.read('TrustyCms::Config')
|
84
|
+
config_cache = Rails.cache.read('TrustyCms::Config')
|
85
|
+
config_cache ? config_cache[key] : nil
|
85
86
|
end
|
86
87
|
end
|
87
88
|
end
|
data/app/models/user.rb
CHANGED
@@ -7,7 +7,6 @@ class User < ActiveRecord::Base
|
|
7
7
|
:recoverable, :rememberable, :trackable, :validatable
|
8
8
|
|
9
9
|
alias_attribute :created_by_id, :id
|
10
|
-
|
11
10
|
attr_accessor :skip_password_validation
|
12
11
|
|
13
12
|
validate :password_complexity
|
@@ -18,6 +17,13 @@ class User < ActiveRecord::Base
|
|
18
17
|
# Associations
|
19
18
|
belongs_to :created_by, class_name: 'User'
|
20
19
|
belongs_to :updated_by, class_name: 'User'
|
20
|
+
has_many :admins_sites, foreign_key: 'admin_id', class_name: 'AdminsSite', dependent: :destroy
|
21
|
+
has_many :sites, through: :admins_sites
|
22
|
+
|
23
|
+
# Roles
|
24
|
+
# Admin - all permissions
|
25
|
+
# Editor - all permissions except for users, sites editing
|
26
|
+
# Content Editor - all permissions except for users, sites, publishing and deleting
|
21
27
|
|
22
28
|
def role?(role)
|
23
29
|
case role
|
@@ -40,12 +46,16 @@ class User < ActiveRecord::Base
|
|
40
46
|
designer
|
41
47
|
end
|
42
48
|
|
49
|
+
def editor?
|
50
|
+
designer
|
51
|
+
end
|
52
|
+
|
43
53
|
def content_editor?
|
44
54
|
content_editor
|
45
55
|
end
|
46
56
|
|
47
|
-
def
|
48
|
-
|
57
|
+
def scoped_site?
|
58
|
+
sites.present?
|
49
59
|
end
|
50
60
|
|
51
61
|
def locale
|
@@ -67,4 +77,5 @@ class User < ActiveRecord::Base
|
|
67
77
|
|
68
78
|
errors.add :password, 'Complexity requirement not met. Length should be 12 characters and include: 1 uppercase, 1 lowercase, 1 digit and 1 special character.'
|
69
79
|
end
|
70
|
-
|
80
|
+
|
81
|
+
end
|
@@ -1,7 +1,9 @@
|
|
1
1
|
- unless current_user.site
|
2
2
|
%label{:for=>'layout_site_id', :class => 'admin_only'}
|
3
3
|
Site
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
:ruby
|
5
|
+
user_sites = current_user.admins_sites.pluck(:site_id)
|
6
|
+
sites = Site.where(:id => user_sites).map { |s| [s.name, s.id] }
|
7
|
+
selection = {:include_blank => Layout.is_shareable?}
|
8
|
+
selection[:selected] = current_site.id if @layout.new_record? && ! Layout.is_shareable?
|
7
9
|
= select :layout, :site_id, sites, selection
|
@@ -1,9 +1,9 @@
|
|
1
|
-
- if current_user.
|
1
|
+
- if current_user.scoped_site? && defined?(Site) && defined?(controller) && controller.sited_model? && controller.template_name == 'index' && Site.several?
|
2
2
|
.site_chooser
|
3
3
|
%ul.nav
|
4
4
|
%li
|
5
5
|
= "Current Site: #{current_site.name}"
|
6
6
|
%ul.expansion
|
7
|
-
-
|
7
|
+
- current_user.sites.each do |site|
|
8
8
|
%li
|
9
9
|
= link_to( site.name, "#{request.path}?site_id=#{site.id}", :class => site == current_site ? 'fg site-link' : 'site-link')
|
@@ -41,9 +41,10 @@
|
|
41
41
|
= fields.label :class_name, t('page_type')
|
42
42
|
= fields.select :class_name, [[t('select.normal'), '']] + Page.descendants.map { |p| [p.display_name, p.name] }.sort_by { |p| p.first }
|
43
43
|
- layout.edit_status do
|
44
|
-
.
|
45
|
-
|
46
|
-
|
44
|
+
- if current_user.admin? || current_user.editor?
|
45
|
+
.status
|
46
|
+
= fields.label :status_id, t('status')
|
47
|
+
= fields.select :status_id, status_to_display
|
47
48
|
- layout.edit_published_at do
|
48
49
|
.published-date
|
49
50
|
#published_at{:class => (@page.published? ? nil : 'hidden')}
|
@@ -1,5 +1,6 @@
|
|
1
1
|
- unless current_user.site
|
2
2
|
%label{:for=>'snippet_site_id', :Class => 'admin_only'}
|
3
3
|
Site
|
4
|
-
-
|
4
|
+
- user_sites = current_user.admins_sites.pluck(:site_id)
|
5
|
+
- sites = Site.where(:id => user_sites).map { |s| [s.name, s.id] }
|
5
6
|
= select :snippet, :site_id, sites, :include_blank => Snippet.is_shareable?, :selected => @snippet.site_id || current_site.id
|
@@ -1,4 +1,5 @@
|
|
1
1
|
- if current_user.admin?
|
2
2
|
%label{:for=>'user_admin'} Can edit site
|
3
|
-
|
3
|
+
.caption (hold ctrl or cmd to select multiple)
|
4
4
|
.caption A user with no site is able to act (to whatever extent their status allows) on any site.
|
5
|
+
= select :user, :site_ids, options_for_select(Site.all.map { |s| [s.name, s.id] }, selected: @user.site_ids), {}, { multiple: true }
|
@@ -25,7 +25,9 @@
|
|
25
25
|
= f.check_box 'admin', :class => 'checkbox'
|
26
26
|
= f.label :admin, t('admin'), :class => 'checkbox'
|
27
27
|
= f.check_box 'designer', :class => 'checkbox'
|
28
|
-
= f.label :designer, t('
|
28
|
+
= f.label :designer, t('editor'), :class => 'checkbox'
|
29
|
+
= f.check_box 'content_editor', :class => 'checkbox'
|
30
|
+
= f.label :content_editor, t('content_editor'), :class => 'checkbox'
|
29
31
|
|
30
32
|
- form.edit_notes do
|
31
33
|
%fieldset
|
data/bin/rails
CHANGED
@@ -3,8 +3,8 @@
|
|
3
3
|
# installed from the root of your application.
|
4
4
|
|
5
5
|
ENGINE_ROOT = File.expand_path('..', __dir__)
|
6
|
-
ENGINE_PATH = File.expand_path('../lib/
|
7
|
-
APP_PATH = File.expand_path('../
|
6
|
+
ENGINE_PATH = File.expand_path('../lib/trusty_cms/engine', __dir__)
|
7
|
+
APP_PATH = File.expand_path('../spec/dummy/config/application', __dir__)
|
8
8
|
|
9
9
|
# Set up gems listed in the Gemfile.
|
10
10
|
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
|
data/config/application.rb
CHANGED
@@ -20,6 +20,7 @@ module TrustyCms
|
|
20
20
|
Rails.autoloaders.log!
|
21
21
|
# Enable the asset pipeline
|
22
22
|
config.assets.enabled = true
|
23
|
+
config.active_record.legacy_connection_handling = false
|
23
24
|
|
24
25
|
# Version of your assets, change this if you want to expire all your assets
|
25
26
|
config.assets.version = '1.0'
|
data/config/locales/en.yml
CHANGED
@@ -140,7 +140,7 @@ en:
|
|
140
140
|
secret: 'Secret'
|
141
141
|
skip_filetype_validation: 'Skip Filetype Validation'
|
142
142
|
storage: 'Storage'
|
143
|
-
url: 'Url'
|
143
|
+
url: 'Url'
|
144
144
|
defaults:
|
145
145
|
locale: 'default language'
|
146
146
|
page:
|
@@ -159,17 +159,18 @@ en:
|
|
159
159
|
allow_password_reset?: "allow password reset"
|
160
160
|
content: 'Content'
|
161
161
|
content_type: 'Content‑Type'
|
162
|
+
content_editor: 'Content Editor'
|
162
163
|
creating_status: 'Creating %{model}…'
|
163
164
|
date:
|
164
|
-
abbr_day_names: [Sun, Mon, Tue, Wed, Thu, Fri, Sat]
|
165
|
-
abbr_month_names: [~, Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec]
|
166
|
-
day_names: [Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday]
|
165
|
+
abbr_day_names: [ Sun, Mon, Tue, Wed, Thu, Fri, Sat ]
|
166
|
+
abbr_month_names: [ ~, Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec ]
|
167
|
+
day_names: [ Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday ]
|
167
168
|
formats:
|
168
169
|
default: "%Y-%m-%d"
|
169
170
|
long: "%B %e, %Y"
|
170
171
|
only_day: "%e"
|
171
172
|
short: "%e %b"
|
172
|
-
month_names: [~, January, February, March, April, May, June, July, August, September, October, November, December]
|
173
|
+
month_names: [ ~, January, February, March, April, May, June, July, August, September, October, November, December ]
|
173
174
|
order:
|
174
175
|
- :year
|
175
176
|
- :month
|
@@ -183,9 +184,10 @@ en:
|
|
183
184
|
designer: 'Designer'
|
184
185
|
draft: 'Draft'
|
185
186
|
edit: 'Edit'
|
187
|
+
editor: 'Editor'
|
186
188
|
edit_configuration: 'Edit Configuration'
|
187
189
|
edit_layout: 'Edit Layout'
|
188
|
-
edit_page:
|
190
|
+
edit_page: 'Edit Page'
|
189
191
|
edit_preferences: 'Edit Preferences'
|
190
192
|
edit_settings: 'Edit Settings'
|
191
193
|
edit_user: 'Edit User'
|
@@ -242,7 +244,7 @@ en:
|
|
242
244
|
published: 'Published'
|
243
245
|
published_at: 'Published at'
|
244
246
|
published_on: 'Published On'
|
245
|
-
reference:
|
247
|
+
reference: 'Reference'
|
246
248
|
remember_me: 'Remember me'
|
247
249
|
remember_me_in_this_browser: 'Remember me in this browser'
|
248
250
|
remove: 'Remove'
|
@@ -277,7 +279,7 @@ en:
|
|
277
279
|
snippets: 'Snippets'
|
278
280
|
snippet: 'Snippet'
|
279
281
|
status: 'Status'
|
280
|
-
|
282
|
+
# Warnings and info text:
|
281
283
|
testing: Testing
|
282
284
|
text:
|
283
285
|
layouts:
|
data/lib/login_system.rb
CHANGED
@@ -40,27 +40,27 @@ module LoginSystem
|
|
40
40
|
true
|
41
41
|
end
|
42
42
|
|
43
|
-
def
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
# permissions = self.class.controller_permissions[action]
|
50
|
-
# flash[:error] = permissions[:denied_message] || 'Access denied.'
|
51
|
-
# respond_to do |format|
|
52
|
-
# format.html { redirect_to(permissions[:denied_url] || { :action => :index }) }
|
53
|
-
# format.any(:xml, :json) { head :forbidden }
|
54
|
-
# end
|
55
|
-
# false
|
56
|
-
# end
|
57
|
-
true
|
43
|
+
def authorize_role
|
44
|
+
action = action_name.to_s.intern
|
45
|
+
return true if user_has_access_to_action?(action)
|
46
|
+
|
47
|
+
handle_unauthorized_access(action)
|
48
|
+
false
|
58
49
|
end
|
59
50
|
|
60
51
|
def user_has_access_to_action?(action)
|
61
52
|
self.class.user_has_access_to_action?(current_user, action, self)
|
62
53
|
end
|
63
54
|
|
55
|
+
def handle_unauthorized_access(action)
|
56
|
+
permissions = self.class.controller_permissions[action]
|
57
|
+
flash[:error] = permissions[:denied_message] || 'Access denied.'
|
58
|
+
respond_to do |format|
|
59
|
+
format.html { redirect_to(permissions[:denied_url] || { action: :index }) }
|
60
|
+
format.any(:xml, :json) { head :forbidden }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
64
|
def login_from_session
|
65
65
|
User.unscoped.find(session['user_id'])
|
66
66
|
rescue StandardError
|
data/lib/trusty_cms/version.rb
CHANGED
@@ -31,6 +31,8 @@ module TrustyCms
|
|
31
31
|
|
32
32
|
# Initialize extension paths
|
33
33
|
config.initialize_extension_paths
|
34
|
+
config.active_record.legacy_connection_handling = false
|
35
|
+
|
34
36
|
extension_loader = ExtensionLoader.instance { |l| l.initializer = self }
|
35
37
|
extension_loader.paths(:load).reverse_each do |path, value|
|
36
38
|
config.autoload_paths.unshift path
|
data/spec/dummy/db/schema.rb
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
#
|
11
11
|
# It's strongly recommended that you check this file into your version control system.
|
12
12
|
|
13
|
-
ActiveRecord::Schema[7.0].define(version:
|
13
|
+
ActiveRecord::Schema[7.0].define(version: 2024_11_08_172942) do
|
14
14
|
create_table "active_storage_attachments", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
15
15
|
t.string "name", null: false
|
16
16
|
t.string "record_type", null: false
|
@@ -69,6 +69,13 @@ ActiveRecord::Schema[7.0].define(version: 2023_10_19_192097) do
|
|
69
69
|
t.datetime "updated_at", precision: nil, null: false
|
70
70
|
end
|
71
71
|
|
72
|
+
create_table "admins_sites", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
73
|
+
t.integer "admin_id", null: false
|
74
|
+
t.integer "site_id", null: false
|
75
|
+
t.index ["admin_id"], name: "index_admins_sites_on_admin_id"
|
76
|
+
t.index ["site_id"], name: "index_admins_sites_on_site_id"
|
77
|
+
end
|
78
|
+
|
72
79
|
create_table "assets", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
73
80
|
t.string "caption"
|
74
81
|
t.string "title"
|
data/spec/factories/user.rb
CHANGED
@@ -1,34 +1,34 @@
|
|
1
1
|
FactoryBot.define do
|
2
2
|
factory :user do
|
3
|
-
|
3
|
+
first_name { 'FirstName' }
|
4
|
+
last_name { 'LastName' }
|
4
5
|
email { 'email@test.com' }
|
5
|
-
|
6
|
-
password { 'password' }
|
6
|
+
password { 'ComplexPass1!' }
|
7
7
|
password_confirmation { password }
|
8
8
|
|
9
9
|
factory :admin do
|
10
|
-
|
11
|
-
|
10
|
+
first_name { 'FirstName' }
|
11
|
+
last_name { 'LastName' }
|
12
12
|
email { 'admin@example.com' }
|
13
13
|
admin { true }
|
14
14
|
end
|
15
15
|
|
16
16
|
factory :existing do
|
17
|
-
|
18
|
-
|
17
|
+
first_name { 'FirstName' }
|
18
|
+
last_name { 'LastName' }
|
19
19
|
email { 'existing@example.com' }
|
20
20
|
end
|
21
21
|
|
22
22
|
factory :designer do
|
23
|
-
|
24
|
-
|
23
|
+
first_name { 'FirstName' }
|
24
|
+
last_name { 'LastName' }
|
25
25
|
email { '' }
|
26
26
|
designer { true }
|
27
27
|
end
|
28
28
|
|
29
29
|
factory :non_admin do
|
30
|
-
|
31
|
-
|
30
|
+
first_name { 'FirstName' }
|
31
|
+
last_name { 'LastName' }
|
32
32
|
admin { false }
|
33
33
|
end
|
34
34
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Snippet do
|
4
|
+
|
5
|
+
let(:snippet) { FactoryBot.build(:snippet) }
|
6
|
+
|
7
|
+
describe 'name' do
|
8
|
+
it 'is invalid when blank' do
|
9
|
+
snippet = FactoryBot.build(:snippet, name: '')
|
10
|
+
snippet.valid?
|
11
|
+
expect(snippet.errors[:name]).to include("This field is required.")
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should validate uniqueness of' do
|
15
|
+
snippet = FactoryBot.build(:snippet, name: 'test_snippet', content: "Content!")
|
16
|
+
snippet.save!
|
17
|
+
other = FactoryBot.build(:snippet, name: 'test_snippet', content: "Content!")
|
18
|
+
expect { other.save! }.to raise_error(ActiveRecord::RecordInvalid)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should validate length of' do
|
22
|
+
snippet = FactoryBot.build(:snippet, name: 'x' * 100)
|
23
|
+
expect(snippet.errors[:name]).to be_blank
|
24
|
+
snippet = FactoryBot.build(:snippet, name: 'x' * 101)
|
25
|
+
expect { snippet.save! }.to raise_error(ActiveRecord::RecordInvalid)
|
26
|
+
expect(snippet.errors[:name]).to include("This must not be longer than 100 characters")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe User do
|
4
|
+
describe '#role?' do
|
5
|
+
let(:user) { create(:user) }
|
6
|
+
|
7
|
+
it 'returns true for admin role' do
|
8
|
+
user.admin = true
|
9
|
+
expect(user.role?(:admin)).to be true
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'returns false for non-admin role' do
|
13
|
+
user.admin = false
|
14
|
+
expect(user.role?(:admin)).to be false
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#password_complexity' do
|
19
|
+
let(:user) { build(:user) }
|
20
|
+
|
21
|
+
it 'is valid with a complex password' do
|
22
|
+
user.password = 'ComplexPass1!'
|
23
|
+
expect(user).to be_valid
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'is invalid with a simple password' do
|
27
|
+
user.password = 'simple'
|
28
|
+
user.valid?
|
29
|
+
expect(user.errors[:password]).to include('Complexity requirement not met. Length should be 12 characters and include: 1 uppercase, 1 lowercase, 1 digit and 1 special character.')
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#password_required?' do
|
34
|
+
let(:user) { build(:user) }
|
35
|
+
|
36
|
+
it 'returns false if skip_password_validation is true' do
|
37
|
+
user.skip_password_validation = true
|
38
|
+
expect(user.password_required?).to be false
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'returns true if skip_password_validation is false' do
|
42
|
+
user.skip_password_validation = false
|
43
|
+
expect(user.password_required?).to be true
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/trusty_cms.gemspec
CHANGED
@@ -43,7 +43,7 @@ a general purpose content management system--not merely a blogging engine.'
|
|
43
43
|
s.add_dependency 'mini_racer'
|
44
44
|
s.add_dependency 'mutex_m'
|
45
45
|
s.add_dependency 'mysql2'
|
46
|
-
s.add_dependency 'rack', '>= 2.0.1', '< 3.
|
46
|
+
s.add_dependency 'rack', '>= 2.0.1', '< 3.2.0'
|
47
47
|
s.add_dependency 'rack-cache', '~> 1.7'
|
48
48
|
s.add_dependency 'radius', '~> 0.7'
|
49
49
|
s.add_dependency 'rails', '~> 7.0.0'
|
@@ -17,7 +17,7 @@ module MultiSite
|
|
17
17
|
# that is, anything without a site is considered to be shared among all sites
|
18
18
|
# the default is false
|
19
19
|
|
20
|
-
def is_site_scoped(options={})
|
20
|
+
def is_site_scoped(options = {})
|
21
21
|
return if is_site_scoped?
|
22
22
|
|
23
23
|
options = {
|
@@ -25,7 +25,7 @@ module MultiSite
|
|
25
25
|
}.merge(options)
|
26
26
|
|
27
27
|
class_eval <<-EO
|
28
|
-
default_scope {where(site_scope_condition)}
|
28
|
+
#{ self == User ? 'default_scope { joins(user_scope_condition) }' : 'default_scope { where(site_scope_condition) }' }
|
29
29
|
extend MultiSite::ScopedModel::ScopedClassMethods
|
30
30
|
include MultiSite::ScopedModel::ScopedInstanceMethods
|
31
31
|
EO
|
@@ -52,8 +52,7 @@ module MultiSite
|
|
52
52
|
|
53
53
|
module ScopedClassMethods
|
54
54
|
|
55
|
-
|
56
|
-
def paginate_with_site(options={})
|
55
|
+
def paginate_with_site(options = {})
|
57
56
|
return paginate_without_site(options) unless sites?
|
58
57
|
where(site_scope_condition) do
|
59
58
|
paginate_without_site(options)
|
@@ -63,7 +62,7 @@ module MultiSite
|
|
63
62
|
%w{count average minimum maximum sum}.each do |getter|
|
64
63
|
define_method("#{getter}_with_site") do |*args|
|
65
64
|
return send("#{getter}_without_site".intern, *args) unless sites?
|
66
|
-
with_scope(:find => {:conditions => site_scope_condition}) do
|
65
|
+
with_scope(:find => { :conditions => site_scope_condition }) do
|
67
66
|
send "#{getter}_without_site".intern, *args
|
68
67
|
end
|
69
68
|
end
|
@@ -73,11 +72,11 @@ module MultiSite
|
|
73
72
|
# and should only be used in odd cases like migration.
|
74
73
|
def find_without_site(*args)
|
75
74
|
options = args.extract_options!
|
76
|
-
#set_readonly_option!(options)
|
75
|
+
# set_readonly_option!(options)
|
77
76
|
|
78
77
|
case args.first
|
79
|
-
|
80
|
-
|
78
|
+
when :first then find_initial_without_site(options) # defined here
|
79
|
+
when :all then all_without_site(options) # already defined by the alias chain
|
81
80
|
end
|
82
81
|
end
|
83
82
|
|
@@ -110,6 +109,12 @@ module MultiSite
|
|
110
109
|
condition
|
111
110
|
end
|
112
111
|
|
112
|
+
def user_scope_condition
|
113
|
+
return "" unless self.current_site
|
114
|
+
|
115
|
+
"INNER JOIN `admins_sites` ON `admins_sites`.`admin_id` = `admins`.`id` AND `admins_sites`.`site_id` = #{self.current_site.id}"
|
116
|
+
end
|
117
|
+
|
113
118
|
def plural_symbol_for_class
|
114
119
|
self.to_s.pluralize.underscore.intern
|
115
120
|
end
|
@@ -125,9 +130,10 @@ module MultiSite
|
|
125
130
|
|
126
131
|
module ScopedInstanceMethods
|
127
132
|
protected
|
128
|
-
|
129
|
-
|
130
|
-
|
133
|
+
|
134
|
+
def set_site
|
135
|
+
self.site ||= self.class.current_site! unless self.class.is_shareable?
|
136
|
+
end
|
131
137
|
end
|
132
138
|
end
|
133
139
|
end
|
@@ -1,14 +1,14 @@
|
|
1
1
|
module MultiSite::SiteChooserHelper
|
2
2
|
|
3
|
-
def sites_chooser_thing
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
end
|
3
|
+
def sites_chooser_thing
|
4
|
+
return "" unless current_user.admin? && defined?(Site) && defined?(controller) && controller.sited_model? && controller.template_name == 'index' && Site.several?
|
5
|
+
options = Site.all.map { |site| "<li>" + link_to(site.name, "#{request.path}?site_id=#{site.id}", :class => site == current_site ? 'fg' : '') + "</li>" }.join("")
|
6
|
+
chooser = %{<div id="site_chooser">}
|
7
|
+
# chooser << link_to("sites", admin_sites_url, {:id => 'show_site_list', :class => 'expandable'})
|
8
|
+
chooser << %{<ul id="nav"><li>Current Site: #{current_site.name}}
|
9
|
+
chooser << %{<ul class="expansion">#{options}</ul></li></ul>}
|
10
|
+
chooser << %{</div>}
|
11
|
+
chooser
|
12
|
+
end
|
13
13
|
|
14
14
|
end
|