/
newsletter_page.rb
executable file
·168 lines (143 loc) · 5.32 KB
/
newsletter_page.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
class NewsletterPage < Page
has_many :subscribers,
:class_name => "NewsletterSubscriber",
:foreign_key => 'newsletter_id',
:dependent => :delete_all
has_many :active_subscribers,
:class_name => "NewsletterSubscriber",
:foreign_key => 'newsletter_id',
:dependent => :delete_all,
:conditions => ["activated_at IS NOT ? AND unsubscribed_at IS ?", nil, nil]
has_many :unsubscribeds,
:class_name => "NewsletterSubscriber",
:foreign_key => 'newsletter_id',
:dependent => :delete_all,
:conditions => ["activated_at IS NOT ? AND unsubscribed_at IS NOT ?", nil, nil]
ACTIONS = {
:public => %w[ subscribe activate unsubscribe confirm_unsubscription ],
:private => %w[ subscribed activated unsubscribed ]
}
def config
default_config = {
"from" => "no-reply@example.com",
"subject_prefix" => self.title
}
string = render_part(:config)
unless string.empty?
hash = YAML::load(string)
default_config.merge(hash)
else
default_config
end
end
def recipients
self.active_subscribers.collect{|s| "#{s.name} <#{s.email}>".gsub(/\s+/, ' ').strip }
end
def process(request, response)
@request, @response = request, response
if request.post?
if @newsletter_action == 'subscribe'
@newsletter_subscriber = NewsletterSubscriber.new
if @newsletter_subscriber.update_attributes((request.parameters[:newsletter_subscriber] || {}).merge({:newsletter_id => self.id}))
@newsletter_action = 'subscribed'
send_activation_email(@newsletter_subscriber)
else
@newsletter_form_errors = true
end
elsif @newsletter_action == 'unsubscribe'
@newsletter_subscriber = NewsletterSubscriber.find_active_subscriber_by_newsletter_and_email(self, request.parameters[:newsletter_subscriber][:email])
if @newsletter_subscriber
@newsletter_action = 'unsubscribed'
send_unsubscription_email(@newsletter_subscriber)
else
@newsletter_form_errors = true
end
end
else # request.get?
if @newsletter_action == 'activate'
newsletter_subscriber = NewsletterSubscriber.find_by_activation_code_and_newsletter_id(@code, self.id)
if newsletter_subscriber && newsletter_subscriber.activate
@newsletter_subscriber_has_been_activated = true
@newsletter_action = 'activated'
end
elsif @newsletter_action == 'confirm_unsubscription'
@newsletter_subscriber = NewsletterSubscriber.find_active_subscriber_by_newsletter_and_unsubscription_code(self, @code)
if @newsletter_subscriber
@newsletter_subscriber.unsubscribe
else
@newsletter_action = 'unsubscribe'
@newsletter_form_errors = true
end
end
end
super(request, response)
end
def find_by_url(url, live = true, clean = false)
url = clean_url(url) if clean
if url =~ /^#{self.url}(#{ACTIONS[:public].join("|")})\/([a-zA-Z0-9]{40,})?\/?$/
@newsletter_action = $1
@code = $2
self
else
super
end
end
def cache?
false
end
tag 'newsletter' do |tag|
tag.expand
end
tag 'newsletter:unless_actions' do |tag|
tag.expand unless (ACTIONS[:private] + ACTIONS[:public]).include?(@newsletter_action)
end
tag 'newsletter:if_actions' do |tag|
tag.expand if (ACTIONS[:private] + ACTIONS[:public]).include?(@newsletter_action)
end
tag 'newsletter:if_form_errors' do |tag|
tag.expand if @newsletter_form_errors
end
tag 'newsletter:unless_action' do |tag|
action_name = tag.attr['name']
tag.expand unless action_name == @newsletter_action
end
tag 'newsletter:if_action' do |tag|
action_name = tag.attr['name']
tag.expand if action_name == @newsletter_action
end
tag 'newsletter:subscriber' do |tag|
tag.locals.newsletter_subscriber = @newsletter_subscriber
tag.expand
end
tag 'newsletter:subscriber:name' do |tag|
tag.locals.newsletter_subscriber.name if tag.locals.newsletter_subscriber
end
tag 'newsletter:subscriber:activation_code' do |tag|
tag.locals.newsletter_subscriber.activation_code if tag.locals.newsletter_subscriber
end
tag 'newsletter:subscriber:unsubscription_code' do |tag|
tag.locals.newsletter_subscriber.unsubscription_code if tag.locals.newsletter_subscriber
end
private
def send_activation_email(newsletter_subscriber)
email = build_system_email(newsletter_subscriber, :activation)
NewsletterMailer.deliver(email)
end
def send_unsubscription_email(newsletter_subscriber)
email = build_system_email(newsletter_subscriber, :unsubscription)
NewsletterMailer.deliver(email)
end
def build_system_email(newsletter_subscriber, mail_action)
html_body = case mail_action
when :activation then render_part(:activation_email)
when :unsubscription then render_part(:unsubscription_email)
end
subject = case mail_action
when :activation then "[#{self.config["subject_prefix"]}] Activation"
when :unsubscription then "[#{self.config["subject_prefix"]}] Confirm unsubscription"
end
recipients = [newsletter_subscriber.email]
from = config["from"]
NewsletterMailer.create_newsletter(subject, html_body, recipients, from)
end
end