radiant-reader-extension 0.9.2
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.
- data/.gitignore +2 -0
- data/README.md +89 -0
- data/Rakefile +140 -0
- data/VERSION +1 -0
- data/app/controllers/admin/messages_controller.rb +20 -0
- data/app/controllers/admin/reader_settings_controller.rb +92 -0
- data/app/controllers/admin/readers_controller.rb +28 -0
- data/app/controllers/password_resets_controller.rb +64 -0
- data/app/controllers/reader_action_controller.rb +84 -0
- data/app/controllers/reader_activations_controller.rb +60 -0
- data/app/controllers/reader_sessions_controller.rb +56 -0
- data/app/controllers/readers_controller.rb +131 -0
- data/app/helpers/admin/reader_settings_helper.rb +36 -0
- data/app/models/message.rb +108 -0
- data/app/models/message_function.rb +37 -0
- data/app/models/message_reader.rb +13 -0
- data/app/models/reader.rb +146 -0
- data/app/models/reader_notifier.rb +34 -0
- data/app/models/reader_session.rb +3 -0
- data/app/views/admin/messages/_form.html.haml +29 -0
- data/app/views/admin/messages/_help.html.haml +41 -0
- data/app/views/admin/messages/_message_description.html.haml +3 -0
- data/app/views/admin/messages/edit.html.haml +16 -0
- data/app/views/admin/messages/new.html.haml +16 -0
- data/app/views/admin/reader_settings/_setting.html.haml +24 -0
- data/app/views/admin/reader_settings/edit.html.haml +10 -0
- data/app/views/admin/reader_settings/index.html.haml +35 -0
- data/app/views/admin/reader_settings/show.html.haml +1 -0
- data/app/views/admin/readers/_avatar.html.haml +3 -0
- data/app/views/admin/readers/_form.html.haml +50 -0
- data/app/views/admin/readers/_list_head.html.haml +9 -0
- data/app/views/admin/readers/_listed.html.haml +22 -0
- data/app/views/admin/readers/_password_fields.html.haml +18 -0
- data/app/views/admin/readers/edit.html.haml +8 -0
- data/app/views/admin/readers/index.html.haml +17 -0
- data/app/views/admin/readers/new.html.haml +7 -0
- data/app/views/admin/readers/remove.html.haml +18 -0
- data/app/views/admin/sites/_choose_reader_layout.html.haml +7 -0
- data/app/views/password_resets/create.html.haml +13 -0
- data/app/views/password_resets/edit.html.haml +71 -0
- data/app/views/password_resets/new.html.haml +31 -0
- data/app/views/reader_activations/_activation_required.html.haml +34 -0
- data/app/views/reader_activations/_on_activation.html.haml +4 -0
- data/app/views/reader_activations/show.html.haml +41 -0
- data/app/views/reader_notifier/message.html.haml +1 -0
- data/app/views/reader_sessions/_login_form.html.haml +59 -0
- data/app/views/reader_sessions/new.html.haml +38 -0
- data/app/views/readers/_contributions.html.haml +2 -0
- data/app/views/readers/_controls.html.haml +25 -0
- data/app/views/readers/_extra_controls.html.haml +0 -0
- data/app/views/readers/_flasher.html.haml +6 -0
- data/app/views/readers/_form.html.haml +73 -0
- data/app/views/readers/create.html.haml +28 -0
- data/app/views/readers/edit.html.haml +47 -0
- data/app/views/readers/index.html.haml +16 -0
- data/app/views/readers/login.html.haml +15 -0
- data/app/views/readers/new.html.haml +41 -0
- data/app/views/readers/permission_denied.html.haml +23 -0
- data/app/views/readers/show.html.haml +35 -0
- data/app/views/wrappers/_field_errors.html.haml +5 -0
- data/config/routes.rb +22 -0
- data/config/settings.rb +9 -0
- data/db/migrate/001_create_readers.rb +31 -0
- data/db/migrate/002_extend_sites.rb +17 -0
- data/db/migrate/003_reader_honorifics.rb +12 -0
- data/db/migrate/004_user_readers.rb +11 -0
- data/db/migrate/005_last_login.rb +15 -0
- data/db/migrate/007_adapt_for_authlogic.rb +27 -0
- data/db/migrate/20090921125653_reader_messages.rb +27 -0
- data/db/migrate/20090924164413_functional_messages.rb +9 -0
- data/db/migrate/20090925081225_standard_messages.rb +106 -0
- data/db/migrate/20091006102438_message_visibility.rb +9 -0
- data/db/migrate/20091010083503_registration_config.rb +10 -0
- data/db/migrate/20091019124021_message_functions.rb +9 -0
- data/db/migrate/20091020133533_forenames.rb +9 -0
- data/db/migrate/20091020135152_contacts.rb +23 -0
- data/db/migrate/20091111090819_ensure_functional_messages_visible.rb +9 -0
- data/db/migrate/20091119092936_messages_have_layout.rb +9 -0
- data/db/migrate/20100922152338_lock_versions.rb +9 -0
- data/db/migrate/20100927095703_default_settings.rb +14 -0
- data/db/migrate/20101004074945_unlock_version.rb +9 -0
- data/lib/config_extensions.rb +5 -0
- data/lib/controller_extensions.rb +77 -0
- data/lib/reader_admin_ui.rb +64 -0
- data/lib/reader_helper.rb +36 -0
- data/lib/reader_site.rb +10 -0
- data/lib/reader_tags.rb +297 -0
- data/lib/rfc822.rb +29 -0
- data/lib/tasks/reader_extension_tasks.rake +28 -0
- data/pkg/radiant-reader-extension-0.9.0.gem +0 -0
- data/public/images/admin/chk_off.png +0 -0
- data/public/images/admin/chk_on.png +0 -0
- data/public/images/admin/new-message.png +0 -0
- data/public/images/admin/new-reader.png +0 -0
- data/public/javascripts/admin/messages.js +13 -0
- data/public/stylesheets/sass/admin/reader.sass +95 -0
- data/radiant-reader-extension.gemspec +184 -0
- data/reader_extension.rb +55 -0
- data/spec/controllers/admin/messages_controller_spec.rb +38 -0
- data/spec/controllers/admin/readers_controller_spec.rb +14 -0
- data/spec/controllers/password_resets_controller_spec.rb +140 -0
- data/spec/controllers/reader_activations_controller_spec.rb +45 -0
- data/spec/controllers/readers_controller_spec.rb +193 -0
- data/spec/datasets/messages_dataset.rb +49 -0
- data/spec/datasets/reader_layouts_dataset.rb +26 -0
- data/spec/datasets/reader_sites_dataset.rb +10 -0
- data/spec/datasets/readers_dataset.rb +51 -0
- data/spec/lib/reader_admin_ui_spec.rb +35 -0
- data/spec/lib/reader_site_spec.rb +18 -0
- data/spec/matchers/reader_login_system_matcher.rb +35 -0
- data/spec/models/message_spec.rb +109 -0
- data/spec/models/reader_notifier_spec.rb +34 -0
- data/spec/models/reader_spec.rb +155 -0
- data/spec/spec.opts +5 -0
- data/spec/spec_helper.rb +48 -0
- metadata +267 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
class ReaderActionController < ApplicationController
|
|
2
|
+
helper_method :current_site, :current_site=, :logged_in?, :logged_in_user?, :logged_in_admin?
|
|
3
|
+
|
|
4
|
+
no_login_required
|
|
5
|
+
before_filter :set_site_title
|
|
6
|
+
|
|
7
|
+
# reader session is normally required for modifying actions
|
|
8
|
+
before_filter :require_reader, :except => [:index, :show]
|
|
9
|
+
|
|
10
|
+
radiant_layout { |controller| Radiant::Config['reader.layout'] }
|
|
11
|
+
|
|
12
|
+
# authorisation helpers
|
|
13
|
+
|
|
14
|
+
def logged_in?
|
|
15
|
+
true if current_reader
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def logged_in_user?
|
|
19
|
+
true if logged_in? && current_reader.is_user?
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def logged_in_admin?
|
|
23
|
+
true if logged_in_user? && current_reader.admin?
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def permission_denied
|
|
27
|
+
session[:return_to] ||= request.referer
|
|
28
|
+
@title = flash[:error] || "Sorry: permission denied"
|
|
29
|
+
render
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
protected
|
|
33
|
+
|
|
34
|
+
# context-setters
|
|
35
|
+
|
|
36
|
+
def set_site_title
|
|
37
|
+
if defined? Site && current_site
|
|
38
|
+
@site_title = current_site.name
|
|
39
|
+
@short_site_title = current_site.abbreviation || @site_title
|
|
40
|
+
@site_url = current_site.base_domain
|
|
41
|
+
else
|
|
42
|
+
@site_title = Radiant::Config['site.title']
|
|
43
|
+
@short_site_title = Radiant::Config['site.abbreviation'] || @site_title
|
|
44
|
+
@site_url = request.host
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def require_reader
|
|
49
|
+
unless set_reader # set_reader is in ControllerExtension and sets Reader.current while checking for current_reader
|
|
50
|
+
store_location
|
|
51
|
+
respond_to do |format|
|
|
52
|
+
format.html { redirect_to reader_login_url }
|
|
53
|
+
format.js {
|
|
54
|
+
@inline = true
|
|
55
|
+
render :partial => 'reader_sessions/login_form'
|
|
56
|
+
}
|
|
57
|
+
end
|
|
58
|
+
false
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def require_activated_reader
|
|
63
|
+
unless current_reader && current_reader.activated?
|
|
64
|
+
respond_to do |format|
|
|
65
|
+
format.html { redirect_to reader_activation_url }
|
|
66
|
+
format.js {
|
|
67
|
+
@inline = true
|
|
68
|
+
render :partial => 'reader_activations/activation_required'
|
|
69
|
+
}
|
|
70
|
+
end
|
|
71
|
+
false
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def require_no_reader
|
|
76
|
+
if set_reader
|
|
77
|
+
store_location
|
|
78
|
+
flash[:notice] = "Please log out first"
|
|
79
|
+
redirect_back_or_to url_for(current_reader)
|
|
80
|
+
return false
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
class ReaderActivationsController < ReaderActionController
|
|
2
|
+
|
|
3
|
+
no_login_required
|
|
4
|
+
skip_before_filter :require_reader
|
|
5
|
+
before_filter :authenticate_reader, :only => [:update]
|
|
6
|
+
before_filter :check_reader_inactive
|
|
7
|
+
|
|
8
|
+
radiant_layout { |controller| Radiant::Config['reader.layout'] }
|
|
9
|
+
|
|
10
|
+
# this is just fake REST: we're actually working on the reader, not an activation object, but in a usefully restricted way:
|
|
11
|
+
# .show sends out an activation message if we can identify the current reader
|
|
12
|
+
# .update activates the reader, if the token is correct
|
|
13
|
+
|
|
14
|
+
def show
|
|
15
|
+
render
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def new
|
|
19
|
+
if current_reader
|
|
20
|
+
@reader = current_reader
|
|
21
|
+
@reader.send_activation_message
|
|
22
|
+
flash[:notice] = "Account activation instructions have been emailed to you."
|
|
23
|
+
end
|
|
24
|
+
render :action => 'show'
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def update
|
|
28
|
+
if @reader
|
|
29
|
+
@reader.activate!
|
|
30
|
+
self.current_reader = @reader
|
|
31
|
+
flash[:notice] = "Thank you! Your account has been activated."
|
|
32
|
+
redirect_back_or_to default_activated_url
|
|
33
|
+
|
|
34
|
+
else
|
|
35
|
+
@error = "Sorry: something was wrong in that link. Please check your email message."
|
|
36
|
+
flash[:error] = "Activation failed."
|
|
37
|
+
render :action => 'show'
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
protected
|
|
42
|
+
|
|
43
|
+
def authenticate_reader
|
|
44
|
+
# not using authlogic's find_using_perishable_token because I don't want the token to expire
|
|
45
|
+
@reader = Reader.find_by_id_and_perishable_token(params[:id], params[:activation_code])
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def check_reader_inactive
|
|
49
|
+
if @reader && @reader.activated?
|
|
50
|
+
flash[:notice] = "Hello #{@reader.name}! Your account is already active."
|
|
51
|
+
redirect_back_or_to default_activated_url
|
|
52
|
+
false
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def default_activated_url
|
|
57
|
+
reader_url(@reader)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
class ReaderSessionsController < ReaderActionController
|
|
2
|
+
|
|
3
|
+
before_filter :require_reader, :only => :destroy
|
|
4
|
+
radiant_layout { |controller| Radiant::Config['reader.layout'] }
|
|
5
|
+
|
|
6
|
+
def new
|
|
7
|
+
@reader_session = ReaderSession.new
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def create
|
|
11
|
+
@reader_session = ReaderSession.new(params[:reader_session])
|
|
12
|
+
if @reader_session.save
|
|
13
|
+
if @reader_session.reader.activated? && @reader_session.reader.clear_password
|
|
14
|
+
@reader_session.reader.clear_password = "" # we forget the cleartext version on the first successful login after activation
|
|
15
|
+
@reader_session.reader.save(false)
|
|
16
|
+
end
|
|
17
|
+
respond_to do |format|
|
|
18
|
+
format.html {
|
|
19
|
+
flash[:notice] = "Hello #{@reader_session.reader.name}. Welcome back."
|
|
20
|
+
redirect_back_or_to default_loggedin_url
|
|
21
|
+
}
|
|
22
|
+
format.js {
|
|
23
|
+
redirect_back_with_format(:js)
|
|
24
|
+
}
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
else
|
|
28
|
+
respond_to do |format|
|
|
29
|
+
format.html {
|
|
30
|
+
flash[:error] = "Sorry: that combination of login and password is not known here."
|
|
31
|
+
render :action => :new
|
|
32
|
+
}
|
|
33
|
+
format.js { render :action => :new, :layout => false }
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def destroy
|
|
39
|
+
current_reader_session.destroy
|
|
40
|
+
if current_user
|
|
41
|
+
cookies[:session_token] = { :expires => 1.day.ago }
|
|
42
|
+
current_user.forget_me
|
|
43
|
+
session['user_id'] = nil
|
|
44
|
+
current_user = nil
|
|
45
|
+
end
|
|
46
|
+
flash[:notice] = "You are logged out. Bye!"
|
|
47
|
+
redirect_back_or_to reader_login_url
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
protected
|
|
51
|
+
|
|
52
|
+
def default_loggedin_url
|
|
53
|
+
reader_url(@reader_session.reader)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
end
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
class ReadersController < ReaderActionController
|
|
2
|
+
@@extended_form_partials = []
|
|
3
|
+
cattr_accessor :extended_form_partials
|
|
4
|
+
|
|
5
|
+
before_filter :check_registration_allowed, :only => [:new, :create]
|
|
6
|
+
before_filter :initialize_form_partials, :only => [:new, :edit, :update, :create]
|
|
7
|
+
before_filter :i_am_me, :only => [:show]
|
|
8
|
+
before_filter :require_reader, :except => [:index, :new, :create, :activate]
|
|
9
|
+
before_filter :restrict_to_self, :only => [:edit, :update, :resend_activation]
|
|
10
|
+
before_filter :no_removing, :only => [:remove, :destroy]
|
|
11
|
+
before_filter :require_password, :only => [:update]
|
|
12
|
+
|
|
13
|
+
def index
|
|
14
|
+
@readers = Reader.paginate(:page => params[:page], :order => 'readers.created_at desc')
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def show
|
|
18
|
+
@reader = Reader.find(params[:id])
|
|
19
|
+
respond_to do |format|
|
|
20
|
+
format.html {
|
|
21
|
+
if @reader.inactive? && @reader == current_reader
|
|
22
|
+
redirect_to reader_activation_url
|
|
23
|
+
else
|
|
24
|
+
render
|
|
25
|
+
end
|
|
26
|
+
}
|
|
27
|
+
format.js {
|
|
28
|
+
@inline = true
|
|
29
|
+
render :partial => 'readers/controls'
|
|
30
|
+
}
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def new
|
|
36
|
+
if current_reader
|
|
37
|
+
flash[:error] = "You're already logged in!"
|
|
38
|
+
redirect_to url_for(current_reader) and return
|
|
39
|
+
end
|
|
40
|
+
@reader = Reader.new
|
|
41
|
+
session[:return_to] = request.referer
|
|
42
|
+
session[:email_field] = @email_field = @reader.generate_email_field_name
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def edit
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def create
|
|
49
|
+
@reader = Reader.new(params[:reader])
|
|
50
|
+
@reader.clear_password = params[:reader][:password]
|
|
51
|
+
|
|
52
|
+
unless @reader.email.blank?
|
|
53
|
+
flash[:error] = "Please don't fill in the spam trap field."
|
|
54
|
+
@reader.email = ''
|
|
55
|
+
@reader.errors.add(:trap, "must be empty")
|
|
56
|
+
render :action => 'new' and return
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
unless @email_field = session[:email_field]
|
|
60
|
+
flash[:error] = "Please use the registration form."
|
|
61
|
+
redirect_to new_reader_url and return
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
@reader.email = params[@email_field.intern]
|
|
65
|
+
if (@reader.valid?)
|
|
66
|
+
@reader.save!
|
|
67
|
+
@reader.send_activation_message
|
|
68
|
+
self.current_reader = @reader
|
|
69
|
+
redirect_to reader_activation_url
|
|
70
|
+
else
|
|
71
|
+
render :action => 'new'
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def update
|
|
76
|
+
@reader.attributes = params[:reader]
|
|
77
|
+
@reader.clear_password = params[:reader][:password] if params[:reader][:password]
|
|
78
|
+
if @reader.save
|
|
79
|
+
flash[:notice] = "Your account has been updated"
|
|
80
|
+
redirect_to url_for(@reader)
|
|
81
|
+
else
|
|
82
|
+
render :action => 'edit'
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
protected
|
|
87
|
+
|
|
88
|
+
def i_am_me
|
|
89
|
+
params[:id] = current_reader.id if params[:id] == 'me' && current_reader
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def restrict_to_self
|
|
93
|
+
flash[:error] = "Sorry. You are not allowed to edit other people's accounts." if params[:id] && params[:id] != current_reader.id
|
|
94
|
+
@reader = current_reader
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def require_password
|
|
98
|
+
return true if @reader.valid_password?(params[:reader][:current_password])
|
|
99
|
+
|
|
100
|
+
# might as well get any other validation messages while we're at it
|
|
101
|
+
@reader.attributes = params[:reader]
|
|
102
|
+
@reader.valid?
|
|
103
|
+
|
|
104
|
+
flash[:error] = 'Sorry. Wrong password.'
|
|
105
|
+
@reader.errors.add(:current_password, "was not correct")
|
|
106
|
+
render :action => 'edit' and return false
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def no_removing
|
|
110
|
+
flash[:error] = "You can't delete readers here. Please log in to the admin interface."
|
|
111
|
+
redirect_to admin_readers_url
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def check_registration_allowed
|
|
115
|
+
unless Radiant::Config['reader.allow_registration?']
|
|
116
|
+
flash[:error] = "Sorry. This site does not allow public registration."
|
|
117
|
+
redirect_to reader_login_url
|
|
118
|
+
false
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def self.add_form_partial(path)
|
|
123
|
+
extended_form_partials.push(path)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
private
|
|
127
|
+
def initialize_form_partials
|
|
128
|
+
@form_partials = extended_form_partials
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module Admin::ReaderSettingsHelper
|
|
2
|
+
|
|
3
|
+
def editable_setting(setting)
|
|
4
|
+
setting = Radiant::Config.find_by_key(setting) unless setting.is_a? Radiant::Config
|
|
5
|
+
domkey = setting.key.gsub('?', '_')
|
|
6
|
+
containerid = "set_#{domkey}"
|
|
7
|
+
link = link_to_remote setting.value,
|
|
8
|
+
:url => edit_admin_reader_setting_url(setting.id),
|
|
9
|
+
:method => 'get',
|
|
10
|
+
:update => containerid,
|
|
11
|
+
:loading => "$('#{containerid}').addClassName('waiting');",
|
|
12
|
+
:loaded => "$('#{containerid}').removeClassName('waiting');"
|
|
13
|
+
%{
|
|
14
|
+
#{link}
|
|
15
|
+
}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def checkbox_for_setting(setting, label)
|
|
19
|
+
setting = Radiant::Config.find_by_key(setting) unless setting.is_a? Radiant::Config
|
|
20
|
+
domkey = setting.key.gsub('?', '_')
|
|
21
|
+
containerid = "set_#{domkey}"
|
|
22
|
+
checkbox = check_box_tag setting.key.to_sym, 1, setting.value, :class => 'fancy', :id => domkey, :onchange => remote_function(
|
|
23
|
+
:url => admin_reader_setting_path(setting.id),
|
|
24
|
+
:with => %{'value=' + (this.checked ? 'true' : 'false')},
|
|
25
|
+
:method => 'put',
|
|
26
|
+
:loading => "$('#{containerid}').addClassName('waiting');",
|
|
27
|
+
:success => "$('#{containerid}').removeClassName('waiting').toggleClassName('true').toggleClassName('false');"
|
|
28
|
+
)
|
|
29
|
+
%{
|
|
30
|
+
#{checkbox}
|
|
31
|
+
<label for="#{domkey}">#{label}</label>
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
class Message < ActiveRecord::Base
|
|
2
|
+
|
|
3
|
+
is_site_scoped if defined? ActiveRecord::SiteNotFound
|
|
4
|
+
|
|
5
|
+
belongs_to :layout
|
|
6
|
+
belongs_to :created_by, :class_name => 'User'
|
|
7
|
+
belongs_to :updated_by, :class_name => 'User'
|
|
8
|
+
|
|
9
|
+
has_many :message_readers
|
|
10
|
+
has_many :readers, :through => :message_readers
|
|
11
|
+
|
|
12
|
+
has_many :deliveries, :class_name => 'MessageReader', :conditions => ["message_readers.sent_at IS NOT NULL and message_readers.sent_at <= ?", Time.now.to_s(:db)]
|
|
13
|
+
has_many :recipients, :through => :deliveries, :source => :reader
|
|
14
|
+
|
|
15
|
+
validates_presence_of :subject
|
|
16
|
+
validates_presence_of :body
|
|
17
|
+
|
|
18
|
+
object_id_attr :filter, TextFilter
|
|
19
|
+
|
|
20
|
+
default_scope :order => 'updated_at DESC, created_at DESC'
|
|
21
|
+
named_scope :for_function, lambda { |f| {:conditions => ["function_id = ?", f.to_s]} }
|
|
22
|
+
named_scope :administrative, { :conditions => "function_id IS NOT NULL" }
|
|
23
|
+
named_scope :ordinary, { :conditions => "function_id IS NULL" }
|
|
24
|
+
named_scope :published, { :conditions => "status_id >= 100" }
|
|
25
|
+
|
|
26
|
+
def filtered_body
|
|
27
|
+
filter.filter(body)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# has to return a named_scope for chainability
|
|
31
|
+
def possible_readers
|
|
32
|
+
Reader.active
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def undelivered_readers
|
|
36
|
+
possible_readers - recipients
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def inactive_readers
|
|
40
|
+
possible_readers.inactive
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def active_readers
|
|
44
|
+
possible_readers.active
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def delivered?
|
|
48
|
+
deliveries.any?
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def delivered_to?(reader)
|
|
52
|
+
recipients.include?(reader)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def preview(reader=nil)
|
|
56
|
+
reader ||= possible_readers.first || Reader.find_or_create_for_user(created_by)
|
|
57
|
+
ReaderNotifier.create_message(reader, self)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def function
|
|
61
|
+
MessageFunction[self.function_id]
|
|
62
|
+
end
|
|
63
|
+
def self.functional(function)
|
|
64
|
+
for_function(MessageFunction[function]).first
|
|
65
|
+
end
|
|
66
|
+
def has_function?
|
|
67
|
+
!function.nil?
|
|
68
|
+
end
|
|
69
|
+
def administrative?
|
|
70
|
+
has_function?
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def status
|
|
74
|
+
Status.find(self.status_id)
|
|
75
|
+
end
|
|
76
|
+
def status=(value)
|
|
77
|
+
self.status_id = value.id
|
|
78
|
+
end
|
|
79
|
+
def published?
|
|
80
|
+
status == Status[:published]
|
|
81
|
+
end
|
|
82
|
+
def published!
|
|
83
|
+
status = Status[:published]
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def deliver(readers)
|
|
87
|
+
failures = []
|
|
88
|
+
readers.each do |reader|
|
|
89
|
+
failures.push(reader) unless deliver_to(reader)
|
|
90
|
+
end
|
|
91
|
+
self.published!
|
|
92
|
+
failures
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def deliver_to(reader, sender=nil)
|
|
96
|
+
ReaderNotifier.deliver_message(reader, self, sender)
|
|
97
|
+
record_delivery(reader)
|
|
98
|
+
true
|
|
99
|
+
rescue => e
|
|
100
|
+
logger.warn "@@ delivery failed: #{e.inspect}"
|
|
101
|
+
raise
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def record_delivery(reader)
|
|
105
|
+
MessageReader.find_or_create_by_message_id_and_reader_id(self.id, reader.id).update_attribute(:sent_at, Time.now)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
end
|