radiant-reader-extension 3.0.0.rc4 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +105 -38
- data/Rakefile +4 -4
- data/app/controllers/accounts_controller.rb +24 -11
- data/app/controllers/admin/groups_controller.rb +15 -0
- data/app/controllers/admin/memberships_controller.rb +13 -7
- data/app/controllers/admin/messages_controller.rb +1 -0
- data/app/controllers/admin/permissions_controller.rb +15 -8
- data/app/controllers/groups_controller.rb +6 -4
- data/app/controllers/password_resets_controller.rb +1 -1
- data/app/controllers/reader_action_controller.rb +7 -51
- data/app/controllers/reader_sessions_controller.rb +9 -11
- data/app/helpers/reader_helper.rb +23 -3
- data/app/models/group.rb +45 -16
- data/app/models/message.rb +4 -11
- data/app/models/permission.rb +4 -0
- data/app/models/reader.rb +61 -26
- data/app/models/reader_notifier.rb +2 -2
- data/app/models/reader_page.rb +9 -5
- data/app/views/accounts/{_memberships.html.haml → _choose_memberships.html.haml} +0 -0
- data/app/views/accounts/_form.html.haml +9 -11
- data/app/views/accounts/_preamble.html.haml +14 -0
- data/app/views/accounts/_profile_form.html.haml +13 -29
- data/app/views/accounts/dashboard.html.haml +0 -1
- data/app/views/accounts/edit.html.haml +3 -3
- data/app/views/accounts/edit_profile.html.haml +10 -10
- data/app/views/admin/groups/_chooser.html.haml +8 -0
- data/app/views/admin/groups/_form.html.haml +7 -5
- data/app/views/admin/groups/_group.html.haml +29 -0
- data/app/views/admin/groups/index.html.haml +2 -28
- data/app/views/admin/groups/show.html.haml +3 -2
- data/app/views/admin/memberships/_reader.html.haml +2 -6
- data/app/views/admin/messages/_form.html.haml +10 -11
- data/app/views/admin/messages/_list_function.haml +2 -3
- data/app/views/admin/messages/{index.haml → index.html.haml} +21 -11
- data/app/views/admin/pages/_page_groups.html.haml +5 -11
- data/app/views/admin/permissions/_page.html.haml +6 -12
- data/app/views/admin/reader_configuration/edit.html.haml +2 -0
- data/app/views/admin/reader_configuration/show.html.haml +2 -0
- data/app/views/groups/_group.html.haml +12 -0
- data/app/views/groups/show.html.haml +10 -3
- data/app/views/readers/_description.html.haml +3 -0
- data/app/views/readers/_groups.html.haml +9 -0
- data/app/views/{accounts → readers}/_links.html.haml +2 -2
- data/app/views/readers/_list.html.haml +23 -0
- data/app/views/{accounts/_groups.html.haml → readers/_memberships.html.haml} +0 -1
- data/app/views/{accounts/_reader.html.haml → readers/_mugshot.html.haml} +1 -1
- data/app/views/readers/_people.html.haml +6 -0
- data/app/views/readers/_profile.html.haml +30 -0
- data/app/views/readers/_reader.html.haml +28 -0
- data/app/views/readers/index.html.haml +20 -0
- data/app/views/{accounts → readers}/show.html.haml +1 -2
- data/app/views/shared/_standard_reader_parts.html.haml +1 -1
- data/app/views/shared/not_allowed.html.haml +16 -0
- data/config/initializers/formats.rb +1 -2
- data/config/initializers/radiant_config.rb +5 -2
- data/config/locales/en.yml +181 -140
- data/config/routes.rb +25 -16
- data/db/migrate/001_create_readers.rb +0 -1
- data/db/migrate/20090921125653_reader_messages.rb +0 -1
- data/db/migrate/20090921125654_group_messages.rb +0 -1
- data/db/migrate/20110812111934_groups_nested_set.rb +19 -0
- data/db/migrate/20110814070858_message_has_many_groups.rb +14 -0
- data/db/migrate/20110905194602_group_ancestry.rb +23 -0
- data/lib/controller_extensions.rb +49 -0
- data/lib/grouped_model.rb +49 -8
- data/lib/grouped_page.rb +17 -5
- data/lib/message_tags.rb +21 -3
- data/lib/radiant-reader-extension.rb +1 -1
- data/lib/reader_admin_ui.rb +7 -8
- data/lib/reader_tags.rb +1 -1
- data/lib/site_controller_extensions.rb +7 -18
- data/public/images/furniture/csv.png +0 -0
- data/public/images/furniture/csv_tiny.png +0 -0
- data/public/images/furniture/vcard.png +0 -0
- data/public/images/furniture/vcard_tiny.png +0 -0
- data/public/javascripts/admin/reader.js +22 -1
- data/public/stylesheets/sass/admin/reader_group.sass +23 -22
- data/public/stylesheets/sass/reader.sass +81 -17
- data/radiant-reader-extension.gemspec +3 -1
- data/reader_extension.rb +7 -9
- data/spec/controllers/accounts_controller_spec.rb +8 -22
- data/spec/controllers/admin/messages_controller_spec.rb +0 -12
- data/spec/datasets/readers_dataset.rb +41 -38
- data/spec/lib/reader_tags_spec.rb +1 -1
- data/spec/models/group_spec.rb +89 -22
- data/spec/models/message_spec.rb +1 -1
- data/spec/models/reader_notifier_spec.rb +1 -1
- data/spec/models/reader_page_spec.rb +34 -18
- data/spec/models/reader_spec.rb +0 -1
- data/spec/spec.opts +4 -3
- metadata +51 -28
- data/app/views/accounts/_contributions.html.haml +0 -2
- data/app/views/accounts/_description.html.haml +0 -2
- data/app/views/accounts/_list.html.haml +0 -17
- data/app/views/accounts/_profile.html.haml +0 -29
- data/app/views/accounts/index.html.haml +0 -23
- data/app/views/groups/_all.html.haml +0 -10
- data/app/views/site/not_allowed.html.haml +0 -4
- data/db/migrate/20100922152338_lock_versions.rb +0 -9
- data/db/migrate/20101004074945_unlock_version.rb +0 -9
@@ -42,7 +42,7 @@ class PasswordResetsController < ReaderActionController
|
|
42
42
|
if @reader.save
|
43
43
|
self.current_reader = @reader
|
44
44
|
flash[:notice] = t('reader_extension.password_updated_notice')
|
45
|
-
redirect_to
|
45
|
+
redirect_to default_welcome_url(@reader)
|
46
46
|
else
|
47
47
|
flash[:error] = t('reader_extension.password_mismatch')
|
48
48
|
render :action => :edit
|
@@ -5,7 +5,6 @@ class ReaderActionController < ApplicationController
|
|
5
5
|
helper_method :current_site, :current_site=, :logged_in?, :logged_in_user?, :logged_in_admin?
|
6
6
|
|
7
7
|
no_login_required
|
8
|
-
before_filter :set_site_title
|
9
8
|
|
10
9
|
# reader session is normally required for modifying actions
|
11
10
|
before_filter :require_reader, :except => [:index, :show]
|
@@ -32,60 +31,25 @@ class ReaderActionController < ApplicationController
|
|
32
31
|
render
|
33
32
|
end
|
34
33
|
|
35
|
-
def default_welcome_url(reader)
|
36
|
-
|
37
|
-
page.url
|
38
|
-
else
|
39
|
-
reader_url(reader) #TODO make this interesting
|
40
|
-
end
|
34
|
+
def default_welcome_url(reader=nil)
|
35
|
+
(reader && reader.home_url) || reader_dashboard_url
|
41
36
|
end
|
42
37
|
|
43
38
|
protected
|
44
39
|
|
45
|
-
#
|
46
|
-
|
47
|
-
def set_site_title
|
48
|
-
if defined? Site && current_site
|
49
|
-
@site_title = current_site.name
|
50
|
-
@short_site_title = current_site.abbreviation || @site_title
|
51
|
-
@site_url = current_site.base_domain
|
52
|
-
else
|
53
|
-
@site_title = Radiant::Config['site.title']
|
54
|
-
@short_site_title = Radiant::Config['site.abbreviation'] || @site_title
|
55
|
-
@site_url = request.host
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
40
|
+
# NB. ReaderError exceptions are caught in ApplicationController rescue_froms
|
41
|
+
|
59
42
|
def require_reader
|
60
|
-
unless set_reader # set_reader is
|
43
|
+
unless set_reader # set_reader is added to ApplicationController and sets Reader.current while checking authentication
|
61
44
|
store_location
|
62
|
-
|
63
|
-
format.html {
|
64
|
-
flash[:explanation] = t('reader_extension.reader_required')
|
65
|
-
flash[:notice] = t('reader_extension.please_log_in')
|
66
|
-
redirect_to reader_login_url
|
67
|
-
}
|
68
|
-
format.js {
|
69
|
-
@inline = true
|
70
|
-
render :partial => 'reader_sessions/login_form'
|
71
|
-
}
|
72
|
-
end
|
45
|
+
raise ReaderError::LoginRequired, t('reader_extension.please_log_in')
|
73
46
|
false
|
74
47
|
end
|
75
48
|
end
|
76
49
|
|
77
50
|
def require_activated_reader
|
78
51
|
unless current_reader && current_reader.activated?
|
79
|
-
|
80
|
-
format.html {
|
81
|
-
flash[:explanation] = t('reader_extension.activation_required')
|
82
|
-
redirect_to reader_activation_url
|
83
|
-
}
|
84
|
-
format.js {
|
85
|
-
@inline = true
|
86
|
-
render :partial => 'reader_activations/activation_required'
|
87
|
-
}
|
88
|
-
end
|
52
|
+
raise ReaderError::ActivationRequired, t('reader_extension.activation_required')
|
89
53
|
false
|
90
54
|
end
|
91
55
|
end
|
@@ -99,12 +63,4 @@ protected
|
|
99
63
|
end
|
100
64
|
end
|
101
65
|
|
102
|
-
def generate_csv(readers=[])
|
103
|
-
columns = %w{forename surname email phone mobile postal_address}
|
104
|
-
table = FasterCSV.generate do |csv|
|
105
|
-
csv << columns.map { |f| t("activerecord.attributes.reader.#{f}") }
|
106
|
-
readers.each { |r| csv << columns.map{ |f| r.send(f.to_sym) } }
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
66
|
end
|
@@ -45,13 +45,15 @@ class ReaderSessionsController < ReaderActionController
|
|
45
45
|
@reader_session.reader.clear_password = "" # we forget the cleartext version on the first successful login
|
46
46
|
@reader_session.reader.save(false)
|
47
47
|
end
|
48
|
-
format
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
48
|
+
respond_to do |format|
|
49
|
+
format.html {
|
50
|
+
flash[:notice] = t('reader_extension.hello').titlecase + " #{@reader_session.reader.name}. " + t('reader_extension.welcome_back')
|
51
|
+
redirect_back_or_to default_welcome_url(@reader_session.reader)
|
52
|
+
}
|
53
|
+
format.js {
|
54
|
+
redirect_back_with_format(:js)
|
55
|
+
}
|
56
|
+
end
|
55
57
|
else
|
56
58
|
respond_to do |format|
|
57
59
|
format.html { render :action => :new }
|
@@ -72,8 +74,4 @@ class ReaderSessionsController < ReaderActionController
|
|
72
74
|
redirect_to reader_login_url
|
73
75
|
end
|
74
76
|
|
75
|
-
def default_welcome_url(reader=nil)
|
76
|
-
reader.home_url || dashboard_url
|
77
|
-
end
|
78
|
-
|
79
77
|
end
|
@@ -1,16 +1,17 @@
|
|
1
1
|
require 'sanitize'
|
2
2
|
require "sanitize/config/generous"
|
3
3
|
require "fastercsv"
|
4
|
+
require "snail_helpers"
|
4
5
|
|
5
6
|
module ReaderHelper
|
6
7
|
include SnailHelpers
|
7
8
|
include Admin::RegionsHelper
|
8
9
|
|
9
10
|
def standard_gravatar_for(reader=nil, url=nil)
|
10
|
-
size = Radiant::Config['
|
11
|
+
size = Radiant::Config['reader.gravatar_size'] || 40
|
11
12
|
url ||= reader_url(reader)
|
12
13
|
gravatar = gravatar_for(reader, {:size => size}, {:class => 'gravatar offset', :width => size, :height => size})
|
13
|
-
content_tag(:div, link_to(gravatar, url), :class => "speaker")
|
14
|
+
content_tag(:div, link_to(gravatar, url), :class => "speaker", :width => size, :height => size)
|
14
15
|
end
|
15
16
|
|
16
17
|
def gravatar_for(reader=nil, gravatar_options={}, img_options ={})
|
@@ -103,7 +104,7 @@ EOM
|
|
103
104
|
def choose_page(object, field, select_options={})
|
104
105
|
root = Page.respond_to?(:homepage) ? Page.homepage : Page.find_by_parent_id(nil)
|
105
106
|
options = page_option_branch(root)
|
106
|
-
options.unshift [
|
107
|
+
options.unshift [t("reader_extension.none_option"), nil]
|
107
108
|
select object, field, options, select_options
|
108
109
|
end
|
109
110
|
|
@@ -142,8 +143,27 @@ EOM
|
|
142
143
|
usps_country_options_for_select(selected, default_selected)
|
143
144
|
end
|
144
145
|
|
146
|
+
def group_options_for_select
|
147
|
+
nested_set_options(Group) {|g| "#{'-' * g.level} #{g.name}" }.unshift([t("reader_extension.any_option"), nil])
|
148
|
+
end
|
149
|
+
|
150
|
+
def parent_group_options_for_select(group=nil)
|
151
|
+
nested_set_options(Group, group) {|g| "#{'-' * g.level} #{g.name}" }.unshift([t("reader_extension.none_option"), nil])
|
152
|
+
end
|
153
|
+
|
145
154
|
def email_link(address)
|
146
155
|
mail_to address, nil, :encode => :hex, :replace_at => ' at ', :class => 'mailto'
|
147
156
|
end
|
148
157
|
|
158
|
+
def generate_csv(readers=[])
|
159
|
+
columns = %w{forename surname email phone mobile postal_address}
|
160
|
+
table = FasterCSV.generate do |csv|
|
161
|
+
csv << columns.map { |f| t("activerecord.attributes.reader.#{f}") }
|
162
|
+
readers.each { |r| csv << columns.map{ |f| r.send(f.to_sym) } }
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def generate_vcard(readers=[])
|
167
|
+
readers.map(&:vcard).join("\n")
|
168
|
+
end
|
149
169
|
end
|
data/app/models/group.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
|
-
|
1
|
+
require 'ancestry'
|
2
2
|
|
3
|
-
|
4
|
-
default_scope :order => 'name'
|
3
|
+
class Group < ActiveRecord::Base
|
5
4
|
|
5
|
+
has_ancestry
|
6
|
+
belongs_to :leader, :class_name => 'Reader'
|
6
7
|
belongs_to :created_by, :class_name => 'User'
|
7
8
|
belongs_to :updated_by, :class_name => 'User'
|
8
9
|
belongs_to :homepage, :class_name => 'Page'
|
9
10
|
|
10
11
|
has_many :messages
|
11
12
|
has_many :permissions
|
12
|
-
has_many :pages, :through => :permissions
|
13
13
|
has_many :memberships
|
14
14
|
has_many :readers, :through => :memberships, :uniq => true
|
15
15
|
|
@@ -17,11 +17,14 @@ class Group < ActiveRecord::Base
|
|
17
17
|
validates_presence_of :name, :slug, :allow_blank => false
|
18
18
|
validates_uniqueness_of :name, :slug
|
19
19
|
|
20
|
+
named_scope :any
|
21
|
+
named_scope :none, { :conditions => "1 = 0" } # nasty! but doesn't break chains
|
20
22
|
named_scope :with_home_page, { :conditions => "homepage_id IS NOT NULL", :include => :homepage }
|
21
23
|
named_scope :subscribable, { :conditions => "public = 1" }
|
22
24
|
named_scope :unsubscribable, { :conditions => "public = 0" }
|
23
|
-
|
24
|
-
named_scope :
|
25
|
+
|
26
|
+
named_scope :find_these, lambda { |ids|
|
27
|
+
ids = ['NULL'] unless ids && ids.any?
|
25
28
|
{ :conditions => ["groups.id IN (#{ids.map{"?"}.join(',')})", *ids] }
|
26
29
|
}
|
27
30
|
|
@@ -45,18 +48,41 @@ class Group < ActiveRecord::Base
|
|
45
48
|
:readonly => false
|
46
49
|
}
|
47
50
|
}
|
48
|
-
|
51
|
+
|
49
52
|
def self.visible_to(reader=nil)
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
53
|
+
case Radiant.config['reader.directory_visibility']
|
54
|
+
when 'public'
|
55
|
+
self.all
|
56
|
+
when 'private'
|
57
|
+
reader ? self.all : self.none
|
58
|
+
when 'grouped'
|
59
|
+
(reader && reader.is_grouped?) ? reader.all_visible_groups : self.none
|
60
|
+
else
|
61
|
+
self.none
|
62
|
+
end
|
54
63
|
end
|
55
64
|
|
56
65
|
def visible_to?(reader=nil)
|
57
|
-
self.class.visible_to(reader).include? self
|
66
|
+
self.class.visible_to(reader).map(&:id).include? self.id
|
58
67
|
end
|
59
68
|
|
69
|
+
def tree
|
70
|
+
# can't quite do this in one step, but we can return a scope
|
71
|
+
self.root.subtree
|
72
|
+
end
|
73
|
+
|
74
|
+
def tree_ids
|
75
|
+
self.root.subtree_ids
|
76
|
+
end
|
77
|
+
|
78
|
+
def members
|
79
|
+
Reader.in_groups(subtree)
|
80
|
+
end
|
81
|
+
|
82
|
+
def inherited_permissions
|
83
|
+
Permission.to_groups(path)
|
84
|
+
end
|
85
|
+
|
60
86
|
def url
|
61
87
|
homepage.url if homepage
|
62
88
|
end
|
@@ -90,12 +116,15 @@ class Group < ActiveRecord::Base
|
|
90
116
|
# Permission.for_pages named_scope
|
91
117
|
# Group.page_permissions => set of permission objects
|
92
118
|
# Group.pages => set of page objects
|
93
|
-
|
119
|
+
#
|
94
120
|
def self.define_retrieval_methods(classname)
|
95
121
|
type_scope = "for_#{classname.downcase.pluralize}".intern
|
96
122
|
Permission.send :named_scope, type_scope, :conditions => { :permitted_type => classname }
|
97
|
-
define_method("#{classname.downcase}_permissions") { self.
|
98
|
-
define_method("#{classname.downcase.pluralize}") {
|
123
|
+
define_method("#{classname.downcase}_permissions") { self.inherited_permissions.send type_scope }
|
124
|
+
define_method("#{classname.downcase.pluralize}") {
|
125
|
+
ids = self.send("#{classname.to_s.downcase}_permissions".intern).map(&:permitted_id)
|
126
|
+
classname.constantize.find_these(ids)
|
127
|
+
}
|
99
128
|
end
|
100
129
|
|
101
130
|
private
|
@@ -103,6 +132,6 @@ private
|
|
103
132
|
def set_slug
|
104
133
|
self.slug ||= self.name.slugify.to_s
|
105
134
|
end
|
106
|
-
|
135
|
+
|
107
136
|
end
|
108
137
|
|
data/app/models/message.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
class Message < ActiveRecord::Base
|
2
2
|
|
3
|
+
has_groups
|
3
4
|
has_site if respond_to? :has_site
|
4
5
|
|
5
6
|
belongs_to :layout
|
6
7
|
belongs_to :created_by, :class_name => 'User'
|
7
8
|
belongs_to :updated_by, :class_name => 'User'
|
8
|
-
belongs_to :group
|
9
9
|
|
10
10
|
has_many :deliveries, :class_name => 'MessageReader', :conditions => ["message_readers.sent_at IS NOT NULL and message_readers.sent_at <= ?", Time.now.to_s(:db)]
|
11
11
|
has_many :recipients, :through => :deliveries, :source => :reader
|
@@ -21,26 +21,19 @@ class Message < ActiveRecord::Base
|
|
21
21
|
named_scope :ordinary, { :conditions => "function_id = '' OR function_id IS NULL" }
|
22
22
|
named_scope :published, { :conditions => "status_id >= 100" }
|
23
23
|
|
24
|
-
named_scope :belonging_to, lambda {|group|
|
25
|
-
{ :conditions => {:group_id => group }}
|
26
|
-
}
|
27
|
-
|
28
|
-
named_scope :ungrouped, :conditions => {:group_id => nil}
|
29
|
-
|
30
24
|
def filtered_body
|
31
25
|
filter.filter(body)
|
32
26
|
end
|
33
27
|
|
34
|
-
# has to return a scope for chainability
|
35
28
|
def possible_readers
|
36
|
-
|
29
|
+
permitted_readers
|
37
30
|
end
|
38
31
|
|
39
32
|
def undelivered_readers
|
40
33
|
if recipients.any?
|
41
34
|
possible_readers.except(recipients)
|
42
35
|
else
|
43
|
-
|
36
|
+
possible_readers
|
44
37
|
end
|
45
38
|
end
|
46
39
|
|
@@ -57,7 +50,7 @@ class Message < ActiveRecord::Base
|
|
57
50
|
end
|
58
51
|
|
59
52
|
def preview(reader=nil)
|
60
|
-
reader ||= possible_readers.first || Reader.for_user(
|
53
|
+
reader ||= possible_readers.first || Reader.for_user(Reader.current)
|
61
54
|
ReaderNotifier.create_message(reader, self)
|
62
55
|
end
|
63
56
|
|
data/app/models/permission.rb
CHANGED
@@ -6,6 +6,10 @@ class Permission < ActiveRecord::Base
|
|
6
6
|
named_scope :for, lambda { |object|
|
7
7
|
{ :conditions => {:permitted_id => object.id, :permitted_type => object.class.name.to_s} }
|
8
8
|
}
|
9
|
+
|
10
|
+
named_scope :to_groups, lambda { |ids|
|
11
|
+
{ :conditions => ["permissions.group_id IN (#{ids.map{"?"}.join(',')})", *ids] }
|
12
|
+
}
|
9
13
|
|
10
14
|
end
|
11
15
|
|
data/app/models/reader.rb
CHANGED
@@ -18,6 +18,8 @@ class Reader < ActiveRecord::Base
|
|
18
18
|
end
|
19
19
|
|
20
20
|
belongs_to :user
|
21
|
+
before_update :update_user
|
22
|
+
|
21
23
|
belongs_to :created_by, :class_name => 'User'
|
22
24
|
belongs_to :updated_by, :class_name => 'User'
|
23
25
|
has_many :message_readers
|
@@ -26,8 +28,6 @@ class Reader < ActiveRecord::Base
|
|
26
28
|
has_many :groups, :through => :memberships, :uniq => true
|
27
29
|
accepts_nested_attributes_for :memberships
|
28
30
|
|
29
|
-
before_update :update_user
|
30
|
-
|
31
31
|
validates_presence_of :name, :email
|
32
32
|
validates_length_of :name, :maximum => 100, :allow_nil => true
|
33
33
|
validates_length_of :password, :minimum => 6, :allow_nil => false, :unless => :existing_reader_keeping_password?
|
@@ -41,6 +41,7 @@ class Reader < ActiveRecord::Base
|
|
41
41
|
|
42
42
|
default_scope :order => 'name ASC'
|
43
43
|
named_scope :any
|
44
|
+
named_scope :none, { :conditions => "1 = 0" } # nasty! but doesn't break chains
|
44
45
|
named_scope :active, :conditions => "activated_at IS NOT NULL"
|
45
46
|
named_scope :inactive, :conditions => "activated_at IS NULL"
|
46
47
|
named_scope :imported, :conditions => "old_id IS NOT NULL"
|
@@ -83,16 +84,65 @@ class Reader < ActiveRecord::Base
|
|
83
84
|
end
|
84
85
|
|
85
86
|
def self.visible_to(reader=nil)
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
87
|
+
case Radiant.config['reader.directory_visibility']
|
88
|
+
when 'public'
|
89
|
+
self.all
|
90
|
+
when 'private'
|
91
|
+
reader ? self.all : self.none
|
92
|
+
when 'grouped'
|
93
|
+
reader ? self.in_groups(reader.all_visible_group_ids) : self.none
|
94
|
+
else
|
95
|
+
self.none
|
96
|
+
end
|
90
97
|
end
|
91
98
|
|
92
99
|
def visible_to?(reader=nil)
|
93
|
-
self.class.visible_to(reader).include?
|
100
|
+
(reader && (reader == self)) || self.class.visible_to(reader).map(&:id).include?(self.id)
|
101
|
+
end
|
102
|
+
|
103
|
+
# returns a useful list of the groups that this person is in and all their ancestor groups.
|
104
|
+
# for most authorisation purposes, that's the set of groups of which this reader is considered a member.
|
105
|
+
#
|
106
|
+
# Returns a scope.
|
107
|
+
#
|
108
|
+
def all_groups
|
109
|
+
Group.find_these(all_group_ids)
|
110
|
+
end
|
111
|
+
|
112
|
+
def all_group_ids
|
113
|
+
self.groups.map(&:path_ids).flatten.uniq
|
114
|
+
end
|
115
|
+
|
116
|
+
# Returns a list of the groups that this person is in along with their whole tree of super and subgroups.
|
117
|
+
# That's the list of groups that this person can see. It is larger than the list of groups that confer permission:
|
118
|
+
# this reader can see subgroups of his own groups in the directory, but he can't see their pages.
|
119
|
+
#
|
120
|
+
def all_visible_groups
|
121
|
+
Group.find_these(all_visible_group_ids)
|
122
|
+
end
|
123
|
+
|
124
|
+
def all_visible_group_ids
|
125
|
+
self.groups.map(&:tree_ids).flatten.uniq
|
126
|
+
end
|
127
|
+
|
128
|
+
def can_see? (this)
|
129
|
+
permitted_groups = this.permitted_groups
|
130
|
+
permitted_groups.empty? or in_any_of_these_groups?(permitted_groups)
|
131
|
+
end
|
132
|
+
|
133
|
+
def in_any_of_these_groups? (grouplist)
|
134
|
+
(grouplist & all_groups).any?
|
94
135
|
end
|
95
136
|
|
137
|
+
def has_group? (group)
|
138
|
+
all_groups.include?(group)
|
139
|
+
end
|
140
|
+
alias :is_in? :has_group?
|
141
|
+
|
142
|
+
def is_grouped?
|
143
|
+
groups.any?
|
144
|
+
end
|
145
|
+
|
96
146
|
# not very i18nal, this
|
97
147
|
def forename
|
98
148
|
read_attribute(:forename) || name.split(/\s+/).first
|
@@ -102,9 +152,12 @@ class Reader < ActiveRecord::Base
|
|
102
152
|
read_attribute(:surname) || name.split(/\s+/).last
|
103
153
|
end
|
104
154
|
|
155
|
+
def postal_address?
|
156
|
+
!post_line1.blank? && !post_city.blank?
|
157
|
+
end
|
158
|
+
|
105
159
|
def postal_address
|
106
160
|
Snail.new(
|
107
|
-
:name => name,
|
108
161
|
:line_1 => post_line1,
|
109
162
|
:line_2 => post_line2,
|
110
163
|
:city => post_city,
|
@@ -207,24 +260,6 @@ class Reader < ActiveRecord::Base
|
|
207
260
|
nil
|
208
261
|
end
|
209
262
|
end
|
210
|
-
|
211
|
-
def can_see? (this)
|
212
|
-
permitted_groups = this.permitted_groups
|
213
|
-
permitted_groups.empty? or in_any_of_these_groups?(permitted_groups)
|
214
|
-
end
|
215
|
-
|
216
|
-
def in_any_of_these_groups? (grouplist)
|
217
|
-
(grouplist & groups).any?
|
218
|
-
end
|
219
|
-
|
220
|
-
def is_in? (group)
|
221
|
-
groups.include?(group)
|
222
|
-
end
|
223
|
-
|
224
|
-
# has_group? is ambiguous: with no argument it means 'is this reader grouped at all?'.
|
225
|
-
def has_group?(group=nil)
|
226
|
-
group.nil? ? groups.any? : is_in?(group)
|
227
|
-
end
|
228
263
|
|
229
264
|
private
|
230
265
|
|